Lec11-pipelined-CPU-exception
한국어판 강의자료 · 28쪽

p.1exception(예외)와 interrupt(인터럽트)

p.2CPU는 '예기치 않은' 사건에 대비해야 한다
- exception(예외)적인 조건을 체계적으로 처리할 수 있는 방법이 필요함 — 비교적 드물지만, 신속하게 탐지하고 대응해야 함
- 명령어가 실패하여 완료되지 않을 수 있음
- 외부 I/O 장치가 서비스가 필요할 수 있음
- Time-Sharing(시간 공유) 시스템에서 시간 단위 만료
- 옵션 1 (폴링): 주기적으로 이벤트 발생 여부를 확인함
- 간단한 임베디드 시스템(예: 토스터)에는 적합함
- 하지만 이벤트가 발생하지 않았을 때도 많은 확인이 필요해 오버헤드가 클 수 있음
- 옵션 2 (인터럽트): 정상적으로 실행하면서 이벤트 발생 시 알림을 받음
- exception(예외)적인 조건에서 interrupt(인터럽트)가 발생함
- exception handler(예외 핸들러)로 control transfer(제어 전달)이 '투명하게' 이루어지며, 조건을 해결한 후 원래 프로그램으로 복귀함

p.3interrupt(인터럽트) control transfer(제어 전달)
- interrupt(인터럽트)는 시스템 루틴(일명 인터럽트 핸들러)으로의 '예기치 않은' 함수 호출임
- 일반적인 함수 호출과 달리, 중단된 스레드는 control transfer(제어 전달)을 미리 예측하거나 준비할 수 없음
- 제어는 나중에 중단된 명령어에서 원래 스레드로 복귀됨
- interrupt handler(인터럽트 핸들러)로의 control transfer(제어 전달)과 복귀는 중단된 스레드에게 완전히 '투명'해야 함 (즉, 시각적으로 영향을 주지 않아야 함)

p.4interrupt(인터럽트)의 종류
- synchronous interrupt(동기적 인터럽트) (일명 exception(예외))
- 특정 명령어와 관련된 exception(예외)적인 조건
- • (예: illegal opcode(불법 연산 코드), illegal operand(불법 피연산자), virtual memory management fault(가상 메모리 관리 폴트))
- faulting instruction(오류 발생 명령어)는 완료될 수 없음
- 즉시 처리되어야 함 — 처리되기 전까지 진행이 멈춤
- asynchronous interrupt(비동기적 인터럽트) (일명 interrupt(인터럽트))
- 특정 명령어와 관련되지 않은 외부 이벤트
- • (예: I/O 이벤트, 타이머 이벤트)
- 처리 시점에 어느 정도 유연성 있음 — 약간의 지연 허용 가능하나, 영원히 미루면 안 됨
- system call(시스템 호출)/trap instruction(트랩 명령어)
- exception(예외)를 발생시키는 유일한 목적의 명령어 (예: C의 printf())
- 참고: 교재에서의 exception(예외) 정의는 interrupt(인터럽트)를 포함함

p.5interrupt sources(인터럽트 소스)
- interrupt(인터럽트) 제어 논리
- interrupt(인터럽트) 요청 큐 (IRQ)
- 외부 장치에서 오는 라인 (I/O, DMA, 타이머 등)
- CPU
- • 실패한 명령어
- • system call(시스템 호출) 명령어
- exception(예외) (일명 synchronous interrupt(동기적 인터럽트))
- interrupt(인터럽트) (일명 asynchronous interrupt(비동기적 인터럽트), 또는 external interrupt(외부 인터럽트))
- 데이터 경로

p.6가상화와 보호
- 현대 운영체제는 Time-Sharing(시간 공유) 다중 처리를 지원하지만, 각 '사용자 수준' 프로세스는 여전히 자신만이 존재한다고 생각함
- 각 프로세스는 사용자 수준 architectural state(아키텍처 상태)의 개인적인 세트를 보며, 사용자 수준 명령어 집합으로 수정 가능함
- 각 프로세스는 이 추상화 외부의 상태와 장치를 직접 보거나 조작할 수 없음
- 운영체제는 중요한 기능을 구현하고 관리함
- 사용자 수준 프로세스에서 하드웨어 세부 사항을 숨김
- (예: 하드웨어 장치 핸들러, 스레드 스케줄러 등)
- 사용자 수준 프로세스 간 및 자기 자신에 대한 보호 수행
- 하드디스크를 직접 접근/관리하고 싶으신가요?
- 친구들이 하드디스크를 직접 접근하게 해도 괜찮으신가요?

