Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Memory and machine-specific definitions.  Used in C and assembler.
 */

/*
 * Sizes
 */
#define BI2BY           8                       /* bits per byte */
#define BI2WD           32                      /* bits per word */
#define BY2WD           4                       /* bytes per word */
#define BY2PG           4096                    /* bytes per page */
#define WD2PG           (BY2PG/BY2WD)           /* words per page */
#define PGSHIFT         12                      /* log(BY2PG) */
#define PGROUND(s)      (((s)+(BY2PG-1))&~(BY2PG-1))

#define MAXMACH         1                       /* max # cpus system can run */

/*
 * Time
 */
#define HZ              (20)                    /* clock frequency */
#define MS2HZ           (1000/HZ)               /* millisec per clock tick */
#define TK2SEC(t)       ((t)/HZ)                /* ticks to seconds */
#define TK2MS(t)        ((((ulong)(t))*1000)/HZ)        /* ticks to milliseconds */
#define MS2TK(t)        ((((ulong)(t))*HZ)/1000)        /* milliseconds to ticks */

/*
 * Fundamental addresses
 */

/*
 *  Address spaces
 *
 *  User is at 0-2GB
 *  Kernel is at 2GB-4GB
 *
 *  To avoid an extra page map, both the user stack (USTKTOP) and
 *  the temporary user stack (TSTKTOP) should be in the the same
 *  4 meg.
 */
#define UZERO           0                        /* base of user address space */
#define UTZERO          (UZERO+BY2PG)           /* first address in user text */
#define KZERO           0x80000000              /* base of kernel address space */
#define KTZERO          KZERO                   /* first address in kernel text */
#define USERADDR        0xC0000000              /* struct User */
#define UREGADDR        (USERADDR+BY2PG-4*19)   
#define TSTKTOP         USERADDR                /* end of new stack in sysexec */
#define TSTKSIZ 10
#define USTKTOP         (TSTKTOP-TSTKSIZ*BY2PG) /* byte just beyond user stack */
#define USTKSIZE        (16*1024*1024 - TSTKSIZ*BY2PG)  /* size of user stack */
#define ROMBIOS         (KZERO|0xF0000)

#define MACHSIZE        4096

#define isphys(x) (((ulong)x)&KZERO)

/*
 *  known 80386 segments (in GDT) and their selectors
 */
#define NULLSEG 0        /* null segment */
#define KDSEG   1       /* kernel data/stack */
#define KESEG   2       /* kernel executable */ 
#define UDSEG   3       /* user data/stack */
#define UESEG   4       /* user executable */
#define TSSSEG  5       /* task segment */

#define SELGDT  (0<<3)  /* selector is in gdt */
#define SELLDT  (1<<3)  /* selector is in ldt */

#define SELECTOR(i, t, p)       (((i)<<3) | (t) | (p))

#define NULLSEL SELECTOR(NULLSEG, SELGDT, 0)
#define KESEL   SELECTOR(KESEG, SELGDT, 0)
#define KDSEL   SELECTOR(KDSEG, SELGDT, 0)
#define UESEL   SELECTOR(UESEG, SELGDT, 3)
#define UDSEL   SELECTOR(UDSEG, SELGDT, 3)
#define TSSSEL  SELECTOR(TSSSEG, SELGDT, 0)

/*
 *  fields in segment descriptors
 */
#define SEGDATA (0x10<<8)       /* data/stack segment */
#define SEGEXEC (0x18<<8)       /* executable segment */
#define SEGTSS  (0x9<<8)        /* TSS segment */
#define SEGCG   (0x0C<<8)       /* call gate */
#define SEGIG   (0x0E<<8)       /* interrupt gate */
#define SEGTG   (0x0F<<8)       /* task gate */
#define SEGTYPE (0x1F<<8)

#define SEGP    (1<<15)         /* segment present */
#define SEGPL(x) ((x)<<13)      /* priority level */
#define SEGB    (1<<22)         /* granularity 1==4k (for expand-down) */
#define SEGG    (1<<23)         /* granularity 1==4k (for other) */
#define SEGE    (1<<10)         /* expand down */
#define SEGW    (1<<9)          /* writable (for data/stack) */
#define SEGR    (1<<9)          /* readable (for code) */
#define SEGD    (1<<22)         /* default 1==32bit (for code) */

/*
 *  virtual MMU
 */
#define PTEMAPMEM       (1024*1024)     /* ??? */       
#define SEGMAPSIZE      16              /* ??? */
#define PTEPERTAB       (PTEMAPMEM/BY2PG)       /* ??? */
#define PPN(x)          ((x)&~(BY2PG-1))

/*
 *  physical MMU
 */
#define PTEVALID        (1<<0)
#define PTEUNCACHED     0                /* everything is uncached */
#define PTEWRITE        (1<<1)
#define PTERONLY        (0<<1)
#define PTEKERNEL       (0<<2)
#define PTEUSER         (1<<2)

/*
 *  flag register bits that we care about
 */
#define IFLAG   0x200

#define OP16    BYTE    $0x66

