Subversion Repositories planix.SVN

Rev

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

typedef struct BIOS32si BIOS32si;
typedef struct BIOS32ci BIOS32ci;
typedef struct Conf     Conf;
typedef struct Confmem  Confmem;
typedef struct FPsave   FPsave;
typedef struct ISAConf  ISAConf;
typedef struct Label    Label;
typedef struct Lock     Lock;
typedef struct MMU      MMU;
typedef struct Mach     Mach;
typedef struct Notsave  Notsave;
typedef struct PCArch   PCArch;
typedef struct Pcidev   Pcidev;
typedef struct PCMmap   PCMmap;
typedef struct PCMslot  PCMslot;
typedef struct Page     Page;
typedef struct PMMU     PMMU;
typedef struct Proc     Proc;
typedef struct Segdesc  Segdesc;
typedef vlong           Tval;
typedef struct Ureg     Ureg;
typedef struct Vctl     Vctl;

#pragma incomplete BIOS32si
#pragma incomplete Pcidev
#pragma incomplete Ureg

#define MAXSYSARG       5       /* for mount(fd, afd, mpt, flag, arg) */

/*
 * Where configuration info is left for the loaded programme.
 * There are 3584 bytes available at CONFADDR.
 */
#define BOOTLINE        ((char*)CONFADDR)
#define BOOTLINELEN     64
#define BOOTARGS        ((char*)(CONFADDR+BOOTLINELEN))
#define BOOTARGSLEN     (3584-0x200-BOOTLINELEN)
#define MAXCONF         100

enum {
        Promptsecs      = 60,
};

char *confname[MAXCONF];
char *confval[MAXCONF];
int nconf;

#define KMESGSIZE 64
#define PCICONSSIZE 64
#define STAGESIZE 64

#define NAMELEN 28

#define GSHORT(p)       (((p)[1]<<8)|(p)[0])
#define GLSHORT(p)      (((p)[0]<<8)|(p)[1])

#define GLONG(p)        ((GSHORT(p+2)<<16)|GSHORT(p))
#define GLLONG(p)       (((ulong)GLSHORT(p)<<16)|GLSHORT(p+2))
#define PLLONG(p,v)     (p)[3]=(v);(p)[2]=(v)>>8;(p)[1]=(v)>>16;(p)[0]=(v)>>24

#define PLVLONG(p,v)    (p)[7]=(v);(p)[6]=(v)>>8;(p)[5]=(v)>>16;(p)[4]=(v)>>24;\
                        (p)[3]=(v)>>32; (p)[2]=(v)>>40;\
                        (p)[1]=(v)>>48; (p)[0]=(v)>>56;

enum {
        Stkpat =        0,
};

/*
 *  parameters for sysproc.c
 */
#define AOUT_MAGIC      (I_MAGIC)

struct Lock
{
        ulong   magic;
        ulong   key;
        ulong   sr;
        ulong   pc;
        Proc    *p;
        Mach    *m;
        ushort  isilock;
        long    lockcycles;
};

struct Label
{
        ulong   sp;
        ulong   pc;
};


/*
 * FPsave.status
 */
enum
{
        /* this is a state */
        FPinit=         0,
        FPactive=       1,
        FPinactive=     2,

        /* the following is a bit that can be or'd into the state */
        FPillegal=      0x100,
};

struct  FPsave
{
        ushort  control;
        ushort  r1;
        ushort  status;
        ushort  r2;
        ushort  tag;
        ushort  r3;
        ulong   pc;
        ushort  selector;
        ushort  r4;
        ulong   operand;
        ushort  oselector;
        ushort  r5;
        uchar   regs[80];       /* floating point registers */
};

struct Confmem
{
        ulong   base;
        ulong   npage;
        ulong   kbase;
        ulong   klimit;
};

