diff options
| author | Amlal <amlal.elmahrouss@icloud.com> | 2025-01-21 20:32:19 +0100 |
|---|---|---|
| committer | Amlal <amlal.elmahrouss@icloud.com> | 2025-01-21 20:32:19 +0100 |
| commit | 046d884b50c32cacd3523071541e7e38241083f3 (patch) | |
| tree | 92ce6fd53e0c031c569270b04aefa8fc0aa1e074 /src | |
ADD: CoreBoot, also comes with my reimplementation of libfdt, which is just a dumb rewrite.
Signed-off-by: Amlal <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'src')
40 files changed, 1724 insertions, 0 deletions
diff --git a/src/32x0/32x0_boot.32x b/src/32x0/32x0_boot.32x new file mode 100644 index 0000000..44ee037 --- /dev/null +++ b/src/32x0/32x0_boot.32x @@ -0,0 +1,42 @@ +;; 32x0 Runtime zero routine +;; org: 0x1000 (very different from the 64x0) +;; interrupts: 0x800 (much like the 64x0) +;; brief: jump to main + +;; Copyright 2024, Amlal EL Mahrouss, all rights reserved. + +%def ROMBOOT_BASE $1000 + +org ROMBOOT_BASE + +move.w r0, __vector_interrupts_table +move.w r1, __vector_interrupts_table_length +move.w r2, 0 + +__vector_L1: + move.b [r0+r2], [$800+r2] + incr r2 + cmp r2, r1 + je __vector_done + jmp __vector_L1 + +__vector_done: + ;; forth interpreter and setup it's stack. + move.w sp, $7c00 + jmp $8000 + + mh + +__vector_interrupts_table: + dw 0 + dw 0 + dw 0 + dw 0 + dw 0 + dw 0 + dw 0 + dw 0 + dw 0 + +__vector_interrupts_table_length: + dw 9 diff --git a/src/64x0/.gitkeep b/src/64x0/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/64x0/.gitkeep diff --git a/src/64x0/64x0_boot.64x b/src/64x0/64x0_boot.64x new file mode 100644 index 0000000..6ee71b2 --- /dev/null +++ b/src/64x0/64x0_boot.64x @@ -0,0 +1,13 @@ +# 64x0 Runtime zero routine +# org: 1M +# interrupts: 1M - 2048 +# brief: jump to r16 which contains the code to jump on. + +# Copyright 2024, Amlal EL Mahrouss, all rights reserved. + +export .text __start + lda r15, 0x7c00 + lda r16, 0x8000 + mv r5, r15 + mv r19, r16 + jrl diff --git a/src/amd64/amd64-boot.asm b/src/amd64/amd64-boot.asm new file mode 100644 index 0000000..bcd6058 --- /dev/null +++ b/src/amd64/amd64-boot.asm @@ -0,0 +1,40 @@ +;; AMD64 CoreBoot Master Boot Program. +;; Written by Amlal EL Mahrouss + +%define ENTRYPOINT 0x00FF + +[bits 16] +[org ENTRYPOINT] + +amd64_bios_start: + cli + cld + + mov ax, cs + mov ds, ax + mov es, ax + mov ss, ax + mov fs, ax + + jmp amd64_bios_programmable_area + jmp 0x0000:0x7c00 + jmp $ + +amd64_vendor_information: + db "ZKA", 0 + dw 0x010 +amd64_vendor_information_end: + +amd64_bios_programmable_area: + times 1024 nop + ret +amd64_bios_programmable_area_end: + +times 2048-13-($-$$) nop + +;; SIZE: 13 Bytes. +;; PURPOSE: BIOS Computer Metadata +amd64_bios_entrypoint_area: + dw ENTRYPOINT ;; ENTRYPOINT. + db "13/21/2024" ;; DATE. + db 0x01 ;; VERSION. diff --git a/src/amd64/amd64-test.asm b/src/amd64/amd64-test.asm new file mode 100644 index 0000000..2a8bef8 --- /dev/null +++ b/src/amd64/amd64-test.asm @@ -0,0 +1,19 @@ +;; AMD64 CoreBoot Sample program. +;; Written by Amlal EL Mahrouss + +[bits 16] +[org 0x7c00] + +; -------------- +; Main entrypoint, just loop. +; -------------- +amd64_main: + jmp $ + cli + hlt + +times 512-6-2-2-($-$$) nop + +db "BOOT1", 0 ;; Payload +dw 0x0100 ;; Version 1 +dw 0 ;; Binary Blob diff --git a/src/amd64/amd64.sh b/src/amd64/amd64.sh new file mode 100755 index 0000000..ea9efa0 --- /dev/null +++ b/src/amd64/amd64.sh @@ -0,0 +1,4 @@ +#! /bin/sh + +nasm amd64-boot.asm -f bin -o amd64-boot.rom +nasm amd64-test.asm -f bin -o amd64-test.bin diff --git a/src/arm64/arm64-30pin.c b/src/arm64/arm64-30pin.c new file mode 100644 index 0000000..aca7628 --- /dev/null +++ b/src/arm64/arm64-30pin.c @@ -0,0 +1,13 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <lib/partition-map.h> + +extern size_t mp_send_read_30pin(voidptr_t blob, size_t* size, size_t* start_lba); + +/// @note This version is for the 30-pin recovery system. + +struct TRB_PACKET;
\ No newline at end of file diff --git a/src/arm64/arm64-boot.S b/src/arm64/arm64-boot.S new file mode 100644 index 0000000..c62a227 --- /dev/null +++ b/src/arm64/arm64-boot.S @@ -0,0 +1,15 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +.text + +.balign 4 +.global mp_reset_vector + +mp_reset_vector: + ldr sp, =__mp_stack_end + /* don't care about page_zero, it's gonna be a raw binary */ + b mp_start_exec diff --git a/src/arm64/arm64-err.c b/src/arm64/arm64-err.c new file mode 100644 index 0000000..5877cca --- /dev/null +++ b/src/arm64/arm64-err.c @@ -0,0 +1,23 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <lib/boot.h> + +/// BUGS: 0 + +/// @brief Goes into a panic state. +/// @param reason why? +void mp_panic(const char* reason) +{ + mp_put_string("Error: "); + mp_put_string(reason); + mp_put_char('\n'); + + while (yes) + { + asm volatile("hlt #0"); + } +} diff --git a/src/arm64/arm64-start-context.S b/src/arm64/arm64-start-context.S new file mode 100644 index 0000000..389f958 --- /dev/null +++ b/src/arm64/arm64-start-context.S @@ -0,0 +1,17 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +.text +.balign 4 +.global mp_start_context +.global mp_boot_processor_ready + +mp_start_context: + bl mp_start_context + ldr pc, [lr] + +mp_boot_processor_ready: + ldr pc, [lr] diff --git a/src/arm64/arm64-uart.c b/src/arm64/arm64-uart.c new file mode 100644 index 0000000..fff3bbf --- /dev/null +++ b/src/arm64/arm64-uart.c @@ -0,0 +1,54 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <lib/boot.h> +#include <lib/string.h> + +/// BUGS: 0 + +#define ARM64_MMIO_REG(addr) (*(volatile uint32_t*)(mp_uart_ptr + addr)) + +/* this file handles the UART */ + +static uint32_t* mp_uart_ptr = (uint32_t*)SYS_UART_BASE; + +// we need that one, to avoid sending mutliple chars to UART. +static boolean mp_locked_put_char = no; + +utf_char_t mp_get_char(void) +{ + while ((ARM64_MMIO_REG(0x018) & (1 << 4))) + { + } + + return (utf_char_t)*mp_uart_ptr; +} + +void mp_put_char(utf_char_t ch) +{ + while ((ARM64_MMIO_REG(0x018) & (1 << 5))) + { + } + + *mp_uart_ptr = ch; +} + +/// @brief UART put string +/// @param text the input text. +size_t mp_put_string(const char* text) +{ + if (text == nil) + return 0; + + size_t i = 0; + + for (; i < strlen(text); i++) + { + mp_put_char(text[i]); + } + + return i; +} diff --git a/src/arm64/makefile b/src/arm64/makefile new file mode 100644 index 0000000..19f88f5 --- /dev/null +++ b/src/arm64/makefile @@ -0,0 +1,69 @@ + # + # ======================================================== + # + # CoreBoot + # Date Added: 08/11/2023 + # Copyright 2024, ZKA Technologies, all rights reserved. + # + # ======================================================== + # + +CC=arm-none-eabi-gcc +AS=arm-none-eabi-as + +FIRMWARE=boot.rom + +FLAGS=-c -D__COMPILE_ARM64__ -I../../ -Wall -c -nostdlib -ffreestanding -fno-builtin \ + -D__BSTRICT__ -D__BDEBUG__ + +C_SRC=$(wildcard *.c) $(wildcard ../*.c) -c + +AS_FLAGS= -c -I../../ + +LD=arm-none-eabi-ld +OBJ=*.o +FLAGS_LD= --script=script.lds -o core-boot.elf -nostdlib + +EMU=qemu-system-arm +EMU_FLAGS=-M virt -cpu cortex-a15 -kernel $(FIRMWARE) -s \ + -drive file=bootstg2.rom,format=raw + +WAIT=sleep 1 + +.PHONY: all +all: firmware-link + @echo "[CoreBoot] build done." + +.PHONY: firmware-link +firmware-link: firmware-compile + $(LD) $(OBJ) $(FLAGS_LD) + +.PHONY: rom +rom: + qemu-img create -f qcow2 epm.img 256M + qemu-img create -f raw boot.rom 512K + qemu-img create -f raw bootstg2.rom 64M + dd if=core-boot.elf of=boot.rom bs=1 seek=0 conv=notrunc + +# compile firmware +.PHONY: firmware-compile +firmware-compile: + $(CC) $(FLAGS) $(C_SRC) + $(AS) -march=armv7-a -mcpu=cortex-a15 arm64-start-context.S -o arm64-start-context.o + $(AS) -march=armv7-a -mcpu=cortex-a15 arm64-boot.S -o arm64-boot.o + + +# launch qemu rule +.PHONY: run +run: + $(EMU) $(EMU_FLAGS) + +# launch qemu with attached debugger +.PHONY: run-dbg +run-dbg: + $(EMU) $(EMU_FLAGS) + +# remove object files +.PHONY: clean +clean: + rm -f $(wildcard *.o) $(wildcard *.elf) $(wildcard *.rom) $(wildcard *.epm) diff --git a/src/arm64/script.lds b/src/arm64/script.lds new file mode 100644 index 0000000..37bd647 --- /dev/null +++ b/src/arm64/script.lds @@ -0,0 +1,14 @@ +ENTRY(mp_reset_vector) +SECTIONS +{ + . = 0x40100000; + + .text : { *(.text) } + .data : { *(.data) } + .bss : { *(.bss COMMON) } + . = ALIGN(8); + . = . + 0x1000; /* 4kB of stack memory */ + __mp_stack_end = .; + + PROVIDE(mp_memory_end = .); +} diff --git a/src/compile_flags.txt b/src/compile_flags.txt new file mode 100644 index 0000000..c76ae60 --- /dev/null +++ b/src/compile_flags.txt @@ -0,0 +1,3 @@ +-std=c17 +-I../ +-I../lib diff --git a/src/coreboot-ahci-driver.c b/src/coreboot-ahci-driver.c new file mode 100644 index 0000000..aae3169 --- /dev/null +++ b/src/coreboot-ahci-driver.c @@ -0,0 +1,108 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +/** + * @file coreboot-ahci-driver.cc + * @author Amlal EL Mahrouss (amlal@el-mahrouss-logic.com) + * @brief PowerPC Disk support, via AHCI. + * @version 0.2 + * @date 2024-01-16 + * + * @copyright Copyright (c) 2024, Amlal EL Mahrouss. + * + */ + +#include <lib/pci-tree.h> +#include <lib/boot.h> + +#define SYS_AHCI_DRIVER_NAME ("@ahci") + +/// BUGS: 0 +/// @brief AHCI support for PowerPC. + +/// @brief AHCI HBA port. +typedef struct hba_port +{ + uint32_t clb; // 0x00, command list base address, 1K-byte aligned + uint32_t clbu; // 0x04, command list base address upper 32 bits + uint32_t fb; // 0x08, FIS base address, 256-byte aligned + uint32_t fbu; // 0x0C, FIS base address upper 32 bits + uint32_t is; // 0x10, interrupt status + uint32_t ie; // 0x14, interrupt enable + uint32_t cmd; // 0x18, command and status + uint32_t reserved0; // 0x1C, Reserved + uint32_t tfd; // 0x20, task file data + uint32_t sig; // 0x24, signature + uint32_t ssts; // 0x28, SATA status (SCR0:SStatus) + uint32_t sctl; // 0x2C, SATA control (SCR2:SControl) + uint32_t serr; // 0x30, SATA error (SCR1:SError) + uint32_t sact; // 0x34, SATA active (SCR3:SActive) + uint32_t ci; // 0x38, command issue + uint32_t sntf; // 0x20, SATA notification (SCR4:SNotification) + uint32_t fbs; // 0x40, FIS-based switch control + uint32_t reserved1[11]; // 0x44 ~ 0x6F, Reserved + uint32_t vendor[4]; // 0x70 ~ 0x7F, vendor specific +} hba_port_t; + +/// @brief Check if port is active. +/// @param port host bus address port. +/// @return +static boolean hba_port_active(volatile hba_port_t* port) +{ + if (!port) + return false; + + return port->sact; +} + +/// @brief Start HBA command. +/// @param port host bus address port. +/// @return +static boolean hba_start_cmd(volatile hba_port_t* port) +{ + if (!port) + return false; + + size_t timeout = 1000000; + + while ((port->cmd & 0x8000)) + { + if (!timeout) + return false; + + --timeout; + } + + port->cmd |= 0x0001; + port->cmd |= 0x0010; + + return true; +} + +/// @brief Stop HBA command. +/// @param port host bus address port. +/// @return +static boolean hba_stop_cmd(volatile hba_port_t* port) +{ + if (!port) + return false; + + port->cmd &= ~0x0001; + port->cmd &= ~0x0010; + + while (1) + { + if ((port->cmd & 0x8000)) + continue; + + if ((port->cmd & 0x4000)) + continue; + + break; + } + + return true; +} diff --git a/src/coreboot-cpu-api.c b/src/coreboot-cpu-api.c new file mode 100644 index 0000000..2f104c4 --- /dev/null +++ b/src/coreboot-cpu-api.c @@ -0,0 +1,22 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <lib/boot.h> + +/// @brief Restarts the computer. +/// @param none. +void mp_restart_machine(void) +{ +#ifdef __COMPILE_RISCV__ + volatile uint32_t* brd_pwr = (volatile uint32_t*)0x100000; + *brd_pwr = 0x7777; // send reboot signal from DMA. + + while (1) + { + asm volatile("wfi"); + } +#endif +} diff --git a/src/coreboot-cxx-abi.cc b/src/coreboot-cxx-abi.cc new file mode 100644 index 0000000..a035e78 --- /dev/null +++ b/src/coreboot-cxx-abi.cc @@ -0,0 +1,91 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <lib/cxx-abi.h> + +/// BUGS: 0 + +extern "C" __SIZE_TYPE__ mp_put_string(const char* text); +extern "C" void mp_panic(const char* reason); + +extern "C" void __stack_chk_fail() +{ + mp_put_string("[stack-canary] Buffer overflow detected, halting...\n"); + mp_panic("stack_canary_fail"); +} + +void* __dso_handle; + +extern "C" __SIZE_TYPE__ mp_put_string(const char* text); +extern "C" void mp_panic(const char* reason); + +atexit_func_entry_t __atexit_funcs[DSO_MAX_OBJECTS]; +uarch_t __atexit_func_count; + +extern "C" void __cxa_pure_virtual() +{ + mp_put_string("[__cxa_pure_virtual] Placeholder\n"); +} + +extern "C" int __cxa_atexit(void (*f)(void*), void* arg, void* dso) +{ + if (__atexit_func_count >= DSO_MAX_OBJECTS) + return -1; + + __atexit_funcs[__atexit_func_count].destructor_func = f; + __atexit_funcs[__atexit_func_count].obj_ptr = arg; + __atexit_funcs[__atexit_func_count].dso_handle = dso; + + __atexit_func_count++; + + return 0; +} + +extern "C" void __cxa_finalize(void* f) +{ + uarch_t i = __atexit_func_count; + if (!f) + { + while (i--) + { + if (__atexit_funcs[i].destructor_func) + { + (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); + }; + } + + return; + } + + while (i--) + { + if (__atexit_funcs[i].destructor_func) + { + (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); + __atexit_funcs[i].destructor_func = 0; + }; + } +} + +namespace cxxabiv1 +{ + extern "C" int __cxa_guard_acquire(__guard* g) + { + (void)g; + return 0; + } + + extern "C" int __cxa_guard_release(__guard* g) + { + *(char*)g = 1; + return 0; + } + + extern "C" void __cxa_guard_abort(__guard* g) + { + (void)g; + } +} // namespace cxxabiv1 diff --git a/src/coreboot-partition-map-parse.c b/src/coreboot-partition-map-parse.c new file mode 100644 index 0000000..b4647ae --- /dev/null +++ b/src/coreboot-partition-map-parse.c @@ -0,0 +1,58 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <lib/partition-map.h> + +bool mp_parse_partition_block_data_at(voidptr_t blob, size_t blob_sz, size_t index, size_t* end_lba, size_t* start_lba, size_t* sector_sz) +{ + if (!start_lba || + !end_lba || + !blob || + !blob_sz || + !sector_sz || + (sizeof(part_block_t) * index) > blob_sz) + return false; + + part_block_t* block = (part_block_t*)(block + (sizeof(part_block_t) * index)); + + if (block->version != EPM_REVISION || + block->num_blocks < 1 || + block->num_blocks > EPM_MAX_BLKS || + strcmp(block->magic, EPM_MAGIC) > 0 || + block->lba_end == 0 || + block->lba_start == 0) + { + return false; + } + + *end_lba = block->lba_end; + *start_lba = block->lba_start; + *sector_sz = block->sector_sz; + + return true; +} + +part_block_t* mp_parse_partition_block_at(voidptr_t blob, size_t blob_sz, size_t index) +{ + if (!blob || + !blob_sz || + (sizeof(part_block_t) * index) > blob_sz) + return nil; + + part_block_t* block = (part_block_t*)(block + (sizeof(part_block_t) * index)); + + if (block->version != EPM_REVISION || + block->num_blocks < 1 || + block->num_blocks > EPM_MAX_BLKS || + strcmp(block->magic, EPM_MAGIC) > 0 || + block->lba_end == 0 || + block->lba_start == 0) + { + return nil; + } + + return block; +}
\ No newline at end of file diff --git a/src/coreboot-partition-map.c b/src/coreboot-partition-map.c new file mode 100644 index 0000000..64ee94d --- /dev/null +++ b/src/coreboot-partition-map.c @@ -0,0 +1,37 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <lib/partition-map.h> +#include <lib/string.h> + +// include this for documentation. + +#define MP_FILESYSTEM_COUNT 3 +#define MP_FILESYSTEM_LIST \ + { \ + "NeFS", "HPFS", "HFS+" \ + } + +/// @brief check if filesystem is supported by CoreBoot. +/// @param fs the filesystem magic, as provided by EPM. +boolean mp_filesystem_exists(caddr_t fs, size_t len) +{ + if (fs == nil || + *fs == 0) + return no; + + char* fs_list[] = MP_FILESYSTEM_LIST; + + for (size_t fs_index = 0; fs_index < MP_FILESYSTEM_COUNT; fs_index++) + { + if (strncmp(fs_list[fs_index], fs, strlen(fs_list[fs_index])) == 0) + { + return yes; + } + } + + return no; +} diff --git a/src/coreboot-pci-tree.c b/src/coreboot-pci-tree.c new file mode 100644 index 0000000..e5082d2 --- /dev/null +++ b/src/coreboot-pci-tree.c @@ -0,0 +1,106 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +/** + * @file coreboot-pci-tree.c + * @author Amlal EL Mahrouss (amlal@el-mahrouss-logic.com) + * @brief PCI tree implementation. + * @version 0.1 + * @date 2024-01-22 + * + * @copyright Copyright (c) 2024 Amlal EL Mahrouss + * + */ + +#include <lib/pci-tree.h> +#include <lib/string.h> + +/// BUGS: 0 + +/// Standard Root table (Mahrouss Table) +#define SYS_PCI_ROOT_NAME "/elmh/@/" + +static struct hw_mp_pci_tree* mp_base_tree = nil; +static struct hw_mp_pci_tree* mp_latest_tree = nil; +static struct hw_mp_pci_tree* mp_last_tree = nil; + +/// \brief Init the PCI device tree structure. +/// \return if it already exists -> false +/// Otherwise true. +boolean mp_pci_init_tree(void) +{ + mp_base_tree = (struct hw_mp_pci_tree*)(SYS_PCI_TREE_BASE); + + // huh? anyway let's ignore it then. + if (mp_base_tree->d_magic != SYS_PCI_DEV_MAGIC) + { + mp_base_tree->d_magic = SYS_PCI_DEV_MAGIC; + + memncpy(mp_base_tree->d_name, SYS_PCI_ROOT_NAME, strlen(SYS_PCI_ROOT_NAME)); + + mp_base_tree->d_next_sibling = 0; + mp_base_tree->d_off_props = 0; + mp_base_tree->d_sz_struct = 0; + mp_base_tree->d_sz_props = 0; + mp_base_tree->d_off_struct = 0; + mp_base_tree->d_version = SYS_PCI_VERSION; + + mp_base_tree->d_next_sibling = + (mp_pci_num_t)(mp_base_tree + sizeof(struct hw_mp_pci_tree)); + mp_base_tree->d_first_node = (mp_pci_num_t)mp_base_tree; + + mp_put_string(">> Append root device: " SYS_PCI_ROOT_NAME "\r\n"); + } + + mp_latest_tree = mp_base_tree; + + return yes; +} + +/// \brief Adds a new device to the tree. +/// \param name the device name. +/// \param struct_ptr the struct containing the device. +/// \param struct_sz the structure size. +boolean mp_pci_append_tree(const caddr_t name, mp_pci_num_t struct_ptr, mp_pci_num_t struct_sz) +{ + if (!name || *name == 0 || mp_latest_tree == nil) + return no; + + struct hw_mp_pci_tree* mp_pci_tree = (struct hw_mp_pci_tree*)(mp_latest_tree); + + while (mp_pci_tree->d_magic == SYS_PCI_DEV_MAGIC) + { + if (strcmp(mp_pci_tree->d_name, name) == 0) + return no; + + mp_pci_tree = + (struct hw_mp_pci_tree*)(mp_pci_tree + + sizeof(struct hw_mp_pci_tree)); + } + + mp_pci_tree->d_magic = SYS_PCI_DEV_MAGIC; + + memncpy(mp_pci_tree->d_name, name, strlen(name)); + + mp_pci_tree->d_off_struct = struct_ptr; + mp_pci_tree->d_sz_struct = struct_sz; + mp_pci_tree->d_off_props = 0; + mp_pci_tree->d_sz_props = 0; + mp_pci_tree->d_version = SYS_PCI_VERSION; + + mp_pci_tree->d_next_sibling = + (mp_pci_num_t)(mp_pci_tree + sizeof(struct hw_mp_pci_tree)); + mp_pci_tree->d_first_node = (mp_pci_num_t)mp_latest_tree; + + mp_latest_tree = mp_pci_tree; + mp_last_tree = mp_pci_tree; + + mp_put_string(">> Append device: "); + mp_put_string(name); + mp_put_string("\r\n"); + + return yes; +} diff --git a/src/coreboot-print-name.c b/src/coreboot-print-name.c new file mode 100644 index 0000000..0ce81f8 --- /dev/null +++ b/src/coreboot-print-name.c @@ -0,0 +1,28 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <lib/boot.h> + +/// @brief Print firmware name. +/// @param +void mp_print_name(void) +{ +#ifdef __COMPILE_POWERPC__ + mp_put_string(">> CoreBoot for POWER.\r\n"); +#endif // __COMPILE_POWERPC__ + +#ifdef __COMPILE_ARM64__ + mp_put_string(">> CoreBoot for ARM64.\r\n"); +#endif // __COMPILE_POWERPC__ + +#ifdef __COMPILE_AMD64__ + mp_put_string(">> CoreBoot for AMD64.\r\n"); +#endif // __COMPILE_POWERPC__ + +#ifdef __COMPILE_RISCV__ + mp_put_string(">> CoreBoot for RISC-V.\r\n"); +#endif // __COMPILE_POWERPC__ +} diff --git a/src/coreboot-start.c b/src/coreboot-start.c new file mode 100644 index 0000000..295ffee --- /dev/null +++ b/src/coreboot-start.c @@ -0,0 +1,136 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <lib/mp-bit.h> +#include <lib/partition-map.h> +#include <lib/pci-tree.h> +#include <lib/boot.h> + +/// BUGS: 0 + +///////////////////////////////////////////////////////////////////////////////////////// + +// @name start.c // + +// @brief Start file // This is where the firmware starts it's initialization // +// code. // + +// @author Amlal EL Mahrouss // + +///////////////////////////////////////////////////////////////////////////////////////// + +extern void mp_append_scsi_tree(void); +extern void mp_append_video_tree(void); + +extern void mp_start_context(uintptr_t); +extern void mp_start_rom(void); + +extern int mp_boot_processor_ready; + +/// @brief hardware thread counter. +uint64_t __mp_hart_counter = 0UL; + +/// @brief Start executing the firmware. +/// @param +void mp_start_exec(void) +{ + ++__mp_hart_counter; + + uintptr_t hart = __mp_hart_counter; + + mp_sync_synchronize(); + + // let the hart 0 init our stuff. + if (hart == 1) + { + mp_put_string("TQ> Welcome to CoreBoot, (c) Amlal EL Mahrouss. Built the "); + mp_put_string(__DATE__); + mp_put_string("\r\r\n"); + +#ifdef __COMPILE_POWERPC__ + mp_put_string("TQ> CPU: PowerPC 64-bit Based SoC.\r\r\n"); +#endif // __COMPILE_POWERPC__ + +#ifdef __COMPILE_AMD64__ + mp_put_string("TQ> CPU: x64 Based SoC.\r\r\n"); +#endif // __COMPILE_AMD64__ + +#ifdef __COMPILE_ARM64__ + mp_put_string("TQ> CPU: AArch64 Based SoC.\r\r\n"); +#endif // __COMPILE_ARM64__ + +#ifdef __COMPILE_ARM32__ + mp_put_string("TQ> CPU: AArch32 Based SoC.\r\r\n"); +#endif // __COMPILE_ARM64__ + +#ifdef __COMPILE_RISCV__ + mp_put_string("TQ> CPU: RV64 Based SoC.\r\r\n"); +#endif // __COMPILE_RISCV__ + } + + /// @brief Boots here if LX header matches what we except. + + volatile struct mp_boot_header* boot_hdr = + (volatile struct mp_boot_header*)(SYS_FLASH_BASE_ADDR); + + /** + boot if: + - ident matches. + - version matches. + */ + + if (boot_hdr->h_mag[0] == SYS_BOOT_MAG_0 && + boot_hdr->h_mag[1] == SYS_BOOT_MAG_1) + { + if (boot_hdr->h_revision != SYS_BOOT_VER) + { + if (hart == 1) + { + mp_put_string("TQ> Can't Boot the Stage2, invalid signature. (CB0003)\r\n"); + } + } + else + { + if (hart == 1) + { + mp_put_string("TQ> Executing Stage2: "); + mp_put_string((const char*)boot_hdr->h_name); + mp_put_char('\r'); + mp_put_char('\n'); + + // printf("TQ> address: %x\n", boot_hdr->h_start_address); + } + + if (boot_hdr->h_start_address != 0) + { + mp_boot_processor_ready = 1; + mp_start_context(boot_hdr->h_start_address); + } + + mp_put_string("TQ> Stage2 has returned? (CB0002)\r\n"); + } + } + else + { + if (hart == 1) + { + mp_put_string("TQ> Can't boot to Stage2. (CB0001)\r\n"); + } + } + + /// end of TODO + + if (hart > 1) + { + while (1) + { + if (__mp_hart_counter == 0) + { + mp_restart_machine(); + } + } + } +} diff --git a/src/coreboot-string.c b/src/coreboot-string.c new file mode 100644 index 0000000..88b5efa --- /dev/null +++ b/src/coreboot-string.c @@ -0,0 +1,185 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +/** + * @file coreboot-string.c + * @author Amlal EL Mahrouss (amlal@el-mahrouss-logic.com) + * @brief string library. + * @version 0.1 + * @date 2024-01-16 + * + * @copyright Copyright (c) 2024 Amlal EL Mahrouss + * + */ + +#include <lib/string.h> + +/// BUGS: 0 + +size_t strncmp(const char* src, const char* cmp, size_t size) +{ + if (src == nil) + return 0; + + int32_t counter = 0; + + for (size_t index = 0; index < size; ++index) + { + if (src[index] != cmp[index]) + ++counter; + } + + return counter; +} + +void* memset(void* ptr, const char value, size_t len) +{ + if (ptr == nil) + return nil; + + char* start = ptr; + + while (len) + { + *start = value; + ++start; + + --len; + } + + return (void*)start; +} + +void* memmove(void* dest, const void* src, size_t len) +{ + memncpy(dest, src, len); + return dest; +} + +size_t memcpy(void* dst, const void* src) +{ + if (src == nil || dst == nil) + return 0; + + const char* src_chr = src; + char* dst_chr = dst; + size_t index = 0; + size_t len = strlen(src); + + while (index < len) + { + dst_chr[index] = src_chr[index]; + ++index; + } + + return 0; +} + +/* @brief unoptimized memcpy, TODO: use isa specific memcpy. */ +size_t memncpy(void* dst, const void* src, size_t len) +{ +#if __OL == 3 && defined(__riscv) + riscv_memncpy(dst, src, len); +#else + + if (src == nil || dst == nil) + return 0; + + const char* src_chr = src; + char* dst_chr = dst; + size_t index = 0; + + while (index < len) + { + dst_chr[index] = src_chr[index]; + ++index; + } + + return 0; +#endif +} + +size_t strlen(const char* str) +{ + if (*str == 0) + return 0; + + size_t len = 0; + while (str[len] != '\0') + ++len; + + return len; +} + +size_t strnlen(const char* str, size_t len) +{ + size_t cnt = 0; + + while (len > cnt) + { + ++cnt; + + if (str[cnt] == '\0') + return (size_t)-1; + } + + return len; +} + +void strreverse(char* s) +{ + if (s == nil) + return; + if (*s == '\0') + return; + + char *first, *last, temp; + + first = s; + last = s + strlen(s) - 1; + + while (first != last) + { + temp = *first; + *(first++) = *last; + *(last--) = temp; + } +} + +char* strchr(char* str, const char chr) +{ + while (*str != chr) + { + ++str; + + if (*str == 0) + return nil; + } + + return str; +} + +/// @brief Compare two strings. +/// @param src source string +/// @param cmp string to compare. +/// @return +size_t strcmp(caddr_t src, caddr_t cmp) +{ + if (src == null || *src == 0) + return 1; + if (cmp == null || *cmp == 0) + return 1; + + int32_t counter = 0; + + for (size_t index = 0; src[index] != 0; ++index) + { + if (cmp[index] != src[index]) + ++counter; + } + + return counter; +} diff --git a/src/custom_hw/coreboot-flash.c b/src/custom_hw/coreboot-flash.c new file mode 100644 index 0000000..1416bc3 --- /dev/null +++ b/src/custom_hw/coreboot-flash.c @@ -0,0 +1,10 @@ +/* ------------------------------------------- + +Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <lib/mp-bit.h> +#include <lib/partition-map.h> +#include <lib/pci-tree.h> +#include <lib/boot.h> diff --git a/src/ppc64/.gdbinit b/src/ppc64/.gdbinit new file mode 100644 index 0000000..bdf82ae --- /dev/null +++ b/src/ppc64/.gdbinit @@ -0,0 +1,3 @@ +set disassemble-next-line on
+target remote : 1234
+
diff --git a/src/ppc64/.gitkeep b/src/ppc64/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/ppc64/.gitkeep diff --git a/src/ppc64/linkscript.ld b/src/ppc64/linkscript.ld new file mode 100644 index 0000000..da9209c --- /dev/null +++ b/src/ppc64/linkscript.ld @@ -0,0 +1,15 @@ +ENTRY(mp_reset_vector)
+SECTIONS
+{
+ . = 0xf00000;
+
+ .startup . : { ppc64-boot.o(.text) }
+ .text : { *(.text) }
+ .data : { *(.data) }
+ .bss : { *(.bss COMMON) }
+ . = ALIGN(8);
+ . = . + 0x1000; /* 4kB of stack memory */
+ stack_top = .;
+
+ PROVIDE(mp_memory_end = .);
+}
diff --git a/src/ppc64/makefile b/src/ppc64/makefile new file mode 100644 index 0000000..9098a05 --- /dev/null +++ b/src/ppc64/makefile @@ -0,0 +1,66 @@ + #
+ # ========================================================
+ #
+ # CoreBoot
+ # Date Added: 08/11/2023
+ # Copyright 2024, ZKA Technologies, all rights reserved.
+ #
+ # ========================================================
+ #
+
+CC=powerpc-linux-gnu-gcc
+AS=powerpc-linux-gnu-as
+
+FIRMWARE=boot.rom
+
+FLAGS=-c -mcpu=e5500 -D__COMPILE_POWERPC__ -I../../ -Wall -c -nostdlib -ffreestanding -fno-builtin \
+ -D__BSTRICT__ -D__BDEBUG__
+
+C_SRC=$(wildcard *.c) $(wildcard ../*.c) -c
+
+AS_FLAGS= -c -I../../
+
+LD=powerpc-linux-gnu-ld
+OBJ=*.o
+FLAGS_LD= --script=linkscript.ld -o core-boot.elf -nostdlib
+
+EMU=qemu-system-ppc64
+EMU_FLAGS= -drive file=epm.img,media=disk,snapshot=off,format=raw \
+ -device virtio-scsi-pci,id=scsi -smp 4 -device VGA -cpu e5500 -d guest_errors,unimp \
+ -M ppce500 -bios $(FIRMWARE) -s
+
+WAIT=sleep 1
+
+IMG_CMD=qemu-img create -f qcow2 epm.img 256M
+
+.PHONY: all
+all: firmware-link
+ @echo "[CoreBoot] build done."
+
+.PHONY: firmware-link
+firmware-link: firmware-compile
+ $(LD) $(OBJ) $(FLAGS_LD)
+ $(IMG_CMD)
+ qemu-img create -f raw boot.rom 512K
+ dd if=core-boot.elf of=boot.rom bs=1 seek=0 conv=notrunc
+
+# compile firmware
+.PHONY: firmware-compile
+firmware-compile:
+ $(CC) $(FLAGS) $(C_SRC)
+ $(AS) $(AS_FLAGS) ppc64-boot.S -o ppc64-boot.o
+
+# launch qemu rule
+.PHONY: run
+run:
+ $(EMU) $(EMU_FLAGS)
+
+# launch qemu with attached debugger
+.PHONY: run-dbg
+run-dbg:
+ $(EMU) $(EMU_FLAGS)
+
+# remove object files
+.PHONY: clean
+clean:
+ rm -f $(wildcard *.o) $(wildcard *.elf) $(wildcard *.rom) $(wildcard *.epm)
diff --git a/src/ppc64/ppc64-boot.S b/src/ppc64/ppc64-boot.S new file mode 100644 index 0000000..f28b4f3 --- /dev/null +++ b/src/ppc64/ppc64-boot.S @@ -0,0 +1,56 @@ +.balign 4
+.section .text
+
+.global mp_reset_vector
+
+mp_reset_vector:
+ bl .Laddr /* get current address */
+.Laddr:
+ mflr 4 /* real address of .Laddr */
+ lwz 0,(.Lstk-.Laddr)(4) /* stack address location */
+ mr 1,0 /* use user defined stack */
+
+ addi 1,1,-4 /* make sure we don't overwrite debug mem */
+ lis 0,0
+ stw 0,0(1) /* clear back chain */
+ stwu 1,-64(1) /* push another stack frame */
+
+ /* Let her rip */
+
+ bl mp_init_hw
+ /* finally execute the firmware */
+ bl mp_start_exec
+ /* return value from main is argument to exit */
+ bl mp_reset_vector
+
+ trap
+
+.global mp_start_rom
+.global mp_start_context
+.global mp_boot_processor_ready
+
+.equ SYS_BOOT_ADDR, 0x1030000
+
+mp_start_rom:
+ lis 3, SYS_BOOT_ADDR@h
+ addi 3, 3, SYS_BOOT_ADDR@l
+
+ blr
+
+mp_start_context:
+ li 4, 0
+ cmp 0, 0, 4, 3
+ blt run_context
+ mr 3, 31
+ blr
+run_context:
+ blr /* r3 is filled here */
+
+.Lstk:
+/* .long __stack*/
+ .long stack_top
+
+.data
+
+mp_boot_processor_ready:
+ .word 0
diff --git a/src/ppc64/ppc64-err.c b/src/ppc64/ppc64-err.c new file mode 100644 index 0000000..ebf8452 --- /dev/null +++ b/src/ppc64/ppc64-err.c @@ -0,0 +1,23 @@ +/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <lib/boot.h>
+
+/// BUGS: 0
+
+/// @brief Goes into a panic state.
+/// @param reason why?
+void mp_panic(const char* reason)
+{
+ mp_put_string("Error: ");
+ mp_put_string(reason);
+ mp_put_char('\n');
+
+ while (yes)
+ {
+ (void)0;
+ }
+}
diff --git a/src/ppc64/ppc64-hal.c b/src/ppc64/ppc64-hal.c new file mode 100644 index 0000000..827471b --- /dev/null +++ b/src/ppc64/ppc64-hal.c @@ -0,0 +1,97 @@ +/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <lib/ppc64/mmu.h>
+#include <lib/ppc64/processor.h>
+
+#include <lib/pci-tree.h>
+#include <lib/boot.h>
+
+void mp_write_tlb(uint32_t mas0, uint32_t mas1, uint32_t mas2, uint32_t mas3, uint32_t mas7)
+{
+ mtspr(MAS0, mas0);
+ mtspr(MAS1, mas1);
+ mtspr(MAS2, mas2);
+ mtspr(MAS3, mas3);
+ mtspr(MAS7, mas7);
+
+ mp_flush_tlb();
+}
+
+void mp_set_tlb(uint8_t tlb,
+ uint32_t epn,
+ uint64_t rpn,
+ uint8_t perms,
+ uint8_t wimge,
+ uint8_t ts,
+ uint8_t esel,
+ uint8_t tsize,
+ uint8_t iprot)
+{
+ if ((mfspr(SPRN_MMUCFG) & MMUCFG_MAVN) == MMUCFG_MAVN_V1 && (tsize & 1))
+ {
+ // this mmu-version does not allow odd tsize values
+ return;
+ }
+ uint32_t mas0 = FSL_BOOKE_MAS0(tlb, esel, 0);
+ uint32_t mas1 = FSL_BOOKE_MAS1(1, iprot, 0, ts, tsize);
+ uint32_t mas2 = FSL_BOOKE_MAS2(epn, wimge);
+ uint32_t mas3 = FSL_BOOKE_MAS3(rpn, 0, perms);
+ uint32_t mas7 = FSL_BOOKE_MAS7(rpn);
+
+ mp_write_tlb(mas0, mas1, mas2, mas3, mas7);
+}
+
+/// @brief Init hardware before jumping to kernel.
+/// @param
+void mp_init_hw(void)
+{
+
+ /// amlal:
+ /// map VGA framebuffer
+ mp_set_tlb(0, SYS_FRAMEBUFFER_ADDR, /* v_addr, 0x0000A0000 */
+ 0x0000A000, /* p_addr. 0x0000A0000 */
+ MAS3_SW | MAS3_SR, /* perm type=TLB_MAP_IO */
+ MAS2_I | MAS2_G, /* wimge type=TLB_MAP_IO */
+ 0, /* ts i.e AS=0 */
+ 1, /* esel (a.k.a tlb_index*/
+ BOOKE_PAGESZ_64K, /* tsize ie 2^10kB ie 1MB */
+ 1);
+
+ // map ccsrbar and uart.
+ // at start we execute from esel = 0, so chose something else..
+ mp_set_tlb(1, SYS_UART_BASE, /* v_addr 0xe0000000 see qemu-ppce500.h */
+ 0xfe0000000, /* p_addr. 0xfe0000000 */
+ MAS3_SW | MAS3_SR, /* perm type=TLB_MAP_IO */
+ MAS2_I | MAS2_G, /* wimge type=TLB_MAP_IO */
+ 0, /* ts i.e AS=0 */
+ 2, /* esel (a.k.a tlb_index*/
+ BOOKE_PAGESZ_1M, /* tsize ie 2^10kB ie 1MB */
+ 1);
+
+ /// amlal:
+ /// map pci base for kernel
+ mp_set_tlb(0, SYS_BASE_ADDRESS, /* v_addr, 0xFE008000 */
+ 0xFE0008000, /* p_addr. 0xfe0000000 */
+ MAS3_SW | MAS3_SR, /* perm type=TLB_MAP_IO */
+ MAS2_I | MAS2_G, /* wimge type=TLB_MAP_IO */
+ 0, /* ts i.e AS=0 */
+ 3, /* esel (a.k.a tlb_index*/
+ BOOKE_PAGESZ_1M, /* tsize ie 2^10kB ie 1MB */
+ 1);
+
+ mp_pci_init_tree();
+
+ mp_pci_append_tree("@fb", SYS_FRAMEBUFFER_ADDR, 0x0);
+ mp_pci_append_tree("@mbci", 0x0, 0x0);
+ mp_pci_append_tree("@serial", SYS_UART_BASE, 0);
+ mp_pci_append_tree("@pci", SYS_BASE_ADDRESS, 0x0);
+}
+
+void mp_flush_tlb(void)
+{
+ asm volatile("isync;tlbwe;msync;isync");
+};
diff --git a/src/ppc64/ppc64-uart.c b/src/ppc64/ppc64-uart.c new file mode 100644 index 0000000..23aeebd --- /dev/null +++ b/src/ppc64/ppc64-uart.c @@ -0,0 +1,48 @@ +/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <lib/string.h>
+#include <lib/boot.h>
+
+/// BUGS: 0
+
+#define SYS_NS16550_COM1 (SYS_UART_BASE + 0x4500)
+#define SYS_NS16550_COM2 (SYS_UART_BASE + 0x4600)
+
+volatile ascii_char_t* const UART0DR = (ascii_char_t*)SYS_NS16550_COM1;
+
+/* this file handles the UART */
+
+/// @brief Get character from UART.
+/// @param
+/// @return
+utf_char_t mp_get_char(void)
+{
+ while (!(*(((volatile uint8_t*)UART0DR) + 0x05) & 0x01))
+ ;
+ return (utf_char_t)*UART0DR;
+}
+
+/// @brief Put character into UART.
+/// @param ch
+void mp_put_char(utf_char_t ch)
+{
+ *UART0DR = (ascii_char_t)(ch);
+}
+
+/// @brief Put string in UART.
+/// @param text the input text.
+size_t mp_put_string(const char* text)
+{
+ while (*text != '\0')
+ { /* Loop until end of string */
+
+ mp_put_char(*text); /* Transmit char */
+
+ text++; /* Next char */
+ }
+ return 0;
+}
diff --git a/src/rv64/.gdbinit b/src/rv64/.gdbinit new file mode 100644 index 0000000..c835b7f --- /dev/null +++ b/src/rv64/.gdbinit @@ -0,0 +1,3 @@ +set disassemble-next-line on +target remote : 1234 + diff --git a/src/rv64/linkscript.ld b/src/rv64/linkscript.ld new file mode 100644 index 0000000..0a82477 --- /dev/null +++ b/src/rv64/linkscript.ld @@ -0,0 +1,46 @@ +ENTRY(mp_reset_vector); + +. = 0x80000000; + +SECTIONS { + .text : ALIGN(4K) { + PROVIDE(_text_start = .); + + *(.init); + *(.text); + + PROVIDE(_text_end = .); + } + + PROVIDE(mp_global_pointer = .); + + .bss : ALIGN(4K) { + PROVIDE(_bss_start = .); + + *(.bss); + + PROVIDE(_bss_end = .); + } + + .rodata : ALIGN(4K) { + PROVIDE(_rodata_start = .); + + *(.rodata); + + PROVIDE(_rodata_end = .); + } + + + .data : ALIGN(4K) { + PROVIDE(_data_start = .); + + *(.data); + + PROVIDE(_data_end = .); + } + + PROVIDE(mp_stack_end = . + 0x1000); + + PROVIDE(mp_memory_end = .); + PROVIDE(mp_boot_processor_ready = . + 0x4); +} diff --git a/src/rv64/makefile b/src/rv64/makefile new file mode 100644 index 0000000..0bd8a28 --- /dev/null +++ b/src/rv64/makefile @@ -0,0 +1,53 @@ + # + # ======================================================== + # + # CoreBoot + # Date Added: 08/11/2023 + # Copyright 2024, ZKA Technologies, all rights reserved. + # + # ======================================================== + # + +CC=riscv64-unknown-elf-gcc +FIRMWARE=core-boot.elf +FLAGS=-D__COMPILE_RISCV__ -I../../ -Wall -c -nostdlib -ffreestanding -fno-builtin -D__BSTRICT__ -D__BDEBUG__ -O0 -mcmodel=medany +C_SRC= $(wildcard *.s) $(wildcard *.c) $(wildcard ../*.c) -c + +CXX=riscv64-unknown-elf-g++ +CXX_SRC= $(wildcard *.cc) $(wildcard ../*.cc) -c + +LD=riscv64-unknown-elf-ld +OBJ=*.o +FLAGS_LD= --script=linkscript.ld -o core-boot.elf + +EMU=qemu-system-riscv64 -m 4G -smp 2 -machine virt -bios $(FIRMWARE) -d int -device VGA + +.PHONY: all +all: firmware-link + @echo "[CoreBoot] Done." + +# link (make firmware) +.PHONY: firmware-link +firmware-link: firmware-compile + $(LD) $(OBJ) $(FLAGS_LD) + +# compile firmware +.PHONY: firmware-compile +firmware-compile: + $(CC) $(FLAGS) $(C_SRC) + $(CXX) -ffreestanding -fno-rtti -fno-exceptions $(FLAGS) $(CXX_SRC) + +# launch qemu rule +.PHONY: run +run: + $(EMU) + +# launch qemu with attached debugger +.PHONY: run-dbg +run-dbg: + $(EMU) -S + +# remove object files +.PHONY: clean +clean: + rm -f $(wildcard *.o) $(wildcard *.elf) $(wildcard *.rom) $(wildcard *.epm) diff --git a/src/rv64/rv64-api.s b/src/rv64/rv64-api.s new file mode 100644 index 0000000..f7427de --- /dev/null +++ b/src/rv64/rv64-api.s @@ -0,0 +1,16 @@ +# ==================================== +# +# Amlal EL Mahrouss CoreBoot +# (c) Amlal EL Mahrouss all rights reserved. +# +# Purpose: Assembler API for RISC-V +# +# ==================================== + +.balign 4 +.global mp_flush_tlb + +mp_flush_tlb: + sfence.vma + + ret diff --git a/src/rv64/rv64-boot.s b/src/rv64/rv64-boot.s new file mode 100644 index 0000000..8fca5de --- /dev/null +++ b/src/rv64/rv64-boot.s @@ -0,0 +1,114 @@ +/* + * ======================================================== + * + * CoreBoot + * Copyright 2024, Amlal EL Mahrouss, all rights reserved. + * + * Purpose: Startup code for RISC-V. + * + * ======================================================== + */ + + +/* Code starts at 8M, everything below is memory mapped hardware. */ + +.option norvc + +.extern mp_start_exec + +.global mp_reset_vector +.global mp_hart_present + +.section .init +.align 4 + +mp_reset_vector: + .cfi_startproc + + csrr t0, mhartid + beqz t0, mp_start_exec_asm + + j mp_start_other + + .cfi_endproc + +mp_start_exec_asm: + lw t0, __mp_hart_counter + lw t1, mp_boot_processor_ready + + not t0, t0 + + addi t1, zero, 1 + +.option push +.option norelax + + la gp, mp_global_pointer + +.option pop + + la sp, mp_stack_end + + la t5, _bss_start + la t6, _bss_end + +crt0_bss_clear: + sd zero, (t5) + addi t5, t5, 8 + bgeu t5, t6, crt0_bss_clear + + + j mp_start_exec + j mp_hang + +mp_start_other: + lw t1, mp_boot_processor_ready + +mp_start_other_wait: + beq t1, zero, mp_start_other_wait + + la t0, mp_stack_list + ld t1, mp_stack_align + mv sp, t0 + add t0, zero, t1 + j mp_hang + +.global mp_start_rom +.global mp_start_context + +mp_start_context: + mv ra, zero + add ra, zero, a1 + mret + +.equ SYS_BOOT_ADDR, 0x80020000 + +mp_start_rom: + li x5, SYS_BOOT_ADDR + mv ra, zero + add ra, zero, t0 + mret + +mp_hang: + j mp_start_exec +L0: + wfi + j L0 + +.bss + +.align 4 +mp_hart_present: + .long 0 + +.data + +.align 4 +mp_stack_list: + .long mp_memory_end + +mp_stack_align: + .word 0x8000 + +__mp_max_harts: + .word 2 diff --git a/src/rv64/rv64-err.c b/src/rv64/rv64-err.c new file mode 100644 index 0000000..19be090 --- /dev/null +++ b/src/rv64/rv64-err.c @@ -0,0 +1,23 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <lib/boot.h> + +/// BUGS: 0 + +/// @brief Goes into a panic state. +/// @param reason why? +void mp_panic(const char* reason) +{ + mp_put_string("Error: "); + mp_put_string(reason); + mp_put_char('\n'); + + while (yes) + { + asm volatile("wfi"); + } +} diff --git a/src/rv64/rv64-uart.c b/src/rv64/rv64-uart.c new file mode 100644 index 0000000..ea896bc --- /dev/null +++ b/src/rv64/rv64-uart.c @@ -0,0 +1,54 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <lib/boot.h> +#include <lib/string.h> + +/// BUGS: 0 + +/* this file handles the UART */ + +static uint8_t* mp_uart_ptr = (uint8_t*)SYS_UART_BASE; + +utf_char_t mp_get_char(void) +{ + uintptr_t ptr = SYS_UART_BASE; + while (!(*(((volatile uint8_t*)ptr) + 0x05) & 0x01)) + ; + + return (utf_char_t)*mp_uart_ptr; +} + +// we need that one, to avoid sending mutliple chars to UART. +static boolean mp_locked_put_char = no; + +void mp_put_char(utf_char_t ch) +{ + while (mp_locked_put_char) + { + } + + mp_locked_put_char = yes; + *mp_uart_ptr = ch; + mp_locked_put_char = no; +} + +/// @brief UART put string +/// @param text the input text. +size_t mp_put_string(const char* text) +{ + if (text == nil) + return 0; + + size_t i = 0; + + for (; i < strlen(text); i++) + { + mp_put_char(text[i]); + } + + return i; +} diff --git a/src/x86s/.gitkeep b/src/x86s/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/x86s/.gitkeep |