/*
 *      about to walk all over ms/dos - turn off interrupts
 */
TEXT    origin(SB),$0

        CLI

#ifdef BOOT
/*
 *      This part of l.s is used only in the boot kernel.
 *      It assumes that we are in real address mode, i.e.,
 *      that we look like an 8086.
 */
/*
 *      relocate everything to a half meg and jump there
 *      - looks wierd because it is being assembled by a 32 bit
 *        assembler for a 16 bit world
 */
        MOVL    $0,BX
        INCL    BX
        SHLL    $15,BX
        MOVL    BX,CX
        MOVW    BX,ES
        MOVL    $0,SI
        MOVL    SI,DI
        CLD; REP; MOVSL
/*      JMPFAR  0X8000:$lowcore(SB) /**/
         BYTE   $0xEA
         WORD   $lowcore(SB)
         WORD   $0X8000

TEXT    lowcore(SB),$0

/*
 *      now that we're in low core, update the DS
 */

        MOVW    BX,DS

/*
 *      goto protected mode
 */
/*      MOVL    tgdtptr(SB),GDTR /**/
         BYTE   $0x0f
         BYTE   $0x01
         BYTE   $0x16
         WORD   $tgdtptr(SB)
        MOVL    CR0,AX
        ORL     $1,AX
        MOVL    AX,CR0

/*
 *      clear prefetch queue (wierd code to avoid optimizations)
 */
        CLC
        JCC     flush
        MOVL    AX,AX
flush:

/*
 *      set all segs
 */
/*      MOVW    $SELECTOR(1, SELGDT, 0),AX      /**/
         BYTE   $0xc7
         BYTE   $0xc0
         WORD   $SELECTOR(1, SELGDT, 0)
        MOVW    AX,DS
        MOVW    AX,SS
        MOVW    AX,ES
        MOVW    AX,FS
        MOVW    AX,GS

/*      JMPFAR  SELECTOR(2, SELGDT, 0):$mode32bit(SB) /**/
         BYTE   $0x66
         BYTE   $0xEA
         LONG   $mode32bit-KZERO(SB)
         WORD   $SELECTOR(2, SELGDT, 0)

TEXT    mode32bit(SB),$0

#endif BOOT

        /*
         * Clear BSS
         */
        LEAL    edata-KZERO(SB),SI
        MOVL    SI,DI
        ADDL    $4,DI
        MOVL    $0,AX
        MOVL    AX,(SI)
        LEAL    end-KZERO(SB),CX
        SUBL    DI,CX
        SHRL    $2,CX
        CLD; REP; MOVSL

        /*
         *  make a bottom level page table page that maps the first
         *  16 meg of physical memory
         */
        LEAL    tpt-KZERO(SB),AX        /* get phys addr of temporary page table */
        ADDL    $(BY2PG-1),AX           /* must be page aligned */
        ANDL    $(~(BY2PG-1)),AX        /* ... */
        MOVL    $(4*1024),CX            /* pte's per page */
        MOVL    $((((4*1024)-1)<<PGSHIFT)|PTEVALID|PTEKERNEL|PTEWRITE),BX
setpte:
        MOVL    BX,-4(AX)(CX*4)
        SUBL    $(1<<PGSHIFT),BX
        LOOP    setpte

        /*
         *  make a top level page table page that maps the first
         *  16 meg of memory to 0 thru 16meg and to KZERO thru KZERO+16meg
         */
        MOVL    AX,BX
        ADDL    $(4*BY2PG),AX
        ADDL    $(PTEVALID|PTEKERNEL|PTEWRITE),BX
        MOVL    BX,0(AX)
        MOVL    BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+0)(AX)
        ADDL    $BY2PG,BX
        MOVL    BX,4(AX)
        MOVL    BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+4)(AX)
        ADDL    $BY2PG,BX
        MOVL    BX,8(AX)
        MOVL    BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+8)(AX)
        ADDL    $BY2PG,BX
        MOVL    BX,12(AX)
        MOVL    BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+12)(AX)

        /*
         *  point processor to top level page & turn on paging
         */
        MOVL    AX,CR3
        MOVL    CR0,AX
        ORL     $0X80000000,AX
        ANDL    $~(0x8|0x2),AX  /* TS=0, MP=0 */
        MOVL    AX,CR0

        /*
         *  use a jump to an absolute location to get the PC into
         *  KZERO.
         */
        LEAL    tokzero(SB),AX
        JMP*    AX

TEXT    tokzero(SB),$0

        /*
         *  stack and mach
         */
        MOVL    $mach0(SB),SP
        MOVL    SP,m(SB)
        MOVL    $0,0(SP)
        ADDL    $(MACHSIZE-4),SP        /* start stack under machine struct */
        MOVL    $0, u(SB)

        /*
         *  clear flags
         */
        MOVL    $0,AX
        PUSHL   AX
        POPFL

        CALL    main(SB)

loop:
        JMP     loop

GLOBL   mach0+0(SB), $MACHSIZE
GLOBL   u(SB), $4
GLOBL   m(SB), $4
GLOBL   tpt(SB), $(BY2PG*6)

