]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc/l.s
[9front] [PATCH] audiohda: add PCI ID for Intel C610/X99
[plan9front.git] / sys / src / 9 / pc / l.s
old mode 100755 (executable)
new mode 100644 (file)
index 7d971a9..ede492a
@@ -1,5 +1,4 @@
 #include "mem.h"
-#include "/sys/src/boot/pc/x16.h"
 #undef DELAY
 
 #define PADDR(a)       ((a) & ~KZERO)
@@ -18,6 +17,8 @@
 #define INVLPG BYTE $0x0F; BYTE $0x01; BYTE $0x39      /* INVLPG (%ecx) */
 #define WBINVD BYTE $0x0F; BYTE $0x09
 
+#define VectorSYSCALL  0x40
+
 /*
  * Macros for calculating offsets within the page directory base
  * and page tables. Note that these are assembler-specific hence
@@ -41,17 +42,41 @@ TEXT _startKADDR(SB), $0
  */
 TEXT _multibootheader(SB), $0
        LONG    $0x1BADB002                     /* magic */
-       LONG    $0x00010003                     /* flags */
-       LONG    $-(0x1BADB002 + 0x00010003)     /* checksum */
+       LONG    $0x00010007                     /* flags */
+       LONG    $-(0x1BADB002 + 0x00010007)     /* checksum */
        LONG    $_multibootheader-KZERO(SB)     /* header_addr */
        LONG    $_startKADDR-KZERO(SB)          /* load_addr */
        LONG    $edata-KZERO(SB)                /* load_end_addr */
        LONG    $end-KZERO(SB)                  /* bss_end_addr */
-       LONG    $_startKADDR-KZERO(SB)          /* entry_addr */
+       LONG    $_multibootentry-KZERO(SB)              /* entry_addr */
        LONG    $0                              /* mode_type */
        LONG    $0                              /* width */
        LONG    $0                              /* height */
-       LONG    $0                              /* depth */
+       LONG    $32                             /* depth */
+
+/* 
+ * the kernel expects the data segment to be page-aligned
+ * multiboot bootloaders put the data segment right behind text
+ */
+TEXT _multibootentry(SB), $0
+       MOVL    $etext-KZERO(SB), SI
+       MOVL    SI, DI
+       ADDL    $0xfff, DI
+       ANDL    $~0xfff, DI
+       MOVL    $edata-KZERO(SB), CX
+       SUBL    DI, CX
+       ADDL    CX, SI
+       ADDL    CX, DI
+       INCL    CX      /* one more for post decrement */
+       STD
+       REP; MOVSB
+       MOVL    BX, multibootptr-KZERO(SB)
+       MOVL    $_startPADDR-KZERO(SB), AX
+       JMP*    AX
+
+/* multiboot structure pointer (physical address) */
+TEXT multibootptr(SB), $0
+       LONG    $0
 
 /*
  * In protected mode with paging turned off and segment registers setup
@@ -72,8 +97,7 @@ TEXT _startPADDR(SB), $0
        CLI                                     /* make sure interrupts are off */
 
        /* set up the gdt so we have sane plan 9 style gdts. */
-       MOVL    $tgdtptr(SB), AX
-       ANDL    $~KZERO, AX
+       MOVL    $tgdtptr-KZERO(SB), AX
        MOVL    (AX), GDTR
        MOVW    $1, AX
        MOVW    AX, MSW
@@ -120,61 +144,53 @@ TEXT tgdtptr(SB), $0
        WORD    $(3*8)
        LONG    $tgdt-KZERO(SB)
 
-TEXT m0rgdtptr(SB), $0
-       WORD    $(NGDT*8-1)
-       LONG    $(CPU0GDT-KZERO)
-
-TEXT m0gdtptr(SB), $0
-       WORD    $(NGDT*8-1)
-       LONG    $CPU0GDT
-
-TEXT m0idtptr(SB), $0
-       WORD $(256*8-1)
-       LONG $IDTADDR
+TEXT vtgdtptr(SB), $0
+       WORD    $(3*8)
+       LONG    $tgdt(SB)
 
 TEXT mode32bit(SB), $0