p.7특권 레벨
- OS는 이러한 추상화를 생성하고 유지하기 위해 더 강력한 방식이 필요하므로, 별도의 특권 모드(또는 보호 모드, 커널 모드)가 필요하다.
- 가상화/보호/격리 제어를 위한 추가적인 architectural state(아키텍처 상태) 및 명령어
- privileged mode(특권 모드)에서 실행되는 커널 코드는 완전한 "bare hardware(베어 하드웨어)" 시스템에 접근할 수 있다.
- 다수의 OS를 가상화하기 위한 "hypervisor(하이퍼바이저)" 레벨
- OS를 위한 특권 레벨
- 사용자 레벨 상태 및 명령어
- 특권 레벨

p.8제어 및 특권 전달
- 사용자 레벨 코드는 privileged mode(특권 모드)에서 절대 실행되지 않는다.
- 프로세서는 interrupt(인터럽트) 발생 시에만 privileged mode(특권 모드)로 진입한다.
- 사용자 코드는 OS 커널의 핸들러에 제어를 양도한다.
- 핸들러는 사용자 코드로 제어를 되돌리기 전에 특권 수준을 user mode(사용자 모드)로 복원한다.
- i1
- i2
- i3
- iH1
- iH2
- iHx
- ...

p.9interrupt(인터럽트) 구현

p.10"정확한" interrupt(인터럽트)/exception(예외)
- 순차적 코드 의미론
- 중첩 실행
- precise interrupt(정확한 인터럽트)는 interrupt handler(인터럽트 핸들러)에게 두 명령어 사이에 정확히 발생한 것처럼 보인다.
- 이전 명령어는 완전히 완료되었고, 이후 명령어는 마치 실행되지 않은 것처럼 보인다.
- synchronous interrupt(동기적 인터럽트)의 경우, 정상 실행은 faulting instruction(오류 발생 명령어) 직전에 멈추고, interrupt(인터럽트) 처리 후 다시 시작된다.
- RISC-V 및 대부분의 현대 아키텍처에서 지원됨. OS 구현을 더 쉽게 만든다.
- 비정확한 exception(예외)와 비교 – 하드웨어를 단순화하지만 소프트웨어는 더 복잡해짐.
- i1
- i2
- i3
- i1:
- i2:
- i3:

p.11pipeline(파이프라인) 정지 및 재시작
- t0
- t1
- t2
- t3
- t4
- t5
- t6
- t7
- t8
- t9
- t10
- IF
- I0
- I1
- I2
- I3
- I4
- I5
- Ih
- Ih+1
- Ih+2
- Ih+3
- Ih+4
- ID
- I0
- I1
- I2
- I3
- I4
- bub
- Ih
- Ih+1
- Ih+2
- Ih+3
- EX
- I0
- I1
- I2
- I3
- bub
- bub
- Ih
- Ih+1
- Ih+2
- MEM
- I0
- I1
- I2
- bub
- bub
- bub
- Ih
- Ih+2
- WB
- I0
- I1
- I2
- bub
- bub
- bub
- Ih

p.12pipeline(파이프라인) 정지 및 재시작
- t0
- t1
- t2
- t3
- t4
- t5
- t6
- t7
- t8
- t9
- t10
- IF
- I0
- I1
- I2
- I3
- I4
- I5
- Ih
- Ih+1
- Ih+2
- Ih+3
- Ih+4
- ID
- I0
- I1
- I2
- I3
- I4
- bub
- Ih
- Ih+1
- Ih+2
- Ih+3
- EX
- I0
- I1
- I2
- I3
- bub
- bub
- Ih
- Ih+1
- Ih+2
- MEM
- I0
- I1
- I2
- bub
- bub
- bub
- Ih
- Ih+2
- WB
- I0
- I1
- I2
- bub
- bub
- bub
- Ih
- I2, I3, I4, I5가 t5에서 모두 exception(예외)를 발생시키면 어떻게 될까?
- asynchronous interrupt(비동기적 인터럽트)의 경우는 어떻게 달라질까?

