diff options
| author | Hanjie Wu <hanjiew@andrew.cmu.edu> | 2023-04-18 02:21:10 -0400 |
|---|---|---|
| committer | Hanjie Wu <hanjiew@andrew.cmu.edu> | 2023-04-18 02:21:10 -0400 |
| commit | c71294cdd3581c3738d24ffd65414f8644a1094d (patch) | |
| tree | c86245d50fad9eee4163dbba169bd1839edbf88f /spec | |
initial commit
Diffstat (limited to 'spec')
| -rw-r--r-- | spec/common_kern.h | 56 | ||||
| -rw-r--r-- | spec/compiler.h | 23 | ||||
| -rw-r--r-- | spec/contracts.h | 32 | ||||
| -rw-r--r-- | spec/hvcall.h | 135 | ||||
| -rw-r--r-- | spec/hvcall_int.h | 49 | ||||
| -rw-r--r-- | spec/limits.h | 36 | ||||
| -rw-r--r-- | spec/syscall.h | 98 | ||||
| -rw-r--r-- | spec/syscall_int.h | 69 | ||||
| -rw-r--r-- | spec/ureg.h | 50 |
9 files changed, 548 insertions, 0 deletions
diff --git a/spec/common_kern.h b/spec/common_kern.h new file mode 100644 index 0000000..0cd862f --- /dev/null +++ b/spec/common_kern.h @@ -0,0 +1,56 @@ +#ifndef _SPEC_COMMON_KERN_H_ +#define _SPEC_COMMON_KERN_H_ + +/*********************************************************************/ +/* */ +/* Interface between Multiboot and our kernel */ +/* */ +/*********************************************************************/ + +/** @brief Query whether we are running as a hypervisor guest. + * + * @return True if we are a guest. + */ +int hv_isguest(void); + +/** @brief Fetch virtual-address cap set by hypervisor. + * + * @return Largest virtual address we are allowed to use. + */ +void *hv_maxvaddr(void); + +/** @brief Return total number of frames (each of PAGE_SIZE bytes) + * that our machine is currently configured with. + * + * @return Frame count. + */ +int machine_phys_frames(void); + +#include <boot/multiboot.h> + + /** @brief User kernel entrypoint + * + * @param mbinfo The kernel's multiboot information structure. + * @param argc Argument count, as parsed from multiboot. + * @param argv Argument vector, as parsed from multiboot. + * @param envp Environment, as parsed from multiboot. + * + * @pre malloc_lmm will have been initialized, stripped of regions that + * are potentially hazardous, and bounded between 1 and 16M. + * + * @note If you plan to write your own allocator for space, you should + * still treat LMM as the official mechanism of getting physical + * frames in the kernel region, unless you are planning to parse + * the multiboot information and/or e820 yourself. + */ +int kernel_main(mbinfo_t *mbinfo, int argc, char **argv, char **envp); + +/*********************************************************************/ +/* */ +/* Kernel memory layout requirements */ +/* */ +/*********************************************************************/ + +#define USER_MEM_START 0x01000000 + +#endif /* _SPEC_COMMON_KERN_H_ */ diff --git a/spec/compiler.h b/spec/compiler.h new file mode 100644 index 0000000..b626f1a --- /dev/null +++ b/spec/compiler.h @@ -0,0 +1,23 @@ +/** @file spec/compiler.h + * @brief Useful macros. Inspired by Linux compiler*.h and kernel.h. + * @author bblum S2011 + */ + +#ifndef _SPEC_COMPILER_H +#define _SPEC_COMPILER_H + +/* Function annotations */ +#ifndef NORETURN +#define NORETURN __attribute__((__noreturn__)) +#endif + +#define MUST_CHECK __attribute__((__warn_unused_result__)) + +/* Force a compilation error if condition is false */ +#define STATIC_ZERO_ASSERT(condition) switch(0){case 0:case (condition):;} +#define STATIC_NULL_ASSERT(condition) STATIC_ZERO_ASSERT(condition) + +/* Force a compilation error if condition is false */ +#define STATIC_ASSERT(condition) STATIC_ZERO_ASSERT(condition) + +#endif /* !_SPEC_COMPILER_H */ diff --git a/spec/contracts.h b/spec/contracts.h new file mode 100644 index 0000000..251caad --- /dev/null +++ b/spec/contracts.h @@ -0,0 +1,32 @@ +/* Debugging with contracts; simulating cc0 -d + * Enable with gcc -DDEBUG ... + * + * 15-122 Principles of Imperative Computation + * Frank Pfenning + */ + +#include <assert.h> + +/* Unlike typical header files, "contracts.h" may be + * included multiple times, with and without DEBUG defined. + * For this to succeed we first undefine the macros in + * question in order to avoid a redefinition warning. + */ + +#undef ASSERT +#undef REQUIRES +#undef ENSURES + +#ifdef DEBUG + +#define ASSERT(COND) assert(COND) +#define REQUIRES(COND) assert(COND) +#define ENSURES(COND) assert(COND) + +#else + +#define ASSERT(COND) ((void)0) +#define REQUIRES(COND) ((void)0) +#define ENSURES(COND) ((void)0) + +#endif diff --git a/spec/hvcall.h b/spec/hvcall.h new file mode 100644 index 0000000..be877b4 --- /dev/null +++ b/spec/hvcall.h @@ -0,0 +1,135 @@ +/** @file hvcall.h + * + * Prototypes for PebPeb hypervisor calls. + * + * @author jwise + * @author de0u + * @author relong + */ + +#ifndef _HVCALL_H +#define _HVCALL_H + +/* vIDT slots match regular x86-32 numbers from x86/idt.h, plus these */ +#define HV_TICKBACK 0x20 /**< vIDT slot for virtual timer interrupt */ +#define HV_KEYBOARD 0x21 /**< vIDT slot for virtual keyboard interrupt */ + +#define HV_MAGIC 0xC001C0DE /**< hv_magic() value for v2 of PebPeb API */ +#define HV_SETIDT_PRIVILEGED 1 +#define HV_PRINT_MAX 410 + +#ifdef ASSEMBLER +#define GUEST_LAUNCH_EAX 0x15410DE0 /**< Value for %EAX at guest launch */ +#else /* ASSEMBLER */ +#define GUEST_LAUNCH_EAX 0x15410DE0U /**< Value for %EAX at guest launch */ +#endif /* ASSEMBLER */ +#define GUEST_CRASH_STATUS 0xDEADC0DE /**< For simulated hv_exit() */ +#define GUEST_INTERRUPT_UMODE 0x13370000 /**< Guest was interrupted in user mode */ +#define GUEST_INTERRUPT_KMODE 0x00001337 /**< Guest was interrupted in kernel mode */ + +#ifndef ASSEMBLER + +#ifndef NORETURN +#define NORETURN __attribute__((__noreturn__)) +#endif + +/** @brief verify we are running under a v2 PebPeb hypervisor + * @return HV_MAGIC + */ +unsigned int hv_magic(void); + +/** @brief Cease execution and pass status to parent task + * @param status Status code to pass to parent task + */ +void hv_exit(int status) NORETURN; + +/** @brief Atomically activate a new privilege level/execution context + * @param eip New value for %eip + * @param eflags New value for %eflags + * @param esp New value for %esp + * @param esp0 If zero, IRET into guest-kernel mode; + * else, remember virtual %esp0 for later and IRET + * into guest-user mode + * @param eax New value for %eax + * + * @note If eflags is invalid, the hypervisor will crash the guest + * @note eip, esp, esp0 addresses are guest-virtual + */ +void hv_iret(void *eip, unsigned int eflags, void *esp, void *esp0, unsigned int eax); + +/** @brief Install a virtual interrupt handler + * @param irqno IDT slot index + * @param eip Address of first instruction of handler + * @param privileged if non-zero only kernel access, else user access permitted + * @note If a slot's eip value is zero when that event happens, the guest crashes + * @note When guest kernel launches, all slots have eip == 0 + * @note eip address is guest-virtual + * @note See HV_SETIDT_PRIVILEGED definition above + */ +void hv_setidt(int irqno, void *eip, int privileged); + +/** @brief Suspend delivery of virtual interrupts (not virtual exceptions) + */ +void hv_disable_interrupts(void); + +/** @brief Begin/resume delivery of virtual interrupts (not virtual exceptions) + */ +void hv_enable_interrupts(void); + +/** @brief Activate an address space + * @param pdbase Base of page directory + * @param wp If non-zero, guest kernel can't write into user-level + * read-only pages (see Intel's description of bit 16 of %cr0) + * @pre pdbase must be page-aligned + * @note pdbase address is guest-physical + */ +void hv_setpd(void *pdbase, int wp); + +/** @brief Re-validate/invalidate/update the mapping + * of one virtual-to-physical translation + * @param addr Base of page whose mapping status has changed + * @pre addr must be page-aligned + * @note addr address is guest-virtual + */ +void hv_adjustpg(void *addr); + +/** @brief Print to console + * @param len Count of bytes to print (must be less than HV_PRINT_MAX) + * @param buf Address of first byte to print + * @note buf address is guest-virtual + */ +void hv_print(int len, unsigned char *buf); + +/** @brief Change printing color + * @param color VGA color code + */ +void hv_cons_set_term_color(int color); + +/** @brief Set cursor position + * @param row Row cursor should be moved to + * @param col Column cursor should be moved to + */ +void hv_cons_set_cursor_pos(int row, int col); + +/** @brief Get cursor position + * @param rowp Pointer to where cursor row should be stored + * @param colp Pointer to where cursor column should be stored + * @note both addresses are guest-virtual + */ +void hv_cons_get_cursor_pos(int *rowp, int *colp); + +/** @brief Print to the console + * @param len Count of bytes to print (must be less than HV_PRINT_MAX) + * @param buf Address of first byte to print + * @param color VGA color code for printing this string + * @param row Row this string should be printed on + * @param col Column this string should be printed at + * @note This moves the cursor, changes the print color, prints, + * then restores the cursor position and print color. + * @note buf address is guest-virtual + */ +void hv_print_at(int len, unsigned char *buf, int row, int col, int color); + +#endif /* ASSEMBLER */ + +#endif /* _HVCALL_H */ diff --git a/spec/hvcall_int.h b/spec/hvcall_int.h new file mode 100644 index 0000000..cc00df4 --- /dev/null +++ b/spec/hvcall_int.h @@ -0,0 +1,49 @@ +/** @file hvcall_int.h + * + * Hypervisor call numbers + * + * @author jwise + */ + +#ifndef _HVCALL_INT_H +#define _HVCALL_INT_H + +/* Protocol: + * + * 1. Parameters on stack in "natural push order" + * 2. Operation number (HV_xxx_OP) in %eax + * 3. INT $HV_INT + */ + +#define HV_INT 0xDE + +#define HV_MAGIC_OP 0x00 +#define HV_EXIT_OP 0x01 +#define HV_IRET_OP 0x02 +#define HV_SETIDT_OP 0x03 +#define HV_DISABLE_OP 0x04 +#define HV_ENABLE_OP 0x05 +#define HV_SETPD_OP 0x06 +#define HV_ADJUSTPG_OP 0x07 +#define HV_PRINT_OP 0x08 +#define HV_SET_COLOR_OP 0x09 +#define HV_SET_CURSOR_OP 0x0A +#define HV_GET_CURSOR_OP 0x0B +#define HV_PRINT_AT_OP 0x0C + +/* The calls in here, INCLUSIVE, are promised not to be + * probed by any grading scripts; as such you are welcome + * to extend the spec by making use of these hvcall numbers + */ +#define HV_RESERVED_START 0x20 +#define HV_RESERVED_0 0x20 +#define HV_RESERVED_1 0x21 +#define HV_RESERVED_2 0x22 +#define HV_RESERVED_3 0x23 +#define HV_RESERVED_4 0x24 +#define HV_RESERVED_5 0x25 +#define HV_RESERVED_6 0x26 +#define HV_RESERVED_7 0x27 +#define HV_RESERVED_END 0x27 + +#endif /* _HVCALL_INT_H */ diff --git a/spec/limits.h b/spec/limits.h new file mode 100644 index 0000000..431d181 --- /dev/null +++ b/spec/limits.h @@ -0,0 +1,36 @@ +/** @file 410kern/inc/limits.h + * @author elly1 U2009 + * @brief Type size limits. + */ + +#ifndef LIMITS_H +#define LIMITS_H + +#define CHAR_BIT 8 + +#define SCHAR_MIN (-128) +#define SCHAR_MAX 127 + +#define UCHAR_MAX 255 + +#define SHRT_MIN (-32768) +#define SHRT_MAX 32767 + +#define USHRT_MAX 65535 + +#define INT_MIN ((signed int)0x80000000) +#define INT_MAX ((signed int)0x7fffffff) + +#define UINT_MAX ((unsigned int)0xffffffff) + +#define LONG_MIN ((signed long)0x80000000L) +#define LONG_MAX ((signed long)0x7FFFFFFFL) + +#define ULONG_MAX ((unsigned long)0xFFFFFFFFL) + +#define LLONG_MIN ((signed long long)0x8000000000000000LL) +#define LLONG_MAX ((signed long long)0x7FFFFFFFFFFFFFFFLL) + +#define ULLONG_MAX ((unsigned long long)0xFFFFFFFFFFFFFFFFLL) + +#endif /* !LIMITS_H */ diff --git a/spec/syscall.h b/spec/syscall.h new file mode 100644 index 0000000..a40fc60 --- /dev/null +++ b/spec/syscall.h @@ -0,0 +1,98 @@ +/* The 15-410 kernel. + * syscall.h + * + * Prototypes for the user-land C library interface + * to system calls. + * + */ + +#ifndef _SYSCALL_H +#define _SYSCALL_H + +#ifndef NORETURN +#define NORETURN __attribute__((__noreturn__)) +#endif + +#ifndef PAGE_SIZE +#define PAGE_SIZE 0x0001000 /* 4096 */ +#endif + +/* Life cycle */ +int fork(void); +int exec(char *execname, char *argvec[]); +void set_status(int status); +void vanish(void) NORETURN; +int wait(int *status_ptr); +void task_vanish(int status) NORETURN; + +/* Thread management */ +int gettid(void); +int yield(int pid); +int deschedule(int *flag); +int make_runnable(int pid); +unsigned int get_ticks(void); +int sleep(int ticks); + +/* Memory management */ +int new_pages(void * addr, int len); +int remove_pages(void * addr); + +/* Console I/O */ +int getchar(void); +int readline(int size, char *buf); +int print(int size, char *buf); +int set_term_color(int color); +int set_cursor_pos(int row, int col); +int get_cursor_pos(int *row, int *col); + +/* Color values for set_term_color() */ +#define FGND_BLACK 0x0 +#define FGND_BLUE 0x1 +#define FGND_GREEN 0x2 +#define FGND_CYAN 0x3 +#define FGND_RED 0x4 +#define FGND_MAG 0x5 +#define FGND_BRWN 0x6 +#define FGND_LGRAY 0x7 /* Light gray. */ +#define FGND_DGRAY 0x8 /* Dark gray. */ +#define FGND_BBLUE 0x9 /* Bright blue. */ +#define FGND_BGRN 0xA /* Bright green. */ +#define FGND_BCYAN 0xB /* Bright cyan. */ +#define FGND_PINK 0xC +#define FGND_BMAG 0xD /* Bright magenta. */ +#define FGND_YLLW 0xE +#define FGND_WHITE 0xF + +#define BGND_BLACK 0x00 +#define BGND_BLUE 0x10 +#define BGND_GREEN 0x20 +#define BGND_CYAN 0x30 +#define BGND_RED 0x40 +#define BGND_MAG 0x50 +#define BGND_BRWN 0x60 +#define BGND_LGRAY 0x70 /* Light gray. */ + +/* Miscellaneous */ +void halt(void); +int readfile(char *filename, char *buf, int count, int offset); + +/* "Special" */ +void misbehave(int mode); + +/* Project 4 F2010 */ +#include <ureg.h> /* may be directly included by kernel guts */ +typedef void (*swexn_handler_t)(void *arg, ureg_t *ureg); +int swexn(void *esp3, swexn_handler_t eip, void *arg, ureg_t *newureg); + +/* Project 4 F2017 */ +int new_console(void); + +/* Previous API */ +/* +void exit(int status) NORETURN; +void task_exit(int status) NORETURN; +int cas2i_runflag(int tid, int *oldp, int ev1, int nv1, int ev2, int nv2); +int ls(int size, char *buf); +*/ + +#endif /* _SYSCALL_H */ diff --git a/spec/syscall_int.h b/spec/syscall_int.h new file mode 100644 index 0000000..aa0365d --- /dev/null +++ b/spec/syscall_int.h @@ -0,0 +1,69 @@ +/* The 15-410 reference kernel. + * syscall_int.h + * + * Prototypes for assembly language wrappers for the + * system call interface. + * + * Adam Chlipala (adamc) + * Jorge Vittes (jvittes) + * Zachary Anderson (zra) + */ + +#ifndef _SYSCALL_INT_H +#define _SYSCALL_INT_H + +#define FORK_INT 0x41 +#define EXEC_INT 0x42 +/* #define EXIT_INT 0x43 */ +#define WAIT_INT 0x44 +#define YIELD_INT 0x45 +#define DESCHEDULE_INT 0x46 +#define MAKE_RUNNABLE_INT 0x47 +#define GETTID_INT 0x48 +#define NEW_PAGES_INT 0x49 +#define REMOVE_PAGES_INT 0x4A +#define SLEEP_INT 0x4B +#define GETCHAR_INT 0x4C +#define READLINE_INT 0x4D +#define PRINT_INT 0x4E +#define SET_TERM_COLOR_INT 0x4F +#define SET_CURSOR_POS_INT 0x50 +#define GET_CURSOR_POS_INT 0x51 +#define THREAD_FORK_INT 0x52 +#define GET_TICKS_INT 0x53 +#define MISBEHAVE_INT 0x54 +#define HALT_INT 0x55 +/* #define LS_INT 0x56 */ +#define TASK_VANISH_INT 0x57 /* previously known as TASK_EXIT_INT */ +#define NEW_CONSOLE_INT 0x58 +#define SET_STATUS_INT 0x59 +#define VANISH_INT 0x60 +/* #define CAS2I_RUNFLAG_INT 0x61 */ +#define READFILE_INT 0x62 + +#define SWEXN_INT 0x74 + +/* The syscalls in here, INCLUSIVE, are promised not to be + * probed by any grading scripts; as such you are welcome + * to extend the spec by making use of these syscall numbers + */ +#define SYSCALL_RESERVED_START 0x80 +#define SYSCALL_RESERVED_0 0x80 +#define SYSCALL_RESERVED_1 0x81 +#define SYSCALL_RESERVED_2 0x82 +#define SYSCALL_RESERVED_3 0x83 +#define SYSCALL_RESERVED_4 0x84 +#define SYSCALL_RESERVED_5 0x85 +#define SYSCALL_RESERVED_6 0x86 +#define SYSCALL_RESERVED_7 0x87 +#define SYSCALL_RESERVED_8 0x88 +#define SYSCALL_RESERVED_9 0x89 +#define SYSCALL_RESERVED_10 0x8A +#define SYSCALL_RESERVED_11 0x8B +#define SYSCALL_RESERVED_12 0x8C +#define SYSCALL_RESERVED_13 0x8D +#define SYSCALL_RESERVED_14 0x8E +#define SYSCALL_RESERVED_15 0x8F +#define SYSCALL_RESERVED_END 0x8F + +#endif /* _SYSCALL_INT_H */ diff --git a/spec/ureg.h b/spec/ureg.h new file mode 100644 index 0000000..2183d59 --- /dev/null +++ b/spec/ureg.h @@ -0,0 +1,50 @@ +#ifndef _UREG_H_ +#define _UREG_H_ + +/* See intel-sys.pdf section 5.12, "Exception and Interrupt Reference" */ +#define SWEXN_CAUSE_DIVIDE 0x00 /* Very clever, Intel */ +#define SWEXN_CAUSE_DEBUG 0x01 +#define SWEXN_CAUSE_BREAKPOINT 0x03 +#define SWEXN_CAUSE_OVERFLOW 0x04 +#define SWEXN_CAUSE_BOUNDCHECK 0x05 +#define SWEXN_CAUSE_OPCODE 0x06 /* SIGILL */ +#define SWEXN_CAUSE_NOFPU 0x07 /* FPU missing/disabled/busy */ +#define SWEXN_CAUSE_SEGFAULT 0x0B /* segment not present */ +#define SWEXN_CAUSE_STACKFAULT 0x0C /* ouch */ +#define SWEXN_CAUSE_PROTFAULT 0x0D /* aka GPF */ +#define SWEXN_CAUSE_PAGEFAULT 0x0E /* cr2 is valid! */ +#define SWEXN_CAUSE_FPUFAULT 0x10 /* old x87 FPU is angry */ +#define SWEXN_CAUSE_ALIGNFAULT 0x11 +#define SWEXN_CAUSE_SIMDFAULT 0x13 /* SSE/SSE2 FPU is angry */ + +#ifndef ASSEMBLER + +typedef struct ureg_t { + unsigned int cause; + unsigned int cr2; /* Or else zero. */ + + unsigned int ds; + unsigned int es; + unsigned int fs; + unsigned int gs; + + unsigned int edi; + unsigned int esi; + unsigned int ebp; + unsigned int zero; /* Dummy %esp, set to zero */ + unsigned int ebx; + unsigned int edx; + unsigned int ecx; + unsigned int eax; + + unsigned int error_code; + unsigned int eip; + unsigned int cs; + unsigned int eflags; + unsigned int esp; + unsigned int ss; +} ureg_t; + +#endif /* ASSEMBLER */ + +#endif /* _UREG_H_ */ |
