Commit 682fb5be authored by Thomas Bogendoerfer's avatar Thomas Bogendoerfer

MIPS: Allow vectored interrupt handler to reside everywhere for 64bit

Setting up vector interrupts worked only with handlers, which resided
in CKSEG0 space. This limits the kernel placement for 64bit platforms.
By patching in the offset into vi_handlers[] instead of the full
handler address, the vectored exception handler can load the
address by itself and jump to it.
Signed-off-by: default avatarThomas Bogendoerfer <tsbogend@alpha.franken.de>
Reviewed-by: default avatarJiaxun Yang <jiaxun.yang@flygoat.com>
parent efe8ee1a
......@@ -272,18 +272,17 @@ NESTED(except_vec_vi, 0, sp)
.set push
.set noreorder
PTR_LA v1, except_vec_vi_handler
FEXPORT(except_vec_vi_lui)
lui v0, 0 /* Patched */
jr v1
FEXPORT(except_vec_vi_ori)
ori v0, 0 /* Patched */
ori v0, zero, 0 /* Offset in vi_handlers[] */
.set pop
END(except_vec_vi)
EXPORT(except_vec_vi_end)
/*
* Common Vectored Interrupt code
* Complete the register saves and invoke the handler which is passed in $v0
* Complete the register saves and invoke the handler, $v0 holds
* offset into vi_handlers[]
*/
NESTED(except_vec_vi_handler, 0, sp)
SAVE_TEMP
......@@ -331,6 +330,7 @@ NESTED(except_vec_vi_handler, 0, sp)
/* Save task's sp on IRQ stack so that unwinding can follow it */
LONG_S s1, 0(sp)
2:
PTR_L v0, vi_handlers(v0)
jalr v0
/* Restore sp */
......
......@@ -2091,16 +2091,14 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
* If no shadow set is selected then use the default handler
* that does normal register saving and standard interrupt exit
*/
extern const u8 except_vec_vi[], except_vec_vi_lui[];
extern const u8 except_vec_vi[];
extern const u8 except_vec_vi_ori[], except_vec_vi_end[];
extern const u8 rollback_except_vec_vi[];
const u8 *vec_start = using_rollback_handler() ?
rollback_except_vec_vi : except_vec_vi;
#if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN)
const int lui_offset = except_vec_vi_lui - vec_start + 2;
const int ori_offset = except_vec_vi_ori - vec_start + 2;
#else
const int lui_offset = except_vec_vi_lui - vec_start;
const int ori_offset = except_vec_vi_ori - vec_start;
#endif
const int handler_len = except_vec_vi_end - vec_start;
......@@ -2119,10 +2117,9 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
#else
handler_len);
#endif
h = (u16 *)(b + lui_offset);
*h = (handler >> 16) & 0xffff;
/* insert offset into vi_handlers[] */
h = (u16 *)(b + ori_offset);
*h = (handler & 0xffff);
*h = n * sizeof(handler);
local_flush_icache_range((unsigned long)b,
(unsigned long)(b+handler_len));
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment