본문 바로가기
Pipe line과 Exception 관계 그리고 ^접미사

실컷 Exception 관련한 얘기를 했습니다. 뒷 처리 얘기도 해야겠죠. 여자친구랑 데이트 하다가 화장실에 가고 싶어지면 화장실에 갔다 와야겠죠. 화장실에 갔다 오려면 가기 전에 무슨 얘기를 하고 있었는지 기억해 두고 가면 화장실에 갔다 오더라도, 하던 얘기를 다시 계속 할 수 있지요.

그러면 여자친구는 화장실에 갔다 온 사실도 모르고 계속 얘기를 진행할 수 있지요. 바보 여자친구. 꾸웩~

Exception이 발생하면 ARM 실행모드로 전환하고, Exception Vector로 PC branch를 하게 됩니다. CPSR은 SPSR에 저장이 되고, 복귀할 때는 프로세서의 상태를 원래대로 복구하고 (CPSR), 예외가 발생한 시점의 상태에 따라 ARM 또는 Thumb 명령어를 실행시킬 수 있도록 해줘야 해요. ARM Pipe line의 동작 때문에 이상한 일이 벌어지는데요, 이를 보상하기 위해 복귀 주소 조정을 해줘야 합니다. Thumb 명령어들은 4byte가 아닌 2byte이므로, Thumb 실행 중에 예외 진입하는 경우에 실제 오프셋은 차이가 있습니다. 그에 맞추어 PC 값이 해당 Exception LR에 복사되어 4byte가 아닌 2byte으로 저장될 때도 있습니다. Exception이 발생하면 그 Exception에 대한 Handler로 들어간 다음에 처리를 하고 어떻게 다시 원래 상태로 돌아올 거냐 하는 문제에 대해서 고심해 보는 시간을 갖지요. 왜!? Exception 발생한 다음 마냥 놀 순 없잖아요.

먼저 Exception들이 Pipe Line의 어느 stage에서 발생하는지부터 짚고 넘어가고 그러면 Exception을 다 처리한 후 어떻게 돌아와야 하는지를 생각해 보면 되겠네요. 이게 뭔 소리냐 잘 보시면 앱니다. 이전에 CPU의 동작 예와 Pipe line에서 보았던 Pipe line에 대한 그림을 한 번 그려놓고요.
자자, 따라가 보시죠.

보통 PC는 현재 Execution하는 곳보다 2단계 앞으로 가리키고 있습니다. 즉 PC는 fetch를 해오는 곳으로 가리키는 것이죠. 왜 이런 얘기를 꺼내느냐… 하면, Exception났을 때 복귀 하는 방법 때문에 이야기를 꺼내는 건데요, ARM 파이프라인 동작을 보상하기 위해 복귀 주소 보정이 됩니다. Thumb 명령어들은 4byte가 아닌 2byte이니까, Thumb 실행 중에 예외 진입하는 경우에 실제 offset은 차이가 있어요. Exception 상황의 PC 값이 해당 Exception Mode의 LR에 저장 되는데, 웬만하면, ARM과 Thumb이 모두 사용 가능한 상황으로 ARM Core가 보정해주려고 한답니다.

한번 handler별로 보시죠. 여기에서 1 Cycle에 처리되는 양은 ARM mode의 경우에는 4byte,
Thumb mode의 경우에는 2byte니까 헷갈리시면 안되어요.

1. Reset Handler
는 Power On이 되면 진입하게 되는 Default Handler니까 다시 어디론가 돌아가야 하는 부담이 없고요. 처리도 없습니다. 물론 Hardware적으로 - 전원이 불안하다던가 하는 물리적인 상황이요 - Reset 신호가 흘러 들어와 Reset Exception이 나는 경우도 있는데 그건 Software적인 Exception이라기 보다는 Hardware적인 Exception이니까 Software로는 어쩔 수 없는 상황인 거죠. Reset Exception은 Pipe line의 어느 stage에서 발생하게 될까요? Hardware적인 Reset Exception은 암때나 납니다. Software의 상황을 봐주면서 내는 게 아니니까요.