-       /* At this point, the GDT setup is done. */
-
-       MOVL    $PADDR(CPU0PDB), DI             /* clear 4 pages for the tables etc. */
+       MOVL    $((CPU0END-CPU0PDB)>>2), CX
+       MOVL    $PADDR(CPU0PDB), DI
        XORL    AX, AX
-       MOVL    $(4*BY2PG), CX
-       SHRL    $2, CX
 
        CLD
        REP;    STOSL
 
+       MOVL    $PADDR(CPU0PTE), DX
+       MOVL    $(PTEWRITE|PTEVALID), BX        /* page permissions */
+       ORL     BX, DX
+
        MOVL    $PADDR(CPU0PDB), AX
        ADDL    $PDO(KZERO), AX                 /* page directory offset for KZERO */
-       MOVL    $PADDR(CPU0PTE), (AX)           /* PTE's for KZERO */
-       MOVL    $(PTEWRITE|PTEVALID), BX        /* page permissions */
-       ORL     BX, (AX)
 
-       ADDL    $4, AX
-       MOVL    $PADDR(CPU0PTE1), (AX)          /* PTE's for KZERO+4MB */
-       MOVL    $(PTEWRITE|PTEVALID), BX        /* page permissions */
-       ORL     BX, (AX)
+       MOVL    DX, 0(AX)                       /* PTE's for KZERO */
+       ADDL    $BY2PG, DX
+       MOVL    DX, 4(AX)                       /* PTE's for KZERO+4MB */
+       ADDL    $BY2PG, DX
+       MOVL    DX, 8(AX)                       /* PTE's for KZERO+8MB */
+       ADDL    $BY2PG, DX
+       MOVL    DX, 12(AX)                      /* PTE's for KZERO+12MB */
 
        MOVL    $PADDR(CPU0PTE), AX             /* first page of page table */
-       MOVL    $1024, CX                       /* 1024 pages in 4MB */
+       MOVL    $end-KZERO(SB), CX
+
+       ADDL    $(16*1024), CX                  /* qemu puts multiboot data after the kernel */
+
+       ADDL    $(BY2XPG-1), CX
+       ANDL    $~(BY2XPG-1), CX                /* round to 4MB */
+       MOVL    CX, MemMin-KZERO(SB)            /* see memory.c */
+       SHRL    $PGSHIFT, CX
+       MOVL    BX, DX
 _setpte:
-       MOVL    BX, (AX)
-       ADDL    $(1<<PGSHIFT), BX
+       MOVL    DX, (AX)
+       ADDL    $BY2PG, DX
        ADDL    $4, AX
        LOOP    _setpte
 
-       MOVL    $PADDR(CPU0PTE1), AX            /* second page of page table */
-       MOVL    $1024, CX                       /* 1024 pages in 4MB */
-_setpte1:
-       MOVL    BX, (AX)
-       ADDL    $(1<<PGSHIFT), BX
-       ADDL    $4, AX
-       LOOP    _setpte1
-
        MOVL    $PADDR(CPU0PTE), AX
        ADDL    $PTO(MACHADDR), AX              /* page table entry offset for MACHADDR */
-       MOVL    $PADDR(CPU0MACH), (AX)          /* PTE for Mach */
-       MOVL    $(PTEWRITE|PTEVALID), BX        /* page permissions */
-       ORL     BX, (AX)
+       ORL     $PADDR(CPU0MACH), BX
+       MOVL    BX, (AX)                        /* PTE for Mach */
 
 /*
  * Now ready to use the new map. Make sure the processor options are what is wanted.
@@ -203,6 +219,9 @@ _setpte1:
  * be initialised here.
  */
 TEXT _startpg(SB), $0
+       MOVL    $vtgdtptr(SB), AX
+       MOVL    (AX), GDTR
+
        MOVL    $0, (PDO(0))(CX)                /* undo double-map of KZERO at 0 */
        MOVL    CX, CR3                         /* load and flush the mmu */
 
@@ -243,231 +262,15 @@ _idle:
        HLT
        JMP     _idle
 
