123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- #include "x16.h"
- #include "mem.h"
- #define WRMSR BYTE $0x0F; BYTE $0x30 /* WRMSR, argument in AX/DX (lo/hi) */
- #define RDTSC BYTE $0x0F; BYTE $0x31 /* RDTSC, result in AX/DX (lo/hi) */
- #define RDMSR BYTE $0x0F; BYTE $0x32 /* RDMSR, result in AX/DX (lo/hi) */
- TEXT _start32v(SB),$0
- CLI
- MOVL $edata(SB), DI
- XORL AX, AX
- MOVL $end(SB), CX
- SUBL DI, CX /* end-edata bytes */
- SHRL $2, CX /* end-edata doublewords */
- CLD
- REP; STOSL /* clear BSS */
- MOVL CR3, AX
- ADDL $KZERO, AX /* VA of PDB */
- MOVL AX, mach0pdb(SB)
- ADDL $(3*BY2PG), AX
- MOVL AX, mach0m(SB)
- MOVL AX, m(SB) /* initialise global Mach pointer */
- MOVL $0, 0(AX) /* initialise machp()->machno */
- ADDL $MACHSIZE, AX
- MOVL AX, SP /* initialise stack */
- MOVL AX, mach0gdt(SB)
- ADDL $BY2PG, AX
- MOVL AX, memstart(SB)
- MOVL $0x240000, AX /* try to set Id|Ac in EFLAGS */
- PUSHL AX
- POPFL
- PUSHFL /* retrieve EFLAGS -> BX */
- POPL BX
- MOVL $0, AX /* clear Id|Ac, EFLAGS initialised */
- PUSHL AX
- POPFL
- PUSHFL /* retrieve EFLAGS -> AX */
- XORL BX, (SP) /* togglable bits */
- CALL main(SB)
- /*
- * Park a processor. Should never fall through a return from main to here,
- * should only be called by application processors when shutting down.
- */
- TEXT idle(SB), $0
- _idle:
- STI
- HLT
- JMP _idle
- TEXT hlt(SB), $0
- STI
- HLT
- RET
- /*
- */
- TEXT _warp9o(SB), $0
- MOVL entry+0(FP), CX
- MOVL $multibootheader-KZERO(SB), BX /* multiboot data pointer */
- MOVL $0x2badb002, AX /* multiboot magic */
- CLI
- JMP* CX
- JMP _idle
- /*
- * Macro for calculating offset within the page directory base.
- * Note that this is assembler-specific hence the '<<2'.
- */
- #define PDO(a) (((((a))>>22) & 0x03FF)<<2)
- /*
- */
- TEXT _warp9(SB), $0
- CLI
- MOVL entry+0(FP), BP
- MOVL CR3, CX /* load address of PDB */
- ADDL $KZERO, CX
- MOVL PDO(KZERO)(CX), DX /* double-map KZERO at 0 */
- MOVL DX, PDO(0)(CX)
- MOVL CR3, CX
- MOVL CX, CR3 /* load and flush the mmu */
- MOVL $_start32id<>-KZERO(SB), AX
- JMP* AX /* jump to identity-map */
- TEXT _start32id<>(SB), $0
- MOVL CR0, DX /* turn off paging */
- ANDL $~0x80000000, DX /* ~(PG) */
- MOVL $_stop32pg<>-KZERO(SB), AX
- MOVL DX, CR0
- JMP* AX /* forward into the past */
- TEXT _stop32pg<>(SB), $0
- MOVL $multibootheader-KZERO(SB), BX /* multiboot data pointer */
- MOVL $0x2badb002, AX /* multiboot magic */
- JMP* BP
- JMP _idle
- /*
- * input a byte
- */
- TEXT inb(SB),$0
- MOVL p+0(FP),DX
- XORL AX,AX
- INB
- RET
- /*
- * input a short from a port
- */
- TEXT ins(SB), $0
- MOVL p+0(FP), DX
- XORL AX, AX
- OPSIZE; INL
- RET
- /*
- * input a long from a port
- */
- TEXT inl(SB), $0
- MOVL p+0(FP), DX
- XORL AX, AX
- INL
- RET
- /*
- * output a byte
- */
- TEXT outb(SB),$0
- MOVL p+0(FP),DX
- MOVL b+4(FP),AX
- OUTB
- RET
- /*
- * output a short to a port
- */
- TEXT outs(SB), $0
- MOVL p+0(FP), DX
- MOVL s+4(FP), AX
- OPSIZE; OUTL
- RET
- /*
- * output a long to a port
- */
- TEXT outl(SB), $0
- MOVL p+0(FP), DX
- MOVL s+4(FP), AX
- OUTL
- RET
- /*
- * input a string of bytes from a port
- */
- TEXT insb(SB),$0
- MOVL p+0(FP),DX
- MOVL a+4(FP),DI
- MOVL c+8(FP),CX
- CLD; REP; INSB
- RET
- /*
- * input a string of shorts from a port
- */
- TEXT inss(SB),$0
- MOVL p+0(FP),DX
- MOVL a+4(FP),DI
- MOVL c+8(FP),CX
- CLD
- REP; OPSIZE; INSL
- RET
- /*
- * output a string of bytes to a port
- */
- TEXT outsb(SB),$0
- MOVL p+0(FP),DX
- MOVL a+4(FP),SI
- MOVL c+8(FP),CX
- CLD; REP; OUTSB
- RET
- /*
- * output a string of shorts to a port
- */
- TEXT outss(SB),$0
- MOVL p+0(FP),DX
- MOVL a+4(FP),SI
- MOVL c+8(FP),CX
- CLD
- REP; OPSIZE; OUTSL
- RET
- /*
- * input a string of longs from a port
- */
- TEXT insl(SB),$0
- MOVL p+0(FP),DX
- MOVL a+4(FP),DI
- MOVL c+8(FP),CX
- CLD; REP; INSL
- RET
- /*
- * output a string of longs to a port
- */
- TEXT outsl(SB),$0
- MOVL p+0(FP),DX
- MOVL a+4(FP),SI
- MOVL c+8(FP),CX
- CLD; REP; OUTSL
- RET
- /*
- * routines to load/read various system registers
- */
- TEXT lgdt(SB), $0 /* GDTR - global descriptor table */
- MOVL gdtptr+0(FP), AX
- MOVL (AX), GDTR
- RET
- TEXT lidt(SB), $0 /* IDTR - interrupt descriptor table */
- MOVL idtptr+0(FP), AX
- MOVL (AX), IDTR
- RET
- TEXT putcr3(SB),$0 /* top level page table pointer */
- MOVL t+0(FP),AX
- MOVL AX,CR3
- RET
- TEXT getcr0(SB),$0 /* coprocessor bits */
- MOVL CR0,AX
- RET
- TEXT getcr2(SB),$0 /* fault address */
- MOVL CR2,AX
- RET
- TEXT getcr3(SB),$0 /* page directory base */
- MOVL CR3,AX
- RET
- TEXT getcr4(SB), $0 /* CR4 - extensions */
- MOVL CR4, AX
- RET
- TEXT _cycles(SB), $0 /* time stamp counter */
- RDTSC
- MOVL vlong+0(FP), CX /* &vlong */
- MOVL AX, 0(CX) /* lo */
- MOVL DX, 4(CX) /* hi */
- RET
- TEXT rdmsr(SB), $0 /* model-specific register */
- MOVL index+0(FP), CX
- RDMSR
- MOVL vlong+4(FP), CX /* &vlong */
- MOVL AX, 0(CX) /* lo */
- MOVL DX, 4(CX) /* hi */
- RET
- TEXT wrmsr(SB), $0
- MOVL index+0(FP), CX
- MOVL lo+4(FP), AX
- MOVL hi+8(FP), DX
- WRMSR
- RET
- TEXT mb386(SB), $0
- POPL AX /* return PC */
- PUSHFL
- PUSHL CS
- PUSHL AX
- IRETL
- /*
- * special traps
- */
- TEXT intr0(SB),$0
- PUSHL $0
- PUSHL $0
- JMP intrcommon
- TEXT intr1(SB),$0
- PUSHL $0
- PUSHL $1
- JMP intrcommon
- TEXT intr2(SB),$0
- PUSHL $0
- PUSHL $2
- JMP intrcommon
- TEXT intr3(SB),$0
- PUSHL $0
- PUSHL $3
- JMP intrcommon
- TEXT intr4(SB),$0
- PUSHL $0
- PUSHL $4
- JMP intrcommon
- TEXT intr5(SB),$0
- PUSHL $0
- PUSHL $5
- JMP intrcommon
- TEXT intr6(SB),$0
- PUSHL $0
- PUSHL $6
- JMP intrcommon
- TEXT intr7(SB),$0
- PUSHL $0
- PUSHL $7
- JMP intrcommon
- TEXT intr8(SB),$0
- PUSHL $8
- JMP intrcommon
- TEXT intr9(SB),$0
- PUSHL $0
- PUSHL $9
- JMP intrcommon
- TEXT intr10(SB),$0
- PUSHL $10
- JMP intrcommon
- TEXT intr11(SB),$0
- PUSHL $11
- JMP intrcommon
- TEXT intr12(SB),$0
- PUSHL $12
- JMP intrcommon
- TEXT intr13(SB),$0
- PUSHL $13
- JMP intrcommon
- TEXT intr14(SB),$0
- PUSHL $14
- JMP intrcommon
- TEXT intr15(SB),$0
- PUSHL $0
- PUSHL $15
- JMP intrcommon
- TEXT intr16(SB),$0
- PUSHL $0
- PUSHL $16
- JMP intrcommon
- TEXT intr24(SB),$0
- PUSHL $0
- PUSHL $24
- JMP intrcommon
- TEXT intr25(SB),$0
- PUSHL $0
- PUSHL $25
- JMP intrcommon
- TEXT intr26(SB),$0
- PUSHL $0
- PUSHL $26
- JMP intrcommon
- TEXT intr27(SB),$0
- PUSHL $0
- PUSHL $27
- JMP intrcommon
- TEXT intr28(SB),$0
- PUSHL $0
- PUSHL $28
- JMP intrcommon
- TEXT intr29(SB),$0
- PUSHL $0
- PUSHL $29
- JMP intrcommon
- TEXT intr30(SB),$0
- PUSHL $0
- PUSHL $30
- JMP intrcommon
- TEXT intr31(SB),$0
- PUSHL $0
- PUSHL $31
- JMP intrcommon
- TEXT intr32(SB),$0
- PUSHL $0
- PUSHL $32
- JMP intrcommon
- TEXT intr33(SB),$0
- PUSHL $0
- PUSHL $33
- JMP intrcommon
- TEXT intr34(SB),$0
- PUSHL $0
- PUSHL $34
- JMP intrcommon
- TEXT intr35(SB),$0
- PUSHL $0
- PUSHL $35
- JMP intrcommon
- TEXT intr36(SB),$0
- PUSHL $0
- PUSHL $36
- JMP intrcommon
- TEXT intr37(SB),$0
- PUSHL $0
- PUSHL $37
- JMP intrcommon
- TEXT intr38(SB),$0
- PUSHL $0
- PUSHL $38
- JMP intrcommon
- TEXT intr39(SB),$0
- PUSHL $0
- PUSHL $39
- JMP intrcommon
- TEXT intr64(SB),$0
- PUSHL $0
- PUSHL $64
- JMP intrcommon
- TEXT intrbad(SB),$0
- PUSHL $0
- PUSHL $0x1ff
- JMP intrcommon
- intrcommon:
- PUSHL DS
- PUSHL ES
- PUSHL FS
- PUSHL GS
- PUSHAL
- MOVL $(KDSEL),AX
- MOVW AX,DS
- MOVW AX,ES
- LEAL 0(SP),AX
- PUSHL AX
- CALL trap(SB)
- POPL AX
- POPAL
- POPL GS
- POPL FS
- POPL ES
- POPL DS
- ADDL $8,SP /* error code and trap type */
- IRETL
- /*
- * interrupt level is interrupts on or off
- */
- TEXT spllo(SB),$0
- PUSHFL
- POPL AX
- STI
- RET
- TEXT splhi(SB),$0
- PUSHFL
- POPL AX
- CLI
- RET
- TEXT splx(SB),$0
- MOVL s+0(FP),AX
- PUSHL AX
- POPFL
- RET
- /*
- * Try to determine the CPU type which requires fiddling with EFLAGS.
- * If the Id bit can be toggled then the CPUID instruciton can be used
- * to determine CPU identity and features. First have to check if it's
- * 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(id[], &ax, &dx);
- */
- #define CPUID BYTE $0x0F; BYTE $0xA2 /* CPUID, argument in AX */
- TEXT cpuid(SB), $0
- MOVL $0x240000, AX
- PUSHL AX
- POPFL /* set Id|Ac */
- PUSHFL
- POPL BX /* retrieve value */
- MOVL $0, AX
- PUSHL AX
- POPFL /* clear Id|Ac, EFLAGS initialised */
- PUSHFL
- POPL AX /* retrieve value */
- XORL BX, AX
- TESTL $0x040000, AX /* Ac */
- JZ _cpu386 /* can't set this bit on 386 */
- TESTL $0x200000, AX /* Id */
- JZ _cpu486 /* can't toggle this bit on some 486 */
- MOVL $0, AX
- CPUID
- MOVL id+0(FP), BP
- MOVL BX, 0(BP) /* "Genu" "Auth" "Cyri" */
- MOVL DX, 4(BP) /* "ineI" "enti" "xIns" */
- MOVL CX, 8(BP) /* "ntel" "cAMD" "tead" */
- MOVL $1, AX
- CPUID
- JMP _cpuid
- _cpu486:
- MOVL $0x400, AX
- MOVL $0, DX
- JMP _cpuid
- _cpu386:
- MOVL $0x300, AX
- MOVL $0, DX
- _cpuid:
- MOVL ax+4(FP), BP
- MOVL AX, 0(BP)
- MOVL dx+8(FP), BP
- MOVL DX, 0(BP)
- RET
- /*
- * basic timing loop to determine CPU frequency
- */
- TEXT aamloop(SB),$0
- MOVL c+0(FP),CX
- aaml1:
- AAM
- LOOP aaml1
- RET
- GLOBL pxe(SB), $4
- #ifdef PXE
- DATA pxe+0(SB)/4, $1
- #else
- DATA pxe+0(SB)/4, $0
- #endif /* PXE */
|