2. Undefined Handler
는 Pipe line의 어느 stage에 발생할까요? 실행하려고 봤더니 모르는 Op code더라… 니까, Decode단계에서 Core가 알아채겠네요. 그러면 PC는 어디가 있을까요? 3번 시간을 예로 보시면 Core가 Decode중에는 바로 다음 번의 instruction을 Fetch하고 있지요? (Fetch가 PC의 위치에요) 그러니까 PC는 현재 Decode하는 것의 +1 instruction입니다. ARM의 경우에는 +4 (bytes)가 될 거고, Thumb의 경우에는 +2 (bytes)가 되겠네요. 그러면 ARM의 경우를 따져보면, Exception이 난 순간에는 + 4 bytes만큼 PC가 더 앞을 가리키고 있을 테고요. 그러면 어떻게 하면 될까요? 기냥~ Undefined LR에 PC를 넣어주고요. 결국 Undefined Exception이 난 순간 Undefined Exception LR에는 Exception을 처리하고 돌아가서 실행해야 할 주소가 제대로 들어 있겠죠. 그러니까, Undefined Exception이 난 경우에 Undefined Exception을 처리 하고 난 후 원래 Exception이 발생한 mode로 돌아가고 싶은 경우에는
PC := LR
CPSR := SPSR 해주면 되겠네요. 냐함~

3. Prefetch Abort Handler

우선 prefetch abort는 어느 stage에서 발생할까요? Prefetch니까 fetch죠 음훼훼. Prefecth는 존재하지 않는 Memory 주소공간에서 Fetch 해오는 경우가 제일 흔한 경우이고요, Fetch할 때 나니까, PC의 위치와 같겠죠! 그러니까 이 경우, Abort LR에는 PC가 그대로 들어간다...?? 아니죠~ 이럴 때 ARM은 아름답게도 예외 처리 후 돌아갈 때의 편의성을 도모해서 1 cycle을 더해줘요. 그래서 LR에는 Prefetch abort난 곳 + 1 cycle이 되어 있어요. 1 Cycle이라고 말하는 건 ARM mode와 Thumb의 차이가 있으니까 그렇게 표현한 거에요. 그래서 예외복귀 할 때는 두 가지 방법을 이용합니다.

첫 번째, Prefetch abort handler에서 Abort난 사항을 처리 하고 돌아가는 거면
PC : = LR
CPSR := SPSR
로 그냥 돌아가면 되고,

Prefecth abort handler에서 abort난 명령어를 다시 수행할 수 있는 환경을 만들어 줬다면
PC : = LR - 1 cycle
CPSR := SPSR
요렇게 처리한 후 돌아갑니다.
수행할 수 있는 환경이라는 건 다음에~ 알아볼 게요. - 힌트만 드리자면 MMU나 MPU에 의하여Access할 수 없던 Memory 공간을 Access 가능한 것으로 바꾼다든가 하는 역할이에요 -

4. Data Abort Handler
Data Abort가 난 경우에는 Pipe line 어느 Stage에서 발생하는 걸까요? Data Abort는 Execute 할 때 알 수 있습니다. 막상 실행을 해봐야 Data가 엉망인 넘 인지 아닌 지 알 수 있겠죠. 그러면 PC는? 2개 Cycle을 앞서가고 있겠죠. 그러니까 Abort LR에는 문제가 된 명령어 + 2 cycle이 되어 있어요. 그러면 Abort LR에는 또 ARM이 친절하게도 문제 명령어 + 1 cycle로 넣어주느냐! 그거 아니죠~ 이 경우에는 LR에 + 2 cycle된 거를 그냥~ 집어 넣습니다. 왜 ARM이 이번에는 안 친절하냐? 하면~ 그건~ 지 맘대로 입니다. 이건 IRQ에서도 마찬가지에요. 이번에도 마찬가지로 복귀하는 방법에는 두 가지가 있겠죠.
다시 실행하고 싶으면 2 cycle을 빼줘야 하고요,
PC := LR - 2 cycle
다음 걸 실행하고 싶으면 1 cycle을 빼줘야 하고요.
PC := LR - 1 cycle 이에요.
물론 CPSR := SPSR은 공통이에요.

