diff options
author | Freya Murphy <freya@freyacat.org> | 2025-04-03 12:29:48 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-04-03 12:29:48 -0400 |
commit | 33b9d606916f3847e0f754693ca49ce56175a330 (patch) | |
tree | eba26ad7722349ced40270f4a9a8083a58a7d453 /include/x86/ops.h | |
parent | track changes (diff) | |
download | comus-33b9d606916f3847e0f754693ca49ce56175a330.tar.gz comus-33b9d606916f3847e0f754693ca49ce56175a330.tar.bz2 comus-33b9d606916f3847e0f754693ca49ce56175a330.zip |
refactor include
Diffstat (limited to 'include/x86/ops.h')
-rw-r--r-- | include/x86/ops.h | 395 |
1 files changed, 0 insertions, 395 deletions
diff --git a/include/x86/ops.h b/include/x86/ops.h deleted file mode 100644 index 81167a1..0000000 --- a/include/x86/ops.h +++ /dev/null @@ -1,395 +0,0 @@ -/** -** @file ops.h -** -** @author Warren R. Carithers -** -** @brief Inline escapes to assembly for efficiency -** -** Inspiration from: -** Martins Mozeiko, https://gist.github.com/mmozeiko/f68ad2546bd6ab953315 -** MIT's xv6, https://github.com/mit-pdos/xv6-public -** -** Note: normally, GCC doesn't inline unless the optimization level is -** over 1. This can be forced by adding -** -** __attribute__((always_inline)) -** -** after the parameter list on each declaration. This is enabled by -** defining the compile-time CPP symbol FORCE_INLINING. -*/ - -#ifndef OPS_H_ -#define OPS_H_ - -#include <common.h> - -#ifndef ASM_SRC - -// control "forced" inlining -#ifdef FORCE_INLINING -#define OPSINLINED __attribute__((always_inline)) -#else -#define OPSINLINED /* no-op */ -#endif /* FORCE_INLINING */ - -/**************************** -** Data movement -****************************/ - -/** -** Block move functions -** -** Variations: movsb(), movsl(), movsq() -** -** Description: Copy from source buffer to destination buffer -** -** @param dst Destination buffer -** @param src Source buffer -** @param len Byte count -*/ -static inline void movsb(void *dst, const void *src, uint32_t len) OPSINLINED -{ - __asm__ __volatile__("cld; rep movsb" - : "+D"(dst), "+S"(src), "+c"(len) - : - : "memory"); -} -static inline void movsw(void *dst, const void *src, uint32_t len) OPSINLINED -{ - __asm__ __volatile__("cld; rep movsw" - : "+D"(dst), "+S"(src), "+c"(len) - : - : "memory"); -} -static inline void movsl(void *dst, const void *src, uint32_t len) OPSINLINED -{ - __asm__ __volatile__("cld; rep movsl" - : "+D"(dst), "+S"(src), "+c"(len) - : - : "memory"); -} -static inline void movsq(void *dst, const void *src, uint32_t len) OPSINLINED -{ - __asm__ __volatile__("cld; rep movsq" - : "+D"(dst), "+S"(src), "+c"(len) - : - : "memory"); -} - -/** -** Block store functions -** -** Variations: stosb(), stosw(), stosl() -** -** Description: Store a specific value into destination buffer -** -** @param dst Destination buffer -** @param val Data to copy -** @param len Byte count -*/ -static inline void stosb(void *dst, uint8_t val, uint32_t len) OPSINLINED -{ - __asm__ __volatile__("cld; rep stosb" - : "=D"(dst), "=c"(len) - : "0"(dst), "1"(len), "a"(val) - : "memory", "cc"); -} -static inline void stosw(void *dst, uint16_t val, uint32_t len) OPSINLINED -{ - __asm__ __volatile__("cld; rep stos2" - : "=D"(dst), "=c"(len) - : "0"(dst), "1"(len), "a"(val) - : "memory", "cc"); -} -static inline void stosl(void *dst, uint32_t val, uint32_t len) OPSINLINED -{ - __asm__ __volatile__("cld; rep stosl" - : "=D"(dst), "=c"(len) - : "0"(dst), "1"(len), "a"(val) - : "memory", "cc"); -} - -/**************************** -** Special register access -****************************/ - -/** -** Register read functions -** -** Variations: r_cr0(), r_cr2(), r_cr3(), r_cr4(), r_eflags(), -** r_ebp(), r_esp() -** -** Description: Reads the register indicated by its name -** -** @return Contents of the register -*/ -static inline uint32_t r_cr0(void) OPSINLINED -{ - uint32_t val; - __asm__ __volatile__("movl %%cr0,%0" : "=r"(val)); - return val; -} -static inline uint32_t r_cr2(void) OPSINLINED -{ - uint32_t val; - __asm__ __volatile__("movl %%cr2,%0" : "=r"(val)); - return val; -} -static inline uint32_t r_cr3(void) OPSINLINED -{ - uint32_t val; - __asm__ __volatile__("movl %%cr3,%0" : "=r"(val)); - return val; -} -static inline uint32_t r_cr4(void) OPSINLINED -{ - uint32_t val; - __asm__ __volatile__("movl %%cr4,%0" : "=r"(val)); - return val; -} -static inline uint32_t r_eflags(void) OPSINLINED -{ - uint32_t val; - __asm__ __volatile__("pushfl; popl %0" : "=r"(val)); - return val; -} -static inline uint32_t r_ebp(void) OPSINLINED -{ - uint32_t val; - __asm__ __volatile__("movl %%ebp,%0" : "=r"(val)); - return val; -} -static inline uint32_t r_esp(void) OPSINLINED -{ - uint32_t val; - __asm__ __volatile__("movl %%esp,%0" : "=r"(val)); - return val; -} - -/** -** Register write functions -** -** Variations: w_cr0(), w_cr2(), w_cr3(), w_cr4(), w_eflags() -** -** Description: Writes a value into the CR indicated by its name -*/ -static inline void w_cr0(uint32_t val) OPSINLINED -{ - __asm__ __volatile__("movl %0,%%cr0" : : "r"(val)); -} -static inline void w_cr2(uint32_t val) OPSINLINED -{ - __asm__ __volatile__("movl %0,%%cr2" : : "r"(val)); -} -static inline void w_cr3(uint32_t val) OPSINLINED -{ - __asm__ __volatile__("movl %0,%%cr3" : : "r"(val)); -} -static inline void w_cr4(uint32_t val) OPSINLINED -{ - __asm__ __volatile__("movl %0,%%cr4" : : "r"(val)); -} -static inline void w_eflags(uint32_t eflags) OPSINLINED -{ - __asm__ __volatile__("pushl %0; popfl" : : "r"(eflags)); -} - -/** -** Descriptor table load functions -** -** Variations: w_gdt(), w_idt() -** -** Description: Load an address into the specified processor register -** -** @param addr The value to be loaded into the register -*/ -static inline void w_gdt(void *addr) OPSINLINED -{ - __asm__ __volatile__("lgdt (%0)" : : "r"(addr)); -} -static inline void w_idt(void *addr) OPSINLINED -{ - __asm__ __volatile__("lidt (%0)" : : "r"(addr)); -} - -/** -** CPU ID access -** -** Description: Retrieve CPUID information -** -** @param op Value to be placed into %eax for the operation -** @param ap Pointer to where %eax contents should be saved, or NULL -** @param bp Pointer to where %ebx contents should be saved, or NULL -** @param cp Pointer to where %ecx contents should be saved, or NULL -** @param dp Pointer to where %edx contents should be saved, or NULL -*/ -static inline void cpuid(uint32_t op, uint32_t *ap, uint32_t *bp, uint32_t *cp, - uint32_t *dp) OPSINLINED -{ - uint32_t eax, ebx, ecx, edx; - __asm__ __volatile__("cpuid" - : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) - : "a"(op)); - if (ap) - *ap = eax; - if (bp) - *bp = ebx; - if (cp) - *cp = ecx; - if (dp) - *dp = edx; -} - -/**************************** -** TLB management -****************************/ - -/** -** TLB invalidation for one page -** -** Description: Invalidate the TLB entry for an address -** -** @param addr An address within the page to be flushed -*/ -static inline void invlpg(uint32_t addr) OPSINLINED -{ - __asm__ __volatile__("invlpg (%0)" : : "r"(addr) : "memory"); -} - -/** -** TLB invalidation for all pages -** -** Description: Flush all entries from the TLB -** -** We do this by changing CR3. -*/ -static inline void flushtlb(void) OPSINLINED -{ - uint32_t cr3; - __asm__ __volatile__("movl %%cr3,%0" : "=r"(cr3)); - __asm__ __volatile__("movl %0,%%cr2" : : "r"(cr3)); -} - -/**************************** -** I/O instructions -****************************/ - -/** -** Name: inN -** -** Variations: inb(), inw(), inl() -** -** Description: Read some amount of data from the supplied I/O port -** -** @param port The i/o port to read from -** -** @return The data read from the specified port -*/ -static inline uint8_t inb(int port) OPSINLINED -{ - uint8_t data; - __asm__ __volatile__("inb %w1,%0" : "=a"(data) : "d"(port)); - return data; -} -static inline uint16_t inw(int port) OPSINLINED -{ - uint16_t data; - __asm__ __volatile__("inw %w1,%0" : "=a"(data) : "d"(port)); - return data; -} -static inline uint32_t inl(int port) OPSINLINED -{ - uint32_t data; - __asm__ __volatile__("inl %w1,%0" : "=a"(data) : "d"(port)); - return data; -} - -/** -** Name: outN -** -** Variations: outb(), outw(), outl() -** -** Description: Write some data to the specified I/O port -** -** @param port The i/o port to write to -** @param data The data to be written to the port -** -** @return The data read from the specified port -*/ -static inline void outb(int port, uint8_t data) OPSINLINED -{ - __asm__ __volatile__("outb %0,%w1" : : "a"(data), "d"(port)); -} -static inline void outw(int port, uint16_t data) OPSINLINED -{ - __asm__ __volatile__("outw %0,%w1" : : "a"(data), "d"(port)); -} -static inline void outl(int port, uint32_t data) OPSINLINED -{ - __asm__ __volatile__("outl %0,%w1" : : "a"(data), "d"(port)); -} - -/**************************** -** Miscellaneous instructions -****************************/ - -/** -** Name: breakpoint -** -** Description: Cause a breakpoint interrupt for debugging purposes -*/ -static inline void breakpoint(void) OPSINLINED -{ - __asm__ __volatile__("int3"); -} - -/** -** Name: get_ra -** -** Description: Get the return address for the calling function -** (i.e., where whoever called us will go back to) -** -** @return The address the calling routine will return to as a uint32_t -*/ -static inline uint32_t get_ra(void) OPSINLINED -{ - uint32_t val; - __asm__ __volatile__("movl 4(%%ebp),%0" : "=r"(val)); - return val; -} - -/** -** Name: ev_wait -** -** Description: Pause until something happens -*/ -static inline void ev_wait(void) OPSINLINED -{ - __asm__ __volatile__("sti ; hlt"); -} - -/** -** Name: xchgl -** -** Description: Perform an atomic exchange with memory -** -** @param addr Memory location to be modified -** @param data Data to exchange -** -** @return The old contents of the memory location -*/ -static inline uint32_t xchgl(volatile uint32_t *addr, uint32_t data) OPSINLINED -{ - uint32_t old; - - // + indicates a read-modify-write operand - __asm__ __volatile__("lock; xchgl %0, %1" - : "+m"(*addr), "=a"(old) - : "1"(data) - : "cc"); - return old; -} - -#endif /* !ASM_SRC */ - -#endif |