-/*
- * Save registers.
- */
-TEXT saveregs(SB), $0
-       /* appease 8l */
-       SUBL $32, SP
-       POPL AX
-       POPL AX
-       POPL AX
-       POPL AX
-       POPL AX
-       POPL AX
-       POPL AX
-       POPL AX
-       
-       PUSHL   AX
-       PUSHL   BX
-       PUSHL   CX
-       PUSHL   DX
-       PUSHL   BP
-       PUSHL   DI
-       PUSHL   SI
-       PUSHFL
-
-       XCHGL   32(SP), AX      /* swap return PC and saved flags */
-       XCHGL   0(SP), AX
-       XCHGL   32(SP), AX
-       RET
-
-TEXT restoreregs(SB), $0
-       /* appease 8l */
-       PUSHL   AX
-       PUSHL   AX
-       PUSHL   AX
-       PUSHL   AX
-       PUSHL   AX
-       PUSHL   AX
-       PUSHL   AX
-       PUSHL   AX
-       ADDL    $32, SP
-       
-       XCHGL   32(SP), AX      /* swap return PC and saved flags */
-       XCHGL   0(SP), AX
-       XCHGL   32(SP), AX
 
-       POPFL
-       POPL    SI
-       POPL    DI
-       POPL    BP
-       POPL    DX
-       POPL    CX
-       POPL    BX
-       POPL    AX
+TEXT load_fs(SB), $0
+       MOVW fs+0(FP), AX
+       MOVW AX, FS
        RET
 
