392 lines
8.5 KiB
C
392 lines
8.5 KiB
C
typedef struct BIOS32si BIOS32si;
|
|
typedef struct BIOS32ci BIOS32ci;
|
|
typedef struct Conf Conf;
|
|
typedef struct Confmem Confmem;
|
|
typedef union FPsave FPsave;
|
|
typedef struct FPssestate FPssestate;
|
|
typedef struct FPstate FPstate;
|
|
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) */
|
|
|
|
/*
|
|
* parameters for sysproc.c
|
|
*/
|
|
#define AOUT_MAGIC (I_MAGIC)
|
|
|
|
struct Lock
|
|
{
|
|
ulong key;
|
|
ulong sr;
|
|
uintptr 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 FPstate
|
|
{
|
|
ushort control;
|
|
ushort r1;
|
|
ushort status;
|
|
ushort r2;
|
|
ushort tag;
|
|
ushort r3;
|
|
ulong pc;
|
|
ushort selector;
|
|
ushort opcode;
|
|
ulong operand;
|
|
ushort oselector;
|
|
ushort r4;
|
|
uchar regs[80]; /* floating point registers */
|
|
};
|
|
|
|
struct FPssestate /* SSE fp state */
|
|
{
|
|
ushort fcw; /* control */
|
|
ushort fsw; /* status */
|
|
ushort ftw; /* tag */
|
|
ushort fop; /* opcode */
|
|
ulong fpuip; /* pc */
|
|
ushort cs; /* pc segment */
|
|
ushort rsrvd1; /* reserved */
|
|
ulong fpudp; /* data pointer */
|
|
ushort ds; /* data pointer segment */
|
|
ushort rsrvd2;
|
|
ulong mxcsr; /* MXCSR register state */
|
|
ulong mxcsr_mask; /* MXCSR mask register */
|
|
uchar xregs[480]; /* extended registers */
|
|
uchar alignpad[FPalign];
|
|
};
|
|
|
|
/*
|
|
* the FP regs must be stored here, not somewhere pointed to from here.
|
|
* port code assumes this.
|
|
*/
|
|
union FPsave {
|
|
FPstate;
|
|
FPssestate;
|
|
};
|
|
|
|
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 */
|
|
};
|
|
|
|
struct Segdesc
|
|
{
|
|
ulong d0;
|
|
ulong d1;
|
|
};
|
|
|
|
/*
|
|
* 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 */
|
|
|
|
Segdesc gdt[NPROCSEG]; /* per process descriptors */
|
|
Segdesc *ldt; /* local descriptor table */
|
|
int nldt; /* number of ldt descriptors allocated */
|
|
};
|
|
|
|
/*
|
|
* 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 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;
|
|
|
|
int cpumhz;
|
|
uvlong cyclefreq; /* Frequency of user readable cycle counter */
|
|
uvlong cpuhz;
|
|
int cpuidax;
|
|
int cpuidcx;
|
|
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; /* about to rebooting another kernel */
|
|
}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);
|
|
};
|
|
|
|
/* cpuid instruction result register bits */
|
|
enum {
|
|
/* cx */
|
|
Monitor = 1<<3,
|
|
|
|
/* dx */
|
|
Fpuonchip = 1<<0,
|
|
Vmex = 1<<1, /* virtual-mode extensions */
|
|
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,
|
|
Acpif = 1<<22, /* therm control msr */
|
|
Mmx = 1<<23,
|
|
Fxsr = 1<<24, /* have SSE FXSAVE/FXRSTOR */
|
|
Sse = 1<<25, /* thus sfence instr. */
|
|
Sse2 = 1<<26, /* thus mfence & lfence instr.s */
|
|
Rdrnd = 1<<30, /* RDRAND support bit */
|
|
};
|
|
|
|
/*
|
|
* 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;
|