p.13다양한 단계에서의 exception(예외) 발생 원인
- IF 단계
- instruction memory address/protection fault(명령어 메모리 주소/보호 폴트)
- ID 단계
- illegal opcode(불법 연산 코드)
- 구현되지 않은 명령어의 소프트웨어 에뮬레이션으로 트랩
- system call(시스템 호출) 명령어 (소프트웨어가 의도한 exception(예외) 요청)
- EX 단계
- 잘못된 결과: Divide-by-Zero(0으로 나누기), 오버플로우 (MIPS에서는 있지만 RISC-V에서는 아님), …
- MEM 단계
- data memory address protection fault(데이터 메모리 주소 보호 폴트)
- WB 단계
- 이제 어떤 명령어도 멈출 수 없음…
- asynchronous interrupt(비동기적 인터럽트) (I/O)는 원하는 명령어/단계와 연결할 수 있음

p.14RISC-V interrupt(인터럽트) 아키텍처

p.15RISC-V interrupt(인터럽트) 아키텍처
- privileged system control registers(특권 시스템 제어 레지스터) (CSRs 또는 Control and Status Registers(제어 및 상태 레지스터))
- CSRRW와 같은 특수 명령어를 통해 접근 가능
- Supervisor Status Register(슈퍼바이저 상태 레지스터) (SSTATUS): interrupt(인터럽트) 활성화/비활성화, privileged mode(특권 모드) 설정 등
- Supervisor Exception Program Counter(슈퍼바이저 예외 프로그램 카운터) (SEPC): 어떤 명령어에서 멈췄는가?
- Supervisor Exception Cause Register(슈퍼바이저 예외 원인 레지스터) (SCAUSE): 어떤 원인이 interrupt(인터럽트)를 유발했는가?
- 출처: RISC-V 명령어 세트 매뉴얼 볼륨 II: 특권 아키텍처, 문서 버전 20190608-Priv-MSU-Ratified (링크)

p.16원인 예시
- interrupt(인터럽트)
- exception(예외) 코드
- 설명
- 1
- 0
- 사용자 software interrupt(소프트웨어 인터럽트)
- 1
- 1
- Supervisor software interrupt(슈퍼바이저 소프트웨어 인터럽트)
- 1
- 4
- 사용자 timer interrupt(타이머 인터럽트)
- 1
- 5
- Supervisor timer interrupt(슈퍼바이저 타이머 인터럽트)
- 1
- 8
- 사용자 external interrupt(외부 인터럽트)
- 1
- 9
- Supervisor external interrupt(슈퍼바이저 외부 인터럽트)
- 0
- 0
- instruction address misaligned(명령어 주소 미정렬)
- 0
- 1
- instruction access fault(명령어 접근 폴트)
- 0
- 2
- illegal instruction(불법 명령어)
- 0
- 3
- breakpoint(브레이크포인트)
- 0
- 5
- load access fault(로드 접근 폴트)
- 0
- 12
- instruction page fault(명령어 페이지 폴트)
- 0
- 13
- load page fault(로드 페이지 폴트)

p.17RISC-V interrupt(인터럽트) 아키텍처 (계속)
- privileged system control registers(특권 시스템 제어 레지스터) (CSRs 또는 Control and Status Registers(제어 및 상태 레지스터))
- interrupt(인터럽트) 전달 시 CPU 하드웨어는 인터럽트 주소를 SEPC에 저장
- PC에 그대로 남겨둘 수 없음: 즉시 덮어쓰임
- 함수 호출처럼 x1을 복귀 주소로 사용할 수 없음: 사용자 값도 저장해야 함
- 일반적으로 CPU 하드웨어는 interrupt handler(인터럽트 핸들러)가 소프트웨어로 저장하고 복원할 수 없는 정보를 반드시 저장해야 함 (매우 적은 수의 경우)

