2014-02-01 09:25:10 +00:00
|
|
|
typedef struct BIOS32si BIOS32si;
|
|
|
|
typedef struct BIOS32ci BIOS32ci;
|
|
|
|
typedef struct Conf Conf;
|
|
|
|
typedef struct Confmem Confmem;
|
kernel: introduce per process FPU struct (PFPU) for more flexible machine specific fpu handling
introducing the PFPU structue which allows the machine specific
code some flexibility on how to handle the FPU process state.
for example, in the pc and pc64 kernel, the FPsave structure is
arround 512 bytes. with avx512, it could grow up to 2K. instead
of embedding that into the Proc strucutre, it is more effective
to allocate it on first use of the fpu, as most processes do not
use simd or floating point in the first place. also, the FPsave
structure has special 16 byte alignment constraint, which further
favours dynamic allocation.
this gets rid of the memmoves in pc/pc64 kernels for the aligment.
there is also devproc, which is now checking if the fpsave area
is actually valid before reading it, avoiding debuggers to see
garbage data.
the Notsave structure is gone now, as it was not used on any
machine.
2017-11-04 19:08:22 +00:00
|
|
|
typedef struct FPsave FPsave;
|
|
|
|
typedef struct PFPU PFPU;
|
2014-02-01 09:25:10 +00:00
|
|
|
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 (S_MAGIC)
|
|
|
|
|
|
|
|
struct Lock
|
|
|
|
{
|
|
|
|
ulong key;
|
|
|
|
ulong sr;
|
|
|
|
uintptr pc;
|
|
|
|
Proc *p;
|
|
|
|
Mach *m;
|
|
|
|
ushort isilock;
|
|
|
|
long lockcycles;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Label
|
|
|
|
{
|
|
|
|
uintptr sp;
|
|
|
|
uintptr pc;
|
|
|
|
};
|
|
|
|
|
kernel: introduce per process FPU struct (PFPU) for more flexible machine specific fpu handling
introducing the PFPU structue which allows the machine specific
code some flexibility on how to handle the FPU process state.
for example, in the pc and pc64 kernel, the FPsave structure is
arround 512 bytes. with avx512, it could grow up to 2K. instead
of embedding that into the Proc strucutre, it is more effective
to allocate it on first use of the fpu, as most processes do not
use simd or floating point in the first place. also, the FPsave
structure has special 16 byte alignment constraint, which further
favours dynamic allocation.
this gets rid of the memmoves in pc/pc64 kernels for the aligment.
there is also devproc, which is now checking if the fpsave area
is actually valid before reading it, avoiding debuggers to see
garbage data.
the Notsave structure is gone now, as it was not used on any
machine.
2017-11-04 19:08:22 +00:00
|
|
|
struct FPsave
|
2014-02-01 09:25:10 +00:00
|
|
|
{
|
|
|
|
u16int fcw; /* x87 control word */
|
|
|
|
u16int fsw; /* x87 status word */
|
|
|
|
u8int ftw; /* x87 tag word */
|
|
|
|
u8int zero; /* 0 */
|
|
|
|
u16int fop; /* last x87 opcode */
|
|
|
|
u64int rip; /* last x87 instruction pointer */
|
|
|
|
u64int rdp; /* last x87 data pointer */
|
|
|
|
u32int mxcsr; /* MMX control and status */
|
|
|
|
u32int mxcsrmask; /* supported MMX feature bits */
|
|
|
|
uchar st[128]; /* shared 64-bit media and x87 regs */
|
|
|
|
uchar xmm[256]; /* 128-bit media regs */
|
|
|
|
uchar ign[96]; /* reserved, ignored */
|
|
|
|
};
|
|
|
|
|
kernel: introduce per process FPU struct (PFPU) for more flexible machine specific fpu handling
introducing the PFPU structue which allows the machine specific
code some flexibility on how to handle the FPU process state.
for example, in the pc and pc64 kernel, the FPsave structure is
arround 512 bytes. with avx512, it could grow up to 2K. instead
of embedding that into the Proc strucutre, it is more effective
to allocate it on first use of the fpu, as most processes do not
use simd or floating point in the first place. also, the FPsave
structure has special 16 byte alignment constraint, which further
favours dynamic allocation.
this gets rid of the memmoves in pc/pc64 kernels for the aligment.
there is also devproc, which is now checking if the fpsave area
is actually valid before reading it, avoiding debuggers to see
garbage data.
the Notsave structure is gone now, as it was not used on any
machine.
2017-11-04 19:08:22 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
/* this is a state */
|
|
|
|
FPinit= 0,
|
|
|
|
FPactive= 1,
|
|
|
|
FPinactive= 2,
|
|
|
|
|
2017-11-12 21:55:54 +00:00
|
|
|
/*
|
|
|
|
* the following are bits that can be or'd into the state.
|
|
|
|
*
|
|
|
|
* this is biased so that FPinit, FPactive and FPinactive
|
|
|
|
* without any flags refer to user fp state in fpslot[0].
|
|
|
|
*/
|
|
|
|
FPillegal= 1<<8, /* fp forbidden in note handler */
|
|
|
|
FPpush= 2<<8, /* trap on use and initialize new fpslot */
|
|
|
|
FPnouser= 4<<8, /* fpslot[0] is kernel regs */
|
|
|
|
FPkernel= 8<<8, /* fp use in kernel (user in fpslot[0] when !FPnouser) */
|
|
|
|
|
|
|
|
FPindexs= 16,
|
|
|
|
FPindex1= 1<<FPindexs,
|
|
|
|
FPindexm= 3<<FPindexs,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PFPU
|
|
|
|
{
|
|
|
|
int fpstate;
|
|
|
|
FPsave *fpsave; /* fpslot[fpstate>>FPindexs] */
|
|
|
|
FPsave *fpslot[(FPindexm+1)>>FPindexs];
|
2014-02-01 09:25:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Confmem
|
|
|
|
{
|
|
|
|
uintptr base;
|
|
|
|
ulong npage;
|
|
|
|
uintptr kbase;
|
|
|
|
uintptr klimit;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Conf
|
|
|
|
{
|
|
|
|
ulong nmach; /* processors */
|
|
|
|
ulong nproc; /* processes */
|
|
|
|
ulong monitor; /* has monitor? */
|
2014-05-01 15:24:50 +00:00
|
|
|
Confmem mem[16]; /* physical memory */
|
2014-02-01 09:25:10 +00:00
|
|
|
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 */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Segdesc
|
|
|
|
{
|
|
|
|
u32int d0;
|
|
|
|
u32int d1;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* MMU structure for PDP, PD, PT pages.
|
|
|
|
*/
|
|
|
|
struct MMU
|
|
|
|
{
|
|
|
|
MMU *next;
|
|
|
|
uintptr *page;
|
|
|
|
int index;
|
|
|
|
int level;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* MMU stuff in proc
|
|
|
|
*/
|
|
|
|
#define NCOLOR 1
|
|
|
|
struct PMMU
|
|
|
|
{
|
2014-02-02 17:01:13 +00:00
|
|
|
MMU* mmuhead;
|
|
|
|
MMU* mmutail;
|
|
|
|
MMU* kmaphead;
|
|
|
|
MMU* kmaptail;
|
2015-07-07 19:13:36 +00:00
|
|
|
ulong kmapcount;
|
|
|
|
ulong kmapindex;
|
|
|
|
ulong mmucount;
|
2017-06-12 19:03:07 +00:00
|
|
|
|
|
|
|
u64int dr[8];
|
2017-08-28 17:27:41 +00:00
|
|
|
void *vmx;
|
2014-02-01 09:25:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#include "../port/portdat.h"
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
u32int _0_;
|
|
|
|
u32int rsp0[2];
|
|
|
|
u32int rsp1[2];
|
|
|
|
u32int rsp2[2];
|
|
|
|
u32int _28_[2];
|
|
|
|
u32int ist[14];
|
|
|
|
u16int _92_[5];
|
|
|
|
u16int iomap;
|
|
|
|
} Tss;
|
|
|
|
|
|
|
|
struct Mach
|
|
|
|
{
|
|
|
|
int machno; /* physical id of processor (KNOWN TO ASSEMBLY) */
|
|
|
|
uintptr splpc; /* pc of last caller to splhi (KNOWN TO ASSEMBLY) */
|
|
|
|
|
|
|
|
Proc* proc; /* current process on this processor (KNOWN TO ASSEMBLY) */
|
|
|
|
|
|
|
|
u64int* pml4; /* pml4 base for this processor (va) */
|
|
|
|
Tss* tss; /* tss for this processor */
|
|
|
|
Segdesc *gdt; /* gdt for this processor */
|
|
|
|
|
|
|
|
u64int mmumap[4]; /* bitmap of pml4 entries for zapping */
|
|
|
|
MMU* mmufree; /* freelist for MMU structures */
|
2015-07-07 19:13:36 +00:00
|
|
|
ulong mmucount; /* number of MMU structures in freelist */
|
2014-02-01 09:25:10 +00:00
|
|
|
|
|
|
|
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;
|
2018-07-11 15:05:03 +00:00
|
|
|
uchar cpuidfamily;
|
|
|
|
uchar cpuidmodel;
|
|
|
|
uchar cpuidstepping;
|
2014-02-01 09:25:10 +00:00
|
|
|
int havetsc;
|
|
|
|
int havepge;
|
2017-06-12 19:03:07 +00:00
|
|
|
int havewatchpt8;
|
2019-08-27 01:55:12 +00:00
|
|
|
int havenx;
|
2014-02-01 09:25:10 +00:00
|
|
|
uvlong tscticks;
|
2017-06-13 00:10:36 +00:00
|
|
|
|
|
|
|
u64int dr7; /* shadow copy of dr7 */
|
2017-08-28 17:27:41 +00:00
|
|
|
|
|
|
|
void* vmx;
|
2014-02-01 09:25:10 +00:00
|
|
|
|
|
|
|
uintptr stack[1];
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* KMap the structure
|
|
|
|
*/
|
|
|
|
typedef void KMap;
|
|
|
|
#define VA(k) ((void*)k)
|
|
|
|
|
2017-03-25 03:08:14 +00:00
|
|
|
extern u32int MemMin;
|
|
|
|
|
2014-02-01 09:25:10 +00:00
|
|
|
struct
|
|
|
|
{
|
2016-01-05 04:32:40 +00:00
|
|
|
char machs[MAXMACH]; /* bitmap of active CPUs */
|
2014-02-01 09:25:10 +00:00
|
|
|
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);
|
2020-11-29 16:43:22 +00:00
|
|
|
int (*intrassign)(Vctl*);
|
|
|
|
int (*intrirqno)(int, int);
|
2014-02-01 09:25:10 +00:00
|
|
|
int (*intrvecno)(int);
|
2020-11-29 16:43:22 +00:00
|
|
|
int (*intrspurious)(int);
|
2014-02-01 09:25:10 +00:00
|
|
|
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 */
|
2014-07-09 20:45:51 +00:00
|
|
|
Mca = 1<<14, /* machine-check architecture */
|
2016-12-17 15:35:26 +00:00
|
|
|
Pat = 1<<16, /* page attribute table */
|
2014-02-01 09:25:10 +00:00
|
|
|
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 */
|
|
|
|
};
|
|
|
|
|
|
|
|
enum { /* MSRs */
|
|
|
|
PerfEvtbase = 0xc0010000, /* Performance Event Select */
|
|
|
|
PerfCtrbase = 0xc0010004, /* Performance Counters */
|
|
|
|
|
|
|
|
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;
|
2020-06-06 12:52:16 +00:00
|
|
|
uvlong port;
|
2014-02-01 09:25:10 +00:00
|
|
|
int irq;
|
|
|
|
ulong dma;
|
|
|
|
ulong mem;
|
|
|
|
ulong size;
|
|
|
|
ulong freq;
|
|
|
|
|
|
|
|
int nopt;
|
|
|
|
char *opt[NISAOPT];
|
|
|
|
};
|
|
|
|
|
|
|
|
extern PCArch *arch; /* PC architecture */
|
|
|
|
|
|
|
|
Mach* machp[MAXMACH];
|
|
|
|
|
|
|
|
#define MACHP(n) (machp[n])
|
|
|
|
|
|
|
|
extern register Mach* m; /* R15 */
|
|
|
|
extern register Proc* up; /* R14 */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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;
|