mips: deal with larger physical offsets
PATCH 4/9 mips: deal with larger physical offsets
TI AR7 has larger physical offsets than other MIPS-based systems. A long jump to the target is required instead of a short jump like on other systems.
Signed-off-by Eugene Konev <[email protected]>
Signed-off-by Florian Fainelli <[email protected]>
---
arch/mips/kernel/traps.c +16 -3
@@ -1256,9 +1256,22 @@ void *set_except_vector(int n, void *addr) exception_handlers[n] = handler;if (n ==0 && cpu_has_divec) { - *(u32 *)(ebase +0x200 ) =0x08000000 | - (0x03ffffff & (handler >>2 )); -local_flush_icache_range (ebase +0x200 , ebase +0x204 ); +if ((handler ^ (ebase +4 )) &0xfc000000 ) { +/* lui k0, 0x0000 */ + *(u32 *)(ebase +0x200 ) =0x3c1a0000 | (handler >>16 ); +/* ori k0, 0x0000 */ + *(u32 *)(ebase +0x204 ) = +0x375a0000 | (handler &0xffff ); +/* jr k0 */ + *(u32 *)(ebase +0x208 ) =0x03400008 ; +/* nop */ + *(u32 *)(ebase +0x20C ) =0x00000000 ; +local_flush_icache_range (ebase +0x200 , ebase +0x210 ); + }else { + *(u32 *)(ebase +0x200 ) = +0x08000000 | (0x03ffffff & (handler >>2 )); +local_flush_icache_range (ebase +0x200 , ebase +0x204 ); + } }return (void *)old_handler; }
Quoted 28 lines · Florian Fainelli
TI AR7 has larger physical offsets than other MIPS-based systems. A long jump to the target is required instead of a short jump like on other systems.
Signed-off-by Eugene Konev <[email protected]>Signed-off-by Florian Fainelli <[email protected]>---
arch/mips/kernel/traps.c +9
-3@@ -1256,9 +1256,22 @@ void *set_except_vector(int n, void *addr) exception_handlers[n] = handler;if (n ==0 && cpu_has_divec) { - *(u32 *)(ebase +0x200 ) =0x08000000 | - (0x03ffffff & (handler >>2 )); -local_flush_icache_range (ebase +0x200 , ebase +0x204 ); +if ((handler ^ (ebase +4 )) &0xfc000000 ) { +/* lui k0, 0x0000 */ + *(u32 *)(ebase +0x200 ) =0x3c1a0000 | (handler >>16 ); +/* ori k0, 0x0000 */ + *(u32 *)(ebase +0x204 ) = +0x375a0000 | (handler &0xffff ); +/* jr k0 */ + *(u32 *)(ebase +0x208 ) =0x03400008 ; +/* nop */
arch/mips/kernel/traps.c void *set_except_vector(int n, void *addr) · line 1277
Quoted 10 lines
arch/mips/kernel/traps.c +7
-0+ *(u32 *)(ebase +0x20C ) =0x00000000 ; +local_flush_icache_range (ebase +0x200 , ebase +0x210 ); + }else { + *(u32 *)(ebase +0x200 ) = +0x08000000 | (0x03ffffff & (handler >>2 )); +local_flush_icache_range (ebase +0x200 , ebase +0x204 ); + } }return (void *)old_handler; }
I had to do a similar change for my mapped kernel patch. However in mine, I used uasm. I wonder if the extra memory occupied by uasm is too steep a penalty to pay for the ability to use it outside of __init code.
If not, we should move uasm out of __init and use it instead of this
manual assembly.
David Daney