2025-03-25 17:36:52 -04:00
|
|
|
/*
|
|
|
|
** @file isrs.S
|
|
|
|
**
|
|
|
|
** @author K. Reek
|
|
|
|
** @authors Jon Coles, Warren R. Carithers, Margaret Reek
|
|
|
|
** @author numerous Systems Programming classes
|
|
|
|
**
|
|
|
|
** Stubs for ISRs.
|
|
|
|
**
|
|
|
|
** This module provides the stubs needed for interrupts to save
|
|
|
|
** the machine state before calling the ISR. All interrupts have
|
|
|
|
** their own stub which pushes the interrupt number on the stack.
|
|
|
|
** This makes it possible for a common ISR to determine which
|
|
|
|
** interrupted occurred.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ASM_SRC
|
|
|
|
|
2025-03-27 11:39:12 -04:00
|
|
|
# .arch i386
|
2025-03-25 17:36:52 -04:00
|
|
|
|
|
|
|
#include <bootstrap.h>
|
2025-03-31 12:41:04 -04:00
|
|
|
#include <offsets.h>
|
|
|
|
#include <vm.h>
|
2025-03-25 17:36:52 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
** Configuration options - define in Makefile
|
|
|
|
**
|
|
|
|
** TRACE_CX include context restore debugging code
|
|
|
|
*/
|
|
|
|
|
|
|
|
.text
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Macros for the isr stubs. Some interrupts push an error code on
|
|
|
|
** the stack and others don't; for those that don't we simply push
|
|
|
|
** a zero so that cleaning up from either type is identical.
|
|
|
|
**
|
|
|
|
** Note: these are not marked as global symbols, as they are never
|
|
|
|
** accessed directly outside of this file. This could be changed
|
|
|
|
** if need be by adding this line to each macro definition right
|
|
|
|
** after the #define line:
|
|
|
|
**
|
|
|
|
** .global isr_##vector
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ISR(vector) \
|
|
|
|
isr_##vector: ; \
|
|
|
|
pushl $0 ; \
|
|
|
|
pushl $vector ; \
|
|
|
|
jmp isr_save
|
|
|
|
|
|
|
|
#define ERR_ISR(vector) \
|
|
|
|
isr_##vector: ; \
|
|
|
|
pushl $vector ; \
|
|
|
|
jmp isr_save
|
|
|
|
|
|
|
|
.globl isr_table
|
|
|
|
.globl isr_restore
|
|
|
|
|
|
|
|
/*
|
|
|
|
** This routine saves the machine state, calls the ISR, and then
|
|
|
|
** restores the machine state and returns from the interrupt.
|
|
|
|
**
|
|
|
|
********************************************************************
|
|
|
|
********************************************************************
|
|
|
|
** NOTE: this code is highly application-specific, and will most **
|
|
|
|
** probably require modification to tailor it. **
|
|
|
|
** **
|
|
|
|
** Examples of mods: switch to/from user stack, context switch **
|
|
|
|
** changes, etc. **
|
|
|
|
********************************************************************
|
|
|
|
********************************************************************
|
|
|
|
*/
|
|
|
|
|
|
|
|
isr_save:
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Begin by saving the CPU state (except for the FP context information).
|
|
|
|
**
|
|
|
|
** At this point, the stack looks like this:
|
|
|
|
**
|
|
|
|
** esp -> vector # saved by the entry macro
|
|
|
|
** error code, or 0 saved by the hardware, or the entry macro
|
|
|
|
** saved EIP saved by the hardware
|
|
|
|
** saved CS saved by the hardware
|
|
|
|
** saved EFLAGS saved by the hardware
|
|
|
|
*/
|
|
|
|
pusha // save E*X, ESP, EBP, ESI, EDI
|
|
|
|
pushl %ds // save segment registers
|
|
|
|
pushl %es
|
|
|
|
pushl %fs
|
|
|
|
pushl %gs
|
|
|
|
pushl %ss
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Stack contents (all 32-bit longwords) and offsets from ESP:
|
|
|
|
**
|
|
|
|
** SS GS FS ES DS EDI ESI EBP ESP EBX EDX ECX EAX vec cod EIP CS EFL
|
|
|
|
** 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68
|
|
|
|
**
|
|
|
|
** Note that the saved ESP is the contents before the PUSHA.
|
|
|
|
**
|
|
|
|
** Set up parameters for the ISR call.
|
|
|
|
*/
|
2025-03-31 12:41:04 -04:00
|
|
|
movl CTX_vector(%esp),%eax // get vector number and error code
|
|
|
|
movl CTX_code(%esp),%ebx
|
2025-03-25 17:36:52 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
***********************
|
|
|
|
** MOD FOR 20245 **
|
|
|
|
***********************
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
** We need to switch to the system stack. This requires that we save
|
|
|
|
** the user context pointer into the current PCB, then load ESP with
|
|
|
|
** the initial system stack pointer.
|
|
|
|
*/
|
|
|
|
|
|
|
|
.globl current
|
|
|
|
.globl kernel_esp
|
|
|
|
|
|
|
|
// save the context pointer
|
|
|
|
movl current, %edx
|
2025-03-31 12:41:04 -04:00
|
|
|
movl %esp, PCB_context(%edx)
|
2025-03-25 17:36:52 -04:00
|
|
|
|
|
|
|
// also save the page directory pointer
|
|
|
|
movl %cr3, %ecx
|
2025-03-31 12:41:04 -04:00
|
|
|
addl $KERN_BASE, %ecx // convert to a virtual address
|
|
|
|
movl %ecx, PCB_pdir(%edx)
|
2025-03-25 17:36:52 -04:00
|
|
|
|
|
|
|
// switch to the system stack
|
|
|
|
//
|
|
|
|
// NOTE: this is inherently non-reentrant! If/when the OS
|
|
|
|
// is converted from monolithic to something that supports
|
|
|
|
// reentrant or interruptable ISRs, this code will need to
|
|
|
|
// be changed to support that!
|
|
|
|
|
|
|
|
movl kernel_esp, %esp
|
|
|
|
|
|
|
|
// we don't change CR3 because all the user PDIRs are
|
|
|
|
// set up with mappings for the OS in the upper half
|
|
|
|
|
|
|
|
/*
|
|
|
|
***********************
|
|
|
|
** END MOD FOR 20245 **
|
|
|
|
***********************
|
|
|
|
*/
|
|
|
|
|
|
|
|
pushl %ebx // put them on the top of the stack ...
|
|
|
|
pushl %eax // ... as parameters for the ISR
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Call the ISR
|
|
|
|
*/
|
|
|
|
movl isr_table(,%eax,4),%ebx
|
|
|
|
call *%ebx
|
|
|
|
addl $8,%esp // pop the two parameters
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Context restore begins here
|
|
|
|
*/
|
|
|
|
|
|
|
|
isr_restore:
|
|
|
|
|
|
|
|
/*
|
|
|
|
***********************
|
|
|
|
** MOD FOR 20245 **
|
|
|
|
***********************
|
|
|
|
*/
|
|
|
|
movl current, %ebx // return to the user stack
|
2025-03-31 12:41:04 -04:00
|
|
|
movl PCB_context(%ebx), %esp // ESP --> context save area
|
|
|
|
movl PCB_pdir(%ebx), %ecx // page directory pointer
|
|
|
|
subl $KERN_BASE, %ecx // convert to a physical address
|
2025-03-25 17:36:52 -04:00
|
|
|
movl %ecx, %cr3
|
|
|
|
|
|
|
|
// now we're operating with the user process'
|
|
|
|
// page directory and stack
|
|
|
|
|
|
|
|
/*
|
|
|
|
***********************
|
|
|
|
** END MOD FOR 20245 **
|
|
|
|
***********************
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef TRACE_CX
|
|
|
|
/*
|
|
|
|
** DEBUGGING CODE PART 1
|
|
|
|
**
|
2025-03-27 14:35:29 -04:00
|
|
|
** This code will execute during each context restore, and
|
2025-03-25 17:36:52 -04:00
|
|
|
** should be modified to print out whatever debugging information
|
|
|
|
** is desired.
|
|
|
|
**
|
|
|
|
** By default, it prints out the CPU context being restored; it
|
|
|
|
** relies on the standard save sequence (see above).
|
|
|
|
*/
|
|
|
|
.globl cio_printf_at
|
|
|
|
|
|
|
|
pushl $fmt
|
|
|
|
pushl $1
|
|
|
|
pushl $0
|
|
|
|
call cio_printf_at
|
|
|
|
addl $12,%esp
|
|
|
|
/*
|
|
|
|
** END OF DEBUGGING CODE PART 1
|
|
|
|
*/
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Restore the context.
|
|
|
|
*/
|
|
|
|
popl %ss // restore the segment registers
|
|
|
|
popl %gs
|
|
|
|
popl %fs
|
|
|
|
popl %es
|
|
|
|
popl %ds
|
|
|
|
popa // restore others
|
|
|
|
addl $8, %esp // discard the error code and vector
|
|
|
|
iret // and return
|
|
|
|
|
|
|
|
#ifdef TRACE_CX
|
|
|
|
/*
|
|
|
|
** DEBUGGING CODE PART 2
|
|
|
|
**
|
|
|
|
** This format string is arranged according to the ordering of values
|
|
|
|
** in the context save area on the stack.
|
|
|
|
*/
|
|
|
|
fmt: .ascii " ss=%08x gs=%08x fs=%08x es=%08x ds=%08x\n"
|
|
|
|
.ascii "edi=%08x esi=%08x ebp=%08x esp=%08x ebx=%08x\n"
|
|
|
|
.ascii "edx=%08x ecx=%08x eax=%08x vec=%08x cod=%08x\n"
|
|
|
|
.string "eip=%08x cs=%08x efl=%08x\n"
|
|
|
|
|
|
|
|
/*
|
|
|
|
** END OF DEBUGGING CODE PART 2
|
|
|
|
*/
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Here we generate the individual stubs for each interrupt.
|
|
|
|
*/
|
|
|
|
ISR(0x00); ISR(0x01); ISR(0x02); ISR(0x03);
|
|
|
|
ISR(0x04); ISR(0x05); ISR(0x06); ISR(0x07);
|
|
|
|
ERR_ISR(0x08); ISR(0x09); ERR_ISR(0x0a); ERR_ISR(0x0b);
|
|
|
|
ERR_ISR(0x0c); ERR_ISR(0x0d); ERR_ISR(0x0e); ISR(0x0f);
|
|
|
|
ISR(0x10); ERR_ISR(0x11); ISR(0x12); ISR(0x13);
|
|
|
|
ISR(0x14); ERR_ISR(0x15); ISR(0x16); ISR(0x17);
|
|
|
|
ISR(0x18); ISR(0x19); ISR(0x1a); ISR(0x1b);
|
|
|
|
ISR(0x1c); ISR(0x1d); ISR(0x1e); ISR(0x1f);
|
|
|
|
ISR(0x20); ISR(0x21); ISR(0x22); ISR(0x23);
|
|
|
|
ISR(0x24); ISR(0x25); ISR(0x26); ISR(0x27);
|
|
|
|
ISR(0x28); ISR(0x29); ISR(0x2a); ISR(0x2b);
|
|
|
|
ISR(0x2c); ISR(0x2d); ISR(0x2e); ISR(0x2f);
|
|
|
|
ISR(0x30); ISR(0x31); ISR(0x32); ISR(0x33);
|
|
|
|
ISR(0x34); ISR(0x35); ISR(0x36); ISR(0x37);
|
|
|
|
ISR(0x38); ISR(0x39); ISR(0x3a); ISR(0x3b);
|
|
|
|
ISR(0x3c); ISR(0x3d); ISR(0x3e); ISR(0x3f);
|
|
|
|
ISR(0x40); ISR(0x41); ISR(0x42); ISR(0x43);
|
|
|
|
ISR(0x44); ISR(0x45); ISR(0x46); ISR(0x47);
|
|
|
|
ISR(0x48); ISR(0x49); ISR(0x4a); ISR(0x4b);
|
|
|
|
ISR(0x4c); ISR(0x4d); ISR(0x4e); ISR(0x4f);
|
|
|
|
ISR(0x50); ISR(0x51); ISR(0x52); ISR(0x53);
|
|
|
|
ISR(0x54); ISR(0x55); ISR(0x56); ISR(0x57);
|
|
|
|
ISR(0x58); ISR(0x59); ISR(0x5a); ISR(0x5b);
|
|
|
|
ISR(0x5c); ISR(0x5d); ISR(0x5e); ISR(0x5f);
|
|
|
|
ISR(0x60); ISR(0x61); ISR(0x62); ISR(0x63);
|
|
|
|
ISR(0x64); ISR(0x65); ISR(0x66); ISR(0x67);
|
|
|
|
ISR(0x68); ISR(0x69); ISR(0x6a); ISR(0x6b);
|
|
|
|
ISR(0x6c); ISR(0x6d); ISR(0x6e); ISR(0x6f);
|
|
|
|
ISR(0x70); ISR(0x71); ISR(0x72); ISR(0x73);
|
|
|
|
ISR(0x74); ISR(0x75); ISR(0x76); ISR(0x77);
|
|
|
|
ISR(0x78); ISR(0x79); ISR(0x7a); ISR(0x7b);
|
|
|
|
ISR(0x7c); ISR(0x7d); ISR(0x7e); ISR(0x7f);
|
|
|
|
ISR(0x80); ISR(0x81); ISR(0x82); ISR(0x83);
|
|
|
|
ISR(0x84); ISR(0x85); ISR(0x86); ISR(0x87);
|
|
|
|
ISR(0x88); ISR(0x89); ISR(0x8a); ISR(0x8b);
|
|
|
|
ISR(0x8c); ISR(0x8d); ISR(0x8e); ISR(0x8f);
|
|
|
|
ISR(0x90); ISR(0x91); ISR(0x92); ISR(0x93);
|
|
|
|
ISR(0x94); ISR(0x95); ISR(0x96); ISR(0x97);
|
|
|
|
ISR(0x98); ISR(0x99); ISR(0x9a); ISR(0x9b);
|
|
|
|
ISR(0x9c); ISR(0x9d); ISR(0x9e); ISR(0x9f);
|
|
|
|
ISR(0xa0); ISR(0xa1); ISR(0xa2); ISR(0xa3);
|
|
|
|
ISR(0xa4); ISR(0xa5); ISR(0xa6); ISR(0xa7);
|
|
|
|
ISR(0xa8); ISR(0xa9); ISR(0xaa); ISR(0xab);
|
|
|
|
ISR(0xac); ISR(0xad); ISR(0xae); ISR(0xaf);
|
|
|
|
ISR(0xb0); ISR(0xb1); ISR(0xb2); ISR(0xb3);
|
|
|
|
ISR(0xb4); ISR(0xb5); ISR(0xb6); ISR(0xb7);
|
|
|
|
ISR(0xb8); ISR(0xb9); ISR(0xba); ISR(0xbb);
|
|
|
|
ISR(0xbc); ISR(0xbd); ISR(0xbe); ISR(0xbf);
|
|
|
|
ISR(0xc0); ISR(0xc1); ISR(0xc2); ISR(0xc3);
|
|
|
|
ISR(0xc4); ISR(0xc5); ISR(0xc6); ISR(0xc7);
|
|
|
|
ISR(0xc8); ISR(0xc9); ISR(0xca); ISR(0xcb);
|
|
|
|
ISR(0xcc); ISR(0xcd); ISR(0xce); ISR(0xcf);
|
|
|
|
ISR(0xd0); ISR(0xd1); ISR(0xd2); ISR(0xd3);
|
|
|
|
ISR(0xd4); ISR(0xd5); ISR(0xd6); ISR(0xd7);
|
|
|
|
ISR(0xd8); ISR(0xd9); ISR(0xda); ISR(0xdb);
|
|
|
|
ISR(0xdc); ISR(0xdd); ISR(0xde); ISR(0xdf);
|
|
|
|
ISR(0xe0); ISR(0xe1); ISR(0xe2); ISR(0xe3);
|
|
|
|
ISR(0xe4); ISR(0xe5); ISR(0xe6); ISR(0xe7);
|
|
|
|
ISR(0xe8); ISR(0xe9); ISR(0xea); ISR(0xeb);
|
|
|
|
ISR(0xec); ISR(0xed); ISR(0xee); ISR(0xef);
|
|
|
|
ISR(0xf0); ISR(0xf1); ISR(0xf2); ISR(0xf3);
|
|
|
|
ISR(0xf4); ISR(0xf5); ISR(0xf6); ISR(0xf7);
|
|
|
|
ISR(0xf8); ISR(0xf9); ISR(0xfa); ISR(0xfb);
|
|
|
|
ISR(0xfc); ISR(0xfd); ISR(0xfe); ISR(0xff);
|
|
|
|
|
|
|
|
.data
|
|
|
|
|
|
|
|
/*
|
|
|
|
** This table contains the addresses where each of the preceding
|
|
|
|
** stubs begins. This information is needed to initialize the
|
|
|
|
** Interrupt Descriptor Table in support.c
|
|
|
|
*/
|
|
|
|
.globl isr_stub_table
|
|
|
|
isr_stub_table:
|
|
|
|
.long isr_0x00, isr_0x01, isr_0x02, isr_0x03
|
|
|
|
.long isr_0x04, isr_0x05, isr_0x06, isr_0x07
|
|
|
|
.long isr_0x08, isr_0x09, isr_0x0a, isr_0x0b
|
|
|
|
.long isr_0x0c, isr_0x0d, isr_0x0e, isr_0x0f
|
|
|
|
.long isr_0x10, isr_0x11, isr_0x12, isr_0x13
|
|
|
|
.long isr_0x14, isr_0x15, isr_0x16, isr_0x17
|
|
|
|
.long isr_0x18, isr_0x19, isr_0x1a, isr_0x1b
|
|
|
|
.long isr_0x1c, isr_0x1d, isr_0x1e, isr_0x1f
|
|
|
|
.long isr_0x20, isr_0x21, isr_0x22, isr_0x23
|
|
|
|
.long isr_0x24, isr_0x25, isr_0x26, isr_0x27
|
|
|
|
.long isr_0x28, isr_0x29, isr_0x2a, isr_0x2b
|
|
|
|
.long isr_0x2c, isr_0x2d, isr_0x2e, isr_0x2f
|
|
|
|
.long isr_0x30, isr_0x31, isr_0x32, isr_0x33
|
|
|
|
.long isr_0x34, isr_0x35, isr_0x36, isr_0x37
|
|
|
|
.long isr_0x38, isr_0x39, isr_0x3a, isr_0x3b
|
|
|
|
.long isr_0x3c, isr_0x3d, isr_0x3e, isr_0x3f
|
|
|
|
.long isr_0x40, isr_0x41, isr_0x42, isr_0x43
|
|
|
|
.long isr_0x44, isr_0x45, isr_0x46, isr_0x47
|
|
|
|
.long isr_0x48, isr_0x49, isr_0x4a, isr_0x4b
|
|
|
|
.long isr_0x4c, isr_0x4d, isr_0x4e, isr_0x4f
|
|
|
|
.long isr_0x50, isr_0x51, isr_0x52, isr_0x53
|
|
|
|
.long isr_0x54, isr_0x55, isr_0x56, isr_0x57
|
|
|
|
.long isr_0x58, isr_0x59, isr_0x5a, isr_0x5b
|
|
|
|
.long isr_0x5c, isr_0x5d, isr_0x5e, isr_0x5f
|
|
|
|
.long isr_0x60, isr_0x61, isr_0x62, isr_0x63
|
|
|
|
.long isr_0x64, isr_0x65, isr_0x66, isr_0x67
|
|
|
|
.long isr_0x68, isr_0x69, isr_0x6a, isr_0x6b
|
|
|
|
.long isr_0x6c, isr_0x6d, isr_0x6e, isr_0x6f
|
|
|
|
.long isr_0x70, isr_0x71, isr_0x72, isr_0x73
|
|
|
|
.long isr_0x74, isr_0x75, isr_0x76, isr_0x77
|
|
|
|
.long isr_0x78, isr_0x79, isr_0x7a, isr_0x7b
|
|
|
|
.long isr_0x7c, isr_0x7d, isr_0x7e, isr_0x7f
|
|
|
|
.long isr_0x80, isr_0x81, isr_0x82, isr_0x83
|
|
|
|
.long isr_0x84, isr_0x85, isr_0x86, isr_0x87
|
|
|
|
.long isr_0x88, isr_0x89, isr_0x8a, isr_0x8b
|
|
|
|
.long isr_0x8c, isr_0x8d, isr_0x8e, isr_0x8f
|
|
|
|
.long isr_0x90, isr_0x91, isr_0x92, isr_0x93
|
|
|
|
.long isr_0x94, isr_0x95, isr_0x96, isr_0x97
|
|
|
|
.long isr_0x98, isr_0x99, isr_0x9a, isr_0x9b
|
|
|
|
.long isr_0x9c, isr_0x9d, isr_0x9e, isr_0x9f
|
|
|
|
.long isr_0xa0, isr_0xa1, isr_0xa2, isr_0xa3
|
|
|
|
.long isr_0xa4, isr_0xa5, isr_0xa6, isr_0xa7
|
|
|
|
.long isr_0xa8, isr_0xa9, isr_0xaa, isr_0xab
|
|
|
|
.long isr_0xac, isr_0xad, isr_0xae, isr_0xaf
|
|
|
|
.long isr_0xb0, isr_0xb1, isr_0xb2, isr_0xb3
|
|
|
|
.long isr_0xb4, isr_0xb5, isr_0xb6, isr_0xb7
|
|
|
|
.long isr_0xb8, isr_0xb9, isr_0xba, isr_0xbb
|
|
|
|
.long isr_0xbc, isr_0xbd, isr_0xbe, isr_0xbf
|
|
|
|
.long isr_0xc0, isr_0xc1, isr_0xc2, isr_0xc3
|
|
|
|
.long isr_0xc4, isr_0xc5, isr_0xc6, isr_0xc7
|
|
|
|
.long isr_0xc8, isr_0xc9, isr_0xca, isr_0xcb
|
|
|
|
.long isr_0xcc, isr_0xcd, isr_0xce, isr_0xcf
|
|
|
|
.long isr_0xd0, isr_0xd1, isr_0xd2, isr_0xd3
|
|
|
|
.long isr_0xd4, isr_0xd5, isr_0xd6, isr_0xd7
|
|
|
|
.long isr_0xd8, isr_0xd9, isr_0xda, isr_0xdb
|
|
|
|
.long isr_0xdc, isr_0xdd, isr_0xde, isr_0xdf
|
|
|
|
.long isr_0xe0, isr_0xe1, isr_0xe2, isr_0xe3
|
|
|
|
.long isr_0xe4, isr_0xe5, isr_0xe6, isr_0xe7
|
|
|
|
.long isr_0xe8, isr_0xe9, isr_0xea, isr_0xeb
|
|
|
|
.long isr_0xec, isr_0xed, isr_0xee, isr_0xef
|
|
|
|
.long isr_0xf0, isr_0xf1, isr_0xf2, isr_0xf3
|
|
|
|
.long isr_0xf4, isr_0xf5, isr_0xf6, isr_0xf7
|
|
|
|
.long isr_0xf8, isr_0xf9, isr_0xfa, isr_0xfb
|
|
|
|
.long isr_0xfc, isr_0xfd, isr_0xfe, isr_0xff
|