struct Conf
{
        ulong   nmach;          /* processors */
        ulong   nproc;          /* processes */
        ulong   monitor;        /* has monitor? */
        Confmem mem[4];         /* physical memory */
        ulong   npage;          /* total physical pages of memory */
        ulong   upages;         /* user page pool */
        ulong   nimage;         /* number of page cache image headers */
        ulong   nswap;          /* number of swap pages */
        int     nswppo;         /* max # of pageouts per segment pass */
        ulong   base0;          /* base of bank 0 */
        ulong   base1;          /* base of bank 1 */
        ulong   copymode;       /* 0 is copy on write, 1 is copy on reference */
        ulong   ialloc;         /* max interrupt time allocation in bytes */
        ulong   pipeqsize;      /* size in bytes of pipe queues */
        int     nuart;          /* number of uart devices */
};

/*
 *  MMU stuff in proc
 */
#define NCOLOR 1
struct PMMU
{
        Page*   mmupdb;                 /* page directory base */
        Page*   mmufree;                /* unused page table pages */
        Page*   mmuused;                /* used page table pages */
        Page*   kmaptable;              /* page table used by kmap */
        uint    lastkmap;               /* last entry used by kmap */
        int     nkmap;                  /* number of current kmaps */
};

/*
 *  things saved in the Proc structure during a notify
 */
struct Notsave
{
        ulong   svflags;
        ulong   svcs;
        ulong   svss;
};

#include "../port/portdat.h"

typedef struct {
        ulong   link;                   /* link (old TSS selector) */
        ulong   esp0;                   /* privilege level 0 stack pointer */
        ulong   ss0;                    /* privilege level 0 stack selector */
        ulong   esp1;                   /* privilege level 1 stack pointer */
        ulong   ss1;                    /* privilege level 1 stack selector */
        ulong   esp2;                   /* privilege level 2 stack pointer */
        ulong   ss2;                    /* privilege level 2 stack selector */
        ulong   xcr3;                   /* page directory base register - not used because we don't use trap gates */
        ulong   eip;                    /* instruction pointer */
        ulong   eflags;                 /* flags register */
        ulong   eax;                    /* general registers */
        ulong   ecx;
        ulong   edx;
        ulong   ebx;
        ulong   esp;
        ulong   ebp;
        ulong   esi;
        ulong   edi;
        ulong   es;                     /* segment selectors */
        ulong   cs;
        ulong   ss;
        ulong   ds;
        ulong   fs;
        ulong   gs;
        ulong   ldt;                    /* selector for task's LDT */
        ulong   iomap;                  /* I/O map base address + T-bit */
} Tss;

struct Segdesc
{
        ulong   d0;
        ulong   d1;
};

struct Mach
{
        int     machno;                 /* physical id of processor (KNOWN TO ASSEMBLY) */
        ulong   splpc;                  /* pc of last caller to splhi */

        ulong*  pdb;                    /* page directory base for this processor (va) */
        Tss*    tss;                    /* tss for this processor */
        Segdesc *gdt;                   /* gdt for this processor */

        Proc*   proc;                   /* current process on this processor */
        Proc*   externup;               /* extern register Proc *up */

        Page*   pdbpool;
        int     pdbcnt;

        ulong   ticks;                  /* of the clock since boot time */
        Label   sched;                  /* scheduler wakeup */
        Lock    alarmlock;              /* access to alarm list */
        void*   alarm;                  /* alarms bound to this clock */
        int     inclockintr;

        Proc*   readied;                /* for runproc */
        ulong   schedticks;             /* next forced context switch */

        int     tlbfault;
        int     tlbpurge;
        int     pfault;
        int     cs;
        int     syscall;
        int     load;
        int     intr;
        int     flushmmu;               /* make current proc flush it's mmu state */
        int     ilockdepth;
        Perf    perf;                   /* performance counters */

        ulong   spuriousintr;
        int     lastintr;

        int     loopconst;

        Lock    apictimerlock;
        int     cpumhz;
        uvlong  cyclefreq;              /* Frequency of user readable cycle counter */
        uvlong  cpuhz;
        int     cpuidax;
        int     cpuiddx;
        char    cpuidid[16];
        char*   cpuidtype;
        int     havetsc;
        int     havepge;
        uvlong  tscticks;
        int     pdballoc;
        int     pdbfree;

