MIPS Assembly: Memory-Mapped I/O and Interrupt Handling CptS 260 Introduction to Computer Architecture Week 7.1 Mon 2014/07/21 Reading Assignment • [P&H14] – Appendix A.8 Input and Output – Appendix A.7 Exceptions and Interrupts – § 4.9 Exceptions Memory-Mapped I/O • Ways to interface to hardware devices: – Device driver – Special ports + protocols – Or: just re-use memory • Memory-Mapped I/O – Certain memory addresses are also I/O “buffers” – Device is hard-wired to these memory addresses (at system design time) • MIPS KEYBOARD 0xffff 000{0,4} 0xffff 000{8,c} DISPLAY .data 0xffff 0000 .data 0xffff 0004 .data 0xffff 0008 .data 0xffff 000c • Receiver control register • Receiver data register • Transmitter control register • Transmitter data register 07 06 05 04 03 02 01 00 1 _ interrupt enable r e a d y 07 06 05 04 03 02 01 00 1 _ 07 06 05 04 03 02 01 00 keyboard ASCII code interrupt enable r e a d y 07 06 05 04 03 02 01 00 ASCII code to display MIPS Memory-Mapped I/O • If enable bit(s) are 1: [P&H14] Appendix A.8 – (receiver): KEYBOARD keypress interrupt at level 1 – (transmitter): DISPLAY ready interrupt at level 0 1. Named memory location – .data word at specific 32-bit address – lw/sw directly from/to named label 2. Compose 32-bit address – ‘lui’ (load upper immediate) loads 16 bits into upper halfword – ‘li’ loads into lower halfword – Or, use ‘offset($reg)’ notation to provide lower 16 bits .data 0xffff 0000 RC: .word 0 RD: .word 0 .text lw $t0, RC andi $t0, 0x1 .text lui $t5, 0xffff ; then either li $t5, 0x0004 lw $t0, 0($t5) ; or lw $t0, 4($t5) Accessing MMIO Registers Using MMIO in a Program • At design-time, decide: Use interrupts or polling? • At program initialization: – Set interrupt enable bit(s) • On event: – Get a key – Emit a character MIPS: Exception/Interrupt Coprocessor c0 CPU $12 … $13 status … cause coprocessor c0 • [P&H14] Appendix A-7 Exception and Interrupt Handling • On all exceptions and interrupts: – MIPS “longjumps” to interrupt handler • Exception/Interrupt handler: – Special code block at .ktext 0x8000 0180 – Only one – Replace default with your own • Interrupt handler must: – Distinguish as exception or interrupt – Save all registers (even $t*, $a*, $v*!) – Enable higher-level events … – Handle event – Clear event – eret address 0x0040 0000 0x1001 0000 0x8000 0180 0xFFFF 0000 value .data .text .ktext 0x7FFF EFFC stack MM I/O I/E handler • Raised by MIPS itself, e.g. DIV0 – Mandatory – can’t be disabled – “Higher-priority” than interrupts Exceptions $12 = Status $13 = Cause On exception [P&H14] p.A-35 After handling 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 Exception Handling 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 1 Exception level • Status bit 1 (exception level) = 1 – prevents self-interruption • Cause bits 2–6 = exception code – Actually 2-5 only, since exc. codes ≤ 15 • Clear Status bit 1 (exception level) to 0 • Clear Cause register to all-0s floating-point coprocessor c0 Exception Code • Raised by hardware devices – Optional (you must enable) – Re-entrant (can be interrupted!) 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 0 0 0 0 0 Interrupt Handling: Multiple Priority Levels (1) 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 1 Interrupt enableInterrupt mask Pending Interrupts Interrupts $12 = Status $13 = Cause Initialization On interrupt After handling floating-point coprocessor c0 • Set Status bit 0 (interrupt enable) = 1 • Set Status bits 8-15 (mask) to some 1s • Status bit 0 (interrupt enable) = 0(?) • Exception code = all-0s • Cause bits 8–15 (pending): find leftmost bit • Restore original Status interrupt mask bits • Clear Cause register to all-0s • Set Status bit 0 (interrupt enable) to 1 • Raised by hardware devices – Optional (you must enable) – Re-entrant (can be interrupted!) 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 0 0 0 0 0 Interrupt Handling: Multiple Priority Levels (1) 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 1 Interrupt enableInterrupt mask Pending Interrupts Interrupts $12 = Status $13 = Cause Initialization On interrupt if handling multiple levels floating-point coprocessor c0 • Set Status bit 0 (interrupt enable) = 1 • Set Status bits 8-15 (mask) to some 1s • Status bit 0 (interrupt enable) = 0(?) • Exception code = all-0s • Cause bits 8–15 (pending): find leftmost bit • Enable Status bits 8-15 (mask) for higher bits • Set Status bit 0 (enable) to 1 • …