Update init.S for new IRQ functionality
This commit is contained in:
parent
278dc8b6a2
commit
c03bc2efb5
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef _HAZARD3_CSR_H
|
||||||
|
#define _HAZARD3_CSR_H
|
||||||
|
|
||||||
|
#define hazard3_csr_midcr 0xbc0
|
||||||
|
#define hazard3_csr_meie0 0xbe0 // External interrupt enable IRQ0 -> 31
|
||||||
|
#define hazard3_csr_meip0 0xfe0 // External interrupt pending IRQ0 -> 31
|
||||||
|
#define hazard3_csr_mlei 0xfe4 // Lowest external interrupt (pending & enabled)
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,4 +1,4 @@
|
||||||
#define COLLAPSE_WEAK_HANDLERS
|
#include "hazard3_csr.h"
|
||||||
|
|
||||||
#define IO_BASE 0x80000000
|
#define IO_BASE 0x80000000
|
||||||
#define IO_PRINT_CHAR (IO_BASE + 0x0)
|
#define IO_PRINT_CHAR (IO_BASE + 0x0)
|
||||||
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
.option push
|
.option push
|
||||||
.option norelax
|
.option norelax
|
||||||
.option norvc
|
|
||||||
|
|
||||||
.section .vectors
|
.section .vectors
|
||||||
|
|
||||||
|
@ -44,13 +43,18 @@ j \name
|
||||||
VEC .halt
|
VEC .halt
|
||||||
VEC .halt
|
VEC .halt
|
||||||
VEC .halt
|
VEC .halt
|
||||||
VEC .halt
|
VEC isr_external_irq
|
||||||
VEC .halt
|
VEC .halt
|
||||||
VEC .halt
|
VEC .halt
|
||||||
VEC .halt
|
VEC .halt
|
||||||
VEC .halt
|
VEC .halt
|
||||||
|
|
||||||
// External interrupts, if vectoring is enabled
|
// When midcr.eivect is 1, hardware vectors IRQs directly to the
|
||||||
|
// platform-specific part of the vector table. Otherwise, software indexes
|
||||||
|
// this table in the prologue of a shared external IRQ handler.
|
||||||
|
|
||||||
|
.p2align 2
|
||||||
|
platform_vectors:
|
||||||
|
|
||||||
VEC isr_irq0
|
VEC isr_irq0
|
||||||
VEC isr_irq1
|
VEC isr_irq1
|
||||||
|
@ -68,6 +72,22 @@ j \name
|
||||||
VEC isr_irq13
|
VEC isr_irq13
|
||||||
VEC isr_irq14
|
VEC isr_irq14
|
||||||
VEC isr_irq15
|
VEC isr_irq15
|
||||||
|
VEC isr_irq16
|
||||||
|
VEC isr_irq17
|
||||||
|
VEC isr_irq18
|
||||||
|
VEC isr_irq19
|
||||||
|
VEC isr_irq20
|
||||||
|
VEC isr_irq21
|
||||||
|
VEC isr_irq22
|
||||||
|
VEC isr_irq23
|
||||||
|
VEC isr_irq24
|
||||||
|
VEC isr_irq25
|
||||||
|
VEC isr_irq26
|
||||||
|
VEC isr_irq27
|
||||||
|
VEC isr_irq28
|
||||||
|
VEC isr_irq29
|
||||||
|
VEC isr_irq30
|
||||||
|
VEC isr_irq31
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -76,9 +96,8 @@ j \name
|
||||||
|
|
||||||
.reset_handler:
|
.reset_handler:
|
||||||
la sp, __stack_top
|
la sp, __stack_top
|
||||||
la t0, .vector_table
|
// mtvec LSB enables vectoring
|
||||||
// Set mtvec LSB to enable vectoring
|
la t0, .vector_table + 1
|
||||||
ori t0, t0, 1
|
|
||||||
csrw mtvec, t0
|
csrw mtvec, t0
|
||||||
|
|
||||||
// newlib _start expects argc, argv on the stack. Leave stack 16-byte aligned.
|
// newlib _start expects argc, argv on the stack. Leave stack 16-byte aligned.
|
||||||
|
@ -115,6 +134,91 @@ heap_ptr:
|
||||||
progname:
|
progname:
|
||||||
.asciz "hazard5-testbench"
|
.asciz "hazard5-testbench"
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Soft external IRQ dispatch
|
||||||
|
|
||||||
|
// Vector isr_external_irq to the relevant ISR, based on mcause. The ISR can
|
||||||
|
// be a standard C-ABI function. This method also leaves the possibility of
|
||||||
|
// using addresses in the IRQ vector table, rather than jump instructions.
|
||||||
|
|
||||||
|
.global isr_external_irq
|
||||||
|
.weak isr_external_irq
|
||||||
|
isr_external_irq:
|
||||||
|
// Save all caller-saves, plus three callee saves for CSR saving
|
||||||
|
addi sp, sp, -80
|
||||||
|
sw ra, 0(sp)
|
||||||
|
sw t0, 4(sp)
|
||||||
|
sw t1, 8(sp)
|
||||||
|
sw t2, 12(sp)
|
||||||
|
sw t3, 16(sp)
|
||||||
|
sw t4, 20(sp)
|
||||||
|
sw t5, 24(sp)
|
||||||
|
sw t6, 28(sp)
|
||||||
|
sw a0, 32(sp)
|
||||||
|
sw a1, 36(sp)
|
||||||
|
sw a2, 40(sp)
|
||||||
|
sw a3, 44(sp)
|
||||||
|
sw a4, 48(sp)
|
||||||
|
sw a5, 52(sp)
|
||||||
|
sw a6, 56(sp)
|
||||||
|
sw a7, 60(sp)
|
||||||
|
sw s0, 64(sp)
|
||||||
|
sw s1, 68(sp)
|
||||||
|
sw s2, 72(sp)
|
||||||
|
|
||||||
|
// Save exception state to callee-saves so we can use it for return
|
||||||
|
csrr s0, mepc
|
||||||
|
csrr s1, mstatus
|
||||||
|
csrr s2, hazard3_csr_meie0
|
||||||
|
|
||||||
|
// Calculate IRQ entry point
|
||||||
|
csrr a0, mcause
|
||||||
|
slli a0, a0, 2
|
||||||
|
csrr a1, mtvec
|
||||||
|
andi a1, a1, -4
|
||||||
|
add a1, a1, a0
|
||||||
|
|
||||||
|
// Mask off higher-numbered IRQs (and this IRQ), then re-enable IRQs so we
|
||||||
|
// can be preempted. Could have some other priority scheme here.
|
||||||
|
srli a0, a0, 2
|
||||||
|
addi a0, a0, -16
|
||||||
|
li a2, -1
|
||||||
|
sll a2, a2, a0
|
||||||
|
csrc hazard3_csr_meie0, a2
|
||||||
|
csrsi mstatus, 8
|
||||||
|
|
||||||
|
// Enter IRQ
|
||||||
|
jalr a1
|
||||||
|
trap_return:
|
||||||
|
// No more preemption until we mret.
|
||||||
|
csrci mstatus, 8
|
||||||
|
|
||||||
|
csrw mepc, s0
|
||||||
|
csrw mstatus, s1
|
||||||
|
csrw hazard3_csr_meie0, s2
|
||||||
|
lw ra, 0(sp)
|
||||||
|
lw t0, 4(sp)
|
||||||
|
lw t1, 8(sp)
|
||||||
|
lw t2, 12(sp)
|
||||||
|
lw t3, 16(sp)
|
||||||
|
lw t4, 20(sp)
|
||||||
|
lw t5, 24(sp)
|
||||||
|
lw t6, 28(sp)
|
||||||
|
lw a0, 32(sp)
|
||||||
|
lw a1, 36(sp)
|
||||||
|
lw a2, 40(sp)
|
||||||
|
lw a3, 44(sp)
|
||||||
|
lw a4, 48(sp)
|
||||||
|
lw a5, 52(sp)
|
||||||
|
lw a6, 56(sp)
|
||||||
|
lw a7, 60(sp)
|
||||||
|
lw s0, 64(sp)
|
||||||
|
lw s1, 68(sp)
|
||||||
|
lw s2, 72(sp)
|
||||||
|
addi sp, sp, 80
|
||||||
|
mret
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Weak handler/ISR symbols
|
// Weak handler/ISR symbols
|
||||||
|
|
||||||
|
@ -186,7 +290,6 @@ _str_sp: .asciz "sp: "
|
||||||
.macro weak_handler name:req
|
.macro weak_handler name:req
|
||||||
.p2align 2
|
.p2align 2
|
||||||
.global \name
|
.global \name
|
||||||
.type \name,%function
|
|
||||||
.weak \name
|
.weak \name
|
||||||
\name:
|
\name:
|
||||||
la x31, _str_\name
|
la x31, _str_\name
|
||||||
|
@ -214,6 +317,22 @@ weak_handler isr_irq12
|
||||||
weak_handler isr_irq13
|
weak_handler isr_irq13
|
||||||
weak_handler isr_irq14
|
weak_handler isr_irq14
|
||||||
weak_handler isr_irq15
|
weak_handler isr_irq15
|
||||||
|
weak_handler isr_irq16
|
||||||
|
weak_handler isr_irq17
|
||||||
|
weak_handler isr_irq18
|
||||||
|
weak_handler isr_irq19
|
||||||
|
weak_handler isr_irq20
|
||||||
|
weak_handler isr_irq21
|
||||||
|
weak_handler isr_irq22
|
||||||
|
weak_handler isr_irq23
|
||||||
|
weak_handler isr_irq24
|
||||||
|
weak_handler isr_irq25
|
||||||
|
weak_handler isr_irq26
|
||||||
|
weak_handler isr_irq27
|
||||||
|
weak_handler isr_irq28
|
||||||
|
weak_handler isr_irq29
|
||||||
|
weak_handler isr_irq30
|
||||||
|
weak_handler isr_irq31
|
||||||
|
|
||||||
// You can relax now
|
// You can relax now
|
||||||
.option pop
|
.option pop
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#ifndef _TB_CXXRTL_IO_H
|
#ifndef _TB_CXXRTL_IO_H
|
||||||
#define _TB_CXXRTL_IO_H
|
#define _TB_CXXRTL_IO_H
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define IO_BASE 0x80000000
|
#define IO_BASE 0x80000000
|
||||||
|
|
||||||
|
@ -30,4 +32,17 @@ static inline void tb_exit(uint32_t ret) {
|
||||||
mm_io->exit = ret;
|
mm_io->exit = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PRINTF_BUF_SIZE
|
||||||
|
#define PRINTF_BUF_SIZE 256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline void tb_printf(const char *fmt, ...) {
|
||||||
|
char buf[PRINTF_BUF_SIZE];
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsnprintf(buf, PRINTF_BUF_SIZE, fmt, args);
|
||||||
|
tb_puts(buf);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
../../../common/hazard3_csr.h
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#define write_csr(csrname, val) __asm__ ("csrw " #csrname ", %0" : : "r" (val))
|
#define write_csr(csrname, val) __asm__ ("csrw " #csrname ", %0" : : "r" (val))
|
||||||
|
|
||||||
void __attribute__((interrupt)) handle_ecall() {
|
void __attribute__((interrupt)) handle_exception() {
|
||||||
uint32_t call_num;
|
uint32_t call_num;
|
||||||
asm volatile ("mv %0, a7" : "=r" (call_num));
|
asm volatile ("mv %0, a7" : "=r" (call_num));
|
||||||
tb_puts("Handling ecall. Call number:\n");
|
tb_puts("Handling ecall. Call number:\n");
|
||||||
|
@ -30,8 +30,12 @@ const uint32_t call_nums[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
tb_puts("mcause initial value:\n");
|
||||||
|
tb_put_u32(read_csr(mcause));
|
||||||
for (int i = 0; i < sizeof(call_nums) / sizeof(*call_nums); ++i)
|
for (int i = 0; i < sizeof(call_nums) / sizeof(*call_nums); ++i)
|
||||||
make_ecall(call_nums[i]);
|
make_ecall(call_nums[i]);
|
||||||
tb_puts("Finished making calls.\n");
|
tb_puts("Finished making calls.\n");
|
||||||
|
tb_puts("mcause final value:\n");
|
||||||
|
tb_put_u32(read_csr(mcause));
|
||||||
tb_exit(0);
|
tb_exit(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
SRCS := ../common/init.S main.c
|
SRCS := ../common/init.S main.c
|
||||||
APP := hellow
|
APP := hellow
|
||||||
CCFLAGS = -march=rv32ic
|
CCFLAGS = -march=rv32imc -Os
|
||||||
|
|
||||||
include ../common/src_only_app.mk
|
include ../common/src_only_app.mk
|
||||||
|
|
Loading…
Reference in New Issue