From d0736af52257b312ae733e4df06fc5e427162ace Mon Sep 17 00:00:00 2001 From: Morten Delenk Date: Thu, 20 Jul 2017 09:26:35 +0100 Subject: [PATCH] added broken raspi2 port fixed all arm ports --- cross/gcc.mk | 7 ++- do_all.sh | 14 ++++- kernel/arch/arm/3ds11/flags.cmake | 2 +- kernel/arch/arm/3ds11/layout.ld | 2 +- kernel/arch/arm/3ds11/start.s | 5 +- kernel/arch/arm/3ds9/flags.cmake | 2 +- kernel/arch/arm/3ds9/start.cpp | 7 +-- kernel/arch/arm/3ds9/start.s | 5 +- kernel/arch/arm/config.py | 2 +- kernel/arch/arm/interrupt.cpp | 1 + kernel/arch/arm/raspi2/config.py | 2 + kernel/arch/arm/raspi2/flags.cmake | 3 + kernel/arch/arm/raspi2/layout.ld | 36 +++++++++++ kernel/arch/arm/raspi2/start.cpp | 14 +++++ kernel/arch/arm/raspi2/start.s | 54 +++++++++++++++++ kernel/arch/arm/sourcegen.py | 3 + kernel/cpu/arm/cortex-a7/config.py | 0 kernel/hw/3ds11/config.py | 1 + kernel/hw/3ds9/config.py | 1 + kernel/hw/framebuffer/framebuffer.cpp | 1 + kernel/hw/pc/config.py | 1 + kernel/hw/raspi2/config.py | 3 + kernel/hw/raspi2/serial/serial.cpp | 72 ++++++++++++++++++++++ kernel/hw/raspi2/serial/serial.hpp | 14 +++++ kernel/hw/raspi2/uart/uart.cpp | 25 ++++++++ kernel/hw/raspi2/uart/uart.hpp | 34 +++++++++++ kernel/hw/raspi2/vector/vector.cpp | 32 ++++++++++ kernel/hw/raspi2/vector/vector.hpp | 2 + kernel/src/cppstubs.cpp | 7 +++ kernel/src/include/base.hpp | 7 ++- kernel/src/include/pmm.hpp | 40 ++++++++++++ kernel/src/object_init.cpp | 14 ++--- kernel/src/pmm.cpp.old | 87 +++++++++++++++++++++++++++ 33 files changed, 477 insertions(+), 23 deletions(-) create mode 100644 kernel/arch/arm/raspi2/config.py create mode 100644 kernel/arch/arm/raspi2/flags.cmake create mode 100644 kernel/arch/arm/raspi2/layout.ld create mode 100644 kernel/arch/arm/raspi2/start.cpp create mode 100644 kernel/arch/arm/raspi2/start.s create mode 100644 kernel/cpu/arm/cortex-a7/config.py create mode 100644 kernel/hw/raspi2/config.py create mode 100644 kernel/hw/raspi2/serial/serial.cpp create mode 100644 kernel/hw/raspi2/serial/serial.hpp create mode 100644 kernel/hw/raspi2/uart/uart.cpp create mode 100644 kernel/hw/raspi2/uart/uart.hpp create mode 100644 kernel/hw/raspi2/vector/vector.cpp create mode 100644 kernel/hw/raspi2/vector/vector.hpp create mode 100644 kernel/src/include/pmm.hpp create mode 100644 kernel/src/pmm.cpp.old diff --git a/cross/gcc.mk b/cross/gcc.mk index 9c3941a..423442b 100644 --- a/cross/gcc.mk +++ b/cross/gcc.mk @@ -1,5 +1,5 @@ -GCC_VERSION=6.3.0 -GCC_MAJOR_VERSION=6.3.0 +GCC_VERSION=7.1.0 +GCC_MAJOR_VERSION=7.1.0 gcc.tar.bz2: gcc-$(GCC_VERSION).tar.bz2 mv $^ $@ @@ -24,7 +24,8 @@ gcc-configure: ../gcc/configure --prefix=$(CROSSPATH) --target=$(TARGET) --disable-nls --enable-languages=c,c++ --without-headers gcc-make: gcc-configure - $(MAKE) -C builddir all-gcc all-target-libgcc + $(MAKE) -C builddir all-gcc + $(MAKE) -C builddir all-target-libgcc gcc-install: gcc-make $(MAKE) -C builddir install-gcc install-target-libgcc diff --git a/do_all.sh b/do_all.sh index c36afc9..6eeee2d 100755 --- a/do_all.sh +++ b/do_all.sh @@ -1,3 +1,4 @@ +unset CFLAGS CXXFLAGS LDFLAGS builddir() { rm -rf build/ && mkdir -pv build/ @@ -59,4 +60,15 @@ mv kernel9 build/kernel && buildtools/sighax-firm.sh && mv sighax.firm out/ && cp -v build/kernel/kernel out/arm11loaderhax.elf -rm -rf build/ + +{ + echo 2 + echo 2 + yes '' +} | ./config.py && +builddir && +pushd build && +cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-none-eabi.cmake .. && +make -j$(nproc) && +popd && +cp -v build/kernel/kernel out/raspi2.elf diff --git a/kernel/arch/arm/3ds11/flags.cmake b/kernel/arch/arm/3ds11/flags.cmake index 49b6aca..c3f49e2 100644 --- a/kernel/arch/arm/3ds11/flags.cmake +++ b/kernel/arch/arm/3ds11/flags.cmake @@ -1,3 +1,3 @@ -SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/3ds11/include -mcpu=mpcore -mlittle-endian -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft -O9") +SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/3ds11/include -mcpu=mpcore -mlittle-endian -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft -O2") SET(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}") SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}") diff --git a/kernel/arch/arm/3ds11/layout.ld b/kernel/arch/arm/3ds11/layout.ld index 973910b..07324f7 100644 --- a/kernel/arch/arm/3ds11/layout.ld +++ b/kernel/arch/arm/3ds11/layout.ld @@ -1,6 +1,6 @@ ENTRY(_start) SECTIONS { - . = 0x20000000; + . = 0x20401000; /*If luma wouldn't put the entire firm at 0x20001000, I'd have used 0x20000000 */ kernel_start = .; .text : { KEEP(*(.text.boot)); diff --git a/kernel/arch/arm/3ds11/start.s b/kernel/arch/arm/3ds11/start.s index 946a6b7..58f1284 100644 --- a/kernel/arch/arm/3ds11/start.s +++ b/kernel/arch/arm/3ds11/start.s @@ -7,7 +7,7 @@ .section .text.boot _start: CPSID aif //Disable interrupts - ldr sp, =kernel_stack + ldr sp, =svc_stack //set other stacks mrs r0, cpsr bic r2, r0, #0x1F @@ -44,9 +44,12 @@ _start: blx start .section .bss +.align 16 .space 4096 interrupt_stack: .space 4096 exception_stack: +.space 4096 +svc_stack: .space 16384 kernel_stack: diff --git a/kernel/arch/arm/3ds9/flags.cmake b/kernel/arch/arm/3ds9/flags.cmake index 2358460..ab52dcb 100644 --- a/kernel/arch/arm/3ds9/flags.cmake +++ b/kernel/arch/arm/3ds9/flags.cmake @@ -1,3 +1,3 @@ -SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/3ds9/include -mcpu=arm946e-s -march=armv5te -mthumb-interwork -marm -O9") +SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/3ds9/include -mcpu=arm946e-s -march=armv5te -mthumb-interwork -marm -Os") SET(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}") SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}") diff --git a/kernel/arch/arm/3ds9/start.cpp b/kernel/arch/arm/3ds9/start.cpp index 0399332..e195178 100644 --- a/kernel/arch/arm/3ds9/start.cpp +++ b/kernel/arch/arm/3ds9/start.cpp @@ -5,13 +5,12 @@ PICAfb term; void main(); -extern "C" void start() { main(); } +extern "C" void start() { main(); + for(;;); +} void drivers_init() { - term << "initing main tty\n"; setMainTTY(&term); --term; - term << "Initing vectors\n"; initVectors(); - term << "trying svc\n"; asm volatile("svc #0"); } diff --git a/kernel/arch/arm/3ds9/start.s b/kernel/arch/arm/3ds9/start.s index f5b1a27..d79bb42 100644 --- a/kernel/arch/arm/3ds9/start.s +++ b/kernel/arch/arm/3ds9/start.s @@ -50,7 +50,7 @@ _start: mov r1, r2 orr r1, #0b10011 //SVC msr cpsr, r1 - ldr sp, =kernel_stack + ldr sp, =svc_stack orr r1, #0b11111 //SYS msr cpsr, r1 ldr sp, =kernel_stack @@ -121,9 +121,12 @@ _start: blx start .section .bss +.align 16 .space 4096 interrupt_stack: .space 4096 exception_stack: +.space 4096 +svc_stack: .space 16384 kernel_stack: diff --git a/kernel/arch/arm/config.py b/kernel/arch/arm/config.py index e31519e..3ed636a 100644 --- a/kernel/arch/arm/config.py +++ b/kernel/arch/arm/config.py @@ -1 +1 @@ -config["SYSTEM"] = get_from_list("System", ["3ds9","3ds11"]) +config["SYSTEM"] = get_from_list("System", ["3ds9","3ds11", "raspi2"]) diff --git a/kernel/arch/arm/interrupt.cpp b/kernel/arch/arm/interrupt.cpp index 71d4857..edec6fb 100644 --- a/kernel/arch/arm/interrupt.cpp +++ b/kernel/arch/arm/interrupt.cpp @@ -42,6 +42,7 @@ extern "C" cpu_state *handleINT(int number, cpu_state *state) { else state->returnAddr -= 4; } + out->puti(state->cpsr); return state; } extern "C" void panic2(char *msg, cpu_state *state) { diff --git a/kernel/arch/arm/raspi2/config.py b/kernel/arch/arm/raspi2/config.py new file mode 100644 index 0000000..3c32e91 --- /dev/null +++ b/kernel/arch/arm/raspi2/config.py @@ -0,0 +1,2 @@ +config["LOWEST_CPU"] = "cortex-a7" + diff --git a/kernel/arch/arm/raspi2/flags.cmake b/kernel/arch/arm/raspi2/flags.cmake new file mode 100644 index 0000000..4652989 --- /dev/null +++ b/kernel/arch/arm/raspi2/flags.cmake @@ -0,0 +1,3 @@ +SET(PLATFORM_C_FLAGS "-I../../kernel/arch/arm/3ds11/include -mcpu=cortex-a7 -mlittle-endian -mtune=cortex-a7 -mfloat-abi=hard -mtp=soft -O2") +SET(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}") +SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}") diff --git a/kernel/arch/arm/raspi2/layout.ld b/kernel/arch/arm/raspi2/layout.ld new file mode 100644 index 0000000..b35fa71 --- /dev/null +++ b/kernel/arch/arm/raspi2/layout.ld @@ -0,0 +1,36 @@ +ENTRY(_start) +SECTIONS { + . = 0x8000; /*If luma wouldn't put the entire firm at 0x20001000, I'd have used 0x20000000 */ + kernel_start = .; + .text : { + KEEP(*(.text.boot)); + *(.text) + } + .data : { + start_ctors = .; + KEEP(*(.init_array)); + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*))); + KEEP(*(.ctors)); + end_ctors = .; + start_dtors = .; + KEEP(*(.fini_array)); + KEEP(*(.fini_array.*)); + KEEP(*(.dtors)); + end_dtors = .; + start_eh_frame = .; + KEEP(*(.eh_frame)); + KEEP(*(.eh_frame.*)); + QUAD(0); + KEEP(*(.gcc_except_table)); + KEEP(*(.gcc_except_table.*)); + *(.data) + } + .rodata : { + *(.rodata) + } + .bss : { + *(.bss) + *(COMMON) + } + kernel_end = .; +} diff --git a/kernel/arch/arm/raspi2/start.cpp b/kernel/arch/arm/raspi2/start.cpp new file mode 100644 index 0000000..62e6214 --- /dev/null +++ b/kernel/arch/arm/raspi2/start.cpp @@ -0,0 +1,14 @@ +#include "../../../hw/raspi2/serial/serial.hpp" +#include "../../../hw/raspi2/vector/vector.hpp" +#include +#include + +Serial term; +void main(); +extern "C" void start() { main(); } +void drivers_init() { + setMainTTY(&term); + --term; + initVectors(); + asm volatile("svc #0"); +} diff --git a/kernel/arch/arm/raspi2/start.s b/kernel/arch/arm/raspi2/start.s new file mode 100644 index 0000000..170c32a --- /dev/null +++ b/kernel/arch/arm/raspi2/start.s @@ -0,0 +1,54 @@ +.arm +.arch armv6k +.fpu vfpv2 +.align 4 +.global _start +.extern start +.section .text.boot +_start: + CPSID aif //Disable interrupts + ldr sp, =svc_stack + push {r0,r1,r2} + //set other stacks + mrs r0, cpsr + bic r2, r0, #0x1F + mov r1, r2 + orr r1, #0b10001 //FIQ + msr cpsr, r1 + ldr sp, =interrupt_stack + mov r1, r2 + orr r1, #0b10010 //IRQ + msr cpsr, r1 + ldr sp, =interrupt_stack + mov r1, r2 + orr r1, #0b10111 //Abort + msr cpsr, r1 + ldr sp, =exception_stack + mov r1, r2 + orr r1, #0b11011 //Undefined + msr cpsr, r1 + ldr sp, =exception_stack + orr r1, #0b11111 //SYS + msr cpsr, r1 + ldr sp, =kernel_stack + //Enable FPU + MRC p15, 0, r0, c1, c1, 2 + ORR r0, r0, #3<<10 // enable fpu + MCR p15, 0, r0, c1, c1, 2 + LDR r0, =(0xF << 20) + MCR p15, 0, r0, c1, c0, 2 + MOV r3, #0x40000000 + VMSR FPEXC, r3 + //Start MTGos + blx start + +.section .bss +.align 16 +.space 4096 +interrupt_stack: +.space 4096 +exception_stack: +.space 4096 +svc_stack: +.space 16384 +kernel_stack: diff --git a/kernel/arch/arm/sourcegen.py b/kernel/arch/arm/sourcegen.py index 7059a85..67a22ad 100644 --- a/kernel/arch/arm/sourcegen.py +++ b/kernel/arch/arm/sourcegen.py @@ -47,6 +47,7 @@ branch_macro: //pop the special registers pop {r0, r3, r4, lr} + msr spsr, r0 tst r0, #0x20 //Is code ARM or thumb? beq 2f orr lr, lr, #1 //Enable thumb mode on return# @@ -93,7 +94,9 @@ pop_regs.append("mov sp, r0") for opc in push_regs: int_handler.write(" "+opc+"\n") +int_handler.write(" push {lr}\n") int_handler.write(" blx handleINT\n") +int_handler.write(" pop {lr}\n") for opc in reversed(pop_regs): int_handler.write(" "+opc+"\n") int_handler.write(" bx lr\n") diff --git a/kernel/cpu/arm/cortex-a7/config.py b/kernel/cpu/arm/cortex-a7/config.py new file mode 100644 index 0000000..e69de29 diff --git a/kernel/hw/3ds11/config.py b/kernel/hw/3ds11/config.py index c0a2d40..9c7737d 100644 --- a/kernel/hw/3ds11/config.py +++ b/kernel/hw/3ds11/config.py @@ -8,5 +8,6 @@ if config["ENABLE_I2C"]: add_driver(True, "framebuffer") add_driver(False, "picafb") add_driver(False, "vectorinit") +add_driver(False, "pmm") print("Enable complete Unicode font: NO (because of the size)") config["ENABLE_FRAMEBUFFER_UNICODE"] = False diff --git a/kernel/hw/3ds9/config.py b/kernel/hw/3ds9/config.py index 0ca4d86..fd8cd7a 100644 --- a/kernel/hw/3ds9/config.py +++ b/kernel/hw/3ds9/config.py @@ -2,5 +2,6 @@ config["ENABLE_EXTRA_MEMORY"] = get_yes_no("Enable 512KB of memory on n3DS", Tru add_driver(True, "framebuffer") add_driver(False, "picafb") add_driver(False, "vectorinit") +add_driver(False, "pmm") print("Enable complete Unicode font: NO (because of the size)") config["ENABLE_FRAMEBUFFER_UNICODE"] = False diff --git a/kernel/hw/framebuffer/framebuffer.cpp b/kernel/hw/framebuffer/framebuffer.cpp index 0e4c459..d91aa56 100644 --- a/kernel/hw/framebuffer/framebuffer.cpp +++ b/kernel/hw/framebuffer/framebuffer.cpp @@ -1,5 +1,6 @@ #include "framebuffer.hpp" #include +#include auto Framebuffer::plotPixel(int x, int y, int col) -> void {} auto Framebuffer::plotChar(int x, int y, int c) -> void { if (c > 65535) return; diff --git a/kernel/hw/pc/config.py b/kernel/hw/pc/config.py index 3529762..bd9a8dc 100644 --- a/kernel/hw/pc/config.py +++ b/kernel/hw/pc/config.py @@ -8,3 +8,4 @@ else: add_driver(False, "cgaterm") add_driver(False, "8259") add_driver(False, "idt") +add_driver(False, "pmm") diff --git a/kernel/hw/raspi2/config.py b/kernel/hw/raspi2/config.py new file mode 100644 index 0000000..42559c9 --- /dev/null +++ b/kernel/hw/raspi2/config.py @@ -0,0 +1,3 @@ +add_driver(False, "uart") +add_driver(False, "serial") +add_driver(False, "vector") diff --git a/kernel/hw/raspi2/serial/serial.cpp b/kernel/hw/raspi2/serial/serial.cpp new file mode 100644 index 0000000..19c007c --- /dev/null +++ b/kernel/hw/raspi2/serial/serial.cpp @@ -0,0 +1,72 @@ +#include "serial.hpp" +Serial::Serial(): TTY(80,25), uart(UART::getInstance()) { + uart[UART_MEM::IBRD] = 1; + uart[UART_MEM::FBRD] = 40; + uart[UART_MEM::LCRH] = 0b1110000; + uart[UART_MEM::IMSC] = 0b11111110010; + uart[UART_MEM::CR] = 0b1100000001; +} +auto Serial::serial_putc(char c) -> void { + while(uart[UART_MEM::FR] & 0x20); + uart[UART_MEM::DR] = (uint8_t)c; +} +auto Serial::serial_putc(int c) -> void { + //UTF-8 encoder + if(c <= 0x7F) + return this->serial_putc((char)c); + if(c <= 0x7FF) { + this->serial_putc((char)(0b11000000 | (c >> 6))); + this->serial_putc((char)(0b10000000 | (c & 0x3F))); + return; + } + if(c <= 0xFFFF) { + this->serial_putc((char)(0b11100000 | (c >> 12))); + this->serial_putc((char)(0b10000000 | ((c >> 6)&0x3F))); + this->serial_putc((char)(0b10000000 | (c&0x3F))); + return; + } + this->serial_putc((char)(0b11110000 | (c >> 18))); + this->serial_putc((char)(0b10000000 | ((c >> 12)&0x3F))); + this->serial_putc((char)(0b10000000 | ((c >> 6)&0x3F))); + this->serial_putc((char)(0b10000000 | (c&0x3F))); +} +auto Serial::serial_puti(int i) -> void { + char buf[65]; + char *ptr=buf+63; + ptr[1]=0; + char *chars = "0123456789"; + do { + *(ptr--) = chars[i%10]; + i/=10; + } while (i && (ptr != buf)); + ptr++; + while(*ptr) + this->serial_putc(*(ptr++)); +} +auto Serial::plotChar(int x, int y, int c) -> void { + //Send position + serial_putc(0x1B); + serial_putc('['); + serial_puti(y+1); + serial_putc(';'); + serial_puti(x+1); + serial_putc('H'); + //Send color + int r = rgbColor >> 16; + int g = (rgbColor >> 8) & 0xFF; + int b = rgbColor & 0xFF; + serial_putc(0x1B); + serial_putc('['); + serial_puti(38); + serial_putc(';'); + serial_puti(2); + serial_putc(';'); + serial_puti(r); + serial_putc(';'); + serial_puti(g); + serial_putc(';'); + serial_puti(b); + serial_putc('m'); + //Actually write the character + serial_putc(c); +} diff --git a/kernel/hw/raspi2/serial/serial.hpp b/kernel/hw/raspi2/serial/serial.hpp new file mode 100644 index 0000000..766217b --- /dev/null +++ b/kernel/hw/raspi2/serial/serial.hpp @@ -0,0 +1,14 @@ +#pragma once +#include "../uart/uart.hpp" +#include +class Serial: public TTY { + private: + UART &uart; + auto serial_putc(int c) -> void; + auto serial_putc(char c) -> void; + auto serial_puti(int i) -> void; + protected: + virtual auto plotChar(int x, int y, int c) -> void; + public: + Serial(); +}; diff --git a/kernel/hw/raspi2/uart/uart.cpp b/kernel/hw/raspi2/uart/uart.cpp new file mode 100644 index 0000000..dae6e8f --- /dev/null +++ b/kernel/hw/raspi2/uart/uart.cpp @@ -0,0 +1,25 @@ +#include "uart.hpp" +static volatile uint32_t x; +auto delay = [&x](uint32_t count) { + for(x=0;x +enum class UART_MEM: uint32_t { + GPPUD = 0x94, + GPPUDCLK0 = 0x98, + DR = 0x00, + RSRECR = 0x04, + FR = 0x18, + ILPR = 0x20, + IBRD = 0x24, + FBRD = 0x28, + LCRH = 0x2C, + CR = 0x30, + IFLS = 0x34, + IMSC = 0x38, + RIS = 0x3C, + MIS = 0x40, + ICR = 0x44, + DMACR = 0x48, + ITCR = 0x80, + ITIP = 0x84, + ITOP = 0x88, + TDR = 0x8C +}; +class UART { + public: + static UART &getInstance(); + uint32_t &operator[](uint32_t off); ///< Returns a reference to the corresponding MMIO register + uint32_t &operator[](UART_MEM off); ///< @see UART::operator[](uint32_t off); + UART(UART const&) = delete; + UART &operator=(UART const&) = delete; + private: + UART(); +}; diff --git a/kernel/hw/raspi2/vector/vector.cpp b/kernel/hw/raspi2/vector/vector.cpp new file mode 100644 index 0000000..397e719 --- /dev/null +++ b/kernel/hw/raspi2/vector/vector.cpp @@ -0,0 +1,32 @@ +#include +extern "C" { +void data_abort(); +void fast_irq(); +void normal_irq(); +void prefetch_abort(); +void svc_call(); +void undefined_op(); +extern uintptr_t branch_macro; +} +void initVectors() { + uintptr_t *vectors = (uintptr_t*)nullptr; + uintptr_t branch = 0xEA000000; + vectors[1] = branch + 5; + vectors[2] = branch + 6; + vectors[3] = branch + 7; + vectors[4] = branch + 8; + vectors[6] = branch + 8; + vectors[7] = branch + 9; + vectors[8] = branch_macro; + vectors[9] = (uintptr_t)&undefined_op; + vectors[10] = branch_macro; + vectors[11] = (uintptr_t)&svc_call; + vectors[12] = branch_macro; + vectors[13] = (uintptr_t)&prefetch_abort; + vectors[14] = branch_macro; + vectors[15] = (uintptr_t)&data_abort; + vectors[16] = branch_macro; + vectors[17] = (uintptr_t)&normal_irq; + vectors[18] = branch_macro; + vectors[19] = (uintptr_t)&fast_irq; +} diff --git a/kernel/hw/raspi2/vector/vector.hpp b/kernel/hw/raspi2/vector/vector.hpp new file mode 100644 index 0000000..55c7734 --- /dev/null +++ b/kernel/hw/raspi2/vector/vector.hpp @@ -0,0 +1,2 @@ +#pragma once +void initVectors(); diff --git a/kernel/src/cppstubs.cpp b/kernel/src/cppstubs.cpp index 79526ee..177390b 100644 --- a/kernel/src/cppstubs.cpp +++ b/kernel/src/cppstubs.cpp @@ -17,3 +17,10 @@ void *operator new(size_t s, void *p) { return p; } void *operator new[](size_t s, void *p) { return p; } void operator delete(void *, void *p) {} void operator delete[](void *, void *p) {} +__extension__ typedef int __guard __attribute__((mode(__DI__))); +extern "C" int __cxa_guard_acquire(__guard *g) { + return !*(char*)g; +} +extern "C" int __cxa_guard_release(__guard *g) { + *(char *)g = 1; +} diff --git a/kernel/src/include/base.hpp b/kernel/src/include/base.hpp index bbf712d..5084aec 100644 --- a/kernel/src/include/base.hpp +++ b/kernel/src/include/base.hpp @@ -5,4 +5,9 @@ extern TTY *out; ///< main TTY for output /*** * Sets the main TTY to some other TTY object. */ -void setMainTTY(Kobject *obj); +void setMainTTY(TTY *obj); + +/** + * Halts the kernel due to a unresolvable error + */ +extern "C" void panic(const char* s); diff --git a/kernel/src/include/pmm.hpp b/kernel/src/include/pmm.hpp new file mode 100644 index 0000000..7dc70f9 --- /dev/null +++ b/kernel/src/include/pmm.hpp @@ -0,0 +1,40 @@ +#pragma once +typedef uintptr_t phys_t; ///< Type used for physical addresses +/** + * A single entry in the PMM list + */ +struct PMM_ent { + PMM_ent* next; ///< Next element in the list + phys_t val; ///< This for not having to cast in the code. +}; +/** + * Structure for a memory map + */ +struct mmap_ent { + phys_t start; + phys_t end; +} +/** + * Physical memory manager. It stores the free memory in a linked list + */ +class PMM { + protected: + PMM_ent *head; ///< Head of the linked list + virtual auto isFree(phys_t addr) -> bool; ///< Returns true if the provided page is free to use + phys_t page_size; ///< Contains the size of a single memory page, in bytes + public: + PMM(phys_t page_size, mmap_ent *entries, int length); + virtual ~PMM(); + virtual auto operator<<(phys_t page) -> PMM &; ///< Frees a page. O(1) + virtual auto operator>>(phys_t &page) -> PMM &; ///< Allocates a page. O(1) + virtual auto operator,(size_t no_pages) -> phys_t; ///< Allocates multiple pages. O(n²) + virtual auto operator(phys_t pages,size_t no_pages) -> void; ///< Deallocates multiple pages. O(n) + virtual auto operator&&(phys_t page) -> bool; //Returns true if this page is free. O(n). +}; +/** + * This definition is for having a python-like syntax - like `page in pmm` + */ +#define in and + +auto operator&&(phys_t a, PMM mm) -> bool; ///< Returns true when page is free. Used for syntax `page in pmm` +auto operator&&(phys_t a, PMM *mm) -> bool; ///< Returns true when page is free. Present in case that mm is a pointer. diff --git a/kernel/src/object_init.cpp b/kernel/src/object_init.cpp index aa1309f..77b2475 100644 --- a/kernel/src/object_init.cpp +++ b/kernel/src/object_init.cpp @@ -1,12 +1,10 @@ #include TTY *out; bool tty_set = false; -void setMainTTY(Kobject *obj) { - if (obj->type == kobjectType::TTY) { - ++*obj; - // if(tty_set) - // --*out; - out = (TTY *)obj; - tty_set = true; - } +void setMainTTY(TTY *obj) { + ++*obj; + // if(tty_set) + // --*out; + out = obj; + tty_set = true; } diff --git a/kernel/src/pmm.cpp.old b/kernel/src/pmm.cpp.old new file mode 100644 index 0000000..5368c0b --- /dev/null +++ b/kernel/src/pmm.cpp.old @@ -0,0 +1,87 @@ +#include +#include +extern "C" int kernel_start; +extern "C" int kernel_end; +auto PMM::isFree(phys_t addr) -> bool { + if(addr == 0) + return false; + phys_t start = (phys_t)(&kernel_start); + phys_t end = (phys_t)(&kernel_end); + if((addr >= start) or (addr < end)) + return false; + return true; +} +PMM::PMM(phys_t page_size, mmap_ent *entries, int length): page_size(page_size), head(nullptr) { + for(int i=0;i< length; i++) { + for(phys_t j=entries[i].start;j PMM & { + *this(page,1); + return *this; +} +auto PMM::operator>>(phys_t &page) -> PMM & { + page = *this, 1; + return *this; +} + +auto PMM::operator,(size_t no_pages) -> phys_t { + if(head == nullptr) + panic("No free physical memory is available."); + if(no_pages == 1) { + //Simple. Just return the fist page. + PMM_ent *curr=head; + head=head->next; + return curr->val; + } + //Now we need to find a free page with n-1 free pages after it + PMM_ent *curr=head; + while(curr) { + //Is curr+n pages free? + if((curr->val+((no_pages-1)*page_size)) in this) { + //We're onto something + bool notfound=false; + phys_t i; + size_t j; + for(i=curr->val,j=0; jval; + } + //Not found. + curr=curr->next; + } + panic("Not enough continuous free memory is available."); +} +auto PMM::operator(phys_t pages, size_t no_pages) -> void { + for(size_t i=0; inext=head; + curr->val=pages; + head=curr; + } +} +virtual auto operator&&(phys_t page) -> bool { + PMM_ent *curr = head; + while(curr) { + if(curr->value==page) + return true; + curr=curr->next; + } + return false; +} +auto operator&&(phys_t a, PMM mm) -> bool { + return mm && a; +} +auto operator&&(phys_t a, PMM *mm) -> bool { + return a in *mm; +}