5. SWI (Software Interrupt)

SWI는 System Programmer가 일부러 SVC mode로 전환하여 뭔가 하려고 Exception을 일으킨 거죠. SWI는 Undefined Exception이랑 똑같다고 보심 됩니다. SWI는 Decoding 할 때 발생하고요, 역시나 PC는 1 cycle 앞에 달려가고 있어요. 그러니까 Exception이 나더라도 PC를 LR에 그냥 넣어주는 거에요. Hardware적인 처리 전혀 없이 자연스럽게~ 갔다 오면 됩니다. 마찬가지로 돌아오는 방법도 Undefined Exception과 똑같이 PC := LR, CPSR := SPSR 입니다.

6. IRQ/ FIQ
IRQ/ FIQ의 경우에는 뭔가 실행하고 있다가 걸리는 거죠. PC는 항상 2개 미래를 가리키고 있어요. 잘~ 동작하고 있는데 중간에 치고 들어 오는 거죠. 물론 IRQ/ FIQ LR에도 2 cycle 앞이 들어가 있어요. 중간에 치고 들어오더라도 현재 실행하던 명령어는 다 실행하고요. 그러면 돌아올 때는 2개 cycle 에서 한 개 cycle만 빼면 바로 다음 실행할 명령어로 돌아오는 거에요.

PC := LR - 1 cycle
CPSR := SPSR

이렇게 돌아오면 됩니다? 라고 생각하면 간단할 텐데.. 한가지 주의할 점은 이 경우에도 ARM core가 장난을 친다는 점이에요. IRQ나 FIQ가 발생하면 ARM mode이건 Thumb mode이건간에 Interrupt가 걸리고 나면 바로 다음에 실행해야 하는 주소 값에서 + 4한 값을 LR에 넣어준다는 거에요. 그러니까 ARM mode이건 Thumb mode이건 -4만 해주면 다음에 실행될 곳으로 돌아가는 신기한 매커니즘이 펼쳐집니다. 한가지 더 계속 PC에다가 뭐 넣고, CPSR에다가 SPSR넣고 두 번씩 하니까 불편하지요. 이런걸 한방에 처리할 수 있는 접미사가 있는데 기억하고 계시겠지요? 그게 S접미사 입니다.

SUBS PC, LR, #4 라든가, MOVS PC, R14를 이용하게 되는데
앞에 것은 PC에다가 LR-4를 넣고 SPSR을 CPSR에 넣어라.
뒤에 것은 PC에다가 LR을 넣고 SPSR을 CPSR에 넣어라. 라는 뜻이에요 좀더 간단해 졌죠.

자자, 대충 이해 하셨겠지요. 이걸 스토리로 이해하고 있으면 좋긴 한데, 너무 복잡하죠. 그래서 Exception이 난 후에 뽕짝뽕짝을 통해서 나온 결과를 보면 아래와 같은 표로 정리할 수 있습니다.

PC_exception은 문제 발생한 지점 입니다, Exception이 발생한 곳이죠.
PC_next_op는 Exception이 발생한 당시에 바로 다음에 실행되어야 하는 주소입니다.

Return Instruction은 Exception아 난 곳으로부터 어디로 돌아갈 거냐는 처리죠. 잘 외우는 방법으로는 Decoding에 Exception난 녀석들은 1 Cycle PC ahead니까, 별로 처리할 것 없고요.Interrupt는 PC가 언제나 2 cycle앞에 있으니까 1 cycle 땡겨야 하고요. 나쁜 넘들.
Abort 중에서는 Data abort는 나쁜 넘 Prefectch Abort는 괜찮은 놈이죠. 음.. 별로 외우기 좋은 방법은 아니네요. ㅋ

가만히 보면 ARM이 ARM mode 일 때는 pipe line 그대로 LR을 잘 맞춰 넣어주죠.근데 Thumb인 경우에는 System Engineer가 편하도록 몇 가지 장난을 쳐준답니다. 와하하.

