View on GitHub

Computer Architecture and Operating Systems

Course taught at Faculty of Computer Science of Higher School of Economics

Lecture 11

Exceptions and Interrupts.

Lecture

Slides (PDF, PPTX).

Outline

Examples:

Workshop

Outline

Exceptions and Interrupts

Exception is an an unscheduled event that disrupts program execution. Interrupt is an exception that comes from outside of the processor. (Some architectures use the term interrupt for all exceptions.) Exceptions require dealing with special system instructions and registers.

Control and Status Registers (CSRs)

The Control and Status Registers (CSRs) are system registers provided by RISC-V to control monitor system states. CSR’s can be read, written and bits can be set/cleared. Each CSR has a special name and is assigned a unique function. In this course, we focus on the user privilege level. We will use user-level CSRs to handle user-level exceptions.

User-level CSRs:

Number Priviledge Name Description
User Trap Setup      
0x000 URW ustatus User status register.
0x004 URW uie User interrupt-enable register.
0x005 URW utvec User trap handler base address.
User Trap Handling      
0x040 URW uscratch Scratch register for user trap handlers.
0x041 URW uepc User exception program counter.
0x042 URW ucause User trap cause.
0x043 URW utval User bad address or instruction.
0x044 URW uip User interrupt pending.
User Floating-Point CSRs      
0x001 URW fflags Floating-Point Accrued Exceptions.
0x002 URW frm Floating-Point Dynamic Rounding Mode.
0x003 URW fcsr Floating-Point Control and Status Register.
User Counter/Timers      
0xC00 URO cycle Cycle counter for RDCYCLE instruction.
0xC01 URO time Timer for RDTIME instruction.
0xC02 URO instret Instructions-retired counter for RDINSTRET instruction.
0xC80 URO cycleh Upper 32 bits of cycle, RV32 only.
0xC81 URO timeh Upper 32 bits of time, RV32 only.
0xC82 URO instreth Upper 32 bits of instret, RV32 only.

System Instructions

CSR Instructions:

csrrc t0, fcsr, t1 Read/Clear CSR: read from the CSR into t0 and clear bits of the CSR according to t1
csrrci t0, fcsr, 10 Read/Clear CSR Immediate: read from the CSR into t0 and clear bits of the CSR according to a constant
csrrs t0, fcsr, t1 Read/Set CSR: read from the CSR into t0 and logical or t1 into the CSR
csrrsi t0, fcsr, 10 Read/Set CSR Immediate: read from the CSR into t0 and logical or a constant into the CSR
csrrw t0, fcsr, t1 Read/Write CSR: read from the CSR into t0 and write t1 into the CSR
csrrwi t0, fcsr, 10 Read/Write CSR Immediate: read from the CSR into t0 and write a constant into the CSR

CSR Pseudo Instructions:

csrc t1, fcsr Clear bits in control and status register
csrci fcsr, 100 Clear bits in control and status register
csrr t1, fcsr Read control and status register
csrs t1, fcsr Set bits in control and status register
csrsi fcsr, 100 Set bits in control and status register
csrw t1, fcsr Write control and status register
csrwi fcsr, 100 Write control and status register

System Instructions:

ebreak Pause execution (at a breakpoint)
ecall Issue a system call : Execute the system call specified by value in a7
uret Return from handling an interrupt or exception (to uepc)
wfi Wait for interrupt

Exceptions

When an exception occurs the PC is written to the uepc register and the exception cause code is written to the ucause.

Exceptions Supported in RARS:

Exception Handling

When an exception occurs the following actions are performed:

In order to have a working exception handler, the program must:

The simplest user-level exception handler that just returns control to the next (PC+4) instruction:

handler:
     # Just ignore it by moving uepc to the next instruction
     csrrw t0, uepc, zero
     addi  t0, t0, 4
     csrrw zero, uepc, t0
     uret

The user-level handler can be registered in the following way:

     la     t0, handler      # load handler address to t0
     csrrw  zero, utvec, t0  # set utvec to the handlers address
     csrrsi zero, ustatus, 1 # set interrupt enable bit in ustatus

Interrupts are exceptions that come from external devices such as I/O devices. These events can be handled. To do this, an interrupt must be enabled in the device and a corresponding bit must be set in uie. See the examples to learn how this works.

Tasks

  1. Study the theory and examples on the current workshop.

  2. Implement an exception handler that prints a message that explains the reason of an exception (the list of exceptions with descriptions is above).

  3. Image how the try-catch construct is implemented in high-level languages. Then write a program that implements a simple function with an exception handler. The function takes an argument that specifies what exception it will raise (0 - no exception, 1 - some exception from list above, 2 - some other exception from the list). The function must return exception cause or 0 if no exception has occurred. The program prints the exception cause.

Homework

Study the theory and the examples and finish the tasks.

  1. Write a program that waits for timer interrupts and counts them. Input data: m is the limit on number of interrupts to process, t is the interval between interrupts in milliseconds. The program exits when the number of handler interrupts reaches the limit.

    Hint: Use the “Tools | Timer Tool” RARS extension. See its help. The MMIO address to get the current time 0xFFFF0018; the MMIO address the set the time for the next interrupt is 0xFFFF0020. To set up the cycle of processing interrupts, the following must be done:

    • The address of your interrupt handler must be stored in the utvec CSR.
    • The fourth bit of the uie CSR must be set to 1 (i.e. ori uie, uie, 0x10).
    • The zeroth bit of the ustatus CSR must be set to 1 (i.e. ori ustatus, ustatus, 0x1).
    • The time for the next interrupt must be written to 0xFFFF0020.
    • When an interrupt is handled the time for the next interrupt must be updated.
  2. Bonus task (2 bonus points):

    How would you simulate multitasking using interrupts and timer? Write a program that contains two for-loops running in a semi-parallel mode. The first prints messages Thread1: 0..Thread1: N and the second prints messages Thread2: 0..Thread2: N. The program must use timer to switch between the threads.

    Hint: Each thread stores in memory (.data section) its PC and values of register it uses. When a timer interrupt occurs, the handler saves current register values, loads the new register values, and return control to the PC of the next thread.

Commit the programs to your private GitHub account. Place them into the folder ca/lab10.

References