]> Zhao Yanbai Git Server - minix.git/commitdiff
Conversion of kernel assembly from ACK to GNU
authorTomas Hruby <tom@minix3.org>
Fri, 30 Oct 2009 16:00:44 +0000 (16:00 +0000)
committerTomas Hruby <tom@minix3.org>
Fri, 30 Oct 2009 16:00:44 +0000 (16:00 +0000)
- .s files removed and replaced by .S as the .S is a standard extension for assembly that needs preprocessing

kernel/arch/i386/Makefile
kernel/arch/i386/klib386.S [new file with mode: 0644]
kernel/arch/i386/klib386.s [deleted file]
kernel/arch/i386/mpx386.S [new file with mode: 0644]
kernel/arch/i386/mpx386.s [deleted file]
kernel/arch/i386/sconst.h

index 20d9181e479e851374e66538f7bc219b1ca60d98..afbeea6687884ab5be6cd7b50b10fc697850e481 100755 (executable)
@@ -23,18 +23,18 @@ OBJS=       arch_do_vmctl.o \
        system.o
 
 CPPFLAGS=-Iinclude
-CFLAGS=$(CPPFLAGS) -Wall
+CFLAGS=$(CPPFLAGS) -Wall $(CPROFILE)
 
 build: $(HEAD) $(ARCHAR)
 
 $(ARCHAR): $(OBJS)
-       aal cr $@ *.o
+       aal cr $@ $(OBJS)
 
 depend: 
-       mkdep "$(CC) -E $(CPPFLAGS)" *.c *.s > .depend
+       mkdep "$(CC) -E $(CPPFLAGS)" *.c *.S > .depend
 
 clean:
-       rm -f *.a *.o *~
+       rm -f *.a *.o *~ *.tmp *.s
 
 # How to build it
 $(ARCHAR)(exception.o): exception.c
@@ -70,11 +70,15 @@ $(ARCHAR)(do_sdevio.o): do_sdevio.c
 $(ARCHAR)(clock.o): clock.c
        $(CC) $(CFLAGS) -c $<
 
-$(ARCHAR)(klib386.o): klib386.s
-       $(CC) $(CFLAGS) -c $<
+klib386.o: klib386.S
+       $(CC) $(CFLAGS)  -E -D__ASSEMBLY__ -o $@.tmp $<
+       gas2ack $@.tmp $@.s
+       $(CC) $(CFLAGS) -c -o $@ $@.s
 
-.s.o:
-       $(CC) $(CFLAGS) -c -o $@ $<
+mpx386.o: mpx386.S
+       $(CC) $(CFLAGS) -E -D__ASSEMBLY__ -o $@.tmp $<
+       gas2ack $@.tmp $@.s
+       $(CC) $(CFLAGS) -c -o $@ $@.s
 
 .c.o:
        $(CC) $(CFLAGS) -c -o $@ $<
