임베디드 레시피

Egloos | Log-in





ARM Mode와 PSR..너희들은 누구냐?

501 ARM Mode와 PSR..너희들은 누구냐?

뭘 알아야 이해를 하지

아래의 그림을 보면서 이야기 해 보죠. 아래는 하드웨어 디버거로 ARM9TDMI의 core 레지스터를 보여 주고 있답니다. 모두 32bit를 가지고 있어요. 막상 이 그림을 보면 레지스터 개수가 상당히 많이 있는 것으로 보이지만 실제로는 그렇지 않답니다. 같이 개수를 세어 보죠.   


 
ARM core는 6개의 모드로 나누어 진답니다.

USR, FIQ, SVC, IRQ, UND, ABT 모드가 있으며, SVC, IRQ, UND, ABT는 3개의 레지스터가 있답니다. FIQ는 8개가 있구요. USR는 R8~R14까지만 있는 것으로 보이겠지만 좀 더 자세히 살펴보시면 R0~R14까지 해서 15개가 있지요. 안 보이시는 분은 눈을 크게 뜨고 자세히 살펴보세요. ㅎㅎ 맞죠?? 보이죠 ㅋㅋ 그리고 마지막으로 PC, CPSR 있답니다. ② 에는 현재 6개의 모드 중에 어떤 모드가 사용 중이고, ①은 해당 모드에서 사용중인 레지스터 값을 보여 주는 거랍니다. R13, R14는 6개 모두 존재하고 있어요. 그 중에서 ②가 어떤 모드인지를 가리키게 되면, 각 모드에서 R13, R14 사용된답니다. 따라서 현재 ②에 SVC 모드라고 보여 주기 때문에 SVC 모드에 있는 R13_svc, R14_svc 레지스터 사용되었고, 레지스터의 값이 ①과 같게 보이는 거죠. 조금 헷갈릴 수도 있으니 정리 해보죠. 
  
 

 
 
이렇게 보니깐 쉽죠잉~~!! 그럼 개수를 세어 보았으니, 각 레지스터가 하는 역할에 대해 알아 보죠. 제일 먼저 PSR(Program Status Register)에 대해 살펴보죠. CPSR(Current PSR)과 SPSR(Saved PSR) 두 가지가 있답니다. CPSR은 condition flag, reserved, extension, control 구간으로 나뉘어요. 32bit로 구성된 레지스터는 각각의 역할들이 있답니다. 
  
 
 

Condition Flags

N

 연산 결과가 마이너스이면 '1'로 셋팅

Z

 연산 결과가 '0' 이면 '1'로 셋팅

C

 연산 결과가 32bit를 넘으면 '1'로 셋팅

V

 연산 결과가 32bit를 넘어 sign bit가 상실되면 '1'로 셋팅

 
N[31] 비트는 ALU 연산 결과에서 마이너스(-) 값이 나왔을 때 ALU bus로부터 PSR로 전달되어 N flag를 '1' 바뀐답니다.



 

 
실제 소스 코드와 ARM core를 비교해 보죠. cmp 명령어가 있습니다. 이 명령어는 CPSR flags := Rn - Op2 실행을 하는 명령어랍니다. 즉, 마이너스 연산 후 CPSR에 flag bit를 반영한답니다. cmp 명령어가 실행되면 ALU에서 빼기 명령을 실행하고, CPSR에 Flag 값을 반영해요. 현재 결과가 마이너스라서 "N" flag 값은 '1' 되네요.


 

R2가 0x5라면 어떻게 될까요? 연산 결과는 '0'이 라서 때문에 Z flag가 반영되고, 32bit 값을 넘겨서 C flag가 '1'로 셋팅 됐어요.



 

그럼 Overflow는 언제 발생할까요? cmp 명령어가 실행되면서 sign bit가 변경이 됐네요. sign bit가 변경이 되면 Overflow가 발생한답니다. 그리고 32bit 값을 넘겨서 C flag가 '1'로 셋팅 됐어요.

 

 

