Skip to content

Commit

Permalink
Merge branch 'badgeteam:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
geekyjoyce72 authored Apr 22, 2024
2 parents fe8752c + 4d76651 commit 6e49ce5
Show file tree
Hide file tree
Showing 46 changed files with 1,027 additions and 260 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ build/
firmware/
app/
root/
.venv/
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@

MAKEFLAGS += --silent
SHELL := /usr/bin/env bash
OUTPUT ?= $(shell pwd)/root

.PHONY: all prepare openocd gdb flash monitor clean-all clean build clang-format-check clang-tidy-check

all: build

prepare:
python -m venv .venv
.venv/bin/pip install esptool
git submodule update --init

build:
Expand Down
26 changes: 9 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# BadgerOS

BadgerOS is the operating system currently in development for the upcoming MCH2025<sup>(1)</sup> badge.
BadgerOS is the operating system currently in development for the upcoming [WHY2025](https://why2025.org/) badge.
The goal is the allow future badge users to get both the performance that native apps can afford as well as the portability made possible by this OS.

_(1) MCH2025 is a preliminary name, MCH2025 is an event that will be organised by IFCAT in 2025._

## Index
- [Contributing](#contributing)
- [Prerequisites](#prerequisites)
Expand All @@ -28,40 +26,34 @@ After that, see [Project structure](./docs/project_structure.md) for reference a


# Prerequisites

To build BadgerOS:

- `git`
- `build-essential`
- `cmake`
- `riscv32-unknown-elf-gcc` ([RISC-V collab toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain))
- `gcc-riscv64-linux-gnu`
- `python3`

To flash to an ESP:

- `esptool.py` from [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/#installation)

Optional recommends:

- `picocom`



# Build system

The build system is based on Makefiles and CMake.
The following commands can be used to perform relevant actions:

To select target chip, choose one of:
- `export BADGEROS_PORT=esp32p4`
- `export BADGEROS_PORT=esp32c6` (default)

To build: `make build`

To remove build files: `make clean`

To flash to an ESP: `source <path to ESP-IDF>/export.sh` (once) `make flash` (every time you flash)
To flash to an ESP: `make flash`

To open picocom: `make monitor`

To build, flash and open picocom: `make` or `make all`

To check cody style: `make clang-format-check` (code formatting) and `make clang-tidy-check` (programming guidelines)
To check code style: `make clang-format-check` (code formatting) and `make clang-tidy-check` (programming guidelines)

Build artifacts will be put into the `kernel/firmware` folder once the project was successfully built.

Expand Down
1 change: 1 addition & 0 deletions files/init/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ int main(int argc, char **argv) {
else
print("No read :c\n");
int volatile *mem = syscall_mem_alloc(0, 32, 0, MEMFLAGS_RW);
*mem = 3;
syscall_mem_dealloc(mem);
return 0;
}
16 changes: 10 additions & 6 deletions kernel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ endif()

# Set the C compiler
if(NOT DEFINED CMAKE_C_COMPILER)
find_program(CMAKE_C_COMPILER NAMES riscv32-unknown-linux-gnu-gcc riscv32-linux-gnu-gcc riscv64-unknown-linux-gnu-gcc riscv64-linux-gnu-gcc REQUIRED)
find_program(CMAKE_C_COMPILER NAMES riscv32-badgeros-linux-gnu-gcc riscv32-unknown-linux-gnu-gcc riscv32-linux-gnu-gcc riscv64-unknown-linux-gnu-gcc riscv64-linux-gnu-gcc REQUIRED)
message("Detected RISC-V C compiler as '${CMAKE_C_COMPILER}'")
else()
message("Using compiler '${CMAKE_C_COMPILER}' from environment")
endif()

# Determine the compiler prefix
get_filename_component(compiler_name "${CMAKE_C_COMPILER}" NAME)
string(REGEX MATCH "^([A-Za-z0-9_]+\-)*" BADGER_COMPILER_PREFIX "${compiler_name}")
find_program(BADGER_OBJCOPY NAMES "${BADGER_COMPILER_PREFIX}objcopy" REQUIRED)
string(REGEX MATCH "^([A-Za-z0-9_]+\-)*" BADGER_COMPILER_PREFIX "${compiler_name}")
find_program(BADGER_OBJCOPY NAMES "${BADGER_COMPILER_PREFIX}objcopy" REQUIRED)
find_program(BADGER_OBJDUMP NAMES "${BADGER_COMPILER_PREFIX}objdump" REQUIRED)

# Include port-specific.
Expand All @@ -38,8 +38,10 @@ include(cpu/riscv/CMakeLists.txt)
# LTO is disabled due to GCC bugs inserting calls to memcpy everywhere
set(common_compiler_flags
-ffreestanding # We do not compile against an OS.
-static -fno-pic # Disable PIC
-fno-exceptions
-march=${target_arch} # Selects the target CPU.
-mabi=${target_abi} # Selects target ABI
-mabi=${target_abi} # Selects target ABI
-nodefaultlibs -nostdlib # Do not link any default libraries like libgcc or libc.
-O2 # Optimize the code.
-ggdb # Generate debug information in default extended format.
Expand All @@ -48,10 +50,12 @@ set(common_compiler_flags
-std=gnu11 # We use the C11 standard
-DBADGEROS_KERNEL # Tell the code we're building for the kernel
-DBADGEROS_PORT_${BADGEROS_PORT}
-DBADGEROS_PORT="${BADGEROS_PORT}"
-DBADGEROS_MALLOC_DEBUG_LEVEL=3 # Malloc debug level set to WARN
-DSOFTBIT # Turn on our emulated bit operations
-fno-omit-frame-pointer # Always use frame pointer
-ffunction-sections
-fno-stack-protector
-fno-exceptions
)
if("${CMAKE_BUILD_TYPE}" MATCHES "Release")
Expand All @@ -60,7 +64,7 @@ else()
message("Building in debug mode")
set(common_compiler_flags ${common_compiler_flags}
-fsanitize=undefined # Adds sanitizer for undefined behaviour.
-fsanitize-undefined-trap-on-error # Invoke a trap instruction instead of calling into the UBsan runtime.
-fsanitize-undefined-trap-on-error
)
endif()

Expand Down Expand Up @@ -141,7 +145,7 @@ add_custom_command(
# Proxy target to allow installation of the bin file
add_custom_target(badger-os.bin.target ALL DEPENDS badger-os.bin)

# Also build a dump file that is put into the
# Also build a dump file that is put into the
add_custom_target(
badger-os.elf.disasm
ALL
Expand Down
20 changes: 1 addition & 19 deletions kernel/cpu/riscv/include/cpu/interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,6 @@

#include <stdbool.h>

// Enable/disable an internal interrupt.
// Returns whether the interrupt was enabled.
static inline bool irq_ch_enable(int int_irq, bool enable) {
long mask = 1 << int_irq;
if (enable) {
asm volatile("csrrs %0, mie, %0" : "+r"(mask));
} else {
asm volatile("csrrc %0, mie, %0" : "+r"(mask));
}
return ((mask) >> int_irq) & 1;
}

// Query whether an internal interrupt is enabled.
static inline bool irq_ch_enabled(int int_irq) {
long mask;
asm("csrr %0, mie" : "=r"(mask));
return ((mask) >> int_irq) & 1;
}

// Globally enable/disable interrupts in this CPU.
// Returns whether interrupts were enabled.
static inline bool irq_enable(bool enable) {
Expand All @@ -37,6 +18,7 @@ static inline bool irq_enable(bool enable) {
}
return (mask >> RISCV_STATUS_MIE_BIT) & 1;
}

// Query whether interrupts are enabled in this CPU.
static inline bool irq_enabled() {
long mask;
Expand Down
9 changes: 8 additions & 1 deletion kernel/cpu/riscv/include/cpu/isr_ctx.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ STRUCT_FIELD_PTR(isr_ctx_t, sched_thread_t, thread, 164)
// Thread is a kernel thread.
// If true, the thread is run in M-mode, otherwise it is run in U-mode.
STRUCT_FIELD_WORD(isr_ctx_t, is_kernel_thread, 168)
// Use SP as the stack, not the ISR stack.
STRUCT_FIELD_WORD(isr_ctx_t, use_sp, 172)
STRUCT_END(isr_ctx_t)


Expand All @@ -75,7 +77,7 @@ enum {
STACK_ALIGNMENT = 16,
};

// Get the current kernel context.
// Get the current ISR context.
static inline isr_ctx_t *isr_ctx_get() {
isr_ctx_t *kctx;
asm("csrr %0, mscratch" : "=r"(kctx));
Expand All @@ -93,6 +95,11 @@ static inline void isr_ctx_switch_set(isr_ctx_t *switch_to) {
asm("csrr %0, mscratch" : "=r"(kctx));
kctx->ctxswitch = switch_to;
}
// Immediately swap the ISR context handle.
static inline isr_ctx_t *isr_ctx_swap(isr_ctx_t *kctx) {
asm("csrrw %0, mscratch, %0" : "+r"(kctx));
return kctx;
}
// Print a register dump given isr_ctx_t.
void isr_ctx_dump(isr_ctx_t const *ctx);
// Print a register dump of the current registers.
Expand Down
19 changes: 16 additions & 3 deletions kernel/cpu/riscv/include/cpu/riscv_pmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@
#include <stddef.h>
#include <stdint.h>

typedef struct proc_memmap_t proc_memmap_t;

static_assert(
RISCV_PMP_REGION_COUNT == 16 || RISCV_PMP_REGION_COUNT == 64, "RISC-V PMP region count must be either 16 or 64."
);

#if __riscv_xlen == 32

// 2^XLEN-byte NAPOT range starting at address 0.
#define RISCV_PMPADDR_NAPOT_GLOBAL 0x1fffffff
#define RISCV_PMPADDR_NAPOT_GLOBAL __LONG_MAX__

#define __RISCV_PMP_CFG_BITPOS_0 0
#define __RISCV_PMP_CFG_BITPOS_1 8
Expand Down Expand Up @@ -354,15 +356,26 @@ void riscv_pmpaddr_write_all(size_t const addr_in[RISCV_PMP_REGION_COUNT]);

// Add a memory protection region.
// For kernels using PMP as memory protection.
bool riscv_pmp_memprotect(riscv_pmp_ctx_t *ctx, size_t paddr, size_t length, uint32_t flags);
bool riscv_pmp_memprotect(proc_memmap_t *new_mm, riscv_pmp_ctx_t *ctx, size_t paddr, size_t length, uint32_t flags);
// Swap in the set of PMP entries.
void riscv_pmp_memprotect_swap(riscv_pmp_ctx_t *ctx);



// Determine whether an address is a valid NAPOT address.
static inline bool riscv_pmpaddr_is_napot(size_t base, size_t size) CONST;
static inline bool riscv_pmpaddr_is_napot(size_t base, size_t size) {
// Size must be a power of 2 >= 8.
if (size < 8 || (size & (size - 1))) {
return false;
}
// Base must be aligned to size.
return (base & (size - 1)) == 0;
}

// Compute NAPOT address value.
// Assumes `base` is aligned to `size` bytes and that `size` is a power of two >= 8.
static inline size_t riscv_pmpaddr_calc_napot(size_t base, size_t size) PURE;
static inline size_t riscv_pmpaddr_calc_napot(size_t base, size_t size) CONST;
static inline size_t riscv_pmpaddr_calc_napot(size_t base, size_t size) {
return (base >> 2) | ((size >> 3) - 1);
}
Expand Down
32 changes: 17 additions & 15 deletions kernel/cpu/riscv/src/entrypoint.S
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
.global __stack_bottom
.global __stack_size
.equ __stack_size, 8192
# .equ __stack_size, 1500*16
.lcomm __stack_bottom, __stack_size
.equ __stack_top, __stack_bottom + __stack_size

Expand All @@ -37,33 +38,34 @@ _start:
# Set up registers.
.option push
.option norelax
la gp, __global_pointer$
mv tp, x0
la sp, __stack_top
la gp, __global_pointer$
mv tp, x0
la sp, __stack_top
.option pop

# Zero out .bss section.
la a0, __start_bss
la a1, __stop_bss
beq a0, a1, .bssinit_skip
la a0, __start_bss
la a1, __stop_bss
beq a0, a1, .bssinit_skip
.bssinit_loop:
sw x0, 0(a0)
sw x0, 0(a0)
addi a0, a0, 4
bne a0, a1, .bssinit_loop
bne a0, a1, .bssinit_loop
.bssinit_skip:

# Run init functions.
la s0, __start_init_array
la s1, __stop_init_array
beq s0, s1, .initfun_skip
li s0, 0
la s1, __start_init_array
la s2, __stop_init_array
beq s1, s2, .initfun_skip
.initfun_loop:
lw ra, 0(s0)
lw ra, 0(s1)
jalr ra, ra
addi s0, s0, 4
bne s0, s1, .initfun_loop
addi s1, s1, 4
bne s1, s2, .initfun_loop
.initfun_skip:

# Jump to the C entrypoint.
jal basic_runtime_init
jal basic_runtime_init
# This function isn't allowed to return.
ebreak
14 changes: 9 additions & 5 deletions kernel/cpu/riscv/src/isr.S
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "cpu/isr.h"
#include "cpu/riscv.h"
#include "port/hardware.h"
.global __global_pointer$
.global memprotect_swap_from_isr

Expand Down Expand Up @@ -56,10 +57,13 @@
# Set up special regs.
li tp, 0
.option push
.option norvc
.option norelax
la gp, __global_pointer$
.option pop
lw t1, isr_ctx_t_use_sp(t0)
bnez t1, .isr_entry_\@
la sp, __interrupt_stack_hi
.isr_entry_\@:
#pragma endregion
.endm

Expand Down Expand Up @@ -388,11 +392,11 @@ riscv_interrupt_vector_table:
.option norvc
# Trap handler.
j __trap_asm
# Interrupt handler.
.rept 31
# Interrupt handlers.
.rept RISCV_VT_INT_COUNT
j __isr_asm
.endr
# Padding to 256-byte size.
.skip 128
# Padding.
.skip RISCV_VT_PADDING*4
.option pop
#pragma endregion
Loading

0 comments on commit 6e49ce5

Please sign in to comment.