Interrupts in ProtectedMode Writing a protectedmode interrupt service

  • Slides: 18
Download presentation
Interrupts in Protected-Mode Writing a protected-mode interrupt -service routine for the timer-tick interrupt

Interrupts in Protected-Mode Writing a protected-mode interrupt -service routine for the timer-tick interrupt

Rationale • Usefulness of a general-purpose computer is dependent on its ability to interact

Rationale • Usefulness of a general-purpose computer is dependent on its ability to interact with various peripheral devices attached to it (e. g. , keyboard, display, disk-drives, etc. ) • Devices require a prompt response from the cpu when various events occur, even when the cpu is busy running a program • The x 86 interrupt-mechanism provides this

New requirements • Unlike real-mode, where all code executes with full privileges (i. e.

New requirements • Unlike real-mode, where all code executes with full privileges (i. e. , ring 0), protectedmode code usually is executed with some privilege restrictions • Normally these restrictions prevent direct control of the peripheral devices • Thus, when responding to an interrupt in protected-mode, a ring-transition (and its accompanying stack-switch) are needed

Interrupt-Gate Descriptors start-offset[ 31. . 16 ] code-segment selector D P P 0 L

Interrupt-Gate Descriptors start-offset[ 31. . 16 ] code-segment selector D P P 0 L gate type start-offset[ 15. . 0 ] Legend: P=present (1=yes, 0=no) DPL=Descriptor Privilege-Level (0, 1, 2, 3) code-selector (specifies memory-segment containing procedure code) start-offset (specifies the procedure’s entry-point within its code-segment) gate-types: 0 x 6 = 16 bit Interrupt-Gate, 0 x 7 = 16 -bit Trap-Gate 0 x. E = 32 bit Interrupt-Gate, 0 x. F = 32 -bit Trap-Gate

Trap-Gate vs. Interrupt-Gate • The only distinction between a Trap-Gate and an Interrupt-Gate is

Trap-Gate vs. Interrupt-Gate • The only distinction between a Trap-Gate and an Interrupt-Gate is in whether or not the CPU will automatically clear the IF-bit (Interrupt-Flag in EFLAGS register) as part of its response to an interrupt-request • This is needed in cases where an Interrupt Service Routine executes outside ring 0, so could not execute ‘cli’ or ‘sti’ instructions

16 bit-Gate vs. 32 bit-Gate • The CPU constructs different stackframes for the 16

16 bit-Gate vs. 32 bit-Gate • The CPU constructs different stackframes for the 16 -bit versus the 32 -bit gate-types 16 -bits 32 -bits ring 0 stack SS SS SP ESP FLAGS EFLAGS CS SS: SP IP CS SS: ESP = always pushed EIP = pushed if privilege-level changed

Return-from-Interrupt • The programmer who writes an Interrupt Service Routine must know whether the

Return-from-Interrupt • The programmer who writes an Interrupt Service Routine must know whether the Gate was 16 -bit or 32 -bit, in order to use the correct ‘interrupt-return’ instruction • In a code-segment whose default-bit is 0 (i. e. , USE 16), the ‘iret’ instruction performs the correct return-actions for a 16 -bit Gate • Use ‘iretl’ for returning with a 32 -bit Gate

Interrupt Descriptor Table • The Gate-Descriptors for device interrupts form an array (called the

Interrupt Descriptor Table • The Gate-Descriptors for device interrupts form an array (called the IDT) and reside in a special system memory-segment • The CPU will locate the IDT by referring to the value in its IDTR register (48 -bits) • A pair of special instructions exists which allow reading and writing this register: sidt mem lidt mem ; store IDTR into a memory-operand ; load IDTR from a memory-operand

Format of register IDTR 47 16 15 0 base_address[ 31. . 0 ] segment-limit[

Format of register IDTR 47 16 15 0 base_address[ 31. . 0 ] segment-limit[ 15. . 0 ] 32 -bits 16 -bits The instruction ‘lidt’ is privileged (can only be executed in ring 0), but the instruction ‘sidt’ is unprivileged (it can execute in any ring) These features are analogous to the instructions ‘sgdt’ and ‘lgdt’ used to store or to load GDTR (Global Descriptor Table Register)

Register relationships code-segment Interrupt Descriptor Table (256 entries) ISR Interrupt-gate Global Descriptor Table code-descriptor

Register relationships code-segment Interrupt Descriptor Table (256 entries) ISR Interrupt-gate Global Descriptor Table code-descriptor INT ID GDTR IDTR

Two Interrupt-Controllers x 86 CPU Slave PIC Keyboard controller Master PIC INTR Programmable Interval-Timer

Two Interrupt-Controllers x 86 CPU Slave PIC Keyboard controller Master PIC INTR Programmable Interval-Timer

Each PIC has a Mask Register Master PIC Interrupt-mask (I/O-port 0 x 21) IRQ

Each PIC has a Mask Register Master PIC Interrupt-mask (I/O-port 0 x 21) IRQ IRQ 7 6 5 4 3 2 1 0 Slave PIC IRQ IRQ Interrupt-mask 15 14 13 12 11 10 9 8 (I/O-port 0 x. A 1) If a mask-bit is 1, the corresponding device-interrupts are masked; If a mask-bit is 0, the corresponding device-interrupts are unmasked

Demo-program: ‘pmtimer. s’ • Let’s create a ‘protected-mode’ program that will handle the timer-tick

Demo-program: ‘pmtimer. s’ • Let’s create a ‘protected-mode’ program that will handle the timer-tick interrupts • Its ISR (Interrupt Service Routine) is very similar to the real-mode interrupt-handler • It increments a 32 -bit counter (at 40: 6 C), and it sets a flag (at 40: 70) at midnight • It decrements an 8 -bit counter (at 40: 40), and turns off diskette motors when zero • It sends EOI-notification to Master PIC

Two ‘threads’ in our demo ROM-BIOS DATA (threads share access) ‘main’ program-thread Build descriptor-tables

Two ‘threads’ in our demo ROM-BIOS DATA (threads share access) ‘main’ program-thread Build descriptor-tables Enter protected-mode (most interrupts masked) Do for ten seconds: { Read tick_count Show tick_count } Leave protected-mode (most interrupts unmasked) Exit to our ‘loader’ tick_count motor_status midnight_flag motor_count Interrupt Service Routine Increment tick_count (maybe set midnight_flag) read write Decrement motor_count (maybe set motor_status) Issue EOI command

Defining INT-8 Gate-Descriptor 0 x 0000 0 x 8600 sel_CS isr. PIT 16 -bit

Defining INT-8 Gate-Descriptor 0 x 0000 0 x 8600 sel_CS isr. PIT 16 -bit Interrupt-Gate selector for ring 0 code-segment Our label for the interrupt-handler’s entry-point P=1 DPL=0 S=0 type=6

Key Steps in the Demo • • Initialize the Descriptor-Table(s) Enter Protected-Mode with IF=0

Key Steps in the Demo • • Initialize the Descriptor-Table(s) Enter Protected-Mode with IF=0 Load GDTR, IDTR and segment-selectors Mask all device-interrupts except timer Set IF=1 to enable unmasked interrupts Continuously show tick-count (for 10 secs) Reset IF=0 to disable interrupts (for exit)

In-class exercise #1 • Try modifying the ‘pmtimer. s’ program so that it uses

In-class exercise #1 • Try modifying the ‘pmtimer. s’ program so that it uses a 32 -bit Interrupt-Gate for the timer interrupt (gate-type 0 x. E) instead of the 16 -bit Interrupt-Gate (gate-type 0 x 6) • NOTE: You will need to adjust the ‘iret’ opcode in your Interrupt Service Routine to accommodate the resulting changes in the layout of your ISR’s stackframe.

In-class Exercise #2 • Apply your knowledge of privilege-rings to modify this demo so

In-class Exercise #2 • Apply your knowledge of privilege-rings to modify this demo so that its main routine (i. e. , ‘exec_timer_tick_demo’) executes at privilege-level 3 (instead of at ring 0) • You will need to add more descriptors to the Global Descriptor Table (for code and stack at ring 3), and also a Call-Gate when returning to ring 0 from ring 3 (for quitting)