View
Interrupt는 CPU와 Peripheral Devices 사이의 소통이다.
Interrupt: IO Device가 generate 하는 것 둘은 미세한 차이가 등장한다.
Exception: CPU가 Internally generates 하는 것 둘 다 CPU에서 신호에 대해 처리한다는 공통점이 있다.
Interrupt
Asynchronous Signal ( HW ), Synchronous Event ( SW : System Call - SVC ( SuperViser Call ) Instruction 을 제공 )
ex) OS의 Scheduling은 time interrupt를 이용한다.
IRQ : Normal Interrupt Request
PC가 0x08로 이동 → Branch로 이동하여 원하는 Instruction을 실행
FIQ : Fast Interrupt Request
PC가 0x1C로 이동 → Branch로 이동하여 원하는 Instruction을 실행
Interrupt Vector Table, Exception Vector Table : Branch Instruction을 통해 어디로 이동할 지 작성해놓은 표
ex) IRQ → 0x08로 이동 ( IRQ가 0x08로 예약되어있음 ) → IRQ를 처리하는 영역으로 이동 ( Branch Instruction )
이 Vector Table도 VBAR - Vector Base Address Register 에서 수정 가능하다. ( Customizing 이 가능 )
Interrupt를 처리하기 위해 Interrupt를 위한 Branch Instruction을 수행한 후, 범용 레지스터에 있는 값들을 저장시킬 필요가 있다. - Push
그러나, FIQ같은 경우에는 물리적으로 분리된 Register를 사용한다. 따라서, 데이터를 push, pop할 필요가 없다.
'FAST' Interrupt Request인 이유가 바로 여기 있다. ( Memory Access에 많은 시간이 걸리기 때문 )
Privilege Level ( 우선순위 레벨 ) 이 존재하는데, High Level일 때는 Low Level의 Register에 접근 가능하지만 그 반대는 불가능하다.
Interrupt가 발생하면, 다음의 일련의 과정을 HardWare가 알아서 처리해준다.
CPSR Mode bit을 User모드에서 해당 모드로 바꾸기
CPSR의 I,F bit을 Set하기 : 해당 Interrupt를 수행하는 동안 IRQ / FIQ를 받지 않겠다면 1로 Set한다. SW적으로 clear 가능하다.
CPSR Value를 SPSR로 저장 ( CPSR 값을 Push 하는 것과 같은 효과 )
PC를 Vector Address로 보내고, LR값을 현재 Address로 저장한다.
이후에 필요한 작업들은 SW적으로 사용자가 해결해야한다.
SW로 처리해줄 작업
Register들을 Memory Stack에 Push하기
Interrupt Service Routine 수행하기 ( ISR )
Memory Stack 에서 data들 Pop해서 Register 원상복구하기
Interrupt를 끝내고 돌아가는 과정에서 MOVS PC, LR을 수행하게 되는데, Rd ( destination register ) 가 PC일 때 -s를 붙이면 Compiler는 내부적으로 SPSR에 저장된 값을 CPSR로 불러오는 작업을 수행하게 된다.
- MOV PC, LR : Return from Function Call
- MOVS PC, LR : Return from Interrupt / Exception 둘의 역할이 다르므로 주의할 필요가 있다!!
Interrupt 또는 Exception에서 돌아올 때, LR 값에 0, 4 또는 8의 값을 빼주는 작업이 필요하다.
- Interrupt / Exception에 따라 파이프라인에서 불러오거나 저장된 값이 달라지기 때문 ⇒ LR값 보정이 필요하다.
LR값 보정은 Adjustment를 확인해보자 ( 값이 달라지므로 추측 x )
PipeLine에서 PC가 instruction을 수행하는 동안, CPU는 두차례 뒤의 instruction을 LR에 Fetch하고 있다. ( PC + 8을 Fetch )
따라서, 원하는 Memory Address ( PC + 4 )를 LR에 가져오기 위해서는, ( LR - 4 ) 를 가져오면 된다.
⇒ SUBS PC, LR, #4 을 통해 PC에 ( LR - 4 ) 의 값을 전달 + SPSR 값 불러오기가 가능하다.
Nested Interrupt가 발생할 수 있다. → SPSR, LR 값을 한 번 더 Stack 에 Push 해주어야 하는 경우도 존재
MRS R0, CPSR : CPSR 값을 Register에 저장하는 Instruction
MSR CPSR, R0 : Register에 저장된 값을 CPSR에 저장하는 Instruction
[ MRS R0, SPSR → PUSH [R0] ] 의 명령어를 통해 SPSR값을 Push할 수 있다.
또는, [ SRSFD sp!, #0x12 ] 같은 Instruction도 있다. ( SRS : Save Return Status, FD : Full Descending - 메모리저장처럼 )
⇒ IRQ mode ( #0x12 ) 의 Stack Pointer가 가리키는 Memory에 SPSR과 LR을 Full Descending으로 저장하겠다.
반대로, RFE ( Return From Exception ) 명령어를 통해 SRS와 같은 방식으로 SPSR, LR값을 Load할 수도 있다.
SVC : SuperViser Call : SW Interrupt를 발생시킨다.
SVC #0xXX ⇒ XX번 Interrupt를 수행 이 경우, SuperViser Mode로 들어간다.
CPS : Change Processor State : Mode Switch에 사용된다.
CPS #0xXX ⇒ XX에 해당하는 mode로 Switch한다.
BIOS → IO Device의 Device Information을 check하는 역할 ( Graphic Card / Network card 등등이 있는가? 사용 방법은? )
→ Init Register ( 8개의 Stack Pointer를 reset - 적당한 위치를 배정해준다. )
// 이 시리즈의 글들은 고려대학교의 Computer System Design 과목 ( COSE321 ) 을 수강하며 제가 공부한 내용입니다.
// 노트필기를 바탕으로 정리하여 올리고 있으므로, 부정확한 정보가 있을 수도 있습니다.
// 추후에 종강을 하면 워터마크를 삽입한 최종노트 PDF를 첨부할 계획입니다.
'학부생 CS > 컴퓨터 시스템 설계' 카테고리의 다른 글
Computer System Deisgn - 10 : Cache Memory (0) | 2019.05.28 |
---|---|
Computer System Design - 9 : IO Interrupt (0) | 2019.05.21 |
Computer System Design - 7 : Thumb, Thumb2 (3) | 2019.05.20 |
Computer System Design - 6 : Timer (0) | 2019.05.20 |
Computer System Design - 5 : Handling IO Device in Software (0) | 2019.05.20 |