-/*
- * Assumed to be in protected mode at time of call.
- * Switch to real mode, execute an interrupt, and
- * then switch back to protected mode.  
- *
- * Assumes:
- *
- *     - no device interrupts are going to come in
- *     - 0-16MB is identity mapped in page tables
- *     - realmode() has copied us down from 0x100000 to 0x8000
- *     - can use code segment 0x0800 in real mode
- *             to get at l.s code
- *     - l.s code is less than 1 page
- */
-#define RELOC  (RMCODE-KTZERO)
-
-TEXT realmodeidtptr(SB), $0
-       WORD    $(4*256-1)
-       LONG    $0
-
-TEXT realmode0(SB), $0
-       CALL    saveregs(SB)
-
-       /* switch to low code address */
-       LEAL    physcode-KZERO(SB), AX
-       JMP *AX
-
-TEXT physcode(SB), $0
-
-       /* switch to low stack */
-       MOVL    SP, AX
-       MOVL    $0x7C00, SP
-       PUSHL   AX
-
-       /* change gdt to physical pointer */
-       MOVL    m0rgdtptr-KZERO(SB), GDTR
-
-       /* load IDT with real-mode version*/
-       MOVL    realmodeidtptr-KZERO(SB), IDTR
-
-       /* edit INT $0x00 instruction below */
-       MOVL    $(RMUADDR-KZERO+48), AX /* &rmu.trap */
-       MOVL    (AX), AX
-       MOVB    AX, realmodeintrinst+(-KZERO+1+RELOC)(SB)
-
-       /* disable paging */
-       MOVL    CR0, AX
-       ANDL    $0x7FFFFFFF, AX
-       MOVL    AX, CR0
-       /* JMP .+2 to clear prefetch queue*/
-       BYTE $0xEB; BYTE $0x00
-
-       /* jump to 16-bit code segment */
-/*     JMPFAR  SELECTOR(KESEG16, SELGDT, 0):$again16bit(SB) /**/
-        BYTE   $0xEA
-        LONG   $again16bit-KZERO(SB)
-        WORD   $SELECTOR(KESEG16, SELGDT, 0)
-
-TEXT again16bit(SB), $0
-       /*
-        * Now in 16-bit compatibility mode.
-        * These are 32-bit instructions being interpreted
-        * as 16-bit instructions.  I'm being lazy and
-        * not using the macros because I know when
-        * the 16- and 32-bit instructions look the same
-        * or close enough.
-        */
-
-       /* disable protected mode and jump to real mode cs */
-       OPSIZE; MOVL CR0, AX
-       OPSIZE; XORL BX, BX
-       OPSIZE; INCL BX
-       OPSIZE; XORL BX, AX
-       OPSIZE; MOVL AX, CR0
-
-       /* JMPFAR 0x0800:now16real */
-        BYTE $0xEA
-        WORD   $now16real-KZERO(SB)
-        WORD   $0x0800
-
-TEXT now16real(SB), $0
-       /* copy the registers for the bios call */
-       LWI(0x0000, rAX)
-       MOVW    AX,SS
-       LWI(RMUADDR, rBP)
-       
-       /* offsets are in Ureg */
-       LXW(44, xBP, rAX)
-       MOVW    AX, DS
-       LXW(40, xBP, rAX)
-       MOVW    AX, ES
-
-       OPSIZE; LXW(0, xBP, rDI)
-       OPSIZE; LXW(4, xBP, rSI)
-       OPSIZE; LXW(16, xBP, rBX)
-       OPSIZE; LXW(20, xBP, rDX)
-       OPSIZE; LXW(24, xBP, rCX)
-       OPSIZE; LXW(28, xBP, rAX)
-
-       CLC
-
-TEXT realmodeintrinst(SB), $0
-       INT $0x00
-
-       /* save the registers after the call */
-
-       LWI(0x7bfc, rSP)
-       OPSIZE; PUSHFL
-       OPSIZE; PUSHL AX
-
-       LWI(0, rAX)
-       MOVW    AX,SS
-       LWI(RMUADDR, rBP)
-       
-       OPSIZE; SXW(rDI, 0, xBP)
-       OPSIZE; SXW(rSI, 4, xBP)
-       OPSIZE; SXW(rBX, 16, xBP)
-       OPSIZE; SXW(rDX, 20, xBP)
-       OPSIZE; SXW(rCX, 24, xBP)
-       OPSIZE; POPL AX
-       OPSIZE; SXW(rAX, 28, xBP)
-
-       MOVW    DS, AX
-       OPSIZE; SXW(rAX, 44, xBP)
-       MOVW    ES, AX
-       OPSIZE; SXW(rAX, 40, xBP)
-
-       OPSIZE; POPL AX
-       OPSIZE; SXW(rAX, 64, xBP)       /* flags */
-
-       /* re-enter protected mode and jump to 32-bit code */
-       OPSIZE; MOVL $1, AX
-       OPSIZE; MOVL AX, CR0
-       
-/*     JMPFAR  SELECTOR(KESEG, SELGDT, 0):$again32bit(SB) /**/
-        OPSIZE
-        BYTE $0xEA
-        LONG   $again32bit-KZERO(SB)
-        WORD   $SELECTOR(KESEG, SELGDT, 0)
-
-TEXT again32bit(SB), $0
-       MOVW    $SELECTOR(KDSEG, SELGDT, 0),AX
-       MOVW    AX,DS
-       MOVW    AX,SS
-       MOVW    AX,ES
-       MOVW    AX,FS
-       MOVW    AX,GS
-
-       /* enable paging and jump to kzero-address code */
-       MOVL    CR0, AX
-       ORL     $0x80010000, AX /* PG|WP */
-       MOVL    AX, CR0
-       LEAL    again32kzero(SB), AX
-       JMP*    AX
-
-TEXT again32kzero(SB), $0
-       /* breathe a sigh of relief - back in 32-bit protected mode */
-
-       /* switch to old stack */       
-       PUSHL   AX      /* match popl below for 8l */
-       MOVL    $0x7BFC, SP
-       POPL    SP
-
-       /* restore idt */
-       MOVL    m0idtptr(SB),IDTR
-
-       /* restore gdt */
-       MOVL    m0gdtptr(SB), GDTR
-
-       CALL    restoreregs(SB)
+TEXT load_gs(SB), $0
+       MOVW gs+0(FP), AX
+       MOVW AX, GS
        RET
 
 /*
@@ -601,6 +404,11 @@ TEXT lgdt(SB), $0                          /* GDTR - global descriptor table */
        MOVL    (AX), GDTR
        RET
 
