summaryrefslogtreecommitdiff
path: root/asm
diff options
context:
space:
mode:
Diffstat (limited to 'asm')
-rw-r--r--asm/multiboot.s4
-rw-r--r--asm/x86.h100
-rw-r--r--asm/x86.s137
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
+