p.18interrupt(인터럽트) 처리
- 원인에 따라 어떤 조치를 취할지 결정해야 함
- 옵션 1: 고정된 기본 interrupt handler(인터럽트 핸들러) 주소로 control transfer(제어 전달)
- 예: RISC-V에서 항상 STVEC 레지스터에 있는 핸들러 위치로 점프 (직접 모드)
- 이 초기 핸들러는 원인을 검사하고 적절한 핸들러 서브루틴으로 분기하여 작업 수행
- 이 주소는 사용자 레벨 프로세스로부터 보호되어 있어, 단순히 점프하거나 분기할 수 없음
- RISC-V, MIPS 등에서 사용됨

p.19interrupt(인터럽트) 처리
- 원인에 따라 취할 조치를 결정해야 한다.
- 옵션 1: 제어가 미리 정해진 기본 interrupt handler(인터럽트 핸들러) 주소로 전달된다.
- 옵션 2: vectored interrupt(벡터 인터럽트): 핸들러 주소는 원인에 따라 결정된다.
- exception vector address(예외 벡터 주소)는 vector table base register(벡터 테이블 베이스 레지스터)에 더해진다:
- • undefined opcode(정의되지 않은 연산 코드): 00 0100 0000₂
- • hardware malfunction(하드웨어 오작동): 01 1000 0000₂
- • …
- 초기 핸들러는 interrupt(인터럽트)를 처리하거나 실제 핸들러로 점프한다.
- x86, Arm, RISC-V(벡터 모드 사용 시) 등에서 사용된다.

p.20핸들러 예제
- external interrupt(외부 인터럽트)의 경우, I/O 장치를 서비스하기 위해 장치별 핸들러가 호출된다.
- exception(예외)의 경우, 커널 핸들러가 호출되어 다음 중 하나를 수행한다:
- • faulting condition(폴트 발생 조건)을 수정하고 프로그램을 계속 실행한다 (예: 누락된 FP 기능을 에뮬레이트하거나 가상 메모리 관리 상태를 업데이트).
- • 사용자 레벨 핸들러 함수가 등록되어 있으면 사용자 프로세스로 "신호"를 보낸다.
- • exception(예외)를 수정할 수 없으면 프로세스를 종료한다.
- “system call(시스템 호출)”은 사용자 프로세스에서 커널 레벨 서비스 루틴으로의 특별한 호출이다.
- • 예: OS를 통해 I/O 장치, 파일에 접근하기.

p.21interrupt(인터럽트) 복귀
- 소프트웨어는 interrupt(인터럽트) 루틴 시작 시 저장된 모든 architectural state(아키텍처 상태)를 복원한다.
- RISC-V는 특별한 점프 명령어(ERET)를 사용하여 원자적으로:
- • 자동으로 저장된 CPU 상태를 복원한다.
- • 특권 수준을 복원한다.
- • SEPC에 저장된 중단된 주소로 점프한다.

p.22매우 짧은 핸들러 예제 (MIPS)
- _handler_shortest:
- # 프롤로그 필요 없음
- # 에필로그
- mfc0 r26, epc
- # 오류 발생 PC 가져오기
- jr r26
- # 오류 발생 PC 재시도로 점프
- rfe
- # exception(예외) 모드에서 복원
- = architectural state(아키텍처 상태) 복원
- . . . 짧은 핸들러 본문 . . .
- # r26과 r27만 사용 가능
- # interrupt(인터럽트)는 매우 빠른 작업을 위해 재활성화되지 않음
- *mfc0: exception(예외) 관련 특수 레지스터를 일반 목적 레지스터로 이동하는 MIPS 명령어

p.23짧은 핸들러 예제 (MIPS)
- _handler_short:
- # 프롤로그
- addi sp, sp, -0x8
- # 스택 공간 할당 (8바이트)
- sw r8, 0x0(sp)
- # 본문에서 사용하기 위해 r8과 r9 백업
- sw r9, 0x4(sp)
- # 에필로그
- lw r8, 0x0(sp)
- # r8, r9 복원
- lw r9, 0x4(sp)
- addi sp, sp, 0x8
- # 스택 포인터 복원
- mfc0 r26, epc
- # EPC 가져오기
- j r26
- # EPC 재시도로 점프
- rfe
- # exception(예외) 모드에서 복원
- . . . 짧은 핸들러 본문 . . .
- # r26, r27 및 r8, r9 사용 가능
- # interrupt(인터럽트)는 재활성화되지 않음

