/* * This file is part of Jehanne. * * Copyright (C) 2015-2016 Giacomo Tesio * * Jehanne is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2 of the License. * * Jehanne is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Jehanne. If not, see . */ typedef struct BIOS32si BIOS32si; typedef struct BIOS32ci BIOS32ci; 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; typedef struct MMMU MMMU; typedef struct Mach Mach; typedef uint64_t Mpl; typedef Mpl Mreg; /* GAK */ typedef struct Ptpage Ptpage; typedef struct Pcidev Pcidev; typedef struct PFPU PFPU; typedef struct PMMU PMMU; typedef struct PNOTIFY PNOTIFY; typedef struct PPAGE PPAGE; typedef uint64_t PTE; typedef struct Proc Proc; typedef struct Sys Sys; typedef uint64_t uintmem; /* horrible name */ typedef struct Ureg Ureg; typedef struct Vctl Vctl; #pragma incomplete BIOS32si #pragma incomplete Ureg #define MAXSYSARG 5 /* for mount(fd, afd, mpt, flag, arg) */ /* * parameters for sysproc.c */ #define AOUT_MAGIC (S_MAGIC) #define ELF_MAGIC (ELF_MAG) /* * machine dependent definitions used by ../port/portdat.h */ struct Lock { LockEntry* head; LockEntry* e; }; struct Label { uintptr_t sp; uintptr_t pc; uintptr_t regs[14]; }; 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 */ }; /* * FPU stuff in Proc */ struct PFPU { int fpustate; uint8_t fxsave[sizeof(Fxsave)+15]; void* fpusave; }; struct Ptpage { PTE* pte; /* kernel-addressible page table entries */ uintmem pa; /* physical address (from physalloc) */ Ptpage* next; /* next in level's set, or free list */ Ptpage* parent; /* parent page table page or page directory */ uint32_t ptoff; /* index of this table's entry in parent */ }; /* * MMU stuff in Proc */ struct PMMU { Ptpage* mmuptp[4]; /* page table pages for each level */ Ptpage* ptpfree; int nptpbusy; }; /* * MMU stuff in Page */ struct PPAGE { uint8_t* nothing; }; /* * 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; #define MAXMDOM 8 /* maximum memory/cpu domains */ #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. */ enum { NPGSZ = 4 }; struct MMMU { Ptpage* pml4; /* pml4 for this processor */ PTE* pmap; /* unused as of yet */ Ptpage* ptpfree; /* per-mach free list */ int nptpfree; uint32_t pgszlg2[NPGSZ]; /* per Mach or per Sys? */ uintmem pgszmask[NPGSZ]; uint32_t pgsz[NPGSZ]; int npgsz; Ptpage pml4kludge; }; /* * 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 */ uint64_t tmp0; /* for syscallentry */ uint64_t tmp1; /* for syscallentry */ 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; void* gdt; void* tss; 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 load; 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; Lock apictimerlock; uint64_t cyclefreq; /* Frequency of user readable cycle counter */ int64_t cpuhz; int cpumhz; uint64_t rdtsc; LockEntry locks[8]; MFPU FPU; MCPU; }; /* * 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. */ struct Sys { uint8_t machstk[MACHSTKSZ]; PTE pml4[PTSZ/sizeof(PTE)]; /* */ PTE pdp[PTSZ/sizeof(PTE)]; PTE pd[PTSZ/sizeof(PTE)]; PTE pt[PTSZ/sizeof(PTE)]; uint8_t vsvmpage[4*KiB]; union { Mach mach; uint8_t machpage[MACHSZ]; }; union { struct { 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 */ uintptr_t vmstart; /* base address for malloc */ uintptr_t vmunused; /* 1st unused va */ uintptr_t vmunmapped; /* 1st unmapped va in KSEG0 */ uint64_t epoch; /* crude time synchronisation */ int nmach; /* how many machs */ int nonline; /* how many machs are online */ uint64_t ticks; /* since boot (type?) */ uint32_t copymode; /* 0=copy on write; 1=copy on reference */ }; uint8_t syspage[4*KiB]; }; union { Mach* machptr[MACHMAX]; uint8_t ptrpage[4*KiB]; }; uint8_t _57344_[2][4*KiB]; /* unused */ }; extern Sys* sys; /* * KMap */ typedef void KMap; #define kunmap(k) #define VA(k) (void*)(k) struct { Lock; 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]; }; 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; /* * 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]; #define dbgprint jehanne_print /* for now */