+TEXT lldt(SB), $0                              /* LDTR - local descriptor table */
+       MOVL    sel+0(FP), AX
+       BYTE $0x0F; BYTE $0x00; BYTE $0xD0      /* LLDT AX */
+       RET
+
 TEXT lidt(SB), $0                              /* IDTR - interrupt descriptor table */
        MOVL    idtptr+0(FP), AX
        MOVL    (AX), IDTR
@@ -619,6 +427,11 @@ TEXT getcr2(SB), $0                                /* CR2 - page fault linear address */
        MOVL    CR2, AX
        RET
 
+TEXT putcr2(SB), $0
+       MOVL    cr2+0(FP), AX
+       MOVL    AX, CR2
+       RET
+
 TEXT getcr3(SB), $0                            /* CR3 - page directory base */
        MOVL    CR3, AX
        RET
@@ -669,18 +482,35 @@ TEXT lcycles(SB),1,$0
        RET
 
 TEXT rdmsr(SB), $0                             /* model-specific register */
+       MOVL    $0, BP
        MOVL    index+0(FP), CX
+TEXT _rdmsrinst(SB), $0
        RDMSR
        MOVL    vlong+4(FP), CX                 /* &vlong */
        MOVL    AX, 0(CX)                       /* lo */
        MOVL    DX, 4(CX)                       /* hi */
+       MOVL    BP, AX                          /* BP set to -1 if traped */
        RET
        
 TEXT wrmsr(SB), $0
+       MOVL    $0, BP
        MOVL    index+0(FP), CX
        MOVL    lo+4(FP), AX
        MOVL    hi+8(FP), DX
+TEXT _wrmsrinst(SB), $0
        WRMSR
+       MOVL    BP, AX                          /* BP set to -1 if traped */
+       RET
+
+/* fault-proof memcpy */
+TEXT peek(SB), $0
+       MOVL    src+0(FP), SI
+       MOVL    dst+4(FP), DI
+       MOVL    cnt+8(FP), CX
+       CLD
+TEXT _peekinst(SB), $0
+       REP; MOVSB
+       MOVL    CX, AX
        RET
 
 /*
@@ -690,7 +520,7 @@ TEXT wrmsr(SB), $0
  * a 386 (Ac bit can't be set). If it's not a 386 and the Id bit can't be
  * toggled then it's an older 486 of some kind.
  *
- *     cpuid(fun, regs[4]);
+ *     cpuid(fn, sublvl, regs[4]);
  */
 TEXT cpuid(SB), $0
        MOVL    $0x240000, AX
@@ -709,6 +539,7 @@ TEXT cpuid(SB), $0
        TESTL   $0x200000, AX                   /* Id */
        JZ      _cpu486                         /* can't toggle this bit on some 486 */
        MOVL    fn+0(FP), AX
+       MOVL    sublvl+4(FP), CX
        CPUID
        JMP     _cpuid
 _cpu486:
@@ -725,7 +556,7 @@ _zaprest:
        XORL    CX, CX
        XORL    DX, DX
 _cpuid:
-       MOVL    regs+4(FP), BP
+       MOVL    regs+8(FP), BP
        MOVL    AX, 0(BP)
        MOVL    BX, 4(BP)
        MOVL    CX, 8(BP)
@@ -749,15 +580,8 @@ _aamloop:
  * FNxxx variations) so WAIT instructions must be explicitly placed in the
  * code as necessary.
  */
-#define        FPOFF(l)                                                 ;\
-       MOVL    CR0, AX                                          ;\
-       ANDL    $0xC, AX                        /* EM, TS */     ;\
-       CMPL    AX, $0x8                                         ;\
-       JEQ     l                                                ;\
-       WAIT                                                     ;\
-l:                                                              ;\
+#define FPOFF                                                   ;\
        MOVL    CR0, AX                                          ;\
-       ANDL    $~0x4, AX                       /* EM=0 */       ;\
        ORL     $0x28, AX                       /* NE=1, TS=1 */ ;\
        MOVL    AX, CR0
 
@@ -765,9 +589,9 @@ l:                                                           ;\
        MOVL    CR0, AX                                          ;\
        ANDL    $~0xC, AX                       /* EM=0, TS=0 */ ;\
        MOVL    AX, CR0
-       
+
 TEXT fpoff(SB), $0                             /* disable */
