Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P4 #71

Merged
merged 6 commits into from
Apr 19, 2024
Merged

P4 #71

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions kernel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ 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")
Expand All @@ -39,6 +39,7 @@ include(cpu/riscv/CMakeLists.txt)
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
-nodefaultlibs -nostdlib # Do not link any default libraries like libgcc or libc.
Expand All @@ -62,7 +63,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
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
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
27 changes: 18 additions & 9 deletions kernel/cpu/riscv/src/isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "cpu/isr_ctx.h"
#include "cpu/panic.h"
#include "log.h"
#include "port/hardware.h"
#include "process/internal.h"
#include "process/types.h"
#include "rawprint.h"
Expand Down Expand Up @@ -53,14 +54,26 @@ void riscv_trap_handler() {
// TODO: Per-CPU double trap detection.
static int trap_depth = 0;

uint32_t mcause, mstatus, mtval, mepc;
asm volatile("csrr %0, mstatus" : "=r"(mstatus));
long mcause, mstatus, mtval, mepc;
asm volatile("csrr %0, mcause" : "=r"(mcause));
if (mcause < 0) {
riscv_interrupt_handler();
return;
}
asm volatile("csrr %0, mstatus" : "=r"(mstatus));

trap_depth++;
if ((mcause & 31) == RISCV_TRAP_U_ECALL) {
isr_ctx_t recurse_ctx;
recurse_ctx.mpu_ctx = NULL;
recurse_ctx.is_kernel_thread = true;
recurse_ctx.use_sp = true;
isr_ctx_t *kctx = isr_ctx_swap(&recurse_ctx);
recurse_ctx.thread = kctx->thread;

if ((mcause & RISCV_VT_ICAUSE_MASK) == RISCV_TRAP_U_ECALL) {
// ECALL from U-mode goes to system call handler instead of trap handler.
sched_raise_from_isr(true, syscall_handler);
isr_ctx_swap(kctx);
trap_depth--;
return;
}
Expand Down Expand Up @@ -100,9 +113,6 @@ void riscv_trap_handler() {
rawputc('\r');
rawputc('\n');

isr_ctx_t *kctx;
asm volatile("csrr %0, mscratch" : "=r"(kctx));

// Print privilige mode.
if (trap_depth == 1) {
if (mstatus & (3 << RISCV_STATUS_MPP_BASE_BIT)) {
Expand All @@ -124,9 +134,7 @@ void riscv_trap_handler() {
rawprintdec(kctx->thread->process->pid, 1);
}
rawprint("\n");
if (trap_depth == 1) {
backtrace_from_ptr(kctx->frameptr);
}
backtrace_from_ptr(kctx->frameptr);

isr_ctx_dump(kctx);

Expand All @@ -137,6 +145,7 @@ void riscv_trap_handler() {
// When the user traps just stop the process.
sched_raise_from_isr(false, kill_proc_on_trap);
}
isr_ctx_swap(kctx);
trap_depth--;
}

Expand Down
18 changes: 7 additions & 11 deletions kernel/cpu/riscv/src/isr_noexc.S
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

# SPDX-License-Identifier: MIT

#include "port/hardware.h"



# Run a restricted function and catch exceptions.
Expand Down Expand Up @@ -100,12 +102,6 @@ isr_noexc_tvec_none:



# Temporary interrupt handler for noexc runtime.
isr_noexc_ivec:
ebreak



# Interrupt vector table for the CPU.
# This must be aligned to a 256-byte boundary, so it is in a special section.
.section ".interrupt_vector_table"
Expand All @@ -114,10 +110,10 @@ isr_noexc_vec:
.option norvc
# Trap handler.
j isr_noexc_tvec
# Interrupt handler.
.rept 31
.word isr_noexc_ivec
# Interrupt handlers.
.rept RISCV_VT_INT_COUNT
ebreak
.endr
# Padding to 256-byte size.
.skip 128
# Padding.
.skip RISCV_VT_PADDING*4
.option pop
7 changes: 4 additions & 3 deletions kernel/include/interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ void irq_ch_prio(int int_irq, int prio);
void irq_ch_ack(int int_irq);

// Enable/disable an internal interrupt on this CPU.
// Returns whether the interrupt was enabled on this CPU.
static inline bool irq_ch_enable(int int_irq, bool enable);
void irq_ch_enable(int int_irq, bool enable);
// Query whether an internal interrupt is enabled on this CPU.
static inline bool irq_ch_enabled(int int_irq);
bool irq_ch_enabled(int int_irq);
// Query whether an internal interrupt is pending.
bool irq_ch_pending(int int_irq);

// Set the interrupt service routine for an interrupt on this CPU.
void irq_ch_set_isr(int int_irq, isr_t isr);
Expand Down
13 changes: 13 additions & 0 deletions kernel/port/esp32c6/include/port/hardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

#pragma once

#ifndef __ASSEMBLER__
#include <stddef.h>
#include <stdint.h>
#endif



Expand All @@ -13,6 +15,15 @@
// Number of PMP regions supported by the CPU.
#define RISCV_PMP_REGION_COUNT 16

// Number of interrupt channels (excluding trap handler) in the vector table.
#define RISCV_VT_INT_COUNT 47
// Number of padding words in the vector table.
#define RISCV_VT_PADDING 16
// Bitmask for interrupt cause.
#define RISCV_VT_ICAUSE_MASK 63
// Bitmask for trap cause.
#define RISCV_VT_TCAUSE_MASK 31


/* ==== SOC INFO ==== */

Expand Down Expand Up @@ -159,8 +170,10 @@



#ifndef __ASSEMBLER__
#define WRITE_REG(addr, val) \
do { \
*(volatile uint32_t *)(addr) = (val); \
} while (0)
#define READ_REG(addr) (*(volatile uint32_t *)(addr))
#endif
1 change: 1 addition & 0 deletions kernel/port/esp32c6/linker.ld
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ PROVIDE(CLINT_U = 0x20001C00);
__start_init_array = .;
KEEP(*(.init_array))
__stop_init_array = .;
. = ALIGN(__section_alignment);
} :rodataseg
.rodata : AT(LOADADDR(.init_array) + SIZEOF(.init_array)) {
*(.rodata) *(.rodata*)
Expand Down
20 changes: 20 additions & 0 deletions kernel/port/esp32c6/src/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,23 @@ void riscv_interrupt_handler() {
// Acknowledge interrupt.
irq_ch_ack(mcause);
}



// Enable/disable an internal interrupt.
void irq_ch_enable(int int_irq, bool enable) {
assert_dev_drop(int_irq > 0 && int_irq < 32);
long mask = 1 << int_irq;
if (enable) {
asm volatile("csrs mie, %0" ::"r"(mask));
} else {
asm volatile("csrc mie, %0" ::"r"(mask));
}
}

// Query whether an internal interrupt is enabled.
bool irq_ch_enabled(int int_irq) {
long mask;
asm("csrr %0, mie" : "=r"(mask));
return ((mask) >> int_irq) & 1;
}
8 changes: 4 additions & 4 deletions kernel/port/esp32p4/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ set(port_src
${CMAKE_CURRENT_LIST_DIR}/src/port.c
)
set(port_include
${CMAKE_CURRENT_LIST_DIR}/include
${CMAKE_CURRENT_LIST_DIR}/../esp_common/include
${CMAKE_CURRENT_LIST_DIR}/../esp_common/esp-idf/components/soc/esp32p4/include
${CMAKE_CURRENT_LIST_DIR}/../esp_common/esp-idf/components/soc/include
${CMAKE_CURRENT_LIST_DIR}/include/
${CMAKE_CURRENT_LIST_DIR}/../esp_common/include/
${CMAKE_CURRENT_LIST_DIR}/../esp_common/esp-idf/components/soc/esp32p4/include/
${CMAKE_CURRENT_LIST_DIR}/../esp_common/esp-idf/components/soc/include/
${CMAKE_CURRENT_LIST_DIR}/../esp_common/esp-idf/components/esp_rom/include/esp32p4/
)
set(port_link
Expand Down
Loading
Loading