Subversion Repositories planix.SVN

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "/sys/src/boot/pc/x16.h"
#include "mem.h"

#define KB              1024
#define MB              (1024*1024)

#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) */
#define CPUID           BYTE $0x0F; BYTE $0xA2  /* CPUID, argument in AX */

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
        /* 1+LOWPTEPAGES zeroed pages at (AX): pdb, pte */
        ADDL    $KZERO, AX              /* VA of PDB */
        MOVL    AX, mach0pdb(SB)
        ADDL    $((1+LOWPTEPAGES)*BY2PG), AX /* skip pdb & n pte */
        MOVL    AX, memstart(SB)        /* start of available memory */

        /* 2 zeroed pages at CPU0MACH: mach, gdt */
        MOVL    $CPU0MACH, AX
        MOVL    AX, mach0m(SB)          /* ... VA of Mach */
        MOVL    AX, m(SB)               /* initialise global Mach pointer */
        MOVL    $0, 0(AX)               /* initialise m->machno */
        ADDL    $MACHSIZE, AX
        MOVL    AX, SP                  /* switch to new stack in Mach */
        MOVL    $CPU0GDT, mach0gdt(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

#ifdef UNUSED
/*
 */
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    $~PG, DX

        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
#endif

/*
 *  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
 */
GLOBL   idtptr(SB),$6
TEXT    putidt(SB),$0           /* interrupt descriptor table */
        MOVL    t+0(FP),AX
        MOVL    AX,idtptr+2(SB)
        MOVL    l+4(FP),AX
        MOVW    AX,idtptr(SB)
        MOVL    idtptr(SB),IDTR
        RET

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 putcr4(SB), $0
        MOVL    cr4+0(FP), AX
        MOVL    AX, CR4
        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

/*
 * memory barriers
 */
TEXT mb386(SB), $0
        POPL    AX                              /* return PC */
        PUSHFL
        PUSHL   CS
        PUSHL   AX
        IRETL

TEXT mb586(SB), $0
        XORL    AX, AX
        CPUID
        RET

TEXT sfence(SB), $0
        BYTE $0x0f
        BYTE $0xae
        BYTE $0xf8
        RET

TEXT lfence(SB), $0
        BYTE $0x0f
        BYTE $0xae
        BYTE $0xe8
        RET

TEXT mfence(SB), $0
        BYTE $0x0f
        BYTE $0xae
        BYTE $0xf0
        RET

/*
 *  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.
 *  kprof knows that spllo to spldone is splx routines.
 */
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

TEXT spldone(SB), $0
        RET

TEXT islo(SB), $0
        PUSHFL
        POPL    AX
        ANDL    $0x200, AX                      /* interrupt enable flag */
        RET

/*
 *  basic timing loop to determine CPU frequency
 */
TEXT    aamloop(SB),$0

        MOVL    c+0(FP),CX
aaml1:
        AAM
        LOOP    aaml1
        RET

Generated by GNU Enscript 1.6.6.