-       FPOFF(l1)
+       FPOFF
        RET
 
 TEXT fpinit(SB), $0                            /* enable and init */
@@ -782,32 +606,40 @@ TEXT fpinit(SB), $0                               /* enable and init */
        WAIT
        RET
 
-TEXT fpsave(SB), $0                            /* save state and disable */
+TEXT fpx87save0(SB), $0                                /* save state and disable */
        MOVL    p+0(FP), AX
        FSAVE   0(AX)                           /* no WAIT */
-       FPOFF(l2)
+       FPOFF
        RET
 
-TEXT fprestore(SB), $0                         /* enable and restore state */
+TEXT fpx87restore0(SB), $0                     /* enable and restore state */
        FPON
        MOVL    p+0(FP), AX
        FRSTOR  0(AX)
        WAIT
        RET
 
-TEXT fpstatus(SB), $0                          /* get floating point status */
-       FSTSW   AX
+TEXT fpclear(SB), $0                           /* clear pending exceptions */
+       FPON
+       FCLEX                                   /* no WAIT */
+       FPOFF
        RET
 
-TEXT fpenv(SB), $0                             /* save state without waiting */
+TEXT fpssesave(SB), $0                         /* save state and disable */
        MOVL    p+0(FP), AX
-       FSTENV  0(AX)
+       FXSAVE  0(AX)                           /* no WAIT */
+       FPOFF
        RET
 
-TEXT fpclear(SB), $0                           /* clear pending exceptions */
+TEXT fpsserestore(SB), $0                      /* enable and restore state */
        FPON
-       FCLEX                                   /* no WAIT */
-       FPOFF(l3)
+       MOVL    p+0(FP), AX
+       FXRSTOR 0(AX)
+       WAIT
+       RET
+
+TEXT ldmxcsr(SB), $0                           /* Load MXCSR */
+       LDMXCSR mxcsr+0(FP)
        RET
 
 /*
@@ -856,30 +688,12 @@ TEXT islo(SB), $0
  * Test-And-Set
  */
 TEXT tas(SB), $0
+TEXT _tas(SB), $0
        MOVL    $0xDEADDEAD, AX
        MOVL    lock+0(FP), BX
        XCHGL   AX, (BX)                        /* lock->key */
        RET
 
-TEXT _xinc(SB), $0                             /* void _xinc(long*); */
-       MOVL    l+0(FP), AX
-       LOCK;   INCL 0(AX)
-       RET
-
-TEXT _xdec(SB), $0                             /* long _xdec(long*); */
-       MOVL    l+0(FP), BX
-       XORL    AX, AX
-       LOCK;   DECL 0(BX)
-       JLT     _xdeclt
-       JGT     _xdecgt
-       RET
-_xdecgt:
-       INCL    AX
-       RET
-_xdeclt:
-       DECL    AX
-       RET
-
 TEXT mb386(SB), $0
        POPL    AX                              /* return PC */
        PUSHFL
@@ -991,6 +805,207 @@ _nothingready:
        HLT
        RET
 
