]> 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
index 4087b3f1a0a8bddc3aeaa707f18031c40fe46bad..ede492af8847fe137a379ffc362b0ac2f5dfd379 100644 (file)
@@ -17,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
@@ -40,8 +42,8 @@ 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 */
@@ -50,7 +52,7 @@ TEXT _multibootheader(SB), $0
        LONG    $0                              /* mode_type */
        LONG    $0                              /* width */
        LONG    $0                              /* height */
-       LONG    $                             /* depth */
+       LONG    $32                             /* depth */
 
 /* 
  * the kernel expects the data segment to be page-aligned
@@ -65,17 +67,15 @@ TEXT _multibootentry(SB), $0
        SUBL    DI, CX
        ADDL    CX, SI
        ADDL    CX, DI
+       INCL    CX      /* one more for post decrement */
        STD
        REP; MOVSB
-       CLD
-       ADDL    $KZERO, BX
-       MOVL    BX, multiboot-KZERO(SB)
-       MOVL    $_startPADDR(SB), AX
-       ANDL    $~KZERO, AX
+       MOVL    BX, multibootptr-KZERO(SB)
+       MOVL    $_startPADDR-KZERO(SB), AX
        JMP*    AX
 
-/* multiboot structure pointer */
-TEXT multiboot(SB), $0
+/* multiboot structure pointer (physical address) */
+TEXT multibootptr(SB), $0
        LONG    $0
 
 /*
@@ -97,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
@@ -145,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.
@@ -228,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 */
 
@@ -279,61 +273,6 @@ TEXT load_gs(SB), $0
        MOVW AX, GS
        RET
 
-/*
- * 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
-       RET
-
 /*
  * BIOS32.
  */
@@ -488,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
@@ -558,6 +502,17 @@ TEXT _wrmsrinst(SB), $0
        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
+
 /*
  * Try to determine the CPU type which requires fiddling with EFLAGS.
  * If the Id bit can be toggled then the CPUID instruction can be used
@@ -565,7 +520,7 @@ TEXT _wrmsrinst(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
@@ -584,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:
@@ -600,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)
@@ -624,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
 
@@ -640,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 */
@@ -657,47 +606,42 @@ TEXT fpinit(SB), $0                               /* enable and init */
        WAIT
        RET
 
-TEXT fpx87save(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 fpx87restore(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
-       RET
-
-TEXT fpenv(SB), $0                             /* save state without waiting */
-       MOVL    p+0(FP), AX
-       FSTENV  0(AX)
-       RET
-
 TEXT fpclear(SB), $0                           /* clear pending exceptions */
        FPON
        FCLEX                                   /* no WAIT */
-       FPOFF(l3)
+       FPOFF
        RET
 
-TEXT fpssesave0(SB), $0                                /* save state and disable */
+TEXT fpssesave(SB), $0                         /* save state and disable */
        MOVL    p+0(FP), AX
        FXSAVE  0(AX)                           /* no WAIT */
-       FPOFF(l4)
+       FPOFF
        RET
 
-TEXT fpsserestore0(SB), $0                     /* enable and restore state */
+TEXT fpsserestore(SB), $0                      /* enable and restore state */
        FPON
        MOVL    p+0(FP), AX
        FXRSTOR 0(AX)
        WAIT
        RET
 
+TEXT ldmxcsr(SB), $0                           /* Load MXCSR */
+       LDMXCSR mxcsr+0(FP)
+       RET
+
 /*
  */
 TEXT splhi(SB), $0
@@ -744,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
@@ -925,7 +851,161 @@ _rndbytes:
        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
@@ -975,6 +1055,28 @@ TEXT _forkretpopds(SB), $0
 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 */
@@ -995,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