An x86-64 operating system built from xv6, now largely rewritten: SMP, a copy-on-write root filesystem (SchFS), PCI/USB/virtio drivers, a TTF rasteriser, and a Linux-numbered syscall ABI. No history before this point -- the tree was never under version control. This commit exists so the rename that follows has something to undo to.
130 lines
5.2 KiB
C
130 lines
5.2 KiB
C
#pragma once
|
|
|
|
// Eflags register
|
|
#define FL_CF 0x00000001 // Carry Flag
|
|
#define FL_PF 0x00000004 // Parity Flag
|
|
#define FL_AF 0x00000010 // Auxiliary carry Flag
|
|
#define FL_ZF 0x00000040 // Zero Flag
|
|
#define FL_SF 0x00000080 // Sign Flag
|
|
#define FL_TF 0x00000100 // Trap Flag
|
|
#define FL_IF 0x00000200 // Interrupt Enable
|
|
#define FL_DF 0x00000400 // Direction Flag
|
|
#define FL_OF 0x00000800 // Overflow Flag
|
|
#define FL_IOPL_MASK 0x00003000 // I/O Privilege Level bitmask
|
|
#define FL_NT 0x00004000 // Nested Task
|
|
#define FL_RF 0x00010000 // Resume Flag
|
|
#define FL_VM 0x00020000 // Virtual 8086 mode
|
|
#define FL_AC 0x00040000 // Alignment Check
|
|
#define FL_VIF 0x00080000 // Virtual Interrupt Flag
|
|
#define FL_VIP 0x00100000 // Virtual Interrupt Pending
|
|
#define FL_ID 0x00200000 // ID flag
|
|
|
|
// Control Register flags
|
|
#define CR0_PE 0x00000001 // Protection Enable
|
|
#define CR0_MP 0x00000002 // Monitor coProcessor
|
|
#define CR0_EM 0x00000004 // Emulation
|
|
#define CR0_TS 0x00000008 // Task Switched
|
|
#define CR0_ET 0x00000010 // Extension Type
|
|
#define CR0_NE 0x00000020 // Numeric Errror
|
|
#define CR0_WP 0x00010000 // Write Protect
|
|
#define CR0_AM 0x00040000 // Alignment Mask
|
|
#define CR0_NW 0x20000000 // Not Writethrough
|
|
#define CR0_CD 0x40000000 // Cache Disable
|
|
#define CR0_PG 0x80000000 // Paging
|
|
|
|
#define CR4_PSE 0x00000010 // Page size extension
|
|
#define CR4_PAE 0x00000020 // Physical address extensions
|
|
#define CR4_OSXFSR 0x00000200 // OS supports FXSAVE and FXRSTOR
|
|
#define CR4_OSXMMEXCPT 0x00000400 // OS supports SSE exceptions
|
|
|
|
// Model specific registers
|
|
#define MSR_EFER 0xC0000080 // Extended Feature Enable Register
|
|
#define MSR_STAR 0xC0000081 // Legacy Mode SYSCALL Target
|
|
#define MSR_LSTAR 0xC0000082 // Long Mode SYSCALL Target
|
|
#define MSR_CSTAR 0xC0000083 // Compatibility Mode SYSCALL Target
|
|
#define MSR_SFMASK 0xC0000084 // SYSCALL Flag Mask
|
|
|
|
// Segment selectors
|
|
#define SEG_KCODE 1
|
|
#define SEG_KDATA 2
|
|
#define SEG_UCODE32 3
|
|
#define SEG_UDATA 4
|
|
#define SEG_UCODE 5
|
|
#define SEG_KCPU 6
|
|
#define SEG_TSS 7 // TSS takes 2 slots in 64-bit GDT
|
|
|
|
#define NSEGS 9
|
|
|
|
#define DPL_USER 0x3
|
|
|
|
#define USER_CS ((SEG_UCODE<<3)|DPL_USER)
|
|
#define USER_DS ((SEG_UDATA<<3)|DPL_USER)
|
|
#define KERNEL_CS (SEG_KCODE<<3)
|
|
|
|
#ifndef __ASSEMBLER__
|
|
// Segment Descriptor
|
|
struct segdesc {
|
|
uint32 lim_15_0 : 16; // Low bits of segment limit
|
|
uint32 base_15_0 : 16; // Low bits of segment base address
|
|
uint32 base_23_16 : 8; // Middle bits of segment base address
|
|
uint32 type : 4; // Segment type
|
|
uint32 s : 1; // 0 = system, 1 = application
|
|
uint32 dpl : 2; // Descriptor Privilege Level
|
|
uint32 p : 1; // Present
|
|
uint32 lim_19_16 : 4; // High bits of segment limit
|
|
uint32 avl : 1; // Available for software use
|
|
uint32 l : 1; // 1 = 64-bit segment (Long mode)
|
|
uint32 db : 1; // 0 = 16-bit, 1 = 32-bit
|
|
uint32 g : 1; // Granularity
|
|
uint32 base_31_24 : 8; // High bits of segment base address
|
|
};
|
|
|
|
// 64-bit System Segment Descriptor (e.g., TSS)
|
|
struct desclong {
|
|
struct segdesc sd;
|
|
uint32 base_63_32; // High bits of 64-bit base address
|
|
uint32 res; // Reserved
|
|
};
|
|
|
|
#define SEG(type, base, lim, dpl) (struct segdesc) \
|
|
{ ((lim) >> 12) & 0xffff, (uint32)(base) & 0xffff, \
|
|
((uint32)(base) >> 16) & 0xff, type, 1, dpl, 1, \
|
|
(uint32)(lim) >> 28, 0, 1, 0, 1, (uint32)(base) >> 24 }
|
|
|
|
#endif
|
|
|
|
// Application segment type bits
|
|
#define STA_X 0x8 // Executable segment
|
|
#define STA_W 0x2 // Writeable (non-executable)
|
|
#define STA_R 0x2 // Readable (executable)
|
|
|
|
// System segment type bits
|
|
#define STS_T64A 0x9 // Available 64-bit TSS
|
|
#define STS_T64B 0xB // Busy 64-bit TSS
|
|
#define STS_IG64 0xE // 64-bit Interrupt Gate
|
|
#define STS_TG64 0xF // 64-bit Trap Gate
|
|
|
|
// Page table structure: 4 levels
|
|
#define PMX(va) (((addr_t)(va) >> 39) & 0x1FF)
|
|
#define PDPX(va) (((addr_t)(va) >> 30) & 0x1FF)
|
|
#define PDX(va) (((addr_t)(va) >> 21) & 0x1FF)
|
|
#define PTX(va) (((addr_t)(va) >> 12) & 0x1FF)
|
|
|
|
#define PGSIZE 4096
|
|
#define PXMASK 0x1FF
|
|
|
|
#define PGROUNDUP(sz) (((sz)+((addr_t)PGSIZE-1)) & ~((addr_t)(PGSIZE-1)))
|
|
#define PGROUNDDOWN(a) (((a)) & ~((addr_t)(PGSIZE-1)))
|
|
|
|
// Page table/directory entry flags
|
|
#define PTE_P 0x001 // Present
|
|
#define PTE_W 0x002 // Writeable
|
|
#define PTE_U 0x004 // User
|
|
#define PTE_PWT 0x008 // Write-Through
|
|
#define PTE_PCD 0x010 // Cache-Disable
|
|
#define PTE_A 0x020 // Accessed
|
|
#define PTE_D 0x040 // Dirty
|
|
#define PTE_PS 0x080 // Page Size (Huge Page)
|
|
|
|
#define PTE_ADDR(pte) ((addr_t)(pte) & 0x000FFFFFFFFFF000ull)
|
|
#define PTE_FLAGS(pte) ((addr_t)(pte) & 0xFFF)
|