+TEXT mwait(SB), $0
+       MOVL    addr+0(FP), AX
+       MOVL    (AX), CX
+       ORL     CX, CX
+       JNZ     _mwaitdone
+       XORL    DX, DX
+       BYTE $0x0f; BYTE $0x01; BYTE $0xc8      /* MONITOR */
+       MOVL    (AX), CX
+       ORL     CX, CX
+       JNZ     _mwaitdone
+       XORL    AX, AX
+       BYTE $0x0f; BYTE $0x01; BYTE $0xc9      /* MWAIT */
+_mwaitdone:
+       RET
+
+#define RDRANDAX       BYTE $0x0f; BYTE $0xc7; BYTE $0xf0
+
+TEXT rdrand32(SB), $-4
+_rloop32:
+       RDRANDAX
+       JCC     _rloop32
+       RET
+
+TEXT rdrandbuf(SB), $0
+       MOVL    buf+0(FP), DI
+       MOVL    cnt+4(FP), CX
+       CLD
+       MOVL    CX, DX
+       SHRL    $2, CX
+       CMPL    CX, $0
+       JE      _rndleft
+_rnddwords:
+       CALL    rdrand32(SB)
+       STOSL
+       LOOP _rnddwords
+_rndleft:
+       MOVL    DX, CX
+       ANDL    $3, CX
+       CMPL    CX, $0
+       JE      _rnddone
+_rndbytes:
+       CALL rdrand32(SB)
+       STOSB
+       LOOP _rndbytes
+_rnddone:
+       RET
+
+/* debug register access */
+
+TEXT putdr(SB), $0
+       MOVL    p+0(FP), SI
+       MOVL    28(SI), AX
+       MOVL    AX, DR7
+_putdr01236:
+       MOVL    0(SI), AX
+       MOVL    AX, DR0
+       MOVL    4(SI), AX
+       MOVL    AX, DR1
+       MOVL    8(SI), AX
+       MOVL    AX, DR2
+       MOVL    12(SI), AX
+       MOVL    AX, DR3
+       MOVL    24(SI), AX
+       MOVL    AX, DR6
+       RET
+
+TEXT putdr01236(SB), $0
+       MOVL p+0(FP), SI
+       JMP _putdr01236
+
+TEXT getdr6(SB), $0
+       MOVL    DR6, AX
+       RET
+
+TEXT putdr6(SB), $0
+       MOVL    p+0(FP), AX
+       MOVL    AX, DR6
+       RET
+       
+TEXT putdr7(SB), $0
+       MOVL    p+0(FP), AX
+       MOVL    AX, DR7
+       RET
+
+/* VMX instructions */
+TEXT vmxon(SB), $0
+       /* VMXON 4(SP) */
+       BYTE    $0xf3; BYTE $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x04
+       JMP     _vmout
+
+TEXT vmxoff(SB), $0
+       BYTE    $0x0f; BYTE $0x01; BYTE $0xc4
+       JMP     _vmout
+
+TEXT vmclear(SB), $0
+       /* VMCLEAR 4(SP) */
+       BYTE    $0x66; BYTE $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x04
+       JMP     _vmout
+
+TEXT vmlaunch(SB), $0
+       MOVL    $0x6C14, DI
+       MOVL    SP, DX
+       BYTE    $0x0f; BYTE $0x79; BYTE $0xfa /* VMWRITE DX, DI */
+       JBE     _vmout
+       MOVL    $0x6C16, DI
+       MOVL    $vmrestore(SB), DX
+       BYTE    $0x0f; BYTE $0x79; BYTE $0xfa /* VMWRITE DX, DI */
+       JBE     _vmout
+       
+       MOVL    resume+4(FP), AX
+       TESTL   AX, AX
+       MOVL    ureg+0(FP), DI
+       MOVL    4(DI), SI
+       MOVL    8(DI), BP
+       MOVL    16(DI), BX
+       MOVL    20(DI), DX
+       MOVL    24(DI), CX
+       MOVL    28(DI), AX
+       MOVL    0(DI), DI
+       JNE     _vmresume
+       BYTE    $0x0f; BYTE $0x01; BYTE $0xc2 /* VMLAUNCH */
+       JMP     _vmout
+_vmresume:
+       BYTE    $0x0f; BYTE $0x01; BYTE $0xc3 /* VMRESUME */
+       JMP _vmout
+
+TEXT vmrestore(SB), $0
+       PUSHL   DI
+       MOVL    ureg+0(FP), DI
+       POPL    0(DI)
+       MOVL    SI, 4(DI)
+       MOVL    BP, 8(DI)
+       MOVL    BX, 16(DI)
+       MOVL    DX, 20(DI)
+       MOVL    CX, 24(DI)
+       MOVL    AX, 28(DI)
+       XORL    AX, AX
+       RET
+
+TEXT vmptrld(SB), $0
+       /* VMPTRLD 4(SP) */
+       BYTE $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x04
+       JMP _vmout
+
+TEXT vmwrite(SB), $0
+       MOVL addr+0(FP),DI
+       MOVL val+4(FP),DX
+       /* VMWRITE DX, DI */
+       BYTE $0x0f; BYTE $0x79; BYTE $0xfa
+       JMP _vmout
+
+TEXT vmread(SB), $0
+       MOVL addr+0(FP),DI
+       MOVL valp+4(FP),SI
+       /* VMREAD (SI), DI */
+       BYTE $0x0f; BYTE $0x78; BYTE $0x3e
+       JMP _vmout
+
+TEXT invept(SB), $0
+       MOVL type+0(FP), AX
+       /* INVEPT AX, 8(SP) */
+       BYTE $0x66; BYTE $0x0f; BYTE $0x38; BYTE $0x80; BYTE $0x44; BYTE $0x24; BYTE $0x08
+       JMP _vmout
+
+TEXT invvpid(SB), $0
+       MOVL type+0(FP), AX
+       /* INVVPID AX, 8(SP) */
+       BYTE $0x66; BYTE $0x0f; BYTE $0x38; BYTE $0x81; BYTE $0x44; BYTE $0x24; BYTE $0x08
+       JMP _vmout
+
+_vmout:
+       JC _vmout1
+       JZ _vmout2
+       XORL AX, AX
+       RET
+_vmout1:
+       MOVL $-1, AX
+       RET
+_vmout2:
+       MOVL $-2, AX
+       RET
+
+/*
+ *  Used to get to the first process:
+ *     set up an interrupt return frame and IRET to user level.
+ */
+TEXT touser(SB), $0
+       PUSHL   $(UDSEL)                        /* old ss */
+       MOVL    sp+0(FP), AX                    /* old sp */
+       PUSHL   AX
+       MOVL    $0x200, AX                      /* interrupt enable flag */
+       PUSHL   AX                              /* old flags */
+       PUSHL   $(UESEL)                        /* old cs */
+       PUSHL   $(UTZERO+32)                    /* old pc */
+       MOVL    $(UDSEL), AX
+       MOVW    AX, DS
+       MOVW    AX, ES
+       MOVW    AX, GS
+       MOVW    AX, FS
+       IRETL
+
 /*
  * Interrupt/exception handling.
  * Each entry in the vector table calls either _strayintr or _strayintrx depending
@@ -1028,13 +1043,40 @@ intrcommon:
 TEXT forkret(SB), $0
        POPL    AX
        POPAL
+TEXT _forkretpopgs(SB), $0
        POPL    GS
+TEXT _forkretpopfs(SB), $0
        POPL    FS
+TEXT _forkretpopes(SB), $0
        POPL    ES
+TEXT _forkretpopds(SB), $0
        POPL    DS
        ADDL    $8, SP                  /* pop error code and trap type */
