initial commit

This commit is contained in:
2026-01-27 20:45:47 +01:00
commit 1e5eb44ca9
53 changed files with 11048 additions and 0 deletions

View File

@@ -0,0 +1,166 @@
/*
Baremetal main program with timer interrupt.
SPDX-License-Identifier: Unlicense
https://five-embeddev.com/
Tested with sifive-hifive-revb, but should not have any
dependencies to any particular implementation.
*/
// Makes use of GCC interrupt and weak reference/alias attributes
// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
// https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Function-Attributes.html#RISC-V-Function-Attributes
// Vector table - not to be called.
void riscv_mtvec_table(void) __attribute__ ((naked, section(".text.mtvec_table") ,aligned(256)));
void riscv_stvec_table(void) __attribute__ ((naked, section(".text.stvec_table") ,aligned(256)));
void riscv_utvec_table(void) __attribute__ ((naked, section(".text.utvec_table") ,aligned(256)));
// Default "NOP" implementations
static void riscv_nop_machine(void) __attribute__ ((interrupt ("machine")) );
static void riscv_nop_supervisor(void) __attribute__ ((interrupt ("supervisor")) );
static void riscv_nop_user(void) __attribute__ ((interrupt ("user")) );
// Weak alias to the "NOP" implementations. If another function
void riscv_mtvec_exception(void) __attribute__ ((interrupt ("machine") , weak, alias("riscv_nop_machine") ));
void riscv_mtvec_msi(void) __attribute__ ((interrupt ("machine") , weak, alias("riscv_nop_machine") ));
void riscv_mtvec_mti(void) __attribute__ ((interrupt ("machine") , weak, alias("riscv_nop_machine") ));
void riscv_mtvec_mei(void) __attribute__ ((interrupt ("machine") , weak, alias("riscv_nop_machine") ));
void riscv_mtvec_ssi(void) __attribute__ ((interrupt ("supervisor") , weak, alias("riscv_nop_machine") ));
void riscv_mtvec_sti(void) __attribute__ ((interrupt ("supervisor") , weak, alias("riscv_nop_machine") ));
void riscv_mtvec_sei(void) __attribute__ ((interrupt ("supervisor") , weak, alias("riscv_nop_machine") ));
void riscv_stvec_exception(void) __attribute__ ((interrupt ("supervisor") , weak, alias("riscv_nop_supervisor") ));
void riscv_stvec_ssi(void) __attribute__ ((interrupt ("supervisor") , weak, alias("riscv_nop_supervisor") ));
void riscv_stvec_sti(void) __attribute__ ((interrupt ("supervisor") , weak, alias("riscv_nop_supervisor") ));
void riscv_stvec_sei(void) __attribute__ ((interrupt ("supervisor") , weak, alias("riscv_nop_supervisor") ));
void riscv_utvec_usi(void) __attribute__ ((interrupt ("user") , weak, alias("riscv_nop_user") ));
void riscv_utvec_uti(void) __attribute__ ((interrupt ("user") , weak, alias("riscv_nop_user") ));
void riscv_utvec_uei(void) __attribute__ ((interrupt ("user") , weak, alias("riscv_nop_user") ));
#ifndef VECTOR_TABLE_MTVEC_PLATFORM_INTS
void moonlight_mtvec_irq0(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq1(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq2(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq3(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq4(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq5(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq6(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq7(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq8(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq9(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq10(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq11(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq12(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq13(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq14(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
void moonlight_mtvec_irq15(void) __attribute__ ((interrupt ("machine"), weak, alias("riscv_nop_machine") ));
#endif // #ifndef VECTOR_TABLE_MTVEC_PLATFORM_INTS
#pragma GCC push_options
// Ensure the vector table is aligned.
// The bottom 4 bits of MTVEC are ignored - so align to 16 bytes
// Vector table. Do not call!
// Possible entries defined by mcause table
// http://five-embeddev.com/riscv-isa-manual/latest/machine.html#sec:mcause
//
// When vectored interrupts are enabled, interrupt cause 0, which
// corresponds to user-mode software interrupts, are vectored to the
// same location as synchronous exceptions. This ambiguity does not
// arise in practice, since user-mode software interrupts are either
// disabled or delegated to user mode.
void riscv_mtvec_table(void) {
__asm__ volatile (
".org riscv_mtvec_table + 0*4;"
"jal zero,riscv_mtvec_exception;" /* 0 */
".org riscv_mtvec_table + 1*4;"
"jal zero,riscv_mtvec_ssi;" /* 1 */
".org riscv_mtvec_table + 3*4;"
"jal zero,riscv_mtvec_msi;" /* 3 */
".org riscv_mtvec_table + 5*4;"
"jal zero,riscv_mtvec_sti;" /* 5 */
".org riscv_mtvec_table + 7*4;"
"jal zero,riscv_mtvec_mti;" /* 7 */
".org riscv_mtvec_table + 9*4;"
"jal zero,riscv_mtvec_sei;" /* 9 */
".org riscv_mtvec_table + 11*4;"
"jal zero,riscv_mtvec_mei;" /* 11 */
#ifndef VECTOR_TABLE_MTVEC_PLATFORM_INTS
".org riscv_mtvec_table + 16*4;"
"jal moonlight_mtvec_irq0;"
"jal moonlight_mtvec_irq1;"
"jal moonlight_mtvec_irq2;"
"jal moonlight_mtvec_irq3;"
"jal moonlight_mtvec_irq4;"
"jal moonlight_mtvec_irq5;"
"jal moonlight_mtvec_irq6;"
"jal moonlight_mtvec_irq7;"
"jal moonlight_mtvec_irq8;"
"jal moonlight_mtvec_irq9;"
"jal moonlight_mtvec_irq10;"
"jal moonlight_mtvec_irq11;"
"jal moonlight_mtvec_irq12;"
"jal moonlight_mtvec_irq13;"
"jal moonlight_mtvec_irq14;"
"jal moonlight_mtvec_irq15;"
#endif
: /* output: none */
: /* input : immediate */
: /* clobbers: none */
);
}
// Vector table. Do not call!
// See scause table for possible entries.
// http://five-embeddev.com/riscv-isa-manual/latest/supervisor.html#sec:scause
void riscv_stvec_table(void) {
__asm__ volatile (
".org riscv_stvec_table + 0*4;"
"jal zero,riscv_stvec_exception;" /* 0 */
".org riscv_stvec_table + 1*4;"
"jal zero,riscv_stvec_ssi;" /* 1 */
".org riscv_stvec_table + 5*4;"
"jal zero,riscv_stvec_sti;" /* 5 */
".org riscv_stvec_table + 9*4;"
"jal zero,riscv_stvec_sei;" /* 9 */
: /* output: none */
: /* input : immediate */
: /* clobbers: none */
);
}
// Vector table. Do not call!
void riscv_utvec_table(void) {
__asm__ volatile (
".org riscv_utvec_table + 0*4;"
"jal zero,riscv_utvec_usi;" /* 0 */
".org riscv_utvec_table + 4*4;"
"jal zero,riscv_utvec_uti;" /* 4 */
".org riscv_utvec_table + 8*4;"
"jal zero,riscv_utvec_uei;" /* 8 */
: /* output: none */
: /* input : immediate */
: /* clobbers: none */
);
}
// Ensure all ISR functions are aligned.
#pragma GCC optimize ("align-functions=4")
static void riscv_nop_machine(void) {
// Nop machine mode interrupt.
}
static void riscv_nop_supervisor(void) {
// Nop supervisor mode interrupt.
}
static void riscv_nop_user(void) {
// Nop user mode interrupt.
}
#pragma GCC pop_options