임베디드/임베디드 레시피

Pipe line과 Exception 관계 그리고 ^접미사

twoweeks-within 2024. 11. 21. 17:48

Exception 발생 > ARM 실행모드로 전환, Exception Vector로 PC branch. 
  CPSR을 SPSR에 저장 > 복귀: CPSR 
 시점에 따라 ARM 또는 Thumb 명령어를 실행시킬 수 있도록 해줘야함
 ARM Pipe line의 동작 > 보상 : 복귀 주소 조정

 Thumb 실행 중 예외 진입 > 실제 오프셋의 차이
      PC 값: 해당 Exception LR에 복사 > 2byte로 저장.  (Thumb 명령어들 : 2byte)

 

pipe line

Exception 발생 >  Handler로 처리후 어떻게 복귀?

보통 PC : fetch 에 위치 > 현재 Execute 보다  2단계 앞, fetch 보다 1단계 앞
   ARM 파이프라인 동작을 보상 > 복귀 주소 보정

Thumb 실행 중에 예외 진입하는 경우에 실제 offset의 차이
    > 웬만하면, ARM과 Thumb이 모두 사용 가능한 상황으로 ARM Core가 보정해주려고함

 handler (1 Cycle에 처리되는 양 :  ARM mode :4byte, Thumb mode :2byte )
1. Reset Handler : Power On이 되면 진입,  Default Handler ( 돌아가야하는 부담, 처리 x)
      Hardware적인 Reset Exception은 언제나 날 수 있음 :  Software의 상황을 봐주면서 내는건 아님.

2. Undefined Handler ( 모르는 Op code 발견 할때 ) : Decode단계에서 Core가 알아챔 
    PC : 현재 Decode하는 것의 +1 instruction.  ( ARM: +4 bytes, Thumb: +2 bytes )
 ARM : Exception이 난 순간 + 4 bytes만큼 PC가 앞을 가르킴
    > Undefined LR에 PC를 넣음.
       LR : Exception 처리후 돌아갈 주소
PC := LR
CPSR := SPSR 

3. Prefetch Abort Handler : fetch 단계
Prefecth : 존재하지 않는 Memory 주소공간에서 Fetch 해오는 경우 >  PC의 위치와 같음
 >  Abort LR : PC 그대로 ? X
 > ARM은 예외 처리 후 돌아갈 때의 편의성을 도모해서 1 cycle을 더해줌
         >  LR : Prefetch abort난 곳 + 1 cycle 

첫번째, Prefetch abort handler에서 Abort난 사항을 처리 하고 돌아갈때
          ( abort 처리 후로 갈때)
PC : = LR
CPSR := SPSR


두번째, Prefecth abort handler에서 abort난 명령어를 다시 수행할 수 있는 환경을 만들어 줬다면 
          ( 즉, abort 났던 곳 으로 갈때)
PC : = LR - 1 cycle
CPSR := SPSR

* 수행한다 : MMU나 MPU에 의하여Access할 수 없던 Memory 공간을 Access 가능한 것으로 바꿈

4. Data Abort Handler : Execute 할 때 (실행을 해봐야 Data 가 엉망인것인지 알 수 있으니
    PC:  2개 Cycle을 앞섬
      > Abort LR : 문제가 된 명령어 + 2 cycle  
(1). 다시 원래것 실행
PC := LR - 2 cycle
(2) 해결 후 다음 걸 실행
PC := LR - 1 cycle 이에요.
물론 CPSR := SPSR은 공통

5. SWI (Software Interrupt) : Decoding 할 때 발생 ==  Undefined Exceptio
  :System Programmer가 SVC mode로 전환하여 뭔가 하려고 Exception을 일으킨것.
 PC: +1 cycle  
 PC := LR,
 CPSR := SPSR 입니다.

6. IRQ/ FIQ : 실행중 뭔가 걸리는것 (execute)  
  PC: +2 cycle 
 IRQ/ FIQ LR : +2 cycle  >  2개 cycle - 1cycle만 바로 다음 실행할 명령어로 돌아옴

PC := LR - 1 cycle 
CPSR := SPSR

@주의@  ARM core의 장난질
  IRQ/ FIQ > ARM ,Thumb : Interrupt가 걸리고 나면 바로 다음에 실행해야 하는 주소 값에서 + 4한 값을 LR에 넣어줌
                ARM, Thumb 둘다 -4만 해주면 다음에 실행될 곳으로 돌아감.

S 접미사
계속 PC에다가 뭐 넣고, CPSR에다가 SPSR넣고 두 번씩 하니까 불편 > 한방에 처리

SUBS PC, LR, #4 , MOVS PC, R14 이용
앞에 것은 PC에다가 LR-4를 넣고 +  SPSR을 CPSR에 넣어라.
뒤에 것은 PC에다가 R14을 넣고 + SPSR을 CPSR에 넣어라.

 

Exception 후의 결과


PC_exception: 문제 발생 지점 > Exception이 발생한 곳.
PC_next_op:  Exception >다음에 실행되어야 하는 주소

 

Return Instruction:  Exception난 곳으로부터 어디로 돌아갈 거냐는 처리

 ARM이 ARM mode : pipe line 그대로 LR을 잘 맞춰 넣어줌
           Thumb : System Engineer가 편하도록 몇 가지 장난을 쳐줌.

ARM,Thumb:  Exception 발생 > 무조건 ARM mode로 바뀜 > Return할 때도 같은 ARM mode기준으로 돌아갈 주소가 결정
몇 가지 경우, 편의성을 위해 Thumb mode일 때 돌아갈 주소를 Thumb mode에 맞추기도 함.

FIQ, IRQ, Prefetch Abort, Data Abort : ARM mode와 같음,
  Thumb mode에서 Exception이 발생한 경우:    MRS 명령어 > SPSR의 T bit field를 확인
       > 이전에 Thumb mode였는지, ARM mode이었는지 확인> Thumb에 맞도록 돌아갈 수 있도록 처리

SWI/ UNDEF의 경우에만 PC_exceptoin + 2
           > 그에 맞추어 PC_exceptoin + 2 를 LR에 넣을 수 있도록 처리.



S 접미사: SPSR을 CPSR로 다시 backup 하는 과정 
Multiple Register Transfer 명령어 : SPSR을 CPSR로 update
  > ldmfd 같은 명령어를 쓸 때, 끝에다 ^ 를 붙여주면 SPSR을 CPSR로 넣어줌

ldmfd sp!, {r0-12, pc}^
// Load Multiple Full Descending 스택에서 값을 읽어오고 , 읽은 만큼 스택 포인터를 증가
   // 스택은 아래로 갈수록 r13, r12, r11,,,, 로 가면서
   // 주소는 sp+0, sp+4, sp+4,,, sp 가 증가
// r0-r12 : r0 ~ r12 까지 13개
 >  r0, r12, pc로 stack에 있는 값을 빼내오면서, ^을 이용해서 SPSR을 CPSR로 넣어주는 일도 함 

if) 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로부터 동시에 복원 ( PC값 (레지스터 값) 복구 + spsr 값 복원)

 

'임베디드 > 임베디드 레시피' 카테고리의 다른 글

Reset Handler에서 main까지 (Entry Point)  (0) 2024.12.01
Coprocessor Assembly  (0) 2024.11.27
SWI 의 진실  (0) 2024.11.26
vector table의 구현과 실제  (0) 2024.11.26
Inline Assembly와 INTLOCK의 구현  (0) 2024.11.20