        vlong   mtrrcap;
        vlong   mtrrdef;
        vlong   mtrrfix[11];
        vlong   mtrrvar[32];            /* 256 max. */

        int     stack[1];
};

/*
 * KMap the structure doesn't exist, but the functions do.
 */
typedef struct KMap             KMap;
#define VA(k)           ((void*)(k))
KMap*   kmap(Page*);
void    kunmap(KMap*);

struct
{
        Lock;
        int     machs;                  /* bitmap of active CPUs */
        int     exiting;                /* shutdown */
        int     ispanic;                /* shutdown in response to a panic */
        int     thunderbirdsarego;      /* lets the added processors continue to schedinit */
        int     rebooting;              /* just idle cpus > 0 */
}active;

/*
 *  routines for things outside the PC model, like power management
 */
struct PCArch
{
        char*   id;
        int     (*ident)(void);         /* this should be in the model */
        void    (*reset)(void);         /* this should be in the model */
        int     (*serialpower)(int);    /* 1 == on, 0 == off */
        int     (*modempower)(int);     /* 1 == on, 0 == off */

        void    (*intrinit)(void);
        int     (*intrenable)(Vctl*);
        int     (*intrvecno)(int);
        int     (*intrdisable)(int);
        void    (*introff)(void);
        void    (*intron)(void);

        void    (*clockenable)(void);
        uvlong  (*fastclock)(uvlong*);
        void    (*timerset)(uvlong);

        void    (*resetothers)(void);   /* put other cpus into reset */
};

/* cpuid instruction result register bits */
enum {
        /* dx */
        Fpuonchip = 1<<0,
        Pse     = 1<<3,         /* page size extensions */
        Tsc     = 1<<4,         /* time-stamp counter */
        Cpumsr  = 1<<5,         /* model-specific registers, rdmsr/wrmsr */
        Pae     = 1<<6,         /* physical-addr extensions */
        Mce     = 1<<7,         /* machine-check exception */
        Cmpxchg8b = 1<<8,
        Cpuapic = 1<<9,
        Mtrr    = 1<<12,        /* memory-type range regs.  */
        Pge     = 1<<13,        /* page global extension */
        Pse2    = 1<<17,        /* more page size extensions */
        Clflush = 1<<19,
        Mmx     = 1<<23,
        Fxsr    = 1<<24,        /* have SSE FXSAVE/FXRSTOR */
        Sse     = 1<<25,        /* thus sfence instr. */
        Sse2    = 1<<26,        /* thus mfence & lfence instr.s */
};

/*
 *  a parsed plan9.ini line
 */
#define NISAOPT         8

struct ISAConf {
        char    *type;
        ulong   port;
        int     irq;
        ulong   dma;
        ulong   mem;
        ulong   size;
        ulong   freq;

        int     nopt;
        char    *opt[NISAOPT];
};

extern PCArch   *arch;                  /* PC architecture */

/*
 * Each processor sees its own Mach structure at address MACHADDR.
 * However, the Mach structures must also be available via the per-processor
 * MMU information array machp, mainly for disambiguation and access to
 * the clock which is only maintained by the bootstrap processor (0).
 */
Mach* machp[MAXMACH];
        
#define MACHP(n)        (machp[n])

extern Mach     *m;
#define up      (((Mach*)MACHADDR)->externup)

/*
 *  hardware info about a device
 */
typedef struct {
        ulong   port;   
        int     size;
} Devport;

struct DevConf
{
        ulong   intnum;                 /* interrupt number */
        char    *type;                  /* card type, malloced */
        int     nports;                 /* Number of ports */
        Devport *ports;                 /* The ports themselves */
};

typedef struct BIOS32ci {               /* BIOS32 Calling Interface */
        u32int  eax;
        u32int  ebx;
        u32int  ecx;
        u32int  edx;
        u32int  esi;
        u32int  edi;
} BIOS32ci;

