From 5aa2f21253caa8e0c0c0746c2ea43ee88ee13334 Mon Sep 17 00:00:00 2001 From: Enrico Fraccaroli Date: Wed, 18 Jan 2023 14:38:36 -0500 Subject: [PATCH] Add missing comments. --- mentos/inc/proc_access.h | 246 +++++++++++++++++++++++--------------- mentos/inc/system/panic.h | 4 +- mentos/src/mem/paging.c | 8 +- 3 files changed, 156 insertions(+), 102 deletions(-) diff --git a/mentos/inc/proc_access.h b/mentos/inc/proc_access.h index eb2f3ae..4b1a4e2 100644 --- a/mentos/inc/proc_access.h +++ b/mentos/inc/proc_access.h @@ -7,9 +7,6 @@ #include "stdint.h" -/// Macro that encapsulate asm and volatile directives. -#define ASM(a) __asm__ __volatile__(a) - #define CR0_PE 0x00000001u ///< Protected mode Enable. #define CR0_MP 0x00000002u ///< "Math" Present (e.g. npx), wait for it. #define CR0_EM 0x00000004u ///< EMulate NPX, e.g. trap, don't execute code. @@ -37,218 +34,275 @@ #define CR4_PVI 0x00000002u ///< Protected-mode Virtual Interrupts. #define CR4_VME 0x00000001u ///< Virtual-8086 Mode Extensions. -static inline uint16_t get_es(void) +/// @brief Reads the Extra Segment (DS). +/// @return the value we read. +static inline uint16_t get_es() { uint16_t es; - ASM("mov %%es, %0" - : "=r"(es)); + __asm__ __volatile__("mov %%es, %0" + : "=r"(es)); return es; } +/// @brief Sets the Extra Segment (DS). +/// @param es the value we set. static inline void set_es(uint16_t es) { - ASM("mov %0, %%es" - : - : "r"(es)); + __asm__ __volatile__("mov %0, %%es" + : + : "r"(es)); } -static inline uint16_t get_ds(void) +/// @brief Reads the Data Segment (DS). +/// @return the value we read. +static inline uint16_t get_ds() { uint16_t ds; - ASM("mov %%ds, %0" - : "=r"(ds)); + __asm__ __volatile__("mov %%ds, %0" + : "=r"(ds)); return ds; } +/// @brief Sets the Data Segment (DS). +/// @param ds the value we set. static inline void set_ds(uint16_t ds) { - ASM("mov %0, %%ds" - : - : "r"(ds)); + __asm__ __volatile__("mov %0, %%ds" + : + : "r"(ds)); } -static inline uint16_t get_fs(void) +/// @brief Reads FS. +/// @return the value we read. +static inline uint16_t get_fs() { uint16_t fs; - ASM("mov %%fs, %0" - : "=r"(fs)); + __asm__ __volatile__("mov %%fs, %0" + : "=r"(fs)); return fs; } +/// @brief Sets FS. +/// @param fs the value we set. static inline void set_fs(uint16_t fs) { - ASM("mov %0, %%fs" - : - : "r"(fs)); + __asm__ __volatile__("mov %0, %%fs" + : + : "r"(fs)); } -static inline uint16_t get_gs(void) +/// @brief Reads GS. +/// @return the value we read. +static inline uint16_t get_gs() { uint16_t gs; - ASM("mov %%gs, %0" - : "=r"(gs)); + __asm__ __volatile__("mov %%gs, %0" + : "=r"(gs)); return gs; } +/// @brief Sets GS. +/// @param gs the value we set. static inline void set_gs(uint16_t gs) { - ASM("mov %0, %%gs" - : - : "r"(gs)); + __asm__ __volatile__("mov %0, %%gs" + : + : "r"(gs)); } -static inline uint16_t get_ss(void) +/// @brief Reads the Stack Segment (SS). +/// @return the value we read. +static inline uint16_t get_ss() { uint16_t ss; - ASM("mov %%ss, %0" - : "=r"(ss)); + __asm__ __volatile__("mov %%ss, %0" + : "=r"(ss)); return ss; } +/// @brief Sets the Stack Segment (SS). +/// @param ss the value we set. static inline void set_ss(uint16_t ss) { - ASM("mov %0, %%ss" - : - : "r"(ss)); + __asm__ __volatile__("mov %0, %%ss" + : + : "r"(ss)); } -static inline uintptr_t get_cr0(void) +/// @brief Reads the current cr0 value. +/// @return the value we read. +static inline uintptr_t get_cr0() { uintptr_t cr0; - ASM("mov %%cr0, %0" - : "=r"(cr0)); + __asm__ __volatile__("mov %%cr0, %0" + : "=r"(cr0)); return (cr0); } +/// @brief Sets the cr0 value. +/// @param cr0 the value we want to set. static inline void set_cr0(uintptr_t cr0) { - ASM("mov %0, %%cr0" - : - : "r"(cr0)); + __asm__ __volatile__("mov %0, %%cr0" + : + : "r"(cr0)); } -static inline uintptr_t get_cr3(void) +/// @brief Reads the current cr3 value. +/// @return the value we read. +static inline uintptr_t get_cr3() { uintptr_t cr3; - ASM("mov %%cr3, %0" - : "=r"(cr3)); + __asm__ __volatile__("mov %%cr3, %0" + : "=r"(cr3)); return (cr3); } +/// @brief Sets the cr3 value. +/// @param cr3 the value we want to set. static inline void set_cr3(uintptr_t cr3) { - ASM("mov %0, %%cr3" - : - : "r"(cr3)); + __asm__ __volatile__("mov %0, %%cr3" + : + : "r"(cr3)); } -static inline uintptr_t get_cr4(void) +/// @brief Reads the current cr4 value. +/// @return the value we read. +static inline uintptr_t get_cr4() { uintptr_t cr4; - ASM("mov %%cr4, %0" - : "=r"(cr4)); + __asm__ __volatile__("mov %%cr4, %0" + : "=r"(cr4)); return (cr4); } +/// @brief Sets the cr4 value. +/// @param cr4 the value we want to set. static inline void set_cr4(uintptr_t cr4) { - ASM("mov %0, %%cr4" - : - : "r"(cr4) - : "memory"); + __asm__ __volatile__("mov %0, %%cr4" + : + : "r"(cr4) + : "memory"); } -static inline uintptr_t get_eflags(void) +/// @brief Reads entire contents of the EFLAGS register. +/// @return the content of EFLAGS. +static inline uintptr_t get_eflags() { uintptr_t eflags; - /* "=rm" is safe here, because "pop" adjusts the stack before - * it evaluates its effective address -- this is part of the - * documented behavior of the "pop" instruction. - */ - ASM("pushf ; pop %0" - : "=rm"(eflags) - : /* no input */ - : "memory"); + // "=rm" is safe here, because "pop" adjusts the stack before + // it evaluates its effective address -- this is part of the + // documented behavior of the "pop" instruction. + __asm__ __volatile__("pushf; pop %0" + : "=rm"(eflags) + : // no input + : "memory"); return eflags; } -static inline void clear_ts(void) +/// @brief Clears the task-switched (TS) flag in the CR0 register. +static inline void clear_ts() { - ASM("clts"); + __asm__ __volatile__("clts"); } -static inline unsigned short get_tr(void) +/// @brief Reads the segment selector from the task register (TR). +/// @return +static inline unsigned short get_tr() { unsigned short seg; - ASM("str %0" - : "=rm"(seg)); + __asm__ __volatile__("str %0" + : "=rm"(seg)); return (seg); } -static inline void set_tr(unsigned int seg) +/// @brief Loads the source operand into the segment selector field of the task register. +/// @param seg the segment selector we want to set. +static inline void set_tr(unsigned short seg) { - ASM("ltr %0" - : - : "rm"((unsigned short)(seg))); + __asm__ __volatile__("ltr %0" + : + : "rm"(seg)); } -static inline unsigned short sldt(void) +/// @brief Reads the segment selector from the local descriptor table register (LDTR). +/// @return the segment selector. +static inline unsigned short sldt() { unsigned short seg; - ASM("sldt %0" - : "=rm"(seg)); + __asm__ __volatile__("sldt %0" + : "=rm"(seg)); return (seg); } -static inline void lldt(unsigned int seg) +/// @brief Loads the source operand into the segment selector field of the local descriptor table register (LDTR). +/// @param seg The segment selector we need to set. +static inline void lldt(unsigned short seg) { - ASM("lldt %0" - : - : "rm"((unsigned short)(seg))); + __asm__ __volatile__("lldt %0" + : + : "rm"(seg)); } +/// @brief Loads the values in the source operand into the global descriptor +/// table register (GDTR) or the interrupt descriptor table register (IDTR). +/// @param desc the value we need to load. static inline void lgdt(uintptr_t *desc) { - ASM("lgdt %0" - : - : "m"(*desc)); + __asm__ __volatile__("lgdt %0" + : + : "m"(*desc)); } +/// @brief Loads the values in the source operand into the global descriptor +/// table register (GDTR) or the interrupt descriptor table register (IDTR). +/// @param desc the value we need to load. static inline void lidt(uintptr_t *desc) { - ASM("lidt %0" - : - : "m"(*desc)); + __asm__ __volatile__("lidt %0" + : + : "m"(*desc)); } -/// @brief Enable IRQs. +/// @brief Set interrupt flag; external, maskable interrupts enabled at the end +/// of the next instruction. static inline void sti() { - ASM("sti" :: - : "memory"); + __asm__ __volatile__("sti" + : + : + : "memory"); } -/// @brief Disable IRQs. +/// @brief Clear interrupt flag; interrupts disabled when interrupt flag +/// cleared. static inline void cli() { - ASM("cli" :: - : "memory"); + __asm__ __volatile__("cli" + : + : + : "memory"); } -static inline void swapgs(void) +/// @brief Exchanges the current GS base register value with the value contained +/// in MSR address C0000102H. +static inline void swapgs() { - ASM("swapgs"); + __asm__ __volatile__("swapgs"); } -static inline void hlt(void) +/// @brief Halts the CPU until the next external interrupt is fired. +static inline void hlt() { - ASM("hlt"); + __asm__ __volatile__("hlt"); } -/// @brief Pause. +/// @brief Gives hint to processor that improves performance of spin-wait loops. static inline void pause() { - ASM("pause"); + __asm__ __volatile__("pause"); } // == Memory clobbers ========================================================= @@ -266,6 +320,6 @@ static inline void pause() // Making an inline asm block "volatile" as in this example, ensures that, // as it optimizes, the compiler does not move any instructions above or // below the block of asm statements. -// ASM(" addic. %0,%1,%2\n" : "=r"(res): "=r"(a),"r"(a)) +// __asm__ __volatile__(" addic. %0,%1,%2\n" : "=r"(res): "=r"(a),"r"(a)) // This can be particularly important in cases when the code is accessing // shared memory. diff --git a/mentos/inc/system/panic.h b/mentos/inc/system/panic.h index 98ca362..26c3769 100644 --- a/mentos/inc/system/panic.h +++ b/mentos/inc/system/panic.h @@ -5,9 +5,9 @@ #pragma once -/// @brief Prints the given message and then safely stop the execution of -/// the kernel. +/// @brief Prints the given message and safely stop the execution of the kernel. /// @param msg The message that has to be shown. void kernel_panic(const char *msg); +/// @brief Sends a kernel panic with the given message. #define TODO(msg) kernel_panic(#msg); diff --git a/mentos/src/mem/paging.c b/mentos/src/mem/paging.c index 7ededbf..0b7149f 100644 --- a/mentos/src/mem/paging.c +++ b/mentos/src/mem/paging.c @@ -68,8 +68,8 @@ void paging_switch_directory_va(page_directory_t *dir) void paging_flush_tlb_single(unsigned long addr) { - ASM("invlpg (%0)" ::"r"(addr) - : "memory"); + __asm__ __volatile__("invlpg (%0)" ::"r"(addr) + : "memory"); } uint32_t create_vm_area(mm_struct_t *mm, @@ -165,12 +165,12 @@ uint32_t clone_vm_area(mm_struct_t *mm, vm_area_struct_t *area, int cow, uint32_ static void __init_pagedir(page_directory_t *pdir) { - *pdir = (page_directory_t){ {0} }; + *pdir = (page_directory_t){ { 0 } }; } static void __init_pagetable(page_table_t *ptable) { - *ptable = (page_table_t){ {0} }; + *ptable = (page_table_t){ { 0 } }; } void paging_init(boot_info_t *info)