ca13734bf0
Add kernel (Cortex-M0/M3/M4, Tricore, S32K, RISC-V ports), drivers, middleware (CAN stack, diagnostics, safety), applications, board support, build/test tooling, and documentation.
238 lines
6.9 KiB
C
238 lines
6.9 KiB
C
/**
|
|
* @file port.c
|
|
* @brief RISC-V RV32 architecture specific port
|
|
* @note RISC-V is emerging in automotive applications
|
|
*/
|
|
|
|
#include "kernel.h"
|
|
#include "task.h"
|
|
#include "scheduler.h"
|
|
#include "portmacro.h"
|
|
|
|
/* Context storage */
|
|
uint32_t* current_task_sp = NULL;
|
|
uint32_t* next_task_sp = NULL;
|
|
|
|
/* Machine Timer registers */
|
|
#define MTIME_ADDR 0x0200BFF8
|
|
#define MTIMECMP_ADDR 0x02004000
|
|
|
|
/* Initialize Architecture Port */
|
|
void port_init(void) {
|
|
/* Configure machine timer for 1ms interrupts */
|
|
volatile uint32_t* mtime = (uint32_t*)MTIME_ADDR;
|
|
volatile uint32_t* mtimecmp = (uint32_t*)MTIMECMP_ADDR;
|
|
|
|
uint32_t current_time = *mtime;
|
|
*mtimecmp = current_time + (SystemCoreClock / 1000);
|
|
|
|
/* Enable machine timer interrupt */
|
|
__asm volatile (
|
|
"li t0, 0x80\n" /* Machine Timer Interrupt Enable */
|
|
"csrs mie, t0\n"
|
|
);
|
|
|
|
/* Enable global interrupts */
|
|
__asm volatile (
|
|
"csrsi mstatus, 0x8\n" /* Machine Interrupt Enable */
|
|
);
|
|
}
|
|
|
|
/* Start First Task */
|
|
void port_start_first_task(void) {
|
|
TaskHandle_t first_task = scheduler_get_current_task();
|
|
|
|
if (first_task == NULL) {
|
|
return;
|
|
}
|
|
|
|
/* Load task stack pointer */
|
|
__asm volatile (
|
|
"mv sp, %0\n"
|
|
"ret\n"
|
|
:
|
|
: "r" (first_task->stack_pointer)
|
|
);
|
|
}
|
|
|
|
/* Context Switch */
|
|
void port_context_switch(uint32_t* current_context, uint32_t* next_context) {
|
|
current_task_sp = current_context;
|
|
next_task_sp = next_context;
|
|
|
|
/* Trigger software interrupt */
|
|
__asm volatile (
|
|
"li t0, 0x8\n" /* Machine Software Interrupt */
|
|
"csrs mip, t0\n"
|
|
);
|
|
}
|
|
|
|
/* Initialize Task Stack */
|
|
uint32_t* port_initialize_task_stack(TaskFunction_t task_function,
|
|
void* parameters,
|
|
uint32_t* stack_top) {
|
|
uint32_t* stack_ptr = stack_top;
|
|
|
|
/* Align to 16 bytes */
|
|
stack_ptr = (uint32_t*)((uint32_t)stack_ptr & ~0xF);
|
|
|
|
/* Initial stack frame */
|
|
*(--stack_ptr) = (uint32_t)parameters; /* a0 */
|
|
*(--stack_ptr) = 0; /* a1 */
|
|
*(--stack_ptr) = 0; /* a2 */
|
|
*(--stack_ptr) = 0; /* a3 */
|
|
*(--stack_ptr) = 0; /* a4 */
|
|
*(--stack_ptr) = 0; /* a5 */
|
|
*(--stack_ptr) = 0; /* a6 */
|
|
*(--stack_ptr) = 0; /* a7 */
|
|
|
|
*(--stack_ptr) = (uint32_t)task_function; /* ra */
|
|
*(--stack_ptr) = 0; /* t0 */
|
|
*(--stack_ptr) = 0; /* t1 */
|
|
*(--stack_ptr) = 0; /* t2 */
|
|
*(--stack_ptr) = 0; /* t3 */
|
|
*(--stack_ptr) = 0; /* t4 */
|
|
*(--stack_ptr) = 0; /* t5 */
|
|
*(--stack_ptr) = 0; /* t6 */
|
|
|
|
*(--stack_ptr) = 0; /* s0 */
|
|
*(--stack_ptr) = 0; /* s1 */
|
|
*(--stack_ptr) = 0; /* s2 */
|
|
*(--stack_ptr) = 0; /* s3 */
|
|
*(--stack_ptr) = 0; /* s4 */
|
|
*(--stack_ptr) = 0; /* s5 */
|
|
*(--stack_ptr) = 0; /* s6 */
|
|
*(--stack_ptr) = 0; /* s7 */
|
|
*(--stack_ptr) = 0; /* s8 */
|
|
*(--stack_ptr) = 0; /* s9 */
|
|
*(--stack_ptr) = 0; /* s10 */
|
|
*(--stack_ptr) = 0; /* s11 */
|
|
|
|
*(--stack_ptr) = 0; /* gp */
|
|
*(--stack_ptr) = 0; /* tp */
|
|
|
|
/* mstatus */
|
|
*(--stack_ptr) = 0x00001880; /* MPP = Machine mode */
|
|
|
|
return stack_ptr;
|
|
}
|
|
|
|
/* Machine Timer Interrupt Handler */
|
|
void machine_timer_interrupt_handler(void) {
|
|
/* Clear interrupt */
|
|
volatile uint32_t* mtimecmp = (uint32_t*)MTIMECMP_ADDR;
|
|
volatile uint32_t* mtime = (uint32_t*)MTIME_ADDR;
|
|
*mtimecmp = *mtime + (SystemCoreClock / 1000);
|
|
|
|
/* Call kernel tick handler */
|
|
extern void kernel_tick_handler(void);
|
|
kernel_tick_handler();
|
|
}
|
|
|
|
/* Machine Software Interrupt Handler */
|
|
void machine_software_interrupt_handler(void) {
|
|
/* Clear interrupt */
|
|
__asm volatile (
|
|
"li t0, 0x8\n"
|
|
"csrc mip, t0\n"
|
|
);
|
|
|
|
/* Perform context switch */
|
|
__asm volatile (
|
|
/* Save current context */
|
|
"addi sp, sp, -128\n"
|
|
"sw ra, 0(sp)\n"
|
|
"sw t0, 4(sp)\n"
|
|
"sw t1, 8(sp)\n"
|
|
"sw t2, 12(sp)\n"
|
|
"sw s0, 16(sp)\n"
|
|
"sw s1, 20(sp)\n"
|
|
"sw a0, 24(sp)\n"
|
|
"sw a1, 28(sp)\n"
|
|
"sw a2, 32(sp)\n"
|
|
"sw a3, 36(sp)\n"
|
|
"sw a4, 40(sp)\n"
|
|
"sw a5, 44(sp)\n"
|
|
"sw a6, 48(sp)\n"
|
|
"sw a7, 52(sp)\n"
|
|
"sw s2, 56(sp)\n"
|
|
"sw s3, 60(sp)\n"
|
|
"sw s4, 64(sp)\n"
|
|
"sw s5, 68(sp)\n"
|
|
"sw s6, 72(sp)\n"
|
|
"sw s7, 76(sp)\n"
|
|
"sw s8, 80(sp)\n"
|
|
"sw s9, 84(sp)\n"
|
|
"sw s10, 88(sp)\n"
|
|
"sw s11, 92(sp)\n"
|
|
"sw t3, 96(sp)\n"
|
|
"sw t4, 100(sp)\n"
|
|
"sw t5, 104(sp)\n"
|
|
"sw t6, 108(sp)\n"
|
|
"csrr t0, mstatus\n"
|
|
"sw t0, 112(sp)\n"
|
|
"csrr t0, mepc\n"
|
|
"sw t0, 116(sp)\n"
|
|
|
|
/* Save current stack pointer */
|
|
"la t0, current_task_sp\n"
|
|
"sw sp, 0(t0)\n"
|
|
|
|
/* Load next stack pointer */
|
|
"la t0, next_task_sp\n"
|
|
"lw sp, 0(t0)\n"
|
|
|
|
/* Restore next context */
|
|
"lw ra, 0(sp)\n"
|
|
"lw t0, 4(sp)\n"
|
|
"lw t1, 8(sp)\n"
|
|
"lw t2, 12(sp)\n"
|
|
"lw s0, 16(sp)\n"
|
|
"lw s1, 20(sp)\n"
|
|
"lw a0, 24(sp)\n"
|
|
"lw a1, 28(sp)\n"
|
|
"lw a2, 32(sp)\n"
|
|
"lw a3, 36(sp)\n"
|
|
"lw a4, 40(sp)\n"
|
|
"lw a5, 44(sp)\n"
|
|
"lw a6, 48(sp)\n"
|
|
"lw a7, 52(sp)\n"
|
|
"lw s2, 56(sp)\n"
|
|
"lw s3, 60(sp)\n"
|
|
"lw s4, 64(sp)\n"
|
|
"lw s5, 68(sp)\n"
|
|
"lw s6, 72(sp)\n"
|
|
"lw s7, 76(sp)\n"
|
|
"lw s8, 80(sp)\n"
|
|
"lw s9, 84(sp)\n"
|
|
"lw s10, 88(sp)\n"
|
|
"lw s11, 92(sp)\n"
|
|
"lw t3, 96(sp)\n"
|
|
"lw t4, 100(sp)\n"
|
|
"lw t5, 104(sp)\n"
|
|
"lw t6, 108(sp)\n"
|
|
"lw t0, 112(sp)\n"
|
|
"csrw mstatus, t0\n"
|
|
"lw t0, 116(sp)\n"
|
|
"csrw mepc, t0\n"
|
|
"addi sp, sp, 128\n"
|
|
|
|
/* Return from interrupt */
|
|
"mret\n"
|
|
);
|
|
}
|
|
|
|
/* Enter Critical Section */
|
|
void port_disable_interrupts(void) {
|
|
__asm volatile (
|
|
"csrci mstatus, 0x8\n" /* Clear Machine Interrupt Enable */
|
|
);
|
|
}
|
|
|
|
/* Exit Critical Section */
|
|
void port_enable_interrupts(void) {
|
|
__asm volatile (
|
|
"csrsi mstatus, 0x8\n" /* Set Machine Interrupt Enable */
|
|
);
|
|
}
|