/* misc. */
extern int      v_flag;

/* APM goo */
typedef struct Apminfo {
        int haveinfo;
        int ax;
        int cx;
        int dx;
        int di;
        int ebx;
        int esi;
} Apminfo;
extern Apminfo  apm;

/*
 * Multiboot grot.
 */
typedef struct Mbi Mbi;
struct Mbi {
        u32int  flags;
        u32int  memlower;
        u32int  memupper;
        u32int  bootdevice;
        u32int  cmdline;
        u32int  modscount;
        u32int  modsaddr;
        u32int  syms[4];
        u32int  mmaplength;
        u32int  mmapaddr;
        u32int  driveslength;
        u32int  drivesaddr;
        u32int  configtable;
        u32int  bootloadername;
        u32int  apmtable;
        u32int  vbe[6];
};

enum {                                          /* flags */
        Fmem            = 0x00000001,           /* mem* valid */
        Fbootdevice     = 0x00000002,           /* bootdevice valid */
        Fcmdline        = 0x00000004,           /* cmdline valid */
        Fmods           = 0x00000008,           /* mod* valid */
        Fsyms           = 0x00000010,           /* syms[] has a.out info */
        Felf            = 0x00000020,           /* syms[] has ELF info */
        Fmmap           = 0x00000040,           /* mmap* valid */
        Fdrives         = 0x00000080,           /* drives* valid */
        Fconfigtable    = 0x00000100,           /* configtable* valid */
        Fbootloadername = 0x00000200,           /* bootloadername* valid */
        Fapmtable       = 0x00000400,           /* apmtable* valid */
        Fvbe            = 0x00000800,           /* vbe[] valid */
};

typedef struct Mod Mod;
struct Mod {
        u32int  modstart;
        u32int  modend;
        u32int  string;
        u32int  reserved;
};

typedef struct MMap MMap;
struct MMap {
        u32int  size;
        u32int  base[2];
        u32int  length[2];
        u32int  type;
};

MMap mmap[32+1];
int nmmap;

Mbi *multibootheader;

enum {
        Maxfile = 4096,
};

/* from 9load */

enum {  /* returned by bootpass */
        MORE, ENOUGH, FAIL
};
enum {
        INITKERNEL,
        READEXEC,
        READ9TEXT,
        READ9DATA,
        READGZIP,
        READEHDR,               /* elf states ... */
        READPHDR,
        READEPAD,
        READEDATA,              /* through here */
        READE64HDR,             /* elf64 states ... */
        READ64PHDR,
        READE64PAD,
        READE64DATA,            /* through here */
        TRYBOOT,
        TRYEBOOT,               /* another elf state */
        TRYE64BOOT,             /* another elf state */
        INIT9LOAD,
        READ9LOAD,
        FAILED
};

typedef struct Execbytes Execbytes;
struct  Execbytes
{
        uchar   magic[4];               /* magic number */
        uchar   text[4];                /* size of text segment */
        uchar   data[4];                /* size of initialized data */
        uchar   bss[4];                 /* size of uninitialized data */
        uchar   syms[4];                /* size of symbol table */
        uchar   entry[4];               /* entry point */
        uchar   spsz[4];                /* size of sp/pc offset table */
        uchar   pcsz[4];                /* size of pc/line number table */
};

typedef struct {
        Execbytes;
        uvlong uvl[1];
} Exechdr;

typedef struct Boot Boot;
struct Boot {
        int state;

        Exechdr hdr;
        uvlong  entry;

        char *bp;       /* base ptr */
        char *wp;       /* write ptr */
        char *ep;       /* end ptr */
};

extern int      debugload;
extern Apminfo  apm;
extern Chan     *conschan;
extern char     *defaultpartition;
extern int      iniread;
extern u32int   memstart;
extern u32int   memend;
extern int      noclock;
extern int      pxe;
extern int      vga;

extern int      biosinited;

extern void _KTZERO(void);
#define KTZERO ((uintptr)_KTZERO)