Skip to content

Commit 6e49ce5

Browse files
authored
Merge branch 'badgeteam:main' into main
2 parents fe8752c + 4d76651 commit 6e49ce5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1027
-260
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ build/
66
firmware/
77
app/
88
root/
9+
.venv/

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33

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

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

109
all: build
1110

1211
prepare:
12+
python -m venv .venv
13+
.venv/bin/pip install esptool
1314
git submodule update --init
1415

1516
build:

README.md

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
# BadgerOS
22

3-
BadgerOS is the operating system currently in development for the upcoming MCH2025<sup>(1)</sup> badge.
3+
BadgerOS is the operating system currently in development for the upcoming [WHY2025](https://why2025.org/) badge.
44
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.
55

6-
_(1) MCH2025 is a preliminary name, MCH2025 is an event that will be organised by IFCAT in 2025._
7-
86
## Index
97
- [Contributing](#contributing)
108
- [Prerequisites](#prerequisites)
@@ -28,40 +26,34 @@ After that, see [Project structure](./docs/project_structure.md) for reference a
2826

2927

3028
# Prerequisites
31-
32-
To build BadgerOS:
33-
29+
- `git`
3430
- `build-essential`
3531
- `cmake`
36-
- `riscv32-unknown-elf-gcc` ([RISC-V collab toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain))
32+
- `gcc-riscv64-linux-gnu`
3733
- `python3`
38-
39-
To flash to an ESP:
40-
41-
- `esptool.py` from [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/#installation)
42-
43-
Optional recommends:
44-
4534
- `picocom`
4635

4736

4837

4938
# Build system
50-
5139
The build system is based on Makefiles and CMake.
5240
The following commands can be used to perform relevant actions:
5341

42+
To select target chip, choose one of:
43+
- `export BADGEROS_PORT=esp32p4`
44+
- `export BADGEROS_PORT=esp32c6` (default)
45+
5446
To build: `make build`
5547

5648
To remove build files: `make clean`
5749

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

6052
To open picocom: `make monitor`
6153

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

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

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

files/init/src/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ int main(int argc, char **argv) {
3232
else
3333
print("No read :c\n");
3434
int volatile *mem = syscall_mem_alloc(0, 32, 0, MEMFLAGS_RW);
35+
*mem = 3;
3536
syscall_mem_dealloc(mem);
3637
return 0;
3738
}

kernel/CMakeLists.txt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@ endif()
1919

2020
# Set the C compiler
2121
if(NOT DEFINED CMAKE_C_COMPILER)
22-
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)
22+
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)
2323
message("Detected RISC-V C compiler as '${CMAKE_C_COMPILER}'")
2424
else()
2525
message("Using compiler '${CMAKE_C_COMPILER}' from environment")
2626
endif()
2727

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

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

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

144-
# Also build a dump file that is put into the
148+
# Also build a dump file that is put into the
145149
add_custom_target(
146150
badger-os.elf.disasm
147151
ALL

kernel/cpu/riscv/include/cpu/interrupt.h

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,6 @@
77

88
#include <stdbool.h>
99

10-
// Enable/disable an internal interrupt.
11-
// Returns whether the interrupt was enabled.
12-
static inline bool irq_ch_enable(int int_irq, bool enable) {
13-
long mask = 1 << int_irq;
14-
if (enable) {
15-
asm volatile("csrrs %0, mie, %0" : "+r"(mask));
16-
} else {
17-
asm volatile("csrrc %0, mie, %0" : "+r"(mask));
18-
}
19-
return ((mask) >> int_irq) & 1;
20-
}
21-
22-
// Query whether an internal interrupt is enabled.
23-
static inline bool irq_ch_enabled(int int_irq) {
24-
long mask;
25-
asm("csrr %0, mie" : "=r"(mask));
26-
return ((mask) >> int_irq) & 1;
27-
}
28-
2910
// Globally enable/disable interrupts in this CPU.
3011
// Returns whether interrupts were enabled.
3112
static inline bool irq_enable(bool enable) {
@@ -37,6 +18,7 @@ static inline bool irq_enable(bool enable) {
3718
}
3819
return (mask >> RISCV_STATUS_MIE_BIT) & 1;
3920
}
21+
4022
// Query whether interrupts are enabled in this CPU.
4123
static inline bool irq_enabled() {
4224
long mask;

kernel/cpu/riscv/include/cpu/isr_ctx.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ STRUCT_FIELD_PTR(isr_ctx_t, sched_thread_t, thread, 164)
6464
// Thread is a kernel thread.
6565
// If true, the thread is run in M-mode, otherwise it is run in U-mode.
6666
STRUCT_FIELD_WORD(isr_ctx_t, is_kernel_thread, 168)
67+
// Use SP as the stack, not the ISR stack.
68+
STRUCT_FIELD_WORD(isr_ctx_t, use_sp, 172)
6769
STRUCT_END(isr_ctx_t)
6870

6971

@@ -75,7 +77,7 @@ enum {
7577
STACK_ALIGNMENT = 16,
7678
};
7779

78-
// Get the current kernel context.
80+
// Get the current ISR context.
7981
static inline isr_ctx_t *isr_ctx_get() {
8082
isr_ctx_t *kctx;
8183
asm("csrr %0, mscratch" : "=r"(kctx));
@@ -93,6 +95,11 @@ static inline void isr_ctx_switch_set(isr_ctx_t *switch_to) {
9395
asm("csrr %0, mscratch" : "=r"(kctx));
9496
kctx->ctxswitch = switch_to;
9597
}
98+
// Immediately swap the ISR context handle.
99+
static inline isr_ctx_t *isr_ctx_swap(isr_ctx_t *kctx) {
100+
asm("csrrw %0, mscratch, %0" : "+r"(kctx));
101+
return kctx;
102+
}
96103
// Print a register dump given isr_ctx_t.
97104
void isr_ctx_dump(isr_ctx_t const *ctx);
98105
// Print a register dump of the current registers.

kernel/cpu/riscv/include/cpu/riscv_pmp.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@
1313
#include <stddef.h>
1414
#include <stdint.h>
1515

16+
typedef struct proc_memmap_t proc_memmap_t;
17+
1618
static_assert(
1719
RISCV_PMP_REGION_COUNT == 16 || RISCV_PMP_REGION_COUNT == 64, "RISC-V PMP region count must be either 16 or 64."
1820
);
1921

2022
#if __riscv_xlen == 32
2123

2224
// 2^XLEN-byte NAPOT range starting at address 0.
23-
#define RISCV_PMPADDR_NAPOT_GLOBAL 0x1fffffff
25+
#define RISCV_PMPADDR_NAPOT_GLOBAL __LONG_MAX__
2426

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

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

361363

362364

365+
// Determine whether an address is a valid NAPOT address.
366+
static inline bool riscv_pmpaddr_is_napot(size_t base, size_t size) CONST;
367+
static inline bool riscv_pmpaddr_is_napot(size_t base, size_t size) {
368+
// Size must be a power of 2 >= 8.
369+
if (size < 8 || (size & (size - 1))) {
370+
return false;
371+
}
372+
// Base must be aligned to size.
373+
return (base & (size - 1)) == 0;
374+
}
375+
363376
// Compute NAPOT address value.
364377
// Assumes `base` is aligned to `size` bytes and that `size` is a power of two >= 8.
365-
static inline size_t riscv_pmpaddr_calc_napot(size_t base, size_t size) PURE;
378+
static inline size_t riscv_pmpaddr_calc_napot(size_t base, size_t size) CONST;
366379
static inline size_t riscv_pmpaddr_calc_napot(size_t base, size_t size) {
367380
return (base >> 2) | ((size >> 3) - 1);
368381
}

kernel/cpu/riscv/src/entrypoint.S

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
.global __stack_bottom
2424
.global __stack_size
2525
.equ __stack_size, 8192
26+
# .equ __stack_size, 1500*16
2627
.lcomm __stack_bottom, __stack_size
2728
.equ __stack_top, __stack_bottom + __stack_size
2829

@@ -37,33 +38,34 @@ _start:
3738
# Set up registers.
3839
.option push
3940
.option norelax
40-
la gp, __global_pointer$
41-
mv tp, x0
42-
la sp, __stack_top
41+
la gp, __global_pointer$
42+
mv tp, x0
43+
la sp, __stack_top
4344
.option pop
4445

4546
# Zero out .bss section.
46-
la a0, __start_bss
47-
la a1, __stop_bss
48-
beq a0, a1, .bssinit_skip
47+
la a0, __start_bss
48+
la a1, __stop_bss
49+
beq a0, a1, .bssinit_skip
4950
.bssinit_loop:
50-
sw x0, 0(a0)
51+
sw x0, 0(a0)
5152
addi a0, a0, 4
52-
bne a0, a1, .bssinit_loop
53+
bne a0, a1, .bssinit_loop
5354
.bssinit_skip:
5455

5556
# Run init functions.
56-
la s0, __start_init_array
57-
la s1, __stop_init_array
58-
beq s0, s1, .initfun_skip
57+
li s0, 0
58+
la s1, __start_init_array
59+
la s2, __stop_init_array
60+
beq s1, s2, .initfun_skip
5961
.initfun_loop:
60-
lw ra, 0(s0)
62+
lw ra, 0(s1)
6163
jalr ra, ra
62-
addi s0, s0, 4
63-
bne s0, s1, .initfun_loop
64+
addi s1, s1, 4
65+
bne s1, s2, .initfun_loop
6466
.initfun_skip:
6567

6668
# Jump to the C entrypoint.
67-
jal basic_runtime_init
69+
jal basic_runtime_init
6870
# This function isn't allowed to return.
6971
ebreak

kernel/cpu/riscv/src/isr.S

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "cpu/isr.h"
55
#include "cpu/riscv.h"
6+
#include "port/hardware.h"
67
.global __global_pointer$
78
.global memprotect_swap_from_isr
89

@@ -56,10 +57,13 @@
5657
# Set up special regs.
5758
li tp, 0
5859
.option push
59-
.option norvc
60+
.option norelax
6061
la gp, __global_pointer$
6162
.option pop
63+
lw t1, isr_ctx_t_use_sp(t0)
64+
bnez t1, .isr_entry_\@
6265
la sp, __interrupt_stack_hi
66+
.isr_entry_\@:
6367
#pragma endregion
6468
.endm
6569

@@ -388,11 +392,11 @@ riscv_interrupt_vector_table:
388392
.option norvc
389393
# Trap handler.
390394
j __trap_asm
391-
# Interrupt handler.
392-
.rept 31
395+
# Interrupt handlers.
396+
.rept RISCV_VT_INT_COUNT
393397
j __isr_asm
394398
.endr
395-
# Padding to 256-byte size.
396-
.skip 128
399+
# Padding.
400+
.skip RISCV_VT_PADDING*4
397401
.option pop
398402
#pragma endregion

0 commit comments

Comments
 (0)