summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorHanjie Wu <hanjiew@andrew.cmu.edu>2023-04-18 02:21:10 -0400
committerHanjie Wu <hanjiew@andrew.cmu.edu>2023-04-18 02:21:10 -0400
commitc71294cdd3581c3738d24ffd65414f8644a1094d (patch)
treec86245d50fad9eee4163dbba169bd1839edbf88f /spec
initial commit
Diffstat (limited to 'spec')
-rw-r--r--spec/common_kern.h56
-rw-r--r--spec/compiler.h23
-rw-r--r--spec/contracts.h32
-rw-r--r--spec/hvcall.h135
-rw-r--r--spec/hvcall_int.h49
-rw-r--r--spec/limits.h36
-rw-r--r--spec/syscall.h98
-rw-r--r--spec/syscall_int.h69
-rw-r--r--spec/ureg.h50
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_ */