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

Interrupts in Protected-Mode

Embed Size (px)

DESCRIPTION

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 with various peripheral devices attached to it (e.g., keyboard, display, disk-drives, etc.) - PowerPoint PPT Presentation

Citation preview

Page 1: Interrupts in Protected-Mode

Interrupts in Protected-Mode

Writing a protected-mode interrupt-service routine for the

timer-tick interrupt

Page 2: Interrupts in Protected-Mode

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 x86 interrupt-mechanism provides this

Page 3: Interrupts in Protected-Mode

New requirements

• Unlike real-mode, where all code executes with full privileges (i.e., ring 0), protected-mode 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

Page 4: Interrupts in Protected-Mode

Interrupt-Gate Descriptors

start-offset[ 31..16 ]

code-segment selector start-offset[ 15..0 ]

gatetype

P 0DPL

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: 0x6 = 16bit Interrupt-Gate, 0x7 = 16-bit Trap-Gate

0xE = 32bit Interrupt-Gate, 0xF = 32-bit Trap-Gate

Page 5: Interrupts in Protected-Mode

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 ring0, so could not execute ‘cli’ or ‘sti’ instructions

Page 6: Interrupts in Protected-Mode

16bit-Gate vs. 32bit-Gate

• The CPU constructs different stackframes for the 16-bit versus the 32-bit gate-types

ring0 stack

ring0 stack

IP

CS

FLAGS

SP

SS

EIP

EFLAGS

ESP

SS:SP SS:ESP

16-bits 32-bits

CS

SS

= always pushed = pushed if privilege-level changed

Page 7: Interrupts in Protected-Mode

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., USE16), the ‘iret’ instruction performs the correct return-actions for a 16-bit Gate

• Use ‘iretl’ for returning with a 32-bit Gate

Page 8: Interrupts in Protected-Mode

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 ; store IDTR into a memory-operand

lidt mem ; load IDTR from a memory-operand

Page 9: Interrupts in Protected-Mode

Format of register IDTR

base_address[ 31..0 ] segment-limit[ 15..0 ]

0151647

16-bits32-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)

Page 10: Interrupts in Protected-Mode

Register relationships

GDTR

IDTR

Interrupt-gate

code-descriptor

Interrupt DescriptorTable (256 entries) ISR

code-segment

Global Descriptor Table

INT ID

Page 11: Interrupts in Protected-Mode

Two Interrupt-Controllers

x86CPU

MasterPICSlave

PIC

INTR

Programmable Interval-TimerKeyboard controller

Page 12: Interrupts in Protected-Mode

Each PIC has a Mask Register

IRQ7

IRQ6

IRQ5

IRQ4

IRQ3

IRQ2

IRQ1

IRQ0

Master PICInterrupt-mask(I/O-port 0x21)

IRQ15

IRQ14

IRQ13

IRQ12

IRQ11

IRQ10

IRQ9

IRQ8

Slave PICInterrupt-mask(I/O-port 0xA1)

If a mask-bit is 1, the corresponding device-interrupts are masked;If a mask-bit is 0, the corresponding device-interrupts are unmasked

Page 13: Interrupts in Protected-Mode

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:6C), 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

Page 14: Interrupts in Protected-Mode

Two ‘threads’ in our demo

Build descriptor-tablesEnter protected-mode (most interrupts masked)

Do for ten seconds:{ Read tick_countShow tick_count }

Leave protected-mode(most interrupts unmasked)

Exit to our ‘loader’

Increment tick_count(maybe set midnight_flag)

Decrement motor_count(maybe set motor_status)

Issue EOI command

‘main’ program-thread

Interrupt Service Routine

ROM-BIOS DATA (threads share access)

tick_count motor_status

motor_countmidnight_flag

read

write

Page 15: Interrupts in Protected-Mode

Defining INT-8 Gate-Descriptor

0x0000

sel_CS isrPIT

0x8600

16-bit Interrupt-Gate

selector for ring0 code-segment

Our label for the interrupt-handler’s entry-point

P=1DPL=0 S=0type=6

Page 16: Interrupts in Protected-Mode

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 10secs)

• Reset IF=0 to disable interrupts (for exit)

Page 17: Interrupts in Protected-Mode

Question

• Why, in our earlier ‘tickdemo.s’ program, did we NOT need to set the PICs’ mask-registers so that only the timer-interrupts were left ‘unmasked’?

• (Your answer to this thought-question will offer an insight into your present grasp of the ‘real-mode’ versus ‘protected-mode’ system-component interrelationships)

Page 18: Interrupts in Protected-Mode

Can’t use ‘anchor’ for this one

• We encounter a problem if we attempt to execute our timer-tick demo-programs on any of the anchor-cluster’s workstations

• These demos (‘tickdemo’ and ‘pmtimer’) need to be executed on a machine in our classroom (or in the CS 5th-floor Lab), so we can watch the display-screen directly, rather than relying on ‘telnet’ (via pyramid)

Page 19: Interrupts in Protected-Mode

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 0xE) instead of the 16-bit Interrupt-Gate (gate-type 0x6)

• 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.

Page 20: Interrupts in Protected-Mode

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 ring3), and also a Call-Gate when returning to ring0 from ring3 (for quitting)