Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
273 lines (237 sloc) 10.5 KB
| This file is part of the lowest layer of the MINIX kernel. All processing
| switching and message handling is done here and in file "proc.c". This file
| is entered on every transition to the kernel, both for sending/receiving
| messages and for all interrupts. In all cases, the trap or interrupt
| routine first calls save() to store the machine state in the proc table.
| Then the stack is switched to k_stack. Finally, the real trap or interrupt
| handler (in C) is called. When it returns, the interrupt routine jumps to
| restart, to run the process or task whose number is in 'cur_proc'.
|
| The external entry points into this file are:
| s_call: process or task wants to send or receive a message
| tty_int: interrupt routine for each key depression and release
| lpr_int: interrupt routine for each line printer interrupt
| disk_int: disk interrupt routine
| wini_int: winchester interrupt routine
| clock_int: clock interrupt routine (HZ times per second)
| surprise: all other interrupts < 16 are vectored here
| trp: all traps with vector >= 16 are vectored here
| divide: divide overflow traps are vectored here
| restart: start running a task or process
| These symbols MUST agree with the values in ../h/com.h to avoid disaster.
K_STACK_BYTES = 256
WINI = -6
FLOPPY = -5
CLOCK = -3
IDLE = -999
DISKINT = 1
CLOCK_TICK = 2
| The following procedures are defined in this file and called from outside it.
.globl _tty_int, _lpr_int, _clock_int, _disk_int, _wini_int
.globl _s_call, _surprise, _trp, _divide, _restart
| The following external procedures are called in this file.
.globl _main, _sys_call, _interrupt, _keyboard, _panic, _unexpected_int, _trap
.globl _pr_char, _div_trap
| Variables, data structures and miscellaneous.
.globl _cur_proc, _proc_ptr, _scan_code, _int_mess, _k_stack, splimit
.globl _sizes, begtext, begdata, begbss
| The following constants are offsets into the proc table.
esreg = 14
dsreg = 16
csreg = 18
ssreg = 20
SP = 22
PC = 24
PSW = 28
SPLIM = 50
OFF = 18
ROFF = 12
.text
begtext:
|*===========================================================================*
|* MINIX *
|*===========================================================================*
MINIX: | this is the entry point for the MINIX kernel.
jmp M.0 | skip over the next few bytes
.word 0,0 | build puts DS at kernel text address 4
M.0: cli | disable interrupts
mov ax,cs | set up segment registers
mov ds,ax | set up ds
mov ax,4 | build has loaded this word with ds value
mov ds,ax | ds now contains proper value
mov ss,ax | ss now contains proper value
mov _scan_code,bx | save scan code for '=' key from bootstrap
mov sp,#_k_stack | set sp to point to the top of the
add sp,#K_STACK_BYTES | kernel stack
call _main | start the main program of MINIX
M.1: jmp M.1 | this should never be executed
|*===========================================================================*
|* s_call *
|*===========================================================================*
_s_call: | System calls are vectored here.
call save | save the machine state
mov bp,_proc_ptr | use bp to access sys call parameters
push 2(bp) | push(pointer to user message) (was bx)
push (bp) | push(src/dest) (was ax)
push _cur_proc | push caller
push 4(bp) | push(SEND/RECEIVE/BOTH) (was cx)
call _sys_call | sys_call(function, caller, src_dest, m_ptr)
jmp _restart | jump to code to restart proc/task running
|*===========================================================================*
|* tty_int *
|*===========================================================================*
_tty_int: | Interrupt routine for terminal input.
call save | save the machine state
call _keyboard | process a keyboard interrupt
jmp _restart | continue execution
|*===========================================================================*
|* lpr_int *
|*===========================================================================*
_lpr_int: | Interrupt routine for terminal input.
call save | save the machine state
call _pr_char | process a line printer interrupt
jmp _restart | continue execution
|*===========================================================================*
|* disk_int *
|*===========================================================================*
_disk_int: | Interrupt routine for the floppy disk.
call save | save the machine state
mov _int_mess+2,*DISKINT| build message for disk task
mov ax,#_int_mess | prepare to call interrupt(FLOPPY, &intmess)
push ax | push second parameter
mov ax,*FLOPPY | prepare to push first parameter
push ax | push first parameter
call _interrupt | this is the call
jmp _restart | continue execution
|*===========================================================================*
|* wini_int *
|*===========================================================================*
_wini_int: | Interrupt routine for the winchester disk.
call save | save the machine state
mov _int_mess+2,*DISKINT| build message for winchester task
mov ax,#_int_mess | prepare to call interrupt(WINI, &intmess)
push ax | push second parameter
mov ax,*WINI | prepare to push first parameter
push ax | push first parameter
call _interrupt | this is the call
jmp _restart | continue execution
|*===========================================================================*
|* clock_int *
|*===========================================================================*
_clock_int: | Interrupt routine for the clock.
call save | save the machine state
mov _int_mess+2,*CLOCK_TICK | build message for clock task
mov ax,#_int_mess | prepare to call interrupt(CLOCK, &intmess)
push ax | push second parameter
mov ax,*CLOCK | prepare to push first parameter
push ax | push first parameter
call _interrupt | this is the call
jmp _restart | continue execution
|*===========================================================================*
|* surprise *
|*===========================================================================*
_surprise: | This is where unexpected interrupts come.
call save | save the machine state
call _unexpected_int | go panic
jmp _restart | never executed
|*===========================================================================*
|* trp *
|*===========================================================================*
_trp: | This is where unexpected traps come.
call save | save the machine state
call _trap | print a message
jmp _restart | this error is not fatal
|*===========================================================================*
|* divide *
|*===========================================================================*
_divide: | This is where divide overflow traps come.
call save | save the machine state
call _div_trap | print a message
jmp _restart | this error is not fatal
|*===========================================================================*
|* save *
|*===========================================================================*
save: | save the machine state in the proc table.
push ds | stack: psw/cs/pc/ret addr/ds
push cs | prepare to restore ds
pop ds | ds has now been set to cs
mov ds,4 | word 4 in kernel text space contains ds value
pop ds_save | stack: psw/cs/pc/ret addr
pop ret_save | stack: psw/cs/pc
mov bx_save,bx | save bx for later ; we need a free register
mov bx,_proc_ptr | start save set up; make bx point to save area
add bx,*OFF | bx points to place to store cs
pop PC-OFF(bx) | store pc in proc table
pop csreg-OFF(bx) | store cs in proc table
pop PSW-OFF(bx) | store psw
mov ssreg-OFF(bx),ss | store ss
mov SP-OFF(bx),sp | sp as it was prior to interrupt
mov sp,bx | now use sp to point into proc table/task save
mov bx,ds | about to set ss
mov ss,bx | set ss
push ds_save | start saving all the registers, sp first
push es | save es between sp and bp
mov es,bx | es now references kernel memory too
push bp | save bp
push di | save di
push si | save si
push dx | save dx
push cx | save cx
push bx_save | save original bx
push ax | all registers now saved
mov sp,#_k_stack | temporary stack for interrupts
add sp,#K_STACK_BYTES | set sp to top of temporary stack
mov splimit,#_k_stack | limit for temporary stack
add splimit,#8 | splimit checks for stack overflow
mov ax,ret_save | ax = address to return to
jmp (ax) | return to caller; Note: sp points to saved ax
|*===========================================================================*
|* restart *
|*===========================================================================*
_restart: | This routine sets up and runs a proc or task.
cmp _cur_proc,#IDLE | restart user; if cur_proc = IDLE, go idle
je idle | no user is runnable, jump to idle routine
cli | disable interrupts
mov sp,_proc_ptr | return to user, fetch regs from proc table
pop ax | start restoring registers
pop bx | restore bx
pop cx | restore cx
pop dx | restore dx
pop si | restore si
pop di | restore di
mov lds_low,bx | lds_low contains bx
mov bx,sp | bx points to saved bp register
mov bp,SPLIM-ROFF(bx) | splimit = p_splimit
mov splimit,bp | ditto
mov bp,dsreg-ROFF(bx) | bp = ds
mov lds_low+2,bp | lds_low+2 contains ds
pop bp | restore bp
pop es | restore es
mov sp,SP-ROFF(bx) | restore sp
mov ss,ssreg-ROFF(bx) | restore ss using the value of ds
push PSW-ROFF(bx) | push psw
push csreg-ROFF(bx) | push cs
push PC-ROFF(bx) | push pc
lds bx,lds_low | restore ds and bx in one fell swoop
iret | return to user or task
|*===========================================================================*
|* idle *
|*===========================================================================*
idle: | executed when there is no work
sti | enable interrupts
L3: wait | just idle while waiting for interrupt
jmp L3 | loop until interrupt
|*===========================================================================*
|* data *
|*===========================================================================*
.data
begdata:
_sizes: .word 0x526F | this must be the first data entry (magic #)
.zerow 7 | build table uses prev word and this space
bx_save: .word 0 | storage for bx
ds_save: .word 0 | storage for ds
ret_save:.word 0 | storage for return address
lds_low: .word 0,0 | storage used for restoring bx
ttyomess: .asciz "RS232 interrupt"
.bss
begbss:
You can’t perform that action at this time.