뭐 대충 간단하지요, 또! Thumb Mode에서 Exception이 났을 경우에도 분명 처리를 잘해야겠죠. 중요한 건 ARM mode이건 Thumb mode이건 Exception이 발생하면 무조건 ARM mode로 바뀌므로 Return할 때도 같은 ARM mode기준으로 돌아갈 주소가 결정 됩니다만, 몇 가지 경우에는 편의성을 위해서 Thumb mode일 때 돌아갈 주소를 Thumb mode에 맞추기도 합니다.

ARM mode인 경우에는 1 cycle이 4, Thumb Mode의 경우에는 1 cycle이 2 이니까요. 그런데 잘 보면 FIQ, IRQ, Prefetch Abort, Data Abort의 경우에는 ARM mode와 같고, SWI/ UNDEF의 경우에만 PC_exceptoin + 2로 되어 있죠. 실제로는 SWI, Undef의 경우에는 Fetch하면서 Decode 단계에서 Exception이 나는 것들이고요. 이 녀석들만 Thumb mode인 경우에 그에 맞추어 PC_exceptoin + 2 를 LR에 넣을 수 있도록 처리해 줍니다. 그렇게 하면 원래 상태로 돌아가기 쉽겠죠.

나머지 IRQ/ FIQ/ Prefetch Abort/ Data Abort 의 경우에는 ARM mode처리 그대로 구요. 그러다 보니, Thumb mode에서 Exception이 발생한 경우에 특별하게 돌아가고 싶다면 MRS 명령어를 이용해서 SPSR의 T bit field를 확인하고 이전에 Thumb mode였는지, ARM mode이었는지 확인 후에 Thumb에 맞도록 돌아갈 수 있도록 처리해 주는 게 정석이죠.

S 접미사를 이용해서 SPSR을 CPSR로 다시 backup 하는 과정을 거쳤는데요, Multiple Register Transfer 명령어를 이용해서, SPSR을 CPSR로 update할 수 있어요. ldmfd 같은 명령어를 쓸 때, 끝에다 ^ 를 붙여주면 SPSR을 CPSR로 넣어준답니다. 예를 들어,

ldmfd sp!, {r0-12, pc}^

요렇게 해주면 r0, r12, pc로 stack에 있는 값을 빼내오면서, ^을 이용해서 SPSR을 CPSR로 넣어주는 일도 한답니다. 만약에 Exception Handler에 들어와서 뭔가를 Register에 stmfd를 이용해서 backup을 했다면 이걸 이용해서 Exception Handling을 다하고 돌아갈 때 편하겠죠. 결국엔, Exception에서 return 할 때 사용될 수 있는 명령은?

* SUBS PC,LR,#4
- Privilege(특권) Mode에서 S 접미사를 사용하면 SPSR로부터 CPSR을 복원해주고,
* LDM SP!, {PC}^
- SP에 저장되어 있는 주소값을 PC에 넣을때 '^'를 붙여주면 CPSR이 SPSR로부터 동시에 복원해줍니다.

Exception 관련한 Table 보면 글씨도 많고, 헷갈릴 수 있을 것 같아서, 조금은 이해를 도울 수 있는 table 하나 붙여요. 함수 call인 BL을 포함한 PC의 상태를 늘어 놓았으니까 이해해 도움이 되길! 굴럭!

 
 
Linked at 임베디드 시스템 개발자 되기 .. at 2009/07/07 19:58

... nbsp; ⓔ Inline Assembly와 INTLOCK()구현 ⓕ Pipeline과 Exception의 관계, 그리고 ^ 접미사 ⓖ Exception Vector Table (EVT)과 각 Handler의 구현 &nbsp ... more

Linked at ssombong : 익셉션헨들.. at 2012/02/10 16:40

... ARM 디벨로퍼 책을 보다 잘 이해가 안되서 검색해보니 레시피에 잘 나와있다. http://recipes.egloos.com/5034407 먼저 인터럽트가 발생하는 시점에 대해서 알아야 한다.답은 인터럽트 마다 다르다. - Reset 헨들러 : 시스템이 동작하게 되면 자동으로 ... more

친절한 임베디드 시스템 개발자 되기 강좌 글 전체 리스트 (링크) -



댓글





친절한 임베디드 개발자 되기 강좌 글 전체 리스트 (링크) -