Control

 인터럽트 Enable/Disable, Thumb 모드 그리고 CPU 수행 모드를 설정한답니다. 인터럽트는 IRQ와 FIQ 인터럽트를 Enable/Disable을 설정할 수 있어요. 예를 들면, 휴대폰으로 게임을 하고 있을 때 전화가 온다면 받게 할 것인가 말 것인가를 이 두 개의 bit를 가지고 결정하죠. IRQ, FIQ가 '1'로 되어 있으면 인터럽트가 발생해도 허용 안 한답니다. RTOS에서 A 태스크가 크리티컬 섹션 진입 전에 인터럽트를 disable을 하고, 크리티컬 섹션 코드 수행이 끝나면 다시 인터럽트를 enable을 할 때 사용되죠. CPSR에 있는 control bit를 조절하는 명령어는 MRS와 MSR 있어요. 소스 코드와 레지스터 값을 비교해 보아요.



0xC0값이 CPSR에 들어가면서 control bit 값이 바뀌게 되고, I와 F bit가 변경된답니다.

다음으로 "T" 비트에 대해 알아보죠. 32bit 명령어(ARM) 동작 중에 16bit 명령어(THUMB)로 전환이 필요하거나 16bit 명령어에서 32bit 명령어로 전환이 필요한 경우 사용되는 bit랍니다. bx 명령어를 사용하며, 명령어 뒤에는 어떤 레지스터를 사용 할 것인가를 지정해요. 이 레지스터 값에 들어 있는 데이타가 홀수이면 THUMB로 전환 하면서 T bit를 '1'로 셋팅하고, 짝수이면 ARM로 전환하면서 T bit를 '0'으로 셋팅한답니다.




bx r14에는 0x1169라는 홀수의 값이 있네요. 그럼 Thumb로 state 변환하면서 T비트를 '1'로 셋팅을 합니다. 그리고 0x1169라는 주소로 점프를 하는데 실제로는 1169-(1) 주소로 간답니다.

마지막으로 MODE bit랍니다. MODE는 5bit로 구성되어 있네요. ARM core를 만들 때 5 bit의 값들을 이렇게 고정시켜 놓았답니다.
 

 

CPSR의 모드 bit 값이 0x10이면 USR, 0x11이면 FIQ, 0x12이면 IRQ, 0x13이라면 svc 모드이며, svc에 있는 ① R13, R14, SPSR 레지스터들이 동작하지요.

지금까지 CPSR를 살펴보았다면, 이제는 SPSR을 보아요. CPSR은 현재 Mode가 무엇인지 가리킨다면 SPSR는 Mode가 바뀔 때 이전모드를 기억하는 temp 와 같은 역할을 한답니다. 현재 어플리케이션이 Usr mode에서 동작하다가 인터럽트가 들어오면 Irq mdoe로 바꾸는 과정에서SPSR은 CPSR이 가지고 있던 usr mode를 백업①하고, CPSR은 usr에서 Irq로 바꾼②답니다. 그리고 Irq mode에서 인터럽트를 처리를 끝낸 후 다시 Usr mode로 복원하기 위해 CPSR은 SPSR에 있는 usr mode를 복원③해서 다시 어플리케이션을 실행하게 한답니다.


이제 ARM11의 CPSR에 대해 알아보죠. ARM9에 비해 좀 더 추가가 됐다는 것을 알 수가 있어요.


새롭게 추가가 된 bit는 Q[27], GE[19:16], E[9], A[8] 랍니다.



여기서 ③에 대해 먼저 잠시 알아보죠. ARM1176 프로세서 시리즈에 있는 이 기능은 TrustZone아라고 하고, OpenOS에서 동작하는 시스템에서 보안 기능을 강화시키는 목적으로 chip에서 보안 기능을 보장해준답니다. 보안 요소들이 Core에서 구현되어 있어서 모든 핵심 기술의 고유 기능을 보안하고 유지시킬 수가 있게 해 주죠. 이 기술을 적용하면 중요한 데이타와 DRM에 대한 보안을 제공해 준답니다. TrustZone은 두 개의 격리된 영역인 Secure area와 Non-secure area 가 있어요.


 