+TEXT _forkretiret(SB), $0
        IRETL
 
+/*
+ * This is merely _strayintr optimised to vector
+ * to syscall() without going through trap().
+ */
+TEXT _syscallintr(SB), $0
+       PUSHL   $VectorSYSCALL          /* trap type */
+
+       PUSHL   DS
+       PUSHL   ES
+       PUSHL   FS
+       PUSHL   GS
+       PUSHAL
+       MOVL    $(KDSEL), AX
+       MOVW    AX, DS
+       MOVW    AX, ES
+
+       MOVL    $syscall(SB), AX
+
+       PUSHL   SP                      /* Ureg* argument to syscall */
+       PUSHL   $forkret(SB)            /* return pc */
+       JMP     *AX
+
 TEXT vectortable(SB), $0
        CALL _strayintr(SB); BYTE $0x00         /* divide error */
        CALL _strayintr(SB); BYTE $0x01         /* debug exception */
@@ -1055,7 +1097,7 @@ TEXT vectortable(SB), $0
        CALL _strayintr(SB); BYTE $0x10         /* coprocessor error */
        CALL _strayintrx(SB); BYTE $0x11        /* alignment check */
        CALL _strayintr(SB); BYTE $0x12         /* machine check */
-       CALL _strayintr(SB); BYTE $0x13
+       CALL _strayintr(SB); BYTE $0x13         /* simd error */
        CALL _strayintr(SB); BYTE $0x14
        CALL _strayintr(SB); BYTE $0x15
        CALL _strayintr(SB); BYTE $0x16