p.24nesting interrupts(중첩 인터럽트)
- interrupt(인터럽트) control transfer(제어 전달) 시, 추가적인 asynchronous interrupt(비동기적 인터럽트)는 하드웨어에 의해 자동으로 비활성화된다.
- 만약 비활성화되지 않으면, 다른 interrupt(인터럽트)가 SEPC/SCAUSE/SSTATUS를 다른 인터럽트로 덮어쓸 수 있다.
- 이 취약 기간 동안 핸들러는 synchronous exception(동기적 예외)를 자체적으로 발생시키지 않도록 신중하게 작성되어야 한다.
- 그러나 긴 실행 시간을 가지는 핸들러의 경우 interrupt(인터럽트)를 재활성화해야 한다.
- interrupt(인터럽트)를 재활성화하기 전에 관련 레지스터의 내용을 메모리(스택)에 저장해야 한다.
- 재활성화 후, 다음 interrupt(인터럽트)에 의해 SEPC/SCAUSE/SSTATUS가 업데이트될 수 있다.

p.25중첩 가능한 핸들러 예제 (MIPS)
- _handler_nest:
- # 프롤로그
- addi sp, sp, -0x8
- # 스택 공간을 EPC용으로 할당
- mfc0 r26, epc
- # EPC를 가져옴
- sw r26, 0x0(sp)
- # EPC를 스택에 저장
- sw r8, 0x4(sp)
- # 나중에 사용할 레지스터를 할당
- addi r26, r0, 0x405
- # interrupt(인터럽트) 허용 비트 설정
- mtc0 r26, status
- # 상태 레지스터에 쓰기
- # 에필로그
- addi r8, r0, 0x404
- # interrupt(인터럽트) 허용 비트 해제
- mtc0 r8, status
- # 상태 레지스터에 쓰기
- ld r26, 0x0(sp)
- # 스택에서 EPC 복원
- ld r8, 0x4(sp)
- # r8 복원
- addi sp, sp, 0x8
- # 스택 포인터 복원
- j r26
- # EPC 재시도로 점프
- rfe
- # exception(예외) 모드에서 복원
- . . . interruptible
- # 필요 시 더 많은 레지스터를 해제할 수 있음
- longer handler body . . .
- # 스택에 저장할 필요가 있을 경우 더 긴 핸들러 본문

p.26interrupt priority(인터럽트 우선순위)
- asynchronous interrupt sources(비동기적 인터럽트 소스)는 우선순위로 정렬됨
- 높은 우선순위 interrupt(인터럽트)는 더 시간에 민감함
- 여러 interrupt(인터럽트)가 발생한 경우, 핸들러는 가장 높은 우선순위 인터럽트부터 처리함
- 상태 레지스터의 마스크를 설정하여 서로 다른 우선순위의 interrupt(인터럽트)를 선택적으로 비활성화할 수 있음
- interrupt(인터럽트)를 서비스하는 동안, 핸들러는 오직 더 높은 우선순위 인터럽트만 재활성화함
- 더 높은 우선순위 interrupt(인터럽트)는 지연되어서는 안 됨
- 같은 또는 낮은 우선순위 interrupt(인터럽트)를 재활성화하면, 장치가 반복적으로 인터럽트를 발생시키는 경우 무한 루프가 발생할 수 있음

p.27exception(예외)에 대한 pipeline(파이프라인) 플러시
- pipeline(파이프라인) 내에서 각 명령어와 함께 PC를 유지함
- 새로운 pipeline(파이프라인) 플러시 지점
- 0
- 0
- 0
- M
- WB
- WB
- Data
- memory
- Instruction
- memory
- ALU
- =
- ID/EX
- EX/MEM
- SCAUSE
- SEPC
- MEM/WB
- Forwarding
- unit
- PC
- Control
- EX
- M
- WB
- IF/ID
- M
- u
- x
- Hazard
- detection
- unit
- Shift
- left 1
- IF.Flush
- ID.Flush
- EX.Flush
- 4
- Imm
- Gen
- 1C090000
- Registers
- +
- +

p.28질문?
- 공지사항
- - 읽기: P&H (RISC-V ed.) Ch 4.16
- - 논문 읽기 (선택 사항): "Implementing precise interrupts in pipelined processors", Smith and Pleszkun, IEEE Trans. on Computers, vol. 37, no. 5, 1988