I am cross compiling with riscv-corev32-elf-gcc.
In a first file 'generic.S' I have the following code:
.section .text.handlers
.weak u_sw_irq_handler
.weak __no_irq_handler
.section .vectors, "ax"
vector_table:
jal x0, u_sw_irq_handler
jal x0, __no_irq_handler
jal x0, __no_irq_handler
...
.section .text
reset_handler:
la t0, vector_table
csrw mtvec, t0
In a second file 'custom.S' I have the following code:
.section .text.handlers
.<x> u_sw_irq_handler
.<x> __no_irq_handler
.section .vectors, "ax"
vector_table:
jal x0, u_sw_irq_handler
jal x0, ISR_1_handler
jal x0, ISR_2_handler
...
where <x> is either global or local
when global, this is the (partial) result of the disassembly:
00001000 <vector_table>:
1000: 7760d06f j e776 <u_sw_irq_handler>
1004: 1880706f j 81cc <ISR_1_handler>
1008: 1e40706f j 822c <ISR_2_handler>
...
1084: 7760d06f j e776 <u_sw_irq_handler>
1088: 7320d06f j e736 <__no_irq_handler>
108c: 72e0d06f j e736 <__no_irq_handler>
...
00001108 <reset_handler>:
1108: 00000297 auipc t0,0x0
110c: f7c28293 addi t0,t0,-264 # 1000 <vector_table>
1110: 30529073 csrw mtvec,t0
when local, this is the (partial) result of the disassembly:
00001000 <vector_table>:
1000: 7760d06f j e776 <u_sw_irq_handler>
1004: 1880706f j 81cc <ISR_1_handler>
1008: 1e40706f j 822c <ISR_2_handler>
...
00001084 <vector_table>:
1084: 7760d06f j e776 <u_sw_irq_handler>
1088: 7320d06f j e736 <__no_irq_handler>
108c: 72e0d06f j e736 <__no_irq_handler>
...
00001108 <reset_handler>:
1108: 00000297 auipc t0,0x0
110c: f7c28293 addi t0,t0,-132 # 1084 <vector_table>
1110: 30529073 csrw mtvec,t0
But this not what I want:
I want the generic definition to be taken if there is no other definition of vector_table
I want the generic definition to be overwritten by the custom.S definition if it exists, and the reset_handler in the generic.S to load the custom address of the vector_table
using 'global' is the closer of what I want but the vector_table continues the
jal x0, ...after the last vectorusing 'local' the vector_table called in the reset_handler will be the generic one and not the custom.
edit: sorry I missed matched the logs for the reset handler disassembly
weakworks differently than you think:weakmakes a symbol global if the symbol does not exist in another object file and it makes a symbol itself (!) disappear if it exists in another object file.Example (sorry that my examples are x86 because I don't know riscv32):
If no other object file contains
.global some_irq_handlernor.global some_other_irq_handler, the.weaklines nearly have the same effect as.globallines.However, if another object file contains these two symbols, the example above is more or less equal to:
Case 1: The
vector_tableneeds not to be located at a certain address in memory:In this case you can do it the following way:
If another vector table is present in you project, the resulting code (after linking) will look like this:
Case 2: The
vector_tableneeds to be located at a certain address in memory:In this case, you can do it the following way:
You will never overwrite the "generic" interrupt vector table by another one but you only overwrite the symbols
interrupt<n>:(This will also work with C-written code. Because the C compiler makes functions
.globaland not.weakby default, the C-written function overwrites the.weakone.)The resulting code will then look like this: