diff options
Diffstat (limited to 'asm')
| -rw-r--r-- | asm/multiboot.s | 4 | ||||
| -rw-r--r-- | asm/x86.h | 100 | ||||
| -rw-r--r-- | asm/x86.s | 137 |
3 files changed, 241 insertions, 0 deletions
diff --git a/asm/multiboot.s b/asm/multiboot.s index 1d808a3..54cffbb 100644 --- a/asm/multiboot.s +++ b/asm/multiboot.s @@ -1,6 +1,10 @@ # https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format # http://wiki.osdev.org/Bare_Bones +# Fill Multiboot Haeder, init stack and call kernel_main passing to params: +# eax - magic number +# ebx - multiboot structure + # Declare constants used for creating a multiboot header. .set ALIGN, 1<<0 # align loaded modules on page boundaries .set MEMINFO, 1<<1 # provide memory map diff --git a/asm/x86.h b/asm/x86.h new file mode 100644 index 0000000..8e6a741 --- /dev/null +++ b/asm/x86.h @@ -0,0 +1,100 @@ +#ifndef FOOLOS_X86_H +#define FOOLOS_X86_H + +/** + * @file + * + * X86 32-bit Basics + * ================= + * + * **All the functions are very specific to the targeted x86 architecture.** + * + * This is the header of our basic **x86** function definitions. + * Most of the functions are implemented in assembler in the file _asm/x86.s_, + * however a few short helper functions are defined in this header itself: + * + * * x86_set_page_directory() + * * x86_paging_enable() + * * x86_paging_disable() + * + * + * Reading and Writing Ports + * ------------------------- + * + * The functions of the form x86_outX() and x86_inX(), where the X + * indicates the value size allow reading and writing ports. + * + * * x86_outb() / x86_inb() + * * x86_outw() / x86_inw() + * * x86_outl() / x86_inl() + * + * The sizes are: + * + * * b - byte (8 bit) + * * w - word (16 bit) + * * l - double word (32 bit) + * + * Remember, that the port address is always 32 bits wide. + * + * Dependencies + * ------------ + * + * All we need are uint32_t, uint16_t and uint8_t as provided by <stdint.h> + * + * References + * ---------- + * * http://wiki.osdev.org/Interrupt_Service_Routines + * * https://wiki.osdev.org/CPU_Registers_x86 + * * ... + * + */ + +// we need uint32_t, uint16_t, uint8_t // +#include <stdint.h> + +/** write byte to port */ +void x86_outb (uint32_t port, uint8_t data); + +/** read byte from port */ +uint8_t x86_inb (uint32_t port); + +/** write word to port */ +void x86_outw (uint32_t port, uint16_t data); + +/** read word from port */ +uint16_t x86_inw (uint32_t port); + +/** write double word to port */ +void x86_outl (uint32_t port, uint32_t data); + +/** read double word from port */ +uint32_t x86_inl (uint32_t port); + +/** disable interrupts */ +void x86_cli (); + +/** enable interrupts */ +void x86_sti (); + +/** xchg - this can be used for semaphors and simlar */ +uint8_t x86_xchg (uint8_t *addr, uint8_t val); + +/** invlpg - invalidate translation lookaside buffer */ +void x86_invlpg(uint32_t addr); + +/** read value from control register specified by num */ +uint32_t x86_get_cr(uint8_t num); + +/** write given value to the control register specified by num */ +void x86_set_cr(uint8_t num, uint32_t value); + +/** Set the address of the page directory. This is required **before** enabling paging */ +static inline void x86_set_page_directory(uint32_t pdir_addr) {x86_set_cr(3,pdir_addr);} + +/** Enable paging */ +static inline void x86_paging_enable() {x86_set_cr(0,x86_get_cr(0)| 0x80000000);} + +/** Disable paging */ +static inline void x86_paging_disable() {x86_set_cr(0,x86_get_cr(0)&~0x80000000);} + +#endif diff --git a/asm/x86.s b/asm/x86.s new file mode 100644 index 0000000..a5bcb1c --- /dev/null +++ b/asm/x86.s @@ -0,0 +1,137 @@ +// Basic low-level x86 32-bit calls // + +// reading and writing ports + +.global x86_outb // 8 bit out +.global x86_inb // 8 bit in +.global x86_outw // 16 bit out +.global x86_inw // 16 bit in +.global x86_outl // 32 bit out +.global x86_inl // 32 bit in + +// interrupts + +.global x86_cli // disable interrupts +.global x86_sti // enable interrupts + +// xchg +.global x86_xchg // exchange (for semaphors etc.) + +// invlpg +.global x86_invlpg // invalidate translation lookaside buffer (tlb) + +// control registers +.global x86_get_cr +.global x86_set_cr + +x86_outb: + mov 4(%esp), %edx + mov 8(%esp), %eax + outb %al,%dx + ret + +x86_inb: + mov 4(%esp), %edx + inb %dx,%al + ret + +x86_outw: + mov 4(%esp), %edx + mov 8(%esp), %eax + outw %ax,%dx + ret + +x86_inw: + mov 4(%esp), %edx + inw %dx,%ax + ret + +x86_outl: + mov 4(%esp), %edx + mov 8(%esp), %eax + outl %eax,%dx + ret + +x86_inl: + mov 4(%esp), %edx + inl %dx,%eax + ret + +x86_cli: + cli + ret + +x86_sti: + sti + ret + +x86_xchg: +// -- uint8_t result; +// -- +// -- // The + in "+m" denotes a read-modify-write operand. +// -- asm volatile("lock xchgb %0, %1" : +// -- "+m" (*addr), "=a" (result) : +// -- "1" (val) : +// -- "cc"); +// -- +// -- return result; +// -- } + ret + +x86_get_cr: + mov 4(%esp), %ecx + cmp %ecx,0 + je get_cr0 + cmp %ecx,2 + je get_cr2 + cmp %ecx,3 + je get_cr3 + cmp %ecx,4 + je get_cr4 + ret + +x86_set_cr: + mov 4(%esp), %eax + mov 8(%esp), %ecx + cmp %ecx,0 + je set_cr0 + cmp %ecx,2 + je set_cr2 + cmp %ecx,3 + je set_cr3 + cmp %ecx,4 + je set_cr4 + ret + +get_cr0: + mov %cr0,%eax + ret + +get_cr2: + mov %cr2,%eax + ret + +get_cr3: + mov %cr3,%eax + ret + +get_cr4: + mov %cr4,%eax + ret + +set_cr0: + mov %eax,%cr0 + ret + +set_cr2: + mov %eax,%cr2 + ret + +set_cr3: + mov %eax,%cr3 + ret + +set_cr4: + mov %eax,%cr4 + ret + |
