initial commit
This commit is contained in:
166
port/moonlight/vector_table.c
Normal file
166
port/moonlight/vector_table.c
Normal 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
|
||||
Reference in New Issue
Block a user