diff --git a/kernel/arch/i386/klib386.S b/kernel/arch/i386/klib386.S
new file mode 100644 (file)
index 0000000..e160c58
--- /dev/null
@@ -0,0 +1,642 @@
+/* sections */
+
+.text; .data; .data; .bss
+
+#include <minix/config.h>
+#include <minix/const.h>
+#include <ibm/interrupt.h>
+#include <archconst.h>
+#include "../../const.h"
+#include "sconst.h"
+
+/*
+ * This file contains a number of assembly code utility routines needed by the
+ * kernel.  They are:
+ */
+
+.globl monitor /* exit Minix and return to the monitor */
+.globl int86   /* let the monitor make an 8086 interrupt call */
+.globl exit    /* dummy for library routines */
+.globl _exit   /* dummy for library routines */
+.globl __exit  /* dummy for library routines */
+.globl __main  /* dummy for GCC */
+.globl phys_insw       /* transfer data from (disk controller) port to memory */
+.globl phys_insb       /* likewise byte by byte */
+.globl phys_outsw      /* transfer data from memory to (disk controller) port */
+.globl phys_outsb      /* likewise byte by byte */
+.globl intr_unmask     /* enable an irq at the 8259 controller */
+.globl intr_mask       /* disable an irq */
+.globl phys_copy       /* copy data from anywhere to anywhere in memory */
+.globl phys_copy_fault /* phys_copy pagefault */
+.globl phys_memset     /* write pattern anywhere in memory */
+.globl mem_rdw /* copy one word from [segment:offset] */
+.globl reset   /* reset the system */
+.globl idle_task       /* task executed when there is no work */
+.globl level0  /* call a function at level 0 */
+.globl read_cpu_flags  /* read the cpu flags */
+.globl read_cr0        /* read cr0 */
+.globl getcr3val
+.globl write_cr0       /* write a value in cr0 */
+.globl read_cr4
+.globl  thecr3
+.globl write_cr4
+
+.globl catch_pagefaults
+.globl read_ds
+.globl  read_cs
+.globl read_ss
+
+/*
+ * The routines only guarantee to preserve the registers the C compiler 
+ * expects to be preserved (ebx, esi, edi, ebp, esp, segment registers, and 
+ * direction bit in the flags). 
+ */
+
+.text
+/*===========================================================================*/
+/*                             monitor                                      */
+/*===========================================================================*/
+/* PUBLIC void monitor(); */
+/* Return to the monitor. */
+
+monitor:
+       movl    mon_sp, %esp    /* restore monitor stack pointer */
+       movw    $SS_SELECTOR, %dx       /* monitor data segment */
+       mov     %dx, %ds
+       mov     %dx, %es
+       mov     %dx, %fs
+       mov     %dx, %gs
+       mov     %dx, %ss
+       pop     %edi
+       pop     %esi
+       pop     %ebp
+       lretw   /* return to the monitor */
+
+
+/*===========================================================================*/
+/*                             int86                                        */
+/*===========================================================================*/
+/* PUBLIC void int86(); */
+int86:
+       cmpb    $0, mon_return  /* is the monitor there? */
+       jne     0f
+       movb    $0x01, %ah      /* an int 13 error seems appropriate */
+       movb    %ah, reg86+0    /* reg86.w.f = 1 (set carry flag) */
+       movb    %ah, reg86+13   /* reg86.b.ah = 0x01 = "invalid command" */
+       ret
+0:
+       push    %ebp    /* save C registers */
+       push    %esi
+       push    %edi
+       push    %ebx
+       pushf   /* save flags */
+       cli     /* no interruptions */
+
+       inb     $INT2_CTLMASK
+       movb    %al, %ah
+       inb     $INT_CTLMASK
+       push    %eax    /* save interrupt masks */
+       movl    irq_use, %eax   /* map of in-use IRQ's */
+       and     $~(1<<CLOCK_IRQ), %eax  /* keep the clock ticking */
+       outb    $INT_CTLMASK    /* enable all unused IRQ's and vv. */
+       movb    %ah, %al
+       outb    $INT2_CTLMASK
+
+       mov     $SS_SELECTOR, %eax      /* monitor data segment */
+       mov     %ax, %ss
+       xchgl   mon_sp, %esp    /* switch stacks */
+       push    reg86+36        /* parameters used in INT call */
+       push    reg86+32
+       push    reg86+28
+       push    reg86+24
+       push    reg86+20
+       push    reg86+16
+       push    reg86+12
+       push    reg86+8
+       push    reg86+4
+       push    reg86+0
+       mov     %ax, %ds        /* remaining data selectors */
+       mov     %ax, %es
+       mov     %ax, %fs
+       mov     %ax, %gs
+       push    %cs
+       push    $return /* kernel return address and selector */
+        ljmpw    *20+2*4+10*4+2*4(%esp)
+return:
+       pop     reg86+0
+       pop     reg86+4
+       pop     reg86+8
+       pop     reg86+12
+       pop     reg86+16
+       pop     reg86+20
+       pop     reg86+24
+       pop     reg86+28
+       pop     reg86+32
+       pop     reg86+36
+       lgdt    gdt+GDT_SELECTOR        /* reload global descriptor table */
+        ljmp    $CS_SELECTOR, $csinit
+csinit:
+       mov     $DS_SELECTOR, %eax
+       mov     %ax, %ds
+       mov     %ax, %es
+       mov     %ax, %fs
+       mov     %ax, %gs
+       mov     %ax, %ss
+       xchgl   mon_sp, %esp    /* unswitch stacks */
+       lidt    gdt+IDT_SELECTOR        /* reload interrupt descriptor table */
+       andb    $~0x02, gdt+TSS_SELECTOR+DESC_ACCESS    /* clear TSS busy bit */
+       mov     $TSS_SELECTOR, %eax
+       ltr     %ax     /* set TSS register */
+
+       pop     %eax
+       outb    $INT_CTLMASK    /* restore interrupt masks */
+       movb    %ah, %al
+       outb    $INT2_CTLMASK
+
+       addl    %ecx, lost_ticks        /* record lost clock ticks */
+
+       popf    /* restore flags */
+       pop     %ebx    /* restore C registers */
+       pop     %edi
+       pop     %esi
+       pop     %ebp
+       ret
+
+/*===========================================================================*/
+/*                             exit                                         */
+/*===========================================================================*/
+/*
+ * PUBLIC void exit(); 
+ * Some library routines use exit, so provide a dummy version. 
+ * Actual calls to exit cannot occur in the kernel. 
+ * GNU CC likes to call ___main from main() for nonobvious reasons. 
+ */
+
+exit:
+_exit:
+__exit:
+       sti
+       jmp     __exit
+
+__main:
+       ret
+
+
+/*===========================================================================*/
+/*                             phys_insw                                    */
+/*===========================================================================*/
+/*
+ * PUBLIC void phys_insw(Port_t port, phys_bytes buf, size_t count); 
+ * Input an array from an I/O port.  Absolute address version of insw(). 
+ */
+
+phys_insw:
+       push    %ebp
+       mov     %esp, %ebp
+       cld
+       push    %edi
+       push    %es
+
+       mov     $FLAT_DS_SELECTOR, %ecx
+       mov     %cx, %es
+       mov     8(%ebp), %edx   /* port to read from */
+       mov     12(%ebp), %edi  /* destination addr */
+       mov     16(%ebp), %ecx  /* byte count */
+       shr     $1, %ecx        /* word count */
+       rep insw        /* input many words */
+       pop     %es
+       pop     %edi
+       pop     %ebp
+       ret
+
+
+/*===========================================================================*/
+/*                             phys_insb                                    */
+/*===========================================================================*/
+/*
+ * PUBLIC void phys_insb(Port_t port, phys_bytes buf, size_t count); 
+ * Input an array from an I/O port.  Absolute address version of insb(). 
+ */
+
+phys_insb:
+       push    %ebp
+       mov     %esp, %ebp
+       cld
+       push    %edi
+       push    %es
+
+       mov     $FLAT_DS_SELECTOR, %ecx
+       mov     %cx, %es
+       mov     8(%ebp), %edx   /* port to read from */
+       mov     12(%ebp), %edi  /* destination addr */
+       mov     16(%ebp), %ecx  /* byte count */
+       rep insb        /* input many bytes */
+       pop     %es
+       pop     %edi
+       pop     %ebp
+       ret
+
+
+/*===========================================================================*/
+/*                             phys_outsw                                   */
+/*===========================================================================*/
+/*
+ * PUBLIC void phys_outsw(Port_t port, phys_bytes buf, size_t count); 
+ * Output an array to an I/O port.  Absolute address version of outsw(). 
+ */
+
+.balign        16
+phys_outsw:
+       push    %ebp
+       mov     %esp, %ebp
+       cld
+       push    %esi
+       push    %ds
+
+       mov     $FLAT_DS_SELECTOR, %ecx
+       mov     %cx, %ds
+       mov     8(%ebp), %edx   /* port to write to */
+       mov     12(%ebp), %esi  /* source addr */
+       mov     16(%ebp), %ecx  /* byte count */
+       shr     $1, %ecx        /* word count */
+       rep outsw       /* output many words */
+       pop     %ds
+       pop     %esi
+       pop     %ebp
+       ret
+
+
+/*===========================================================================*/
+/*                             phys_outsb                                   */
+/*===========================================================================*/
+/* 
+ * PUBLIC void phys_outsb(Port_t port, phys_bytes buf, size_t count);
+ * Output an array to an I/O port.  Absolute address version of outsb().
+ */
+
+.balign        16
+phys_outsb:
+       push    %ebp
+       mov     %esp, %ebp
+       cld
+       push    %esi
+       push    %ds
+
+       mov     $FLAT_DS_SELECTOR, %ecx
+       mov     %cx, %ds
+       mov     8(%ebp), %edx   /* port to write to */
+       mov     12(%ebp), %esi  /* source addr */
+       mov     16(%ebp), %ecx  /* byte count */
+       rep outsb       /* output many bytes */
+       pop     %ds
+       pop     %esi
+       pop     %ebp
+       ret
+
+
+/*==========================================================================*/
+/*                             intr_unmask                                 */
+/*==========================================================================*/
+/*
+ * PUBLIC void intr_unmask(irq_hook_t *hook) 
+ * Enable an interrupt request line by clearing an 8259 bit. 
+ * Equivalent C code for hook->irq < 8: 
+ *   if ((irq_actids[hook->irq] &= ~hook->id) == 0) 
+ *     outb(INT_CTLMASK, inb(INT_CTLMASK) & ~(1 << irq)); 
+ */
+
+.balign        16
+intr_unmask:
+       push    %ebp
+       mov     %esp, %ebp
+       pushf
+       cli
+       mov     8(%ebp), %eax   /* hook */
+       mov     8(%eax), %ecx   /* irq */
+       mov     12(%eax), %eax  /* id bit */
+       not     %eax
+       and     %eax, irq_actids(,%ecx) /* clear this id bit */
+       jne     en_done /* still masked by other handlers? */
+       movb    $~1, %ah
+       rolb    %cl, %ah        /* ah = ~(1 << (irq % 8)) */
+       mov     $INT_CTLMASK, %edx      /* enable irq < 8 at the master 8259 */
+       cmpb    $8, %cl
+       jb      0f
+       mov     $INT2_CTLMASK, %edx     /* enable irq >= 8 at the slave 8259 */
+0:
+       inb     %dx
+       andb    %ah, %al
+       outb    %dx     /* clear bit at the 8259 */
+en_done:
+       popf
+       leave
+       ret
+
+
+/*==========================================================================*/
+/*                             intr_mask                                   */
+/*==========================================================================*/
+/*
+ * PUBLIC int intr_mask(irq_hook_t *hook) 
+ * Disable an interrupt request line by setting an 8259 bit. 
+ * Equivalent C code for irq < 8: 
+ *   irq_actids[hook->irq] |= hook->id; 
+ *   outb(INT_CTLMASK, inb(INT_CTLMASK) | (1 << irq)); 
+ * Returns true iff the interrupt was not already disabled. 
+ */
+
+.balign        16
+intr_mask:
+       push    %ebp
+       mov     %esp, %ebp
+       pushf
+       cli
+       mov     8(%ebp), %eax   /* hook */
+       mov     8(%eax), %ecx   /* irq */
+       mov     12(%eax), %eax  /* id bit */
+       or      %eax, irq_actids(,%ecx) /* set this id bit */
+       movb    $1, %ah
+       rolb    %cl, %ah        /* ah = (1 << (irq % 8)) */
+       mov     $INT_CTLMASK, %edx      /* disable irq < 8 at the master 8259 */
+       cmpb    $8, %cl
+       jb      0f
+       mov     $INT2_CTLMASK, %edx     /* disable irq >= 8 at the slave 8259 */
+0:
+       inb     %dx
+       testb   %ah, %al
+       jne     dis_already     /* already disabled? */
+       orb     %ah, %al
+       outb    %dx     /* set bit at the 8259 */
+       mov     $1, %eax        /* disabled by this function */
+       popf
+       leave
+       ret
+dis_already:
+       xor     %eax, %eax      /* already disabled */
+       popf
+       leave
+       ret
+
+
+/*===========================================================================*/
+/*                             phys_copy                                    */
+/*===========================================================================*/
+/*
+ * PUBLIC phys_bytes phys_copy(phys_bytes source, phys_bytes destination,
+ *                     phys_bytes bytecount); 
+ * Copy a block of physical memory. 
+ */
+
+       PC_ARGS = 4+4+4+4       /* 4 + 4 + 4 */
+/*             es edi esi eip   src dst len */
+
+.balign        16
+phys_copy:
+       cld
+       push    %esi
+       push    %edi
+       push    %es
+
+       mov     $FLAT_DS_SELECTOR, %eax
+       mov     %ax, %es
+
+       mov     PC_ARGS(%esp), %esi
+       mov     PC_ARGS+4(%esp), %edi
+       mov     PC_ARGS+4+4(%esp), %eax
+
+       cmp     $10, %eax       /* avoid align overhead for small counts */
+       jb      pc_small
+       mov     %esi, %ecx      /* align source, hope target is too */
+       neg     %ecx
+       and     $3, %ecx        /* count for alignment */
+       sub     %ecx, %eax
+
+       rep     movsb %es:(%esi), %es:(%edi)
+       mov     %eax, %ecx
+       shr     $2, %ecx        /* count of dwords */
+
+       rep     movsl %es:(%esi), %es:(%edi)
+       and     $3, %eax
+pc_small:
+       xchg    %eax, %ecx      /* remainder */
+
+       rep     movsb %es:(%esi), %es:(%edi)
+
+       mov     $0, %eax                /* 0 means: no fault */
+phys_copy_fault:                       /* kernel can send us here */
+       pop     %es
+       pop     %edi
+       pop     %esi
+       ret
+
+/*===========================================================================*/
+/*                             phys_memset                                  */
+/*===========================================================================*/
+/*
+ * PUBLIC void phys_memset(phys_bytes source, unsigned long pattern, 
+ *     phys_bytes bytecount); 
+ * Fill a block of physical memory with pattern. 
+ */
+
+.balign        16
+phys_memset:
+       push    %ebp
+       mov     %esp, %ebp
+       push    %esi
+       push    %ebx
+       push    %ds
+
+       mov     8(%ebp), %esi
+       mov     16(%ebp), %eax
+       mov     $FLAT_DS_SELECTOR, %ebx
+       mov     %bx, %ds
+       mov     12(%ebp), %ebx
+       shr     $2, %eax
+fill_start:
+       mov     %ebx, (%esi)
+       add     $4, %esi
+       dec     %eax
+       jne     fill_start
+/* Any remaining bytes? */
+       mov     16(%ebp), %eax
+       and     $3, %eax
+remain_fill:
+       cmp     $0, %eax
+       je      fill_done
+       movb    12(%ebp), %bl
+       movb    %bl, (%esi)
+       add     $1, %esi
+       inc     %ebp
+       dec     %eax
+       jmp     remain_fill
+fill_done:
+       pop     %ds
+       pop     %ebx
+       pop     %esi
+       pop     %ebp
+       ret
+
+
+/*===========================================================================*/
+/*                             mem_rdw                                      */
+/*===========================================================================*/
+/* 
+ * PUBLIC u16_t mem_rdw(U16_t segment, u16_t *offset); 
+ * Load and return word at far pointer segment:offset. 
+ */
+
+.balign        16
+mem_rdw:
+       mov     %ds, %cx
+       mov     4(%esp), %ds
+       mov     4+4(%esp), %eax /* offset */
+       movzwl  (%eax), %eax    /* word to return */
+       mov     %cx, %ds
+       ret
+
+
+/*===========================================================================*/
+/*                             reset                                        */
+/*===========================================================================*/
+/*
+ * PUBLIC void reset(); 
+ * Reset the system by loading IDT with offset 0 and interrupting. 
+ */
+
+reset:
+       lidt    idt_zero
+       int     $3      /* anything goes, the 386 will not like it */
+.data
+idt_zero:
+.long  0, 0
+.text
+
+
+/*===========================================================================*/
+/*                             idle_task                                    */
+/*===========================================================================*/
+idle_task:
+/*
+ * This task is called when the system has nothing else to do.  The HLT 
+ * instruction puts the processor in a state where it draws minimum power. 
+ */
+       push    $halt
+       call    level0  /* level0(halt) */
+       pop     %eax
+       jmp     idle_task
+halt:
+       sti
+       hlt
+       cli
+       ret
+
+/*===========================================================================*/
+/*                           level0                                         */
+/*===========================================================================*/
+/*
+ * PUBLIC void level0(void (*func)(void)) 
+ * Call a function at permission level 0.  This allows kernel tasks to do 
+ * things that are only possible at the most privileged CPU level. 
+ */ 
+level0:
+       mov     4(%esp), %eax
+       cmpb    $-1, k_reenter
+       jne     0f
+       int     $LEVEL0_VECTOR
+       ret
+
+0:
+       call    *%eax
+       ret
+
+
+
+
+/*===========================================================================*/
+/*                           read_flags                                             */
+/*===========================================================================*/
+/*
+ * PUBLIC unsigned long read_cpu_flags(void);
+ * Read CPU status flags from C.
+ */
+.balign        16
+read_cpu_flags:
+       pushf
+       mov     (%esp), %eax
+       popf
+       ret
+
+read_ds:
+       mov     $0, %eax
+       mov     %ds, %ax
+       ret
+
+read_cs:
+       mov     $0, %eax
+       mov     %cs, %ax
+       ret
+
+read_ss:
+       mov     $0, %eax
+       mov     %ss, %ax
+       ret
+
+
+/*===========================================================================*/
+/*                           read_cr0                                       */
+/*===========================================================================*/
+/* PUBLIC unsigned long read_cr0(void); */
+read_cr0:
+       push    %ebp
+       mov     %esp, %ebp
+       mov     %cr0, %eax
+       pop     %ebp
+       ret
+
+/*===========================================================================*/
+/*                           write_cr0                                      */
+/*===========================================================================*/
+/* PUBLIC void write_cr0(unsigned long value); */
+write_cr0:
+       push    %ebp
+       mov     %esp, %ebp
+       mov     8(%ebp), %eax
+       mov     %eax, %cr0
+       jmp     0f      /* A jump is required for some flags */
+0:
+       pop     %ebp
+       ret
+
+/*===========================================================================*/
+/*                           read_cr4                                       */
+/*===========================================================================*/
+/* PUBLIC unsigned long read_cr4(void); */
+read_cr4:
+       push    %ebp
+       mov     %esp, %ebp
+       mov     %cr4, %eax
+       pop     %ebp
+       ret
+
+/*===========================================================================*/
+/*                           write_cr4                                      */
+/*===========================================================================*/
+/* PUBLIC void write_cr4(unsigned long value); */
+write_cr4:
+       push    %ebp
+       mov     %esp, %ebp
+       mov     8(%ebp), %eax
+       mov     %eax, %cr4
+       jmp     0f
+0:
+       pop     %ebp
+       ret
+/*===========================================================================*/
+/*                             getcr3val                                    */
+/*===========================================================================*/
+/* PUBLIC unsigned long getcr3val(void); */
+getcr3val:
+       mov     %cr3, %eax
+       mov     %eax, thecr3
+       ret
+
diff --git a/kernel/arch/i386/klib386.s b/kernel/arch/i386/klib386.s
deleted file mode 100755 (executable)
index ed0cc22..0000000
+++ /dev/null
@@ -1,607 +0,0 @@
-# 
-! sections
-
-.sect .text; .sect .rom; .sect .data; .sect .bss
-
-#include <minix/config.h>
-#include <minix/const.h>
-#include <ibm/interrupt.h>
-#include <archconst.h>
-#include "../../const.h"
-#include "sconst.h"
-
-! This file contains a number of assembly code utility routines needed by the
-! kernel.  They are:
-
-.define        _monitor        ! exit Minix and return to the monitor
-.define        _int86          ! let the monitor make an 8086 interrupt call
-!.define       _cp_mess        ! copies messages from source to destination
-.define        _exit           ! dummy for library routines
-.define        __exit          ! dummy for library routines
-.define        ___exit         ! dummy for library routines
-.define        ___main         ! dummy for GCC
-.define        _phys_insw      ! transfer data from (disk controller) port to memory
-.define        _phys_insb      ! likewise byte by byte
-.define        _phys_outsw     ! transfer data from memory to (disk controller) port
-.define        _phys_outsb     ! likewise byte by byte
-.define        _intr_unmask    ! enable an irq at the 8259 controller
-.define        _intr_mask      ! disable an irq
-.define        _phys_copy      ! copy data from anywhere to anywhere in memory
-.define        _phys_copy_fault! phys_copy pagefault
-.define        _phys_memset    ! write pattern anywhere in memory
-.define        _mem_rdw        ! copy one word from [segment:offset]
-.define        _reset          ! reset the system
-.define        _idle_task      ! task executed when there is no work
-.define        _level0         ! call a function at level 0
-.define        _read_cpu_flags ! read the cpu flags
-.define        _read_cr0       ! read cr0
-.define        _getcr3val
-.define        _write_cr0      ! write a value in cr0
-.define        _read_cr4
-.define        _thecr3
-.define        _write_cr4
-.define        _catch_pagefaults
-.define        _read_ds
-.define        _read_cs
-.define        _read_ss
-
-! The routines only guarantee to preserve the registers the C compiler
-! expects to be preserved (ebx, esi, edi, ebp, esp, segment registers, and
-! direction bit in the flags).
-
-.sect .text
-!*===========================================================================*
-!*                             monitor                                      *
-!*===========================================================================*
-! PUBLIC void monitor();
-! Return to the monitor.
-
-_monitor:
-       mov     esp, (_mon_sp)          ! restore monitor stack pointer
-    o16 mov    dx, SS_SELECTOR         ! monitor data segment
-       mov     ds, dx
-       mov     es, dx
-       mov     fs, dx
-       mov     gs, dx
-       mov     ss, dx
-       pop     edi
-       pop     esi
-       pop     ebp
-    o16 retf                           ! return to the monitor
-
-
-!*===========================================================================*
-!*                             int86                                        *
-!*===========================================================================*
-! PUBLIC void int86();
-_int86:
-       cmpb    (_mon_return), 0        ! is the monitor there?
-       jnz     0f
-       movb    ah, 0x01                ! an int 13 error seems appropriate
-       movb    (_reg86+ 0), ah         ! reg86.w.f = 1 (set carry flag)
-       movb    (_reg86+13), ah         ! reg86.b.ah = 0x01 = "invalid command"
-       ret
-0:     push    ebp                     ! save C registers
-       push    esi
-       push    edi
-       push    ebx
-       pushf                           ! save flags
-       cli                             ! no interruptions
-
-       inb     INT2_CTLMASK
-       movb    ah, al
-       inb     INT_CTLMASK
-       push    eax                     ! save interrupt masks
-       mov     eax, (_irq_use)         ! map of in-use IRQ's
-       and     eax, ~[1<<CLOCK_IRQ]    ! keep the clock ticking
-       outb    INT_CTLMASK             ! enable all unused IRQ's and vv.
-       movb    al, ah
-       outb    INT2_CTLMASK
-
-       mov     eax, SS_SELECTOR        ! monitor data segment
-       mov     ss, ax
-       xchg    esp, (_mon_sp)          ! switch stacks
-       push    (_reg86+36)             ! parameters used in INT call
-       push    (_reg86+32)
-       push    (_reg86+28)
-       push    (_reg86+24)
-       push    (_reg86+20)
-       push    (_reg86+16)
-       push    (_reg86+12)
-       push    (_reg86+ 8)
-       push    (_reg86+ 4)
-       push    (_reg86+ 0)
-       mov     ds, ax                  ! remaining data selectors
-       mov     es, ax
-       mov     fs, ax
-       mov     gs, ax
-       push    cs
-       push    return                  ! kernel return address and selector
-    o16        jmpf    20+2*4+10*4+2*4(esp)    ! make the call
-return:
-       pop     (_reg86+ 0)
-       pop     (_reg86+ 4)
-       pop     (_reg86+ 8)
-       pop     (_reg86+12)
-       pop     (_reg86+16)
-       pop     (_reg86+20)
-       pop     (_reg86+24)
-       pop     (_reg86+28)
-       pop     (_reg86+32)
-       pop     (_reg86+36)
-       lgdt    (_gdt+GDT_SELECTOR)     ! reload global descriptor table
-       jmpf    CS_SELECTOR:csinit      ! restore everything
-csinit:        mov     eax, DS_SELECTOR
-       mov     ds, ax
-       mov     es, ax
-       mov     fs, ax
-       mov     gs, ax
-       mov     ss, ax
-       xchg    esp, (_mon_sp)          ! unswitch stacks
-       lidt    (_gdt+IDT_SELECTOR)     ! reload interrupt descriptor table
-       andb    (_gdt+TSS_SELECTOR+DESC_ACCESS), ~0x02  ! clear TSS busy bit
-       mov     eax, TSS_SELECTOR
-       ltr     ax                      ! set TSS register
-
-       pop     eax
-       outb    INT_CTLMASK             ! restore interrupt masks
-       movb    al, ah
-       outb    INT2_CTLMASK
-
-       add     (_lost_ticks), ecx      ! record lost clock ticks
-
-       popf                            ! restore flags
-       pop     ebx                     ! restore C registers
-       pop     edi
-       pop     esi
-       pop     ebp
-       ret
-
-
-!*===========================================================================*
-!*                             exit                                         *
-!*===========================================================================*
-! PUBLIC void exit();
-! Some library routines use exit, so provide a dummy version.
-! Actual calls to exit cannot occur in the kernel.
-! GNU CC likes to call ___main from main() for nonobvious reasons.
-
-_exit:
-__exit:
-___exit:
-       sti
-       jmp     ___exit
-
-___main:
-       ret
-
-
-!*===========================================================================*
-!*                             phys_insw                                    *
-!*===========================================================================*
-! PUBLIC void phys_insw(Port_t port, phys_bytes buf, size_t count);
-! Input an array from an I/O port.  Absolute address version of insw().
-
-_phys_insw:
-       push    ebp
-       mov     ebp, esp
-       cld
-       push    edi
-       push    es
-
-       mov     ecx, FLAT_DS_SELECTOR
-       mov     es, cx
-       mov     edx, 8(ebp)             ! port to read from
-       mov     edi, 12(ebp)            ! destination addr
-       mov     ecx, 16(ebp)            ! byte count
-       shr     ecx, 1                  ! word count
-rep o16        ins                             ! input many words
-       pop     es
-       pop     edi
-       pop     ebp
-       ret
-
-
-!*===========================================================================*
-!*                             phys_insb                                    *
-!*===========================================================================*
-! PUBLIC void phys_insb(Port_t port, phys_bytes buf, size_t count);
-! Input an array from an I/O port.  Absolute address version of insb().
-
-_phys_insb:
-       push    ebp
-       mov     ebp, esp
-       cld
-       push    edi
-       push    es
-
-       mov     ecx, FLAT_DS_SELECTOR
-       mov     es, cx
-       mov     edx, 8(ebp)             ! port to read from
-       mov     edi, 12(ebp)            ! destination addr
-       mov     ecx, 16(ebp)            ! byte count
-!      shr     ecx, 1                  ! word count
-   rep insb                            ! input many bytes
-       pop     es
-       pop     edi
-       pop     ebp
-       ret
-
-
-!*===========================================================================*
-!*                             phys_outsw                                   *
-!*===========================================================================*
-! PUBLIC void phys_outsw(Port_t port, phys_bytes buf, size_t count);
-! Output an array to an I/O port.  Absolute address version of outsw().
-
-       .align  16
-_phys_outsw:
-       push    ebp
-       mov     ebp, esp
-       cld
-       push    esi
-       push    ds
-
-       mov     ecx, FLAT_DS_SELECTOR
-       mov     ds, cx
-       mov     edx, 8(ebp)             ! port to write to
-       mov     esi, 12(ebp)            ! source addr
-       mov     ecx, 16(ebp)            ! byte count
-       shr     ecx, 1                  ! word count
-rep o16        outs                            ! output many words
-       pop     ds
-       pop     esi
-       pop     ebp
-       ret
-
-
-!*===========================================================================*
-!*                             phys_outsb                                   *
-!*===========================================================================*
-! PUBLIC void phys_outsb(Port_t port, phys_bytes buf, size_t count);
-! Output an array to an I/O port.  Absolute address version of outsb().
-
-       .align  16
-_phys_outsb:
-       push    ebp
-       mov     ebp, esp
-       cld
-       push    esi
-       push    ds
-
-       mov     ecx, FLAT_DS_SELECTOR
-       mov     ds, cx
-       mov     edx, 8(ebp)             ! port to write to
-       mov     esi, 12(ebp)            ! source addr
-       mov     ecx, 16(ebp)            ! byte count
-   rep outsb                           ! output many bytes
-       pop     ds
-       pop     esi
-       pop     ebp
-       ret
-
-
-!*==========================================================================*
-!*                             intr_unmask                                 *
-!*==========================================================================*/
-! PUBLIC void intr_unmask(irq_hook_t *hook)
-! Enable an interrupt request line by clearing an 8259 bit.
-! Equivalent C code for hook->irq < 8:
-!   if ((irq_actids[hook->irq] &= ~hook->id) == 0)
-!      outb(INT_CTLMASK, inb(INT_CTLMASK) & ~(1 << irq));
-
-       .align  16
-_intr_unmask:
-       push    ebp
-       mov     ebp, esp
-       pushf
-       cli
-       mov     eax, 8(ebp)             ! hook
-       mov     ecx, 8(eax)             ! irq
-       mov     eax, 12(eax)            ! id bit
-       not     eax
-       and     _irq_actids(ecx*4), eax ! clear this id bit
-       jnz     en_done                 ! still masked by other handlers?
-       movb    ah, ~1
-       rolb    ah, cl                  ! ah = ~(1 << (irq % 8))
-       mov     edx, INT_CTLMASK        ! enable irq < 8 at the master 8259
-       cmpb    cl, 8
-       jb      0f
-       mov     edx, INT2_CTLMASK       ! enable irq >= 8 at the slave 8259
-0:     inb     dx
-       andb    al, ah
-       outb    dx                      ! clear bit at the 8259
-en_done:popf
-       leave
-       ret
-
-
-!*==========================================================================*
-!*                             intr_mask                                   *
-!*==========================================================================*/
-! PUBLIC int intr_mask(irq_hook_t *hook)
-! Disable an interrupt request line by setting an 8259 bit.
-! Equivalent C code for irq < 8:
-!   irq_actids[hook->irq] |= hook->id;
-!   outb(INT_CTLMASK, inb(INT_CTLMASK) | (1 << irq));
-! Returns true iff the interrupt was not already disabled.
-
-       .align  16
-_intr_mask:
-       push    ebp
-       mov     ebp, esp
-       pushf
-       cli
-       mov     eax, 8(ebp)             ! hook
-       mov     ecx, 8(eax)             ! irq
-       mov     eax, 12(eax)            ! id bit
-       or      _irq_actids(ecx*4), eax ! set this id bit
-       movb    ah, 1
-       rolb    ah, cl                  ! ah = (1 << (irq % 8))
-       mov     edx, INT_CTLMASK        ! disable irq < 8 at the master 8259
-       cmpb    cl, 8
-       jb      0f
-       mov     edx, INT2_CTLMASK       ! disable irq >= 8 at the slave 8259
-0:     inb     dx
-       testb   al, ah
-       jnz     dis_already             ! already disabled?
-       orb     al, ah
-       outb    dx                      ! set bit at the 8259
-       mov     eax, 1                  ! disabled by this function
-       popf
-       leave
-       ret
-dis_already:
-       xor     eax, eax                ! already disabled
-       popf
-       leave
-       ret
-
-
-!*===========================================================================*
-!*                             phys_copy                                    *
-!*===========================================================================*
-! PUBLIC phys_bytes phys_copy(phys_bytes source, phys_bytes destination,
-!                      phys_bytes bytecount);
-! Copy a block of physical memory.
-
-PC_ARGS        =       4 + 4 + 4 + 4   ! 4 + 4 + 4
-!              es edi esi eip   src dst len
-
-       .align  16
-_phys_copy:
-       cld
-       push    esi
-       push    edi
-       push    es
-
-       mov     eax, FLAT_DS_SELECTOR
-       mov     es, ax
-
-       mov     esi, PC_ARGS(esp)
-       mov     edi, PC_ARGS+4(esp)
-       mov     eax, PC_ARGS+4+4(esp)
-
-       cmp     eax, 10                 ! avoid align overhead for small counts
-       jb      pc_small
-       mov     ecx, esi                ! align source, hope target is too
-       neg     ecx
-       and     ecx, 3                  ! count for alignment
-       sub     eax, ecx
-       rep
-   eseg        movsb
-       mov     ecx, eax
-       shr     ecx, 2                  ! count of dwords
-       rep
-   eseg        movs
-       and     eax, 3
-pc_small:
-       xchg    ecx, eax                ! remainder
-       rep
-   eseg        movsb
-
-       mov     eax, 0                  ! 0 means: no fault
-_phys_copy_fault:                      ! kernel can send us here
-       pop     es
-       pop     edi
-       pop     esi
-       ret
-
-!*===========================================================================*
-!*                             phys_memset                                  *
-!*===========================================================================*
-! PUBLIC void phys_memset(phys_bytes source, unsigned long pattern,
-!      phys_bytes bytecount);
-! Fill a block of physical memory with pattern.
-
-       .align  16
-_phys_memset:
-       push    ebp
-       mov     ebp, esp
-       push    esi
-       push    ebx
-       push    ds
-
-       mov     esi, 8(ebp)
-       mov     eax, 16(ebp)
-       mov     ebx, FLAT_DS_SELECTOR
-       mov     ds, bx
-       mov     ebx, 12(ebp)
-       shr     eax, 2
-fill_start:
-       mov     (esi), ebx
-       add     esi, 4
-       dec     eax
-       jnz     fill_start
-       ! Any remaining bytes?
-       mov     eax, 16(ebp)
-       and     eax, 3
-remain_fill:
-       cmp     eax, 0
-       jz      fill_done
-       movb    bl, 12(ebp)
-       movb    (esi), bl
-       add     esi, 1
-       inc     ebp
-       dec     eax
-       jmp     remain_fill
-fill_done:
-       pop     ds
-       pop     ebx
-       pop     esi
-       pop     ebp
-       ret
-       
-
-!*===========================================================================*
-!*                             mem_rdw                                      *
-!*===========================================================================*
-! PUBLIC u16_t mem_rdw(U16_t segment, u16_t *offset);
-! Load and return word at far pointer segment:offset.
-
-       .align  16
-_mem_rdw:
-       mov     cx, ds
-       mov     ds, 4(esp)              ! segment
-       mov     eax, 4+4(esp)           ! offset
-       movzx   eax, (eax)              ! word to return
-       mov     ds, cx
-       ret
-
-
-!*===========================================================================*
-!*                             reset                                        *
-!*===========================================================================*
-! PUBLIC void reset();
-! Reset the system by loading IDT with offset 0 and interrupting.
-
-_reset:
-       lidt    (idt_zero)
-       int     3               ! anything goes, the 386 will not like it
-.sect .data
-idt_zero:      .data4  0, 0
-.sect .text
-
-
-!*===========================================================================*
-!*                             idle_task                                    *
-!*===========================================================================*
-_idle_task:
-! This task is called when the system has nothing else to do.  The HLT
-! instruction puts the processor in a state where it draws minimum power.
-       push    _halt
-       call    _level0         ! level0(halt)
-       pop     eax
-       jmp     _idle_task
-_halt:
-       sti
-       hlt
-       cli
-       ret
-
-!*===========================================================================*
-!*                           level0                                         *
-!*===========================================================================*
-! PUBLIC void level0(void (*func)(void))
-! Call a function at permission level 0.  This allows kernel tasks to do
-! things that are only possible at the most privileged CPU level.
-!
-_level0:
-       mov     eax, 4(esp)
-       cmpb    (_k_reenter), -1
-       jne     direct
-       int     LEVEL0_VECTOR
-       ret
-
-direct:
-       call    eax
-       ret
-
-
-!*===========================================================================*
-!*                           read_flags                                             *
-!*===========================================================================*
-! PUBLIC unsigned long read_cpu_flags(void);
-! Read CPU status flags from C.
-.align 16
-_read_cpu_flags:
-       pushf
-       mov eax, (esp)
-       popf
-       ret
-
-
-!*===========================================================================*
-!*                           read_cr0                                       *
-!*===========================================================================*
-! PUBLIC unsigned long read_cr0(void);
-_read_cr0:
-       push    ebp
-       mov     ebp, esp
-       mov     eax, cr0
-       pop     ebp
-       ret
-
-!*===========================================================================*
-!*                           write_cr0                                      *
-!*===========================================================================*
-! PUBLIC void write_cr0(unsigned long value);
-_write_cr0:
-       push    ebp
-       mov     ebp, esp
-       mov     eax, 8(ebp)
-       mov     cr0, eax
-       jmp     0f              ! A jump is required for some flags
-0:
-       pop     ebp
-       ret
-
-!*===========================================================================*
-!*                           read_cr4                                       *
-!*===========================================================================*
-! PUBLIC unsigned long read_cr4(void);
-_read_cr4:
-       push    ebp
-       mov     ebp, esp
-.data1 0x0f, 0x20, 0xe0 ! mov eax, cr4
-       pop     ebp
-       ret
-
-!*===========================================================================*
-!*                           write_cr4                                      *
-!*===========================================================================*
-! PUBLIC void write_cr4(unsigned long value);
-_write_cr4:
-       push    ebp
-       mov     ebp, esp
-       mov     eax, 8(ebp)
-.data1 0x0f, 0x22, 0xe0 ! mov cr4, eax
-       jmp     0f
-0:
-       pop     ebp
-       ret
-
-_read_ds:
-       mov     eax, 0
-       mov     ax, ds
-       ret
-
-_read_cs:
-       mov     eax, 0
-       mov     ax, cs
-       ret
-
-_read_ss:
-       mov     eax, 0
-       mov     ax, ss
-       ret
-
-!*===========================================================================*
-!*                             getcr3val                               *
-!*===========================================================================*
-! PUBLIC unsigned long getcr3val(void);
-_getcr3val:
-       mov     eax, cr3
-       mov     (_thecr3), eax
-       ret
-
diff --git a/kernel/arch/i386/mpx386.S b/kernel/arch/i386/mpx386.S
new file mode 100644 (file)
index 0000000..56c68f9
--- /dev/null
@@ -0,0 +1,656 @@
+/* 
+ * This file, mpx386.s, is included by mpx.s when Minix is compiled for  
+ * 32-bit Intel CPUs. The alternative mpx88.s is compiled for 16-bit CPUs. 
+ *
+ * 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. 
+ * Furthermore it contains the assembler startup code for Minix and the 32-bit 
+ * interrupt handlers.  It cooperates with the code in "start.c" to set up a  
+ * good environment for main(). 
+ *
+ * Every transition to the kernel goes through this file.  Transitions to the  
+ * kernel may be nested.  The initial entry may be with a system call (i.e.,  
+ * send or receive a message), an exception or a hardware interrupt;  kernel  
+ * 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.
+ */
+
+/* sections */
+
+#include <sys/vm_i386.h>
+
+#ifdef __ACK__
+.text
+begtext:
+#ifdef __ACK__
+.rom
+#else
+.data
+#endif
+begrom:
+.data
+begdata:
+.bss
+begbss:
+#endif
+
+
+#include <minix/config.h>
+#include <minix/const.h>
+#include <minix/com.h>
+#include <ibm/interrupt.h>
+#include <archconst.h>
+#include "../../const.h"
+#include "sconst.h"
+
+/* Selected 386 tss offsets. */
+#define TSS3_S_SP0     4
+
+/*
+ * Exported functions 
+ * 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. 
+ */
+
+.globl restart
+.globl save
+.globl reload_cr3
+.globl write_cr3
+
+.globl errexception
+.globl exception1
+.globl exception
+
+.globl divide_error
+.globl single_step_exception
+.globl nmi
+.globl breakpoint_exception
+.globl overflow
+.globl bounds_check
+.globl inval_opcode
+.globl copr_not_available
+.globl double_fault
+.globl copr_seg_overrun
+.globl inval_tss
+.globl segment_not_present
+.globl stack_exception
+.globl general_protection
+.globl page_fault
+.globl copr_error
+.globl params_size
+.globl params_offset
+.globl mon_ds
+.globl  schedcheck
+.globl  dirtypde
+
+.globl hwint00 /* handlers for hardware interrupts */
+.globl hwint01
+.globl hwint02
+.globl hwint03
+.globl hwint04
+.globl hwint05
+.globl hwint06
+.globl hwint07
+.globl hwint08
+.globl hwint09
+.globl hwint10
+.globl hwint11
+.globl hwint12
+.globl hwint13
+.globl hwint14
+.globl hwint15
+
+.globl s_call
+.globl p_s_call
+.globl level0_call
+
+/* Exported variables. */
+.globl begbss
+.globl begdata
+
+.text
+/*===========================================================================*/
+/*                             MINIX                                        */
+/*===========================================================================*/
+.global MINIX
+MINIX:
+/* this is the entry point for the MINIX kernel */
+       jmp     over_flags      /* skip over the next few bytes */
+.short CLICK_SHIFT     /* for the monitor: memory granularity */
+
+flags:
+/* boot monitor flags:
+ *     call in 386 mode, make bss, make stack, 
+ *     load high, don't patch, will return, 
+ *     uses generic INT, memory vector, 
+ *     new boot code return 
+ */
+.short 0x01FD  
+       nop     /* extra byte to sync up disassembler */
+over_flags:
+
+/* Set up a C stack frame on the monitor stack.  (The monitor sets cs and ds */
+/* right.  The ss descriptor still references the monitor data segment.) */
+       movzwl  %sp, %esp       /* monitor stack is a 16 bit stack */
+       push    %ebp
+       mov     %esp, %ebp
+       push    %esi
+       push    %edi
+       cmp     $0, 4(%ebp)     /* monitor return vector is */
+       je      noret   /* nonzero if return possible */
+       incl    mon_return
+noret:
+       movl    %esp, mon_sp    /* save stack pointer for later return */
+
+/* Copy the monitor global descriptor table to the address space of kernel and */
+/* switch over to it.  Prot_init() can then update it with immediate effect. */
+
+       sgdt    gdt+GDT_SELECTOR        /* get the monitor gdtr */
+       movl    gdt+GDT_SELECTOR+2, %esi        /* absolute address of GDT */
+       mov     $gdt, %ebx      /* address of kernel GDT */
+       mov     $8*8, %ecx      /* copying eight descriptors */
+copygdt:
+       movb    %es:(%esi), %al
+       movb    %al, (%ebx)
+       inc     %esi
+       inc     %ebx
+       loop    copygdt
+       movl    gdt+DS_SELECTOR+2, %eax /* base of kernel data */
+       and     $0x00FFFFFF, %eax       /* only 24 bits */
+       add     $gdt, %eax      /* eax = vir2phys(gdt) */
+       movl    %eax, gdt+GDT_SELECTOR+2        /* set base of GDT */
+       lgdt    gdt+GDT_SELECTOR        /* switch over to kernel GDT */
+
+/* Locate boot parameters, set up kernel segment registers and stack. */
+       mov     8(%ebp), %ebx   /* boot parameters offset */
+       mov     12(%ebp), %edx  /* boot parameters length */
+       mov     16(%ebp), %eax  /* address of a.out headers */
+       movl    %eax, aout
+       mov     %ds, %ax        /* kernel data */
+       mov     %ax, %es
+       mov     %ax, %fs
+       mov     %ax, %gs
+       mov     %ax, %ss
+       mov     $k_stktop, %esp /* set sp to point to the top of kernel stack */
+
+/* Save boot parameters into these global variables for i386 code */
+       movl    %edx, params_size
+       movl    %ebx, params_offset
+       movl    $SS_SELECTOR, mon_ds
+
+/* Call C startup code to set up a proper environment to run main(). */
+       push    %edx
+       push    %ebx
+       push    $SS_SELECTOR
+       push    $DS_SELECTOR
+       push    $CS_SELECTOR
+       call    cstart  /* cstart(cs, ds, mds, parmoff, parmlen) */
+       add     $5*4, %esp
+
+/* Reload gdtr, idtr and the segment registers to global descriptor table set */
+/* up by prot_init(). */
+
+       lgdt    gdt+GDT_SELECTOR
+       lidt    gdt+IDT_SELECTOR
+
+       ljmp    $CS_SELECTOR, $csinit
+csinit:
+       movw    $DS_SELECTOR, %ax
+       mov     %ax, %ds
+       mov     %ax, %es
+       mov     %ax, %fs
+       mov     %ax, %gs
+       mov     %ax, %ss
+       movw    $TSS_SELECTOR, %ax      /* no other TSS is used */
+       ltr     %ax
+       push    $0      /* set flags to known good state */
+       popf    /* esp, clear nested task and int enable */
+       jmp     main    /* main() */
+
+
+/*===========================================================================*/
+/*                             interrupt handlers                           */
+/*             interrupt handlers for 386 32-bit protected mode             */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/*                             hwint00 - 07                                 */
+/*===========================================================================*/
+/* Note this is a macro, it just looks like a subroutine. */
+#define hwint_master(irq)      \
+       call    save                    /* save interrupted process state */;\
+       push    (irq_handlers+4*irq)    /* irq_handlers[irq]              */;\
+       call    intr_handle             /* intr_handle(irq_handlers[irq]) */;\
+       pop     %ecx                                                        ;\
+       cmp     $0, (irq_actids+4*irq)  /* interrupt still active?        */;\
+       jz      0f                                                          ;\
+       inb     $INT_CTLMASK            /* get current mask */              ;\
+       orb     $(1<<irq), %al          /* mask irq */                      ;\
+       outb    $INT_CTLMASK            /* disable the irq                */;\
+0:     movb    $END_OF_INT, %al                                                    ;\
+       outb    $INT_CTL                        /* reenable master 8259           */;\
+       ret                             /* restart (another) process      */
+
+/* Each of these entry points is an expansion of the hwint_master macro */
+.balign        16
+hwint00:
+/* Interrupt routine for irq 0 (the clock). */
+       hwint_master(0)
+
+.balign        16
+hwint01:
+/* Interrupt routine for irq 1 (keyboard) */
+       hwint_master(1)
+
+.balign        16
+hwint02:
+/* Interrupt routine for irq 2 (cascade!) */
+       hwint_master(2)
+
+.balign        16
+hwint03:
+/* Interrupt routine for irq 3 (second serial) */
+       hwint_master(3)
+
+.balign        16
+hwint04:
+/* Interrupt routine for irq 4 (first serial) */
+       hwint_master(4)
+
+.balign        16
+hwint05:
+/* Interrupt routine for irq 5 (XT winchester) */
+       hwint_master(5)
+
+.balign        16
+hwint06:
+/* Interrupt routine for irq 6 (floppy) */
+       hwint_master(6)
+
+.balign        16
+hwint07:
+/* Interrupt routine for irq 7 (printer) */
+       hwint_master(7)
+
+/*===========================================================================*/
+/*                             hwint08 - 15                                 */
+/*===========================================================================*/
+/* Note this is a macro, it just looks like a subroutine. */
+#define hwint_slave(irq)       \
+       call    save                    /* save interrupted process state */;\
+       push    (irq_handlers+4*irq)    /* irq_handlers[irq]              */;\
+       call    intr_handle             /* intr_handle(irq_handlers[irq]) */;\
+       pop     %ecx                                                        ;\
+       cmp     $0, (irq_actids+4*irq)  /* interrupt still active?        */;\
+       jz      0f                                                          ;\
+       inb     $INT2_CTLMASK                                               ;\
+       orb     $(1<<(irq-8)), %al                                          ;\
+       outb    $INT2_CTLMASK           /* disable the irq                */;\
+0:     movb    $END_OF_INT, %al                                                    ;\
+       outb    $INT_CTL                        /* reenable master 8259           */;\
+       outb    $INT2_CTL               /* reenable slave 8259            */;\
+       ret                             /* restart (another) process      */
+
+/* Each of these entry points is an expansion of the hwint_slave macro */
+.balign        16
+hwint08:
+/* Interrupt routine for irq 8 (realtime clock) */
+       hwint_slave(8)
+
+.balign        16
+hwint09:
+/* Interrupt routine for irq 9 (irq 2 redirected) */
+       hwint_slave(9)
+
+.balign        16
+hwint10:
+/* Interrupt routine for irq 10 */
+       hwint_slave(10)
+
+.balign        16
+hwint11:
+/* Interrupt routine for irq 11 */
+       hwint_slave(11)
+
+.balign        16
+hwint12:
+/* Interrupt routine for irq 12 */
+       hwint_slave(12)
+
+.balign        16
+hwint13:
+/* Interrupt routine for irq 13 (FPU exception) */
+       hwint_slave(13)
+
+.balign        16
+hwint14:
+/* Interrupt routine for irq 14 (AT winchester) */
+       hwint_slave(14)
+
+.balign        16
+hwint15:
+/* Interrupt routine for irq 15 */
+       hwint_slave(15)
+
+/*===========================================================================*/
+/*                             save                                         */
+/*===========================================================================*/
+/*
+ * Save for protected mode. 
+ * This is much simpler than for 8086 mode, because the stack already points 
+ * into the process table, or has already been switched to the kernel stack. 
+ */
+
+.balign        16
+save:
+       cld     /* set direction flag to a known value */
+       pushal  /* save "general" registers */
+       pushw   %ds     /* save ds */
+       pushw   %es     /* save es */
+       pushw   %fs     /* save fs */
+       pushw   %gs     /* save gs */
+       mov     %ss, %dx        /* ss is kernel data segment */
+       mov     %dx, %ds        /* load rest of kernel segments */
+       mov     %dx, %es        /* kernel does not use fs, gs */
+       mov     %esp, %eax      /* prepare to return */
+       incb    k_reenter       /* from -1 if not reentering */
+       jne     set_restart1    /* stack is already kernel stack */
+       mov     $k_stktop, %esp
+       push    $restart        /* build return address for int handler */
+       xor     %ebp, %ebp      /* for stacktrace */
+       jmp     *RETADR-P_STACKBASE(%eax)
+
+.balign        4
+set_restart1:
+       push    $restart1
+       jmp     *RETADR-P_STACKBASE(%eax)
+
+/*===========================================================================*/
+/*                             _s_call                                      */
+/*===========================================================================*/
+.balign        16
+s_call:
+p_s_call:
+       cld     /* set direction flag to a known value */
+       sub     $4, %esp        /* skip RETADR */
+       pusha                   /* save "general" registers */
+       pushw   %ds
+       pushw   %es
+       pushw   %fs
+       pushw   %gs
+
+       mov     %ss, %si        /* ss is kernel data segment */
+       mov     %si, %ds        /* load rest of kernel segments */
+       mov     %si, %es        /* kernel does not use fs, gs */
+       incb    k_reenter       /* increment kernel entry count */
+       mov     %esp, %esi      /* assumes P_STACKBASE == 0 */
+       mov     $k_stktop, %esp
+       xor     %ebp, %ebp      /* for stacktrace */
+/* end of inline save */
+/* now set up parameters for sys_call() */
+       push    %edx    /* event set or flags bit map  */
+       push    %ebx    /* pointer to user message */
+       push    %eax    /* source / destination */
+       push    %ecx    /* call number (ipc primitive to use) */
+
+       call    sys_call        /* sys_call(call_nr, src_dst, m_ptr, bit_map) */
+/* caller is now explicitly in proc_ptr */
+       mov     %eax, AXREG(%esi)
+
+/* Fall into code to restart proc/task running. */
+
+/*===========================================================================*/
+/*                             restart                                      */
+/*===========================================================================*/
+restart:
+
+/* Restart the current process or the next process if it is set.  */
+
+       cli
+       call    schedcheck
+       movl    proc_ptr, %esp  /* will assume P_STACKBASE == 0 */
+       lldt    P_LDT_SEL(%esp) /* enable process' segment descriptors  */
+       cmpl    $0, P_CR3(%esp)
+       jz      0f
+       mov     P_CR3(%esp), %eax
+       cmpl    loadedcr3, %eax
+       jz      0f
+       mov     %eax, %cr3
+       mov     %eax, loadedcr3
+       mov     proc_ptr, %eax
+       mov     %eax, ptproc
+       movl    $0, dirtypde
+0:
+       lea     P_STACKTOP(%esp), %eax  /* arrange for next interrupt */
+       movl    %eax, tss+TSS3_S_SP0    /* to save state in process table */
+restart1:
+       decb    k_reenter
+       popw    %gs
+       popw    %fs
+       popw    %es
+       popw    %ds
+       popal
+       add     $4, %esp        /* skip return adr */
+       iret    /* continue process */
+
+/*===========================================================================*/
+/*                             exception handlers                           */
+/*===========================================================================*/
+divide_error:
+       push    $DIVIDE_VECTOR
+       jmp     handle_exception
+
+single_step_exception:
+       push    $DEBUG_VECTOR
+       jmp     handle_exception
+
+nmi:
+       push    $NMI_VECTOR
+       jmp     handle_exception
+
+breakpoint_exception:
+       push    $BREAKPOINT_VECTOR
+       jmp     handle_exception
+
+overflow:
+       push    $OVERFLOW_VECTOR
+       jmp     handle_exception
+
+bounds_check:
+       push    $BOUNDS_VECTOR
+       jmp     handle_exception
+
+inval_opcode:
+       push    $INVAL_OP_VECTOR
+       jmp     handle_exception
+
+copr_not_available:
+       push    $COPROC_NOT_VECTOR
+       jmp     handle_exception
+
+double_fault:
+       push    $DOUBLE_FAULT_VECTOR
+       jmp     errexception
+
+copr_seg_overrun:
+       push    $COPROC_SEG_VECTOR
+       jmp     handle_exception
+
+inval_tss:
+       push    $INVAL_TSS_VECTOR
+       jmp     errexception
+
+segment_not_present:
+       push    $SEG_NOT_VECTOR
+       jmp     errexception
+
+stack_exception:
+       push    $STACK_FAULT_VECTOR
+       jmp     errexception
+
+general_protection:
+       push    $PROTECTION_VECTOR
+       jmp     errexception
+
+page_fault:
+       push    $PAGE_FAULT_VECTOR
+       push    %eax
+       mov     %cr2, %eax
+       movl    %eax, %ss:pagefaultcr2
+       pop     %eax
+       jmp     errexception
+
+copr_error:
+       push    $COPROC_ERR_VECTOR
+       jmp     handle_exception
+
+/*===========================================================================*/
+/*                             handle_exception                                     */
+/*===========================================================================*/
+/* This is called for all exceptions which do not push an error code. */
+
+.balign        16
+handle_exception:
+       movl    $0, %ss:trap_errno      /* clear trap_errno */
+       pop     %ss:ex_number
+       jmp     exception1
+
+/*===========================================================================*/
+/*                             errexception                                 */
+/*===========================================================================*/
+/* This is called for all exceptions which push an error code. */
+
+.balign        16
+errexception:
+       pop     %ss:ex_number
+       pop     %ss:trap_errno
+exception1:
+/* Common for all exceptions. */
+       movl    %esp, %ss:old_eax_ptr           /* where will eax be saved */
+       subl    $PCREG-AXREG, %ss:old_eax_ptr   /* here */
+
+       push    %eax    /* eax is scratch register */
+
+       mov     0+4(%esp), %eax /* old eip */
+       movl    %eax, %ss:old_eip
+       mov     %esp, %eax
+       add     $4, %eax
+       mov     %eax, %ss:old_eip_ptr
+       movzwl  4+4(%esp), %eax /* old cs */
+       movl    %eax, %ss:old_cs
+       mov     8+4(%esp), %eax /* old eflags */
+       movl    %eax, %ss:old_eflags
+
+       pop     %eax
+       call    save
+       push    pagefaultcr2
+       push    old_eax_ptr
+       push    old_eip_ptr
+       push    old_eflags
+       push    old_cs
+       push    old_eip
+       push    trap_errno
+       push    ex_number
+       call    exception       /* (ex_number, trap_errno, old_eip, */
+                               /* old_cs, old_eflags) */
+       add     $8*4, %esp
+       ret
+
+/*===========================================================================*/
+/*                             write_cr3                                    */
+/*===========================================================================*/
+/* PUBLIC void write_cr3(unsigned long value); */
+write_cr3:
+       push    %ebp
+       mov     %esp, %ebp
+       mov     8(%ebp), %eax
+       cmpl    loadedcr3, %eax
+       jz      0f
+       mov     %eax, %cr3
+       mov     %eax, loadedcr3
+       movl    $0, dirtypde
+0:
+       pop     %ebp
+       ret
+
+/*===========================================================================*/
+/*                             level0_call                                  */
+/*===========================================================================*/
+level0_call:
+/*
+ * which level0 function to call was passed here by putting it in eax, so
+ * we get that from the saved state.
+ */
+       call    save
+       movl    proc_ptr, %eax
+       movl    AXREG(%eax), %eax
+       jmp     *%eax
+
+
+/*===========================================================================*/
+/*                             reload_cr3                                   */
+/*===========================================================================*/
+/* PUBLIC void reload_cr3(void); */
+reload_cr3:
+       push    %ebp
+       mov     %esp, %ebp
+       movl    $0, dirtypde
+       mov     %cr3, %eax
+       mov     %eax, %cr3
+       pop     %ebp
+       ret
+
+/*===========================================================================*/
+/*                             data                                         */
+/*===========================================================================*/
+
+#ifdef __ACK__
+.rom   /* Before the string table please */
+#else
+.data
+#endif
+.short 0x526F  /* this must be the first data entry (magic #) */
+
+.bss
+k_stack:
+.space K_STACK_BYTES   /* kernel stack */
+k_stktop:
+/* top of kernel stack */
+.lcomm ex_number, 4
+.lcomm trap_errno, 4
+.lcomm  old_eip_ptr, 4
+.lcomm  old_eax_ptr, 4
+.lcomm old_eip, 4
+.lcomm old_cs, 4
+.lcomm old_eflags, 4
+.lcomm  pagefaultcr2, 4
+.lcomm  loadedcr3, 4
diff --git a/kernel/arch/i386/mpx386.s b/kernel/arch/i386/mpx386.s
deleted file mode 100755 (executable)
index ccebabf..0000000
+++ /dev/null
@@ -1,615 +0,0 @@
-#
-! This file, mpx386.s, is included by mpx.s when Minix is compiled for 
-! 32-bit Intel CPUs. The alternative mpx88.s is compiled for 16-bit CPUs.
-
-! 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.
-! Furthermore it contains the assembler startup code for Minix and the 32-bit
-! interrupt handlers.  It cooperates with the code in "start.c" to set up a 
-! good environment for main().
-
-! Every transition to the kernel goes through this file.  Transitions to the 
-! kernel may be nested.  The initial entry may be with a system call (i.e., 
-! send or receive a message), an exception or a hardware interrupt;  kernel 
-! 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.
-
-! sections
-
-#include <sys/vm_i386.h>
-
-.sect .text
-begtext:
-.sect .rom
-begrom:
-.sect .data
-begdata:
-.sect .bss
-begbss:
-
-#include <minix/config.h>
-#include <minix/const.h>
-#include <minix/com.h>
-#include <ibm/interrupt.h>
-#include <archconst.h>
-#include "../../const.h"
-#include "sconst.h"
-
-/* Selected 386 tss offsets. */
-#define TSS3_S_SP0     4
-
-! Exported functions
-! 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        _restart
-.define        save
-.define _reload_cr3
-.define        _write_cr3      ! write cr3
-
-.define errexception
-.define exception1
-.define exception
-
-.define        _divide_error
-.define        _single_step_exception
-.define        _nmi
-.define        _breakpoint_exception
-.define        _overflow
-.define        _bounds_check
-.define        _inval_opcode
-.define        _copr_not_available
-.define        _double_fault
-.define        _copr_seg_overrun
-.define        _inval_tss
-.define        _segment_not_present
-.define        _stack_exception
-.define        _general_protection
-.define        _page_fault
-.define        _copr_error
-.define        _params_size
-.define _params_offset
-.define _mon_ds
-.define _schedcheck
-.define _dirtypde
-
-.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        _s_call
-.define        _p_s_call
-.define        _level0_call
-
-! Exported variables.
-.define        begbss
-.define        begdata
-
-.sect .text
-!*===========================================================================*
-!*                             MINIX                                        *
-!*===========================================================================*
-MINIX:                         ! this is the entry point for the MINIX kernel
-       jmp     over_flags      ! skip over the next few bytes
-       .data2  CLICK_SHIFT     ! for the monitor: memory granularity
-flags:
-       .data2  0x01FD          ! boot monitor flags:
-                               !       call in 386 mode, make bss, make stack,
-                               !       load high, don't patch, will return,
-                               !       uses generic INT, memory vector,
-                               !       new boot code return
-       nop                     ! extra byte to sync up disassembler
-over_flags:
-
-! Set up a C stack frame on the monitor stack.  (The monitor sets cs and ds
-! right.  The ss descriptor still references the monitor data segment.)
-       movzx   esp, sp         ! monitor stack is a 16 bit stack
-       push    ebp
-       mov     ebp, esp
-       push    esi
-       push    edi
-       cmp     4(ebp), 0       ! monitor return vector is
-       jz      noret           ! nonzero if return possible
-       inc     (_mon_return)
-noret: mov     (_mon_sp), esp  ! save stack pointer for later return
-
-! Copy the monitor global descriptor table to the address space of kernel and
-! switch over to it.  Prot_init() can then update it with immediate effect.
-
-       sgdt    (_gdt+GDT_SELECTOR)             ! get the monitor gdtr
-       mov     esi, (_gdt+GDT_SELECTOR+2)      ! absolute address of GDT
-       mov     ebx, _gdt                       ! address of kernel GDT
-       mov     ecx, 8*8                        ! copying eight descriptors
-copygdt:
- eseg  movb    al, (esi)
-       movb    (ebx), al
-       inc     esi
-       inc     ebx
-       loop    copygdt
-       mov     eax, (_gdt+DS_SELECTOR+2)       ! base of kernel data
-       and     eax, 0x00FFFFFF                 ! only 24 bits
-       add     eax, _gdt                       ! eax = vir2phys(gdt)
-       mov     (_gdt+GDT_SELECTOR+2), eax      ! set base of GDT
-       lgdt    (_gdt+GDT_SELECTOR)             ! switch over to kernel GDT
-
-! Locate boot parameters, set up kernel segment registers and stack.
-       mov     ebx, 8(ebp)     ! boot parameters offset
-       mov     edx, 12(ebp)    ! boot parameters length
-       mov     eax, 16(ebp)    ! address of a.out headers
-       mov     (_aout), eax
-       mov     ax, ds          ! kernel data
-       mov     es, ax
-       mov     fs, ax
-       mov     gs, ax
-       mov     ss, ax
-       mov     esp, k_stktop   ! set sp to point to the top of kernel stack
-
-! Save boot parameters into these global variables for i386 code
-       mov     (_params_size), edx
-       mov     (_params_offset), ebx
-       mov     (_mon_ds), SS_SELECTOR
-
-! Call C startup code to set up a proper environment to run main().
-       push    edx
-       push    ebx
-       push    SS_SELECTOR
-       push    DS_SELECTOR
-       push    CS_SELECTOR
-       call    _cstart         ! cstart(cs, ds, mds, parmoff, parmlen)
-       add     esp, 5*4
-
-! Reload gdtr, idtr and the segment registers to global descriptor table set
-! up by prot_init().
-
-       lgdt    (_gdt+GDT_SELECTOR)
-       lidt    (_gdt+IDT_SELECTOR)
-
-       jmpf    CS_SELECTOR:csinit
-csinit:
-    o16        mov     ax, DS_SELECTOR
-       mov     ds, ax
-       mov     es, ax
-       mov     fs, ax
-       mov     gs, ax
-       mov     ss, ax
-    o16        mov     ax, TSS_SELECTOR        ! no other TSS is used
-       ltr     ax
-       push    0                       ! set flags to known good state
-       popf                            ! esp, clear nested task and int enable
-       jmp     _main                   ! main()
-
-
-!*===========================================================================*
-!*                             interrupt handlers                           *
-!*             interrupt handlers for 386 32-bit protected mode             *
-!*===========================================================================*
-
-!*===========================================================================*
-!*                             hwint00 - 07                                 *
-!*===========================================================================*
-! Note this is a macro, it just looks like a subroutine.
-#define hwint_master(irq)      \
-       call    save                    /* save interrupted process state */;\
-       push    (_irq_handlers+4*irq)   /* irq_handlers[irq]              */;\
-       call    _intr_handle            /* intr_handle(irq_handlers[irq]) */;\
-       pop     ecx                                                         ;\
-       cmp     (_irq_actids+4*irq), 0  /* interrupt still active?        */;\
-       jz      0f                                                          ;\
-       inb     INT_CTLMASK             /* get current mask */              ;\
-       orb     al, [1<<irq]            /* mask irq */                      ;\
-       outb    INT_CTLMASK             /* disable the irq                */;\
-0:     movb    al, END_OF_INT                                              ;\
-       outb    INT_CTL                 /* reenable master 8259           */;\
-       ret                             /* restart (another) process      */
-
-! Each of these entry points is an expansion of the hwint_master macro
-       .align  16
-_hwint00:              ! Interrupt routine for irq 0 (the clock).
-       hwint_master(0)
-
-       .align  16
-_hwint01:              ! Interrupt routine for irq 1 (keyboard)
-       hwint_master(1)
-
-       .align  16
-_hwint02:              ! Interrupt routine for irq 2 (cascade!)
-       hwint_master(2)
-
-       .align  16
-_hwint03:              ! Interrupt routine for irq 3 (second serial)
-       hwint_master(3)
-
-       .align  16
-_hwint04:              ! Interrupt routine for irq 4 (first serial)
-       hwint_master(4)
-
-       .align  16
-_hwint05:              ! Interrupt routine for irq 5 (XT winchester)
-       hwint_master(5)
-
-       .align  16
-_hwint06:              ! Interrupt routine for irq 6 (floppy)
-       hwint_master(6)
-
-       .align  16
-_hwint07:              ! Interrupt routine for irq 7 (printer)
-       hwint_master(7)
-
-!*===========================================================================*
-!*                             hwint08 - 15                                 *
-!*===========================================================================*
-! Note this is a macro, it just looks like a subroutine.
-#define hwint_slave(irq)       \
-       call    save                    /* save interrupted process state */;\
-       push    (_irq_handlers+4*irq)   /* irq_handlers[irq]              */;\
-       call    _intr_handle            /* intr_handle(irq_handlers[irq]) */;\
-       pop     ecx                                                         ;\
-       cmp     (_irq_actids+4*irq), 0  /* interrupt still active?        */;\
-       jz      0f                                                          ;\
-       inb     INT2_CTLMASK                                                ;\
-       orb     al, [1<<[irq-8]]                                            ;\
-       outb    INT2_CTLMASK            /* disable the irq                */;\
-0:     movb    al, END_OF_INT                                              ;\
-       outb    INT_CTL                 /* reenable master 8259           */;\
-       outb    INT2_CTL                /* reenable slave 8259            */;\
-       ret                             /* restart (another) process      */
-
-! Each of these entry points is an expansion of the hwint_slave macro
-       .align  16
-_hwint08:              ! Interrupt routine for irq 8 (realtime clock)
-       hwint_slave(8)
-
-       .align  16
-_hwint09:              ! Interrupt routine for irq 9 (irq 2 redirected)
-       hwint_slave(9)
-
-       .align  16
-_hwint10:              ! Interrupt routine for irq 10
-       hwint_slave(10)
-
-       .align  16
-_hwint11:              ! Interrupt routine for irq 11
-       hwint_slave(11)
-
-       .align  16
-_hwint12:              ! Interrupt routine for irq 12
-       hwint_slave(12)
-
-       .align  16
-_hwint13:              ! Interrupt routine for irq 13 (FPU exception)
-       hwint_slave(13)
-
-       .align  16
-_hwint14:              ! Interrupt routine for irq 14 (AT winchester)
-       hwint_slave(14)
-
-       .align  16
-_hwint15:              ! Interrupt routine for irq 15
-       hwint_slave(15)
-
-!*===========================================================================*
-!*                             save                                         *
-!*===========================================================================*
-! Save for protected mode.
-! This is much simpler than for 8086 mode, because the stack already points
-! into the process table, or has already been switched to the kernel stack.
-
-       .align  16
-save:
-       cld                     ! set direction flag to a known value
-       pushad                  ! save "general" registers
-    o16        push    ds              ! save ds
-    o16        push    es              ! save es
-    o16        push    fs              ! save fs
-    o16        push    gs              ! save gs
-       mov     dx, ss          ! ss is kernel data segment
-       mov     ds, dx          ! load rest of kernel segments
-       mov     es, dx          ! kernel does not use fs, gs
-       mov     eax, esp        ! prepare to return
-       incb    (_k_reenter)    ! from -1 if not reentering
-       jnz     set_restart1    ! stack is already kernel stack
-       mov     esp, k_stktop
-       push    _restart        ! build return address for int handler
-       xor     ebp, ebp        ! for stacktrace
-       jmp     RETADR-P_STACKBASE(eax)
-
-       .align  4
-set_restart1:
-       push    restart1
-       jmp     RETADR-P_STACKBASE(eax)
-
-!*===========================================================================*
-!*                             _s_call                                      *
-!*===========================================================================*
-       .align  16
-_s_call:
-_p_s_call:
-       cld                     ! set direction flag to a known value
-       sub     esp, 4          ! skip RETADR
-       pushad                  ! save "general" registers
-    o16        push    ds
-    o16        push    es
-    o16        push    fs
-    o16        push    gs
-
-       mov     si, ss          ! ss is kernel data segment
-       mov     ds, si          ! load rest of kernel segments
-       mov     es, si          ! kernel does not use fs, gs
-       incb    (_k_reenter)    ! increment kernel entry count
-       mov     esi, esp        ! assumes P_STACKBASE == 0
-       mov     esp, k_stktop
-       xor     ebp, ebp        ! for stacktrace
-                               ! end of inline save
-                               ! now set up parameters for sys_call()
-       push    edx             ! event set or flags bit map 
-       push    ebx             ! pointer to user message
-       push    eax             ! source / destination
-       push    ecx             ! call number (ipc primitive to use)
-
-       call    _sys_call       ! sys_call(call_nr, src_dst, m_ptr, bit_map)
-                               ! caller is now explicitly in proc_ptr
-       mov     AXREG(esi), eax
-
-! Fall into code to restart proc/task running.
-
-!*===========================================================================*
-!*                             restart                                      *
-!*===========================================================================*
-_restart:
-
-! Restart the current process or the next process if it is set. 
-
-       cli
-       call    _schedcheck             ! ask C function who we're running
-       mov     esp, (_proc_ptr)        ! will assume P_STACKBASE == 0
-       lldt    P_LDT_SEL(esp)          ! enable process' segment descriptors 
-       cmp     P_CR3(esp), 0           ! process does not have its own PT
-       jz      0f      
-       mov     eax, P_CR3(esp)
-       cmp     eax, (loadedcr3)
-       jz      0f
-       mov     cr3, eax
-       mov     (loadedcr3), eax
-       mov     eax, (_proc_ptr)
-       mov     (_ptproc), eax
-       mov     (_dirtypde), 0
-0:
-       lea     eax, P_STACKTOP(esp)    ! arrange for next interrupt
-       mov     (_tss+TSS3_S_SP0), eax  ! to save state in process table
-restart1:
-       decb    (_k_reenter)
-    o16        pop     gs
-    o16        pop     fs
-    o16        pop     es
-    o16        pop     ds
-       popad
-       add     esp, 4          ! skip return adr
-       iretd                   ! continue process
-
-!*===========================================================================*
-!*                             exception handlers                           *
-!*===========================================================================*
-_divide_error:
-       push    DIVIDE_VECTOR
-       jmp     exception
-
-_single_step_exception:
-       push    DEBUG_VECTOR
-       jmp     exception
-
-_nmi:
-       push    NMI_VECTOR
-       jmp     exception
-
-_breakpoint_exception:
-       push    BREAKPOINT_VECTOR
-       jmp     exception
-
-_overflow:
-       push    OVERFLOW_VECTOR
-       jmp     exception
-
-_bounds_check:
-       push    BOUNDS_VECTOR
-       jmp     exception
-
-_inval_opcode:
-       push    INVAL_OP_VECTOR
-       jmp     exception
-
-_copr_not_available:
-       push    COPROC_NOT_VECTOR
-       jmp     exception
-
-_double_fault:
-       push    DOUBLE_FAULT_VECTOR
-       jmp     errexception
-
-_copr_seg_overrun:
-       push    COPROC_SEG_VECTOR
-       jmp     exception
-
-_inval_tss:
-       push    INVAL_TSS_VECTOR
-       jmp     errexception
-
-_segment_not_present:
-       push    SEG_NOT_VECTOR
-       jmp     errexception
-
-_stack_exception:
-       push    STACK_FAULT_VECTOR
-       jmp     errexception
-
-_general_protection:
-       push    PROTECTION_VECTOR
-       jmp     errexception
-
-_page_fault:
-       push    PAGE_FAULT_VECTOR
-       push    eax
-       mov     eax, cr2
-sseg   mov     (pagefaultcr2), eax
-       pop     eax
-       jmp     errexception
-
-_copr_error:
-       push    COPROC_ERR_VECTOR
-       jmp     exception
-
-!*===========================================================================*
-!*                             exception                                    *
-!*===========================================================================*
-! This is called for all exceptions which do not push an error code.
-
-       .align  16
-exception:
- sseg  mov     (trap_errno), 0         ! clear trap_errno
- sseg  pop     (ex_number)
-       jmp     exception1
-
-!*===========================================================================*
-!*                             errexception                                 *
-!*===========================================================================*
-! This is called for all exceptions which push an error code.
-
-       .align  16
-errexception:
- sseg  pop     (ex_number)
- sseg  pop     (trap_errno)
-exception1:                            ! Common for all exceptions.
- sseg  mov     (old_eax_ptr), esp      ! where will eax be saved?
- sseg  sub     (old_eax_ptr), PCREG-AXREG      ! here
-
-       push    eax                     ! eax is scratch register
-
-       mov     eax, 0+4(esp)           ! old eip
- sseg  mov     (old_eip), eax
-       mov     eax, esp
-       add     eax, 4
- sseg  mov     (old_eip_ptr), eax
-       movzx   eax, 4+4(esp)           ! old cs
- sseg  mov     (old_cs), eax
-       mov     eax, 8+4(esp)           ! old eflags
- sseg  mov     (old_eflags), eax
-
-       pop     eax
-       call    save
-       push    (pagefaultcr2)
-       push    (old_eax_ptr)
-       push    (old_eip_ptr)
-       push    (old_eflags)
-       push    (old_cs)
-       push    (old_eip)
-       push    (trap_errno)
-       push    (ex_number)
-       call    _exception              ! (ex_number, trap_errno, old_eip,
-                                       !       old_cs, old_eflags)
-       add     esp, 8*4
-       ret
-
-
-!*===========================================================================*
-!*                             write_cr3                               *
-!*===========================================================================*
-! PUBLIC void write_cr3(unsigned long value);
-_write_cr3:
-       push    ebp
-       mov     ebp, esp
-       mov     eax, 8(ebp)
-       cmp     eax, (loadedcr3)
-       jz      0f
-       mov     cr3, eax
-       mov     (loadedcr3), eax
-       mov     (_dirtypde), 0
-0:
-       pop     ebp
-       ret
-
-!*===========================================================================*
-!*                             reload_cr3                              *
-!*===========================================================================*
-! PUBLIC void reload_cr3(void);
-_reload_cr3:
-       push    ebp
-       mov     ebp, esp
-       mov     (_dirtypde), 0
-       mov     eax, cr3
-       mov     cr3, eax
-       pop     ebp
-       ret
-
-!*===========================================================================*
-!*                             level0_call                                  *
-!*===========================================================================*
-_level0_call:
-! which level0 function to call was passed here by putting it in eax, so
-! we get that from the saved state.
-       call    save
-       mov     eax, (_proc_ptr)
-       mov     eax, AXREG(eax)
-       jmp     eax
-
-!*===========================================================================*
-!*                             data                                         *
-!*===========================================================================*
-
-.sect .rom     ! Before the string table please
-       .data2  0x526F          ! this must be the first data entry (magic #)
-
-.sect .bss
-k_stack:
-       .space  K_STACK_BYTES   ! kernel stack
-k_stktop:                      ! top of kernel stack
-       .comm   ex_number, 4
-       .comm   trap_errno, 4
-       .comm   old_eip_ptr, 4
-       .comm   old_eax_ptr, 4
-       .comm   old_eip, 4
-       .comm   old_cs, 4
-       .comm   old_eflags, 4
-       .comm   pagefaultcr2, 4
-       .comm   loadedcr3, 4
-
index 34254f03a55c0b4a1c19916db29f892515d38314..1837fa51a8672e875dec4c28d2a71fce9b54e6a5 100755 (executable)
@@ -1,28 +1,28 @@
-! Miscellaneous constants used in assembler code.
-W              =       _WORD_SIZE      ! Machine word size.
+/* Miscellaneous constants used in assembler code. */
+       W = _WORD_SIZE  /* Machine word size. */
 
-! Offsets in struct proc. They MUST match proc.h.
-P_STACKBASE    =       0
-GSREG          =       P_STACKBASE
-FSREG          =       GSREG + 2       ! 386 introduces FS and GS segments
-ESREG          =       FSREG + 2
-DSREG          =       ESREG + 2
-DIREG          =       DSREG + 2
-SIREG          =       DIREG + W
-BPREG          =       SIREG + W
-STREG          =       BPREG + W       ! hole for another SP
-BXREG          =       STREG + W
-DXREG          =       BXREG + W
-CXREG          =       DXREG + W
-AXREG          =       CXREG + W
-RETADR         =       AXREG + W       ! return address for save() call
-PCREG          =       RETADR + W
-CSREG          =       PCREG + W
-PSWREG         =       CSREG + W
-SPREG          =       PSWREG + W
-SSREG          =       SPREG + W
-P_STACKTOP     =       SSREG + W
-P_LDT_SEL      =       P_STACKTOP
-P_CR3          =       P_LDT_SEL + W
-P_LDT          =       P_CR3 + W
-Msize          =       9               ! size of a message in 32-bit words
+/* Offsets in struct proc. They MUST match proc.h. */
+       P_STACKBASE = 0
+       GSREG = P_STACKBASE
+       FSREG = GSREG+2 /* 386 introduces FS and GS segments*/
+       ESREG = FSREG+2
+       DSREG = ESREG+2
+       DIREG = DSREG+2
+       SIREG = DIREG+W
+       BPREG = SIREG+W
+       STREG = BPREG+W /* hole for another SP*/
+       BXREG = STREG+W
+       DXREG = BXREG+W
+       CXREG = DXREG+W
+       AXREG = CXREG+W
+       RETADR = AXREG+W        /* return address for save() call*/
+       PCREG = RETADR+W
+       CSREG = PCREG+W
+       PSWREG = CSREG+W
+       SPREG = PSWREG+W
+       SSREG = SPREG+W
+       P_STACKTOP = SSREG+W
+       P_LDT_SEL = P_STACKTOP
+       P_CR3 = P_LDT_SEL+W
+       P_LDT = P_CR3+W
+       Msize = 9       /* size of a message in 32-bit words*/