ARM core에서는 MON mode가 동작한답니다. 그럼 Secure 모드를 진입하려면 어떻게 하는지 알아보죠. 우선 Co-processor 15번인 SCR 레지스터에 NS bit값이 '0' 이면 secure area로 된답니다.




Co-processor 명령어를 이용하여 SCR 레지스터 값을 직접 변경 가능하답니다.

 MCR p15, 0, Rd, c1, c0, 0

 

Q[27] Flag

  연산결과가 '+'의 최대값(0x7FFFFFFF)과 '-'의 최소값(0x80000000)이 넘지 않게 하기 위해서 사용되고, 주로 분수 연산을 위해 새로운 명령어가 만들어졌답니다.

 QADD

 Add and Saturating

 QSUB

 Subtract and Saturating

 QDADD

 Add and Double Saturating

 QDSUB

 Subtract and Double Saturating

이러한 명령어가 사용되면 Q flag 값이 '1'로 된답니다. 일반적인 산술 연산의 예를 들어보죠.

 덧셈

 뺄셈

  mov r0, #0x7FFFFFFF
  mov r1, #0x1
  add r3, r0, r1
  mov r0, #0x80000000
  mov r1, #1
  sub r3, r0, r1

  r3 = 0x80000000, -1 

  (+ 최대값 넘어감)

  r3 = 0x7FFFFFFF, +1

  (-최소값 넘어감)

r3의 값이 r0의 값으로 그대로 유지하면서 연산을 하려면 QDADD와 같은 명령어를 사용하고
0x7FFFFFFF +1은 0x7FFFFFFF 유지하고, Q bit가 '1'로 된답니다.
0x80000000-1은 0x80000000 유지하고, Q bit가 '1'로 된답니다.

GE[19:16] bit

 CPSR의 [19:16] bit가 ② 그림의 GE 비트를 나타내죠. GE[3], GE[2], GE[1], GE[0]번까지 해서 총 4개가 있답니다. 하나의 명령어로 여러 개의 데이타를 동일한 연산 수행을 할 수 있는 명령어가 추가가 됐답니다. SADD, SSUB, QADD, QSUB, SHADD, SHSUB, SXT, SXTA, SSAT, SEL, PKH 명령어들이고, 일반적으로 SIMD(Single Instruction Multiple Data) instructions 이라고 부른답니다. 이 명령어는 다시 16bit냐 8bit냐에 따라 달라지며 또한 Signed과 Unsigned로 구분된답니다.

 Signed

 Unsigned

 SADD16
 SSUB16
 SADD8
 SSUB8
 UADD16
 USUB16
 UADD8
 USUB8

연산결과 R0 값을 16 bit씩 나누어 각각 (+ ) or (-) 이냐에 따라 GE bit가 '1'로 된답니다. [31:16] 까지는 GE2,3번 반영되며, [15:0]까지는 GE0,1번에 반영되죠.

 

E[9] bit

메모리에 있는 데이타를 읽어올 때, Big과 Little endian 두 가지 방식을 모두 지원해 준답니다. 개발자는 직접 endian을 바꿔가면서 프로그램을 할 수 있도록 해 주는데, SETEND 명령어 사용한답니다. 아래 그림의 ①은 Little endian으로 읽어 왔을 때 R0 값이고, ②는 Big endian으로 읽어 왔을 때 R0 값이며, ③와 같이 E bit가 '1'로 된답니다.

A[8] bit Imprecise Data Abort mask bit라고 불린답니다. A bit가 '1'이면 imprecise Data Abort는 Data Abort를 발생시키지 않고, '0'이면 발생시킨답니다.

 

크리티컬 섹션 - "401” 인터럽트 - "206” ARM명령어 - "500"

 

by 히언 | 2012/01/04 12:26 | SOTO Story | 트랙백 | 핑백(1)

Linked at 친절한 임베디드 시스템 개발자.. at 2012/01/04 13:08

... ARM Mode와 PSR..너희들은 누구냐? ... more

◀ 이전 페이지          다음 페이지 ▶