2018-01-02 01:00:07 +01:00
|
|
|
/* Copyright (C) Charles Forsyth
|
|
|
|
* See /doc/license/NOTICE.Plan9-9k.txt for details about the licensing.
|
|
|
|
*/
|
|
|
|
/* Portions of this file are Copyright (C) 2015-2018 Giacomo Tesio <giacomo@tesio.it>
|
|
|
|
* See /doc/license/gpl-2.0.txt for details about the licensing.
|
|
|
|
*/
|
|
|
|
/* Portions of this file are Copyright (C) 9front's team.
|
|
|
|
* See /doc/license/9front-mit for details about the licensing.
|
|
|
|
* See http://code.9front.org/hg/plan9front/ for a list of authors.
|
2016-11-25 17:18:40 +01:00
|
|
|
*/
|
2017-01-22 03:34:17 +01:00
|
|
|
typedef struct BIOS32si BIOS32si;
|
|
|
|
typedef struct BIOS32ci BIOS32ci;
|
2017-08-11 01:47:15 +02:00
|
|
|
typedef struct Confmem Confmem;
|
2016-11-25 17:18:40 +01:00
|
|
|
typedef struct Fxsave Fxsave;
|
|
|
|
typedef struct IOConf IOConf;
|
|
|
|
typedef struct ISAConf ISAConf;
|
|
|
|
typedef struct Label Label;
|
|
|
|
typedef struct Lock Lock;
|
|
|
|
typedef struct LockEntry LockEntry;
|
|
|
|
typedef struct MCPU MCPU;
|
|
|
|
typedef struct MFPU MFPU;
|
2017-08-11 01:47:15 +02:00
|
|
|
typedef struct MMU MMU;
|
2016-11-25 17:18:40 +01:00
|
|
|
typedef struct MMMU MMMU;
|
|
|
|
typedef struct Mach Mach;
|
|
|
|
typedef uint64_t Mpl;
|
|
|
|
typedef Mpl Mreg; /* GAK */
|
2017-08-11 01:47:15 +02:00
|
|
|
typedef struct Segdesc Segdesc;
|
2016-11-25 17:18:40 +01:00
|
|
|
typedef struct Pcidev Pcidev;
|
|
|
|
typedef struct PFPU PFPU;
|
|
|
|
typedef struct PMMU PMMU;
|
|
|
|
typedef struct PNOTIFY PNOTIFY;
|
|
|
|
typedef struct PPAGE PPAGE;
|
|
|
|
typedef uint64_t PTE;
|
2017-08-11 01:47:15 +02:00
|
|
|
typedef struct RMap RMap;
|
2016-11-25 17:18:40 +01:00
|
|
|
typedef struct Proc Proc;
|
|
|
|
typedef struct Sys Sys;
|
|
|
|
typedef uint64_t uintmem; /* horrible name */
|
2017-08-11 01:47:15 +02:00
|
|
|
typedef long Tval;
|
2016-11-25 17:18:40 +01:00
|
|
|
typedef struct Ureg Ureg;
|
|
|
|
typedef struct Vctl Vctl;
|
2017-08-11 01:47:15 +02:00
|
|
|
typedef struct PCArch PCArch;
|
|
|
|
typedef union FPsave FPsave;
|
|
|
|
typedef struct Fxsave Fxsave;
|
|
|
|
typedef struct FPstate FPstate;
|
|
|
|
typedef struct PCMmap PCMmap;
|
2016-11-25 17:18:40 +01:00
|
|
|
|
2017-01-22 03:34:17 +01:00
|
|
|
#pragma incomplete BIOS32si
|
2016-11-25 17:18:40 +01:00
|
|
|
#pragma incomplete Ureg
|
|
|
|
|
2019-11-26 02:25:23 +01:00
|
|
|
#define MAXSYSARG 6 /* for sys_mount(fd, afd, mpt, flag, arg, dc) */
|
2016-11-25 17:18:40 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* parameters for sysproc.c
|
|
|
|
*/
|
|
|
|
#define AOUT_MAGIC (S_MAGIC)
|
|
|
|
#define ELF_MAGIC (ELF_MAG)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* machine dependent definitions used by ../port/portdat.h
|
|
|
|
*/
|
|
|
|
struct Lock
|
|
|
|
{
|
2017-08-11 01:47:15 +02:00
|
|
|
uint64_t sr;
|
|
|
|
uintptr_t pc;
|
|
|
|
Proc *lp;
|
|
|
|
Mach *lm;
|
|
|
|
uint32_t key;
|
|
|
|
uint16_t isilock;
|
|
|
|
long lockcycles;
|
2016-11-25 17:18:40 +01:00
|
|
|
};
|
|
|
|
|
2017-08-11 01:47:15 +02:00
|
|
|
|
2016-11-25 17:18:40 +01:00
|
|
|
struct Label
|
|
|
|
{
|
|
|
|
uintptr_t sp;
|
|
|
|
uintptr_t pc;
|
|
|
|
uintptr_t regs[14];
|
|
|
|
};
|
|
|
|
|
2017-08-11 01:47:15 +02:00
|
|
|
/*
|
|
|
|
* 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,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* the FP regs must be stored here, not somewhere pointed to from here.
|
|
|
|
* port code assumes this.
|
|
|
|
*/
|
2016-11-25 17:18:40 +01:00
|
|
|
struct Fxsave {
|
|
|
|
uint16_t fcw; /* x87 control word */
|
|
|
|
uint16_t fsw; /* x87 status word */
|
|
|
|
uint8_t ftw; /* x87 tag word */
|
|
|
|
uint8_t zero; /* 0 */
|
|
|
|
uint16_t fop; /* last x87 opcode */
|
|
|
|
uint64_t rip; /* last x87 instruction pointer */
|
|
|
|
uint64_t rdp; /* last x87 data pointer */
|
|
|
|
uint32_t mxcsr; /* MMX control and status */
|
|
|
|
uint32_t mxcsrmask; /* supported MMX feature bits */
|
|
|
|
uint8_t st[128]; /* shared 64-bit media and x87 regs */
|
|
|
|
uint8_t xmm[256]; /* 128-bit media regs */
|
|
|
|
uint8_t ign[96]; /* reserved, ignored */
|
|
|
|
};
|
|
|
|
|
2017-08-11 01:47:15 +02:00
|
|
|
union FPsave {
|
|
|
|
uint8_t align[512+15];
|
|
|
|
Fxsave;
|
2016-11-25 17:18:40 +01:00
|
|
|
};
|
|
|
|
|
2017-08-11 01:47:15 +02:00
|
|
|
struct Segdesc
|
2016-11-25 17:18:40 +01:00
|
|
|
{
|
2017-08-11 01:47:15 +02:00
|
|
|
uint32_t d0;
|
|
|
|
uint32_t d1;
|
2016-11-25 17:18:40 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
2017-08-11 01:47:15 +02:00
|
|
|
* MMU structure for PDP, PD, PT pages.
|
2016-11-25 17:18:40 +01:00
|
|
|
*/
|
2017-08-11 01:47:15 +02:00
|
|
|
struct MMU
|
2016-11-25 17:18:40 +01:00
|
|
|
{
|
2017-08-11 01:47:15 +02:00
|
|
|
MMU* next;
|
|
|
|
uintptr_t* page;
|
|
|
|
int index;
|
|
|
|
int level;
|
2016-11-25 17:18:40 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
2017-08-11 01:47:15 +02:00
|
|
|
* MMU stuff in Proc
|
2016-11-25 17:18:40 +01:00
|
|
|
*/
|
2017-08-11 01:47:15 +02:00
|
|
|
#define NCOLOR 1
|
|
|
|
struct PMMU
|
2016-11-25 17:18:40 +01:00
|
|
|
{
|
2017-08-11 01:47:15 +02:00
|
|
|
MMU* mmuhead;
|
|
|
|
MMU* mmutail;
|
|
|
|
MMU* kmaphead;
|
|
|
|
MMU* kmaptail;
|
|
|
|
unsigned long kmapcount;
|
|
|
|
unsigned long kmapindex;
|
|
|
|
unsigned long mmucount;
|
2016-11-25 17:18:40 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* things saved in the Proc structure during a notify
|
|
|
|
*/
|
|
|
|
struct PNOTIFY
|
|
|
|
{
|
|
|
|
char emptiness;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct IOConf
|
|
|
|
{
|
|
|
|
int nomsi;
|
|
|
|
int nolegacyprobe; /* acpi tells us. all negated in case acpi unavailable */
|
|
|
|
int noi8042kbd;
|
|
|
|
int novga;
|
|
|
|
int nocmos;
|
|
|
|
};
|
|
|
|
extern IOConf ioconf;
|
|
|
|
|
|
|
|
#include "../port/portdat.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* CPU stuff in Mach.
|
|
|
|
*/
|
|
|
|
struct MCPU {
|
|
|
|
uint32_t cpuinfo[2][4]; /* CPUID instruction output E[ABCD]X */
|
|
|
|
int ncpuinfos; /* number of standard entries */
|
|
|
|
int ncpuinfoe; /* number of extended entries */
|
|
|
|
int isintelcpu; /* */
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* FPU stuff in Mach.
|
|
|
|
*/
|
|
|
|
struct MFPU {
|
|
|
|
uint16_t fcw; /* x87 control word */
|
|
|
|
uint32_t mxcsr; /* MMX control and status */
|
|
|
|
uint32_t mxcsrmask; /* supported MMX feature bits */
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* MMU stuff in Mach.
|
|
|
|
*/
|
2017-08-11 01:47:15 +02:00
|
|
|
typedef struct {
|
|
|
|
uint32_t _0_;
|
|
|
|
uint32_t rsp0[2];
|
|
|
|
uint32_t rsp1[2];
|
|
|
|
uint32_t rsp2[2];
|
|
|
|
uint32_t _28_[2];
|
|
|
|
uint32_t ist[14];
|
|
|
|
uint16_t _92_[5];
|
|
|
|
uint16_t iomap;
|
|
|
|
} Tss;
|
2016-11-25 17:18:40 +01:00
|
|
|
|
|
|
|
struct MMMU
|
|
|
|
{
|
2017-08-11 01:47:15 +02:00
|
|
|
uint64_t* pml4; /* pml4 base for this processor (va) */
|
|
|
|
Tss* tss; /* tss for this processor */
|
|
|
|
Segdesc* gdt; /* gdt for this processor */
|
2016-11-25 17:18:40 +01:00
|
|
|
|
2017-08-11 01:47:15 +02:00
|
|
|
uint64_t mmumap[4]; /* bitmap of pml4 entries for zapping */
|
|
|
|
MMU* mmufree; /* freelist for MMU structures */
|
|
|
|
unsigned long mmucount; /* number of MMU structures in freelist */
|
2016-11-25 17:18:40 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Per processor information.
|
|
|
|
*
|
|
|
|
* The offsets of the first few elements may be known
|
|
|
|
* to low-level assembly code, so do not re-order:
|
|
|
|
* machno - no dependency, convention
|
|
|
|
* splpc - splhi, spllo, splx
|
|
|
|
* proc - syscallentry
|
|
|
|
*/
|
|
|
|
struct Mach
|
|
|
|
{
|
|
|
|
uint64_t machno; /* physical id of processor */
|
|
|
|
uint64_t splpc; /* pc of last caller to splhi */
|
|
|
|
Proc* proc; /* current process on this processor */
|
2017-05-21 00:15:51 +02:00
|
|
|
uint64_t tmp0; /* for syscallentry */
|
|
|
|
uint64_t tmp1; /* for syscallentry */
|
2016-11-25 17:18:40 +01:00
|
|
|
|
|
|
|
int apicno;
|
|
|
|
int online;
|
|
|
|
int mode; /* fold into online? GAK */
|
|
|
|
|
|
|
|
void* dbgreg; /* registers for debugging this processor */
|
|
|
|
void* dbgsp; /* sp for debugging this processor */
|
|
|
|
|
|
|
|
MMMU;
|
|
|
|
|
|
|
|
uintptr_t stack;
|
|
|
|
uint8_t* vsvm;
|
|
|
|
|
|
|
|
uint64_t 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 */
|
|
|
|
uint64_t schedticks; /* next forced context switch */
|
|
|
|
|
|
|
|
int color;
|
|
|
|
|
|
|
|
int tlbfault;
|
|
|
|
int tlbpurge;
|
|
|
|
int pfault;
|
|
|
|
int cs;
|
|
|
|
int syscall;
|
|
|
|
int intr;
|
|
|
|
int mmuflush; /* make current proc flush it's mmu state */
|
|
|
|
int ilockdepth;
|
|
|
|
uintptr_t ilockpc;
|
|
|
|
Perf perf; /* performance counters */
|
|
|
|
void (*perfintr)(Ureg*, void*);
|
|
|
|
|
|
|
|
int lastintr;
|
|
|
|
|
2017-08-11 01:47:15 +02:00
|
|
|
int loopconst;
|
|
|
|
|
2016-11-25 17:18:40 +01:00
|
|
|
Lock apictimerlock;
|
|
|
|
uint64_t cyclefreq; /* Frequency of user readable cycle counter */
|
2017-08-11 01:47:15 +02:00
|
|
|
uint64_t cpuhz;
|
2016-11-25 17:18:40 +01:00
|
|
|
int cpumhz;
|
2017-08-11 01:47:15 +02:00
|
|
|
int cpuidax;
|
|
|
|
int cpuidcx;
|
|
|
|
int cpuiddx;
|
|
|
|
char cpuidid[16];
|
|
|
|
char* cpuidtype;
|
|
|
|
int havetsc;
|
|
|
|
int havepge;
|
|
|
|
uint64_t tscticks;
|
2016-11-25 17:18:40 +01:00
|
|
|
uint64_t rdtsc;
|
|
|
|
|
2017-08-11 01:47:15 +02:00
|
|
|
// LockEntry locks[8];
|
2016-11-25 17:18:40 +01:00
|
|
|
|
|
|
|
MFPU FPU;
|
|
|
|
MCPU;
|
|
|
|
};
|
|
|
|
|
2017-08-11 01:47:15 +02:00
|
|
|
struct Confmem
|
|
|
|
{
|
|
|
|
uintptr_t base;
|
|
|
|
unsigned long npage;
|
|
|
|
uintptr_t kbase;
|
|
|
|
uintptr_t klimit;
|
|
|
|
};
|
|
|
|
|
2016-11-25 17:18:40 +01:00
|
|
|
/*
|
|
|
|
* This is the low memory map, between 0x100000 and 0x110000.
|
|
|
|
* It is located there to allow fundamental datastructures to be
|
|
|
|
* created and used before knowing where free memory begins
|
|
|
|
* (e.g. there may be modules located after the kernel BSS end).
|
|
|
|
* The layout is known in the bootstrap code in l32p.s.
|
|
|
|
* It is logically two parts: the per processor data structures
|
|
|
|
* for the bootstrap processor (stack, Mach, vsvm, and page tables),
|
|
|
|
* and the global information about the system (syspage, ptrpage).
|
|
|
|
* Some of the elements must be aligned on page boundaries, hence
|
|
|
|
* the unions.
|
|
|
|
*/
|
2017-08-11 01:47:15 +02:00
|
|
|
struct Sys
|
|
|
|
{
|
|
|
|
Ureg* boot_regs;
|
|
|
|
unsigned int nmach; /* processors */
|
|
|
|
unsigned int nproc; /* processes */
|
|
|
|
unsigned int monitor; /* has monitor? */
|
|
|
|
unsigned int npages; /* total physical pages of memory */
|
|
|
|
unsigned int upages; /* user page pool */
|
|
|
|
unsigned int nimage; /* number of images */
|
|
|
|
Confmem mem[16]; /* physical memory */
|
|
|
|
|
|
|
|
unsigned int copymode; /* 0 is copy on write, 1 is copy on reference */
|
|
|
|
unsigned int ialloc; /* max interrupt time allocation in bytes */
|
|
|
|
unsigned int pipeqsize; /* size in bytes of pipe queues */
|
|
|
|
int nuart; /* number of uart devices */
|
|
|
|
|
2020-02-17 00:19:03 +01:00
|
|
|
int load;
|
|
|
|
|
2017-08-11 01:47:15 +02:00
|
|
|
char* architecture;
|
|
|
|
uint64_t ticks;
|
|
|
|
Mach* machptr[MACHMAX];
|
|
|
|
|
|
|
|
uint64_t pmstart; /* physical memory */
|
|
|
|
uint64_t pmoccupied; /* how much is occupied */
|
|
|
|
uint64_t pmunassigned; /* how much to keep back from page pool */
|
|
|
|
uint64_t pmpaged; /* how much assigned to page pool */
|
2016-11-25 17:18:40 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
extern Sys* sys;
|
2017-08-11 01:47:15 +02:00
|
|
|
extern uint32_t MemMin; /* set by entry.S */
|
2016-11-25 17:18:40 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* KMap
|
|
|
|
*/
|
|
|
|
typedef void KMap;
|
|
|
|
|
|
|
|
#define VA(k) (void*)(k)
|
|
|
|
|
2017-08-11 01:47:15 +02:00
|
|
|
/*
|
|
|
|
* 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);
|
|
|
|
uint64_t (*fastclock)(uint64_t*);
|
|
|
|
void (*timerset)(uint64_t);
|
|
|
|
};
|
|
|
|
|
|
|
|
extern PCArch *arch; /* PC architecture */
|
|
|
|
|
|
|
|
/* 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 */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Informations about active processors for
|
|
|
|
* bootstrap and shutdown.
|
|
|
|
*/
|
2016-11-25 17:18:40 +01:00
|
|
|
struct
|
|
|
|
{
|
2017-08-11 01:47:15 +02:00
|
|
|
char machs[MACHMAX]; /* bitmap of active CPUs */
|
2016-11-25 17:18:40 +01:00
|
|
|
int exiting; /* shutdown */
|
|
|
|
int ispanic; /* shutdown in response to a panic */
|
|
|
|
int thunderbirdsarego; /* F.A.B. */
|
|
|
|
}active;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* a parsed plan9.ini line
|
|
|
|
*/
|
|
|
|
#define NISAOPT 8
|
|
|
|
|
|
|
|
struct ISAConf {
|
|
|
|
char* type;
|
|
|
|
uintptr_t port;
|
|
|
|
int irq;
|
|
|
|
uint32_t dma;
|
|
|
|
uintptr_t mem;
|
|
|
|
usize size;
|
|
|
|
uint32_t freq;
|
|
|
|
int tbdf; /* type+busno+devno+funcno */
|
|
|
|
|
|
|
|
int nopt;
|
|
|
|
char* opt[NISAOPT];
|
|
|
|
};
|
|
|
|
|
2017-01-22 03:34:17 +01:00
|
|
|
typedef struct BIOS32ci { /* BIOS32 Calling Interface */
|
|
|
|
uint32_t eax;
|
|
|
|
uint32_t ebx;
|
|
|
|
uint32_t ecx;
|
|
|
|
uint32_t edx;
|
|
|
|
uint32_t esi;
|
|
|
|
uint32_t edi;
|
|
|
|
} BIOS32ci;
|
|
|
|
|
2017-08-11 01:47:15 +02:00
|
|
|
#define MACHP(n) (sys->machptr[n])
|
|
|
|
|
2016-11-25 17:18:40 +01:00
|
|
|
/*
|
|
|
|
* The Mach structures must be available via the per-processor
|
|
|
|
* MMU information array machptr, mainly for disambiguation and access to
|
|
|
|
* the clock which is only maintained by the bootstrap processor (0).
|
|
|
|
*/
|
|
|
|
register Mach* m asm("r15");
|
|
|
|
register Proc* up asm("r14");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Horrid.
|
|
|
|
*/
|
|
|
|
#ifdef _DBGC_
|
|
|
|
#define DBGFLG (dbgflg[_DBGC_])
|
|
|
|
#else
|
|
|
|
#define DBGFLG (0)
|
|
|
|
#endif /* _DBGC_ */
|
|
|
|
|
|
|
|
#define DBG(...) if(!DBGFLG){}else dbgprint(__VA_ARGS__)
|
|
|
|
|
|
|
|
extern char dbgflg[256];
|
|
|
|
|
2017-04-19 23:33:14 +02:00
|
|
|
#define dbgprint jehanne_print /* for now */
|