![cinap_lenrek](/assets/img/avatar_default.png)
To avoid a MAXMACH limit of 32 and make txtflush into an array for the bitmap. Provide portable macros for testing and clearing the bits: needtxtflush(), donetxtflush(). On pc/pc64, define inittxtflush()/settxtflush() as no-op macros, avoiding the storage overhead of the txtflush array alltogether.
382 lines
8.2 KiB
C
382 lines
8.2 KiB
C
typedef struct BIOS32si BIOS32si;
|
|
typedef struct BIOS32ci BIOS32ci;
|
|
typedef struct Conf Conf;
|
|
typedef struct Confmem Confmem;
|
|
typedef union FPsave FPsave;
|
|
typedef struct FPx87state FPx87state;
|
|
typedef struct FPssestate FPssestate;
|
|
typedef struct PFPU PFPU;
|
|
typedef struct ISAConf ISAConf;
|
|
typedef struct Label Label;
|
|
typedef struct Lock Lock;
|
|
typedef struct MMU MMU;
|
|
typedef struct Mach Mach;
|
|
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;
|
|
};
|
|
|
|
struct FPx87state /* x87 fp state */
|
|
{
|
|
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 */
|
|
};
|
|
|
|
union FPsave {
|
|
FPx87state;
|
|
FPssestate;
|
|
};
|
|
|
|
struct PFPU
|
|
{
|
|
int fpstate;
|
|
FPsave *fpsave;
|
|
};
|
|
|
|
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 Confmem
|
|
{
|
|
ulong base;
|
|
ulong npage;
|
|
ulong kbase;
|
|
ulong klimit;
|
|
};
|
|
|
|
struct Conf
|
|
{
|
|
ulong nmach; /* processors */
|
|
ulong nproc; /* processes */
|
|
ulong monitor; /* has monitor? */
|
|
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 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 */
|
|
Confmem mem[64]; /* physical memory */
|
|
};
|
|
|
|
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 */
|
|
|
|
u32int dr[8]; /* debug registers */
|
|
void *vmx;
|
|
};
|
|
|
|
#define inittxtflush(p)
|
|
#define settxtflush(p,c)
|
|
|
|
#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 */
|
|
uintptr splpc; /* pc of last caller to splhi */
|
|
Proc* proc; /* current process on this processor */
|
|
Proc* externup; /* extern register Proc *up */
|
|
|
|
PMach;
|
|
|
|
uvlong tscticks;
|
|
ulong spuriousintr;
|
|
int lastintr;
|
|
|
|
int loopconst;
|
|
int aalcycles;
|
|
int cpumhz;
|
|
uvlong cpuhz;
|
|
|
|
int cpuidax;
|
|
int cpuidcx;
|
|
int cpuiddx;
|
|
char cpuidid[16];
|
|
char* cpuidtype;
|
|
uchar cpuidfamily;
|
|
uchar cpuidmodel;
|
|
uchar cpuidstepping;
|
|
|
|
char havetsc;
|
|
char havepge;
|
|
char havewatchpt8;
|
|
char havenx;
|
|
|
|
ulong* pdb; /* page directory base for this processor (va) */
|
|
Tss* tss; /* tss for this processor */
|
|
Segdesc*gdt; /* gdt for this processor */
|
|
|
|
u32int dr7; /* shadow copy of dr7 */
|
|
u32int xcr0;
|
|
void* vmx;
|
|
|
|
Page* pdbpool;
|
|
int pdbcnt;
|
|
int pdballoc;
|
|
int pdbfree;
|
|
|
|
uintptr 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*);
|
|
|
|
extern u32int MemMin;
|
|
|
|
struct
|
|
{
|
|
char machs[MAXMACH]; /* active CPUs */
|
|
int exiting; /* shutdown */
|
|
}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 */
|
|
|
|
void (*intrinit)(void);
|
|
int (*intrassign)(Vctl*);
|
|
int (*intrirqno)(int, int);
|
|
int (*intrspurious)(int);
|
|
int (*intrvecno)(int);
|
|
void (*introff)(void);
|
|
void (*intron)(void);
|
|
|
|
void (*clockinit)(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 */
|
|
Mca = 1<<14, /* machine-check architecture */
|
|
Pat = 1<<16, /* page attribute table */
|
|
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 */
|
|
};
|
|
|
|
/* model-specific registers, for compatibility with pc64 code */
|
|
enum {
|
|
Efer = 0xc0000080, /* Extended Feature Enable */
|
|
Star = 0xc0000081, /* Legacy Target IP and [CS]S */
|
|
Lstar = 0xc0000082, /* Long Mode Target IP */
|
|
Cstar = 0xc0000083, /* Compatibility Target IP */
|
|
Sfmask = 0xc0000084, /* SYSCALL Flags Mask */
|
|
FSbase = 0xc0000100, /* 64-bit FS Base Address */
|
|
GSbase = 0xc0000101, /* 64-bit GS Base Address */
|
|
KernelGSbase = 0xc0000102, /* SWAPGS instruction */
|
|
};
|
|
|
|
/*
|
|
* a parsed plan9.ini line
|
|
*/
|
|
#define NISAOPT 8
|
|
|
|
struct ISAConf {
|
|
char *type;
|
|
uvlong 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;
|