summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorAmlal <amlal.elmahrouss@icloud.com>2025-01-21 20:32:19 +0100
committerAmlal <amlal.elmahrouss@icloud.com>2025-01-21 20:32:19 +0100
commit046d884b50c32cacd3523071541e7e38241083f3 (patch)
tree92ce6fd53e0c031c569270b04aefa8fc0aa1e074 /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')
-rw-r--r--src/32x0/32x0_boot.32x42
-rw-r--r--src/64x0/.gitkeep0
-rw-r--r--src/64x0/64x0_boot.64x13
-rw-r--r--src/amd64/amd64-boot.asm40
-rw-r--r--src/amd64/amd64-test.asm19
-rwxr-xr-xsrc/amd64/amd64.sh4
-rw-r--r--src/arm64/arm64-30pin.c13
-rw-r--r--src/arm64/arm64-boot.S15
-rw-r--r--src/arm64/arm64-err.c23
-rw-r--r--src/arm64/arm64-start-context.S17
-rw-r--r--src/arm64/arm64-uart.c54
-rw-r--r--src/arm64/makefile69
-rw-r--r--src/arm64/script.lds14
-rw-r--r--src/compile_flags.txt3
-rw-r--r--src/coreboot-ahci-driver.c108
-rw-r--r--src/coreboot-cpu-api.c22
-rw-r--r--src/coreboot-cxx-abi.cc91
-rw-r--r--src/coreboot-partition-map-parse.c58
-rw-r--r--src/coreboot-partition-map.c37
-rw-r--r--src/coreboot-pci-tree.c106
-rw-r--r--src/coreboot-print-name.c28
-rw-r--r--src/coreboot-start.c136
-rw-r--r--src/coreboot-string.c185
-rw-r--r--src/custom_hw/coreboot-flash.c10
-rw-r--r--src/ppc64/.gdbinit3
-rw-r--r--src/ppc64/.gitkeep0
-rw-r--r--src/ppc64/linkscript.ld15
-rw-r--r--src/ppc64/makefile66
-rw-r--r--src/ppc64/ppc64-boot.S56
-rw-r--r--src/ppc64/ppc64-err.c23
-rw-r--r--src/ppc64/ppc64-hal.c97
-rw-r--r--src/ppc64/ppc64-uart.c48
-rw-r--r--src/rv64/.gdbinit3
-rw-r--r--src/rv64/linkscript.ld46
-rw-r--r--src/rv64/makefile53
-rw-r--r--src/rv64/rv64-api.s16
-rw-r--r--src/rv64/rv64-boot.s114
-rw-r--r--src/rv64/rv64-err.c23
-rw-r--r--src/rv64/rv64-uart.c54
-rw-r--r--src/x86s/.gitkeep0
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