/*
 *  gdt to get us to 32-bit/segmented/unpaged mode
 */
TEXT    tgdt(SB),$0

        /* null descriptor */
        LONG    $0
        LONG    $0

        /* data segment descriptor for 4 gigabytes (PL 0) */
        LONG    $(0xFFFF)
        LONG    $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)

        /* exec segment descriptor for 4 gigabytes (PL 0) */
        LONG    $(0xFFFF)
        LONG    $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)

/*
 *  pointer to initial gdt
 */
TEXT    tgdtptr(SB),$0

        WORD    $(3*8)
        LONG    $tgdt-KZERO(SB)

/*
 *  input a byte
 */
TEXT    inb(SB),$0

        MOVL    p+0(FP),DX
        XORL    AX,AX
        INB
        RET

/*
 *  output a byte
 */
TEXT    outb(SB),$0

        MOVL    p+0(FP),DX
        MOVL    b+4(FP),AX
        OUTB
        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; OP16; INSL
        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; OP16; OUTSL
        RET

/*
 *  test and set
 */
TEXT    tas(SB),$0
        MOVL    $0xdeadead,AX
        MOVL    l+0(FP),BX
        XCHGL   AX,(BX)
        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

GLOBL   gdtptr(SB),$6
TEXT    putgdt(SB),$0           /* global descriptor table */
        MOVL    t+0(FP),AX
        MOVL    AX,gdtptr+2(SB)
        MOVL    l+4(FP),AX
        MOVW    AX,gdtptr(SB)
        MOVL    gdtptr(SB),GDTR
        RET

TEXT    putcr3(SB),$0           /* top level page table pointer */
        MOVL    t+0(FP),AX
        MOVL    AX,CR3
        RET

TEXT    puttr(SB),$0            /* task register */
        MOVL    t+0(FP),AX
        MOVW    AX,TASK
        RET

TEXT    getcr0(SB),$0           /* coprocessor bits */
        MOVL    CR0,AX
        RET

TEXT    getcr2(SB),$0           /* fault address */
        MOVL    CR2,AX
        RET

#define FPOFF\
        WAIT;\
        MOVL    CR0,AX;\
        ORL     $0x4,AX         /* EM=1 */;\
        MOVL    AX,CR0

#define FPON\
        MOVL    CR0,AX;\
        ANDL    $~0x4,AX        /* EM=0 */;\
        MOVL    AX,CR0
        
TEXT    fpoff(SB),$0            /* turn off floating point */
        FPOFF
        RET

TEXT    fpinit(SB),$0           /* turn on & init the floating point */
        FPON
        FINIT
        WAIT
        PUSHW   $0x0330
        FLDCW   0(SP)           /* ignore underflow/precision, signal others */
        POPW    AX
        WAIT
        RET

TEXT    fpsave(SB),$0           /* save floating point state and turn off */
        MOVL    p+0(FP),AX
        WAIT
        FSAVE   0(AX)
        FPOFF
        RET

TEXT    fprestore(SB),$0        /* turn on floating point and restore regs */
        FPON
        MOVL    p+0(FP),AX
        FRSTOR  0(AX)
        WAIT
        RET

TEXT    fpstatus(SB),$0         /* get floating point status */
        FSTSW   AX
        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     intrscommon
TEXT    intr9(SB),$0
        PUSHL   $0
        PUSHL   $9
        JMP     intrcommon
TEXT    intr10(SB),$0
        PUSHL   $10
        JMP     intrscommon
TEXT    intr11(SB),$0
        PUSHL   $11
        JMP     intrscommon
TEXT    intr12(SB),$0
        PUSHL   $12
        JMP     intrscommon
TEXT    intr13(SB),$0
        PUSHL   $13
        JMP     intrscommon
TEXT    intr14(SB),$0
        PUSHL   $14
        JMP     intrscommon
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   $16
        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

intrscommon:
        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

/*
 *  do nothing whatsoever till interrupt happens
 */
TEXT    idle(SB),$0
        HLT
        RET

/*
 *  label consists of a stack pointer and a PC
 */
TEXT    gotolabel(SB),$0
        MOVL    l+0(FP),AX
        MOVL    0(AX),SP        /* restore sp */
        MOVL    4(AX),AX        /* put return pc on the stack */
        MOVL    AX,0(SP)
        MOVL    $1,AX           /* return 1 */
        RET

TEXT    setlabel(SB),$0
        MOVL    l+0(FP),AX
        MOVL    SP,0(AX)        /* store sp */
        MOVL    0(SP),BX        /* store return pc */
        MOVL    BX,4(AX)
        MOVL    $0,AX           /* return 0 */
        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 */
        PUSHL   $(USTKTOP)              /* old sp */
        PUSHFL                          /* 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

/*
 *  set configuration register
 */
TEXT    config(SB),$0
        MOVL    l+0(FP),AX
        MOVL    $0x3F3,DX
        OUTB
        OUTB
        RET

Generated by GNU Enscript 1.6.6.