# ! This file, mpx88.s, is included by mpx.s when Minix is compiled for ! 16-bit Intel CPUs. The alternative mpx386.s is compiled for 32-bit CPUs. ! ! This file contains the assembler startup code for Minix and the 16-bit ! interrupt handlers. It cooperates with cstart.c to set up a good ! environment for main(). ! This file is part of the lowest layer of the MINIX kernel. The other part ! is "proc.c". The lowest layer does process switching and message handling. ! Every transition to the kernel goes through this file. Transitions are ! caused by sending/receiving messages and by most interrupts. (RS232 ! interrupts may be handled in the file "rs2.s" and then they rarely enter ! the kernel.) ! Transitions to the kernel may be nested. The initial entry may be with a ! system call, exception or hardware interrupt; reentries may only be made ! by hardware interrupts. The count of reentries is kept in "k_reenter". ! It is important for deciding whether to switch to the kernel stack and ! for protecting the message passing code in "proc.c". ! For the message passing trap, most of the machine state is saved in the ! proc table. (Some of the registers need not be saved.) Then the stack is ! switched to "k_stack", and interrupts are reenabled. Finally, the system ! call handler (in C) is called. When it returns, interrupts are disabled ! again and the code falls into the restart routine, to finish off held-up ! interrupts and run the process or task whose pointer is in "proc_ptr". ! Hardware interrupt handlers do the same, except (1) The entire state must ! be saved. (2) There are too many handlers to do this inline, so the save ! routine is called. A few cycles are saved by pushing the address of the ! appropiate restart routine for a return later. (3) A stack switch is ! avoided when the stack is already switched. (4) The (master) 8259 interrupt ! controller is reenabled centrally in save(). (5) Each interrupt handler ! masks its interrupt line using the 8259 before enabling (other unmasked) ! interrupts, and unmasks it after servicing the interrupt. This limits the ! nest level to the number of lines and protects the handler from itself. ! For communication with the boot monitor at startup time some constant ! data are compiled into the beginning of the text segment. This facilitates ! reading the data at the start of the boot process, since only the first ! sector of the file needs to be read. ! Some data storage is also allocated at the end of this file. This data ! will be at the start of the data segment of the kernel and will be read ! and modified by the boot monitor before the kernel starts. #include #include #include #include "const.h" #include "sconst.h" #include "protect.h" ! The external entry points into this file are: ! Note: in assembly language the .define statement applied to a function name ! is loosely equivalent to a prototype in C code -- it makes it possible to ! link to an entity declared in the assembly code but does not create ! the entity. .define _int00 ! handlers for traps and exceptions .define _int01 .define _int02 .define _int03 .define _int04 .define _int05 .define _int06 .define _int07 .define _hwint00 ! handlers for hardware interrupts .define _hwint01 .define _hwint02 .define _hwint03 .define _hwint04 .define _hwint05 .define _hwint06 .define _hwint07 .define _hwint08 .define _hwint09 .define _hwint10 .define _hwint11 .define _hwint12 .define _hwint13 .define _hwint14 .define _hwint15 .define _restart ! start running a task or process .define save ! save the machine state in the proc table .define _s_call ! process or task wants to send or receive a message ! Exported variables. .define kernel_ds .define begbss .define begdata .text !*===========================================================================* !* MINIX * !*===========================================================================* MINIX: ! this is the entry point for the MINIX kernel jmp over_kernel_ds ! skip over the next few bytes .data2 CLICK_SHIFT ! for the monitor: memory granularity kernel_ds: .data2 0x01B4 ! boot monitor flags: (later kernel DS) ! call in 8086 mode, make bss, make stack, ! load low, don`t patch, will return, ! (has own INT calls), memory vector, ! new boot code return over_kernel_ds: ! Set up a C stack frame on the monitor stack. (The monitor sets cs and ds ! right. The ss register still references the monitor data segment.) push bp mov bp, sp push si push di cmp 4(bp), #0 ! monitor code segment is jz noret ! nonzero if return possible inc _mon_return noret: mov _mon_ss, ss ! save stack location for later return mov _mon_sp, sp ! Locate boot parameters, set up kernel segment registers and stack. mov bx, 6(bp) ! boot parameters offset mov dx, 8(bp) ! boot parameters length mov ax, 10(bp) ! address of a.out headers mov _aout+0, ax mov ax, 12(bp) mov _aout+2, ax mov ax, ds ! kernel data mov es, ax mov ss, ax mov sp, #k_stktop ! set sp to point to the top of kernel stack ! Real mode needs to get kernel DS from the code segment. Protected mode ! needs CS in the jump back to real mode. cseg mov kernel_cs, cs cseg mov kernel_ds, ds ! Call C startup code to set up a proper environment to run main(). push dx push bx push _mon_ss push ds push cs call _cstart ! cstart(cs, ds, mds, parmoff, parmlen) add sp, #5*2 cmp _protected_mode, #0 jz nosw ! ok to switch to protected mode? call klib_init_prot ! initialize klib functions for protected mode call real2prot ! switch to protected mode push #0 ! set flags to known good state popf ! especially, clear nested task and int enable nosw: jmp _main ! main() !*===========================================================================* !* interrupt handlers * !*===========================================================================* !*===========================================================================* !* hwint00 - 07 * !*===========================================================================* ! Note that the first few lines are a macro #define hwint_master(irq) \ call save /* save interrupted process state */;\ mov si, *[2*irq] /* load array index offset */;\ mov di, *[1<