9bb6050d40
Since we can catch exceptions like data aborts on read/write, it takes very little to also catch exceptions in calls. When extending this with the catching of illegal instructions, the call instruction now becomes much more robust and also for address and instruction probing. Since we can catch several types of exception, rename set_data_abort_jmp to set_exception_jmp. At the same time, simplify the logic in read/write request handlers. Also fix a bug in ARM jump code: it was using stmia r1, {..., pc} as if pc would get current pc + 8 but this is actually implementation defined on older ARMs (typically pc + 12) and deprecated on newer ARMs, so rewrite the code avoid that. The set_exception_jmp() function now also reports the exception type. Change-Id: Icd0dd52d2456b361b27c4776be09c3d13528ed93
106 lines
3.2 KiB
ArmAsm
106 lines
3.2 KiB
ArmAsm
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
*
|
|
* Copyright (C) 2015 by Marcin Bukat
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
#include "mips.h"
|
|
#include "target-config.h"
|
|
#include "system.h"
|
|
|
|
/* Handling of exception:
|
|
* the code can register a "longjmp" buffer to restore the context in case of
|
|
* fault */
|
|
.data
|
|
.global exception_jmp_ctx_ptr
|
|
exception_jmp_ctx_ptr:
|
|
/* buffer contains in order: s0-s7, sp, s8, ra */
|
|
.skip 44 /* = 4 * (9 callee saved registers + sp + ra) */
|
|
|
|
.set noreorder
|
|
.section .icode, "ax", %progbits
|
|
/* Prototype: int set_exception_jmp()
|
|
* Return: 1 in case of data abort, 0 otherwise */
|
|
.global set_exception_jmp
|
|
set_exception_jmp:
|
|
la v0, exception_jmp_ctx_ptr
|
|
sw s0, 0(v0)
|
|
sw s1, 4(v0)
|
|
sw s2, 8(v0)
|
|
sw s3, 12(v0)
|
|
sw s4, 16(v0)
|
|
sw s5, 20(v0)
|
|
sw s6, 24(v0)
|
|
sw s7, 28(v0)
|
|
sw sp, 32(v0)
|
|
sw s8, 36(v0)
|
|
sw ra, 40(v0)
|
|
jr ra
|
|
move v0, zero
|
|
|
|
/* restore context on read/write error, performs the interrupt return
|
|
* arguments:
|
|
* a0: exception type (EXCEPTION_*) */
|
|
.global restore_exception_jmp
|
|
restore_exception_jmp:
|
|
la k1, exception_jmp_ctx_ptr
|
|
lw s0, 0(k1)
|
|
lw s1, 4(k1)
|
|
lw s2, 8(k1)
|
|
lw s3, 12(k1)
|
|
lw s4, 16(k1)
|
|
lw s5, 20(k1)
|
|
lw s6, 24(k1)
|
|
lw s7, 28(k1)
|
|
lw sp, 32(k1)
|
|
lw s8, 36(k1)
|
|
lw k1, 40(k1)
|
|
mtc0 k1, C0_EPC
|
|
#ifdef CONFIG_JZ4760B
|
|
/* XBurst has a 3 interlock cycle delay, but we don't know if the interlock
|
|
* works with eret */
|
|
nop
|
|
#else
|
|
ehb
|
|
#endif
|
|
move v0, a0 /* set exception type */
|
|
eret
|
|
nop
|
|
.set reorder
|
|
|
|
#ifdef CONFIG_FLUSH_CACHES
|
|
.set noreorder
|
|
.text
|
|
.global target_flush_caches
|
|
target_flush_caches:
|
|
/* commit dcache and invalidate icache */
|
|
la t0, 0x80000000 /* an idx op should use an unmappable address */
|
|
ori t1, t0, DCACHE_SIZE /* cache size */
|
|
reloc_dcache_loop:
|
|
cache DCIndexWBInv, 0(t0) /* invalidate and write-back dcache index */
|
|
addiu t0, t0, DCACHE_LINE_SIZE /* bytes per cache line */
|
|
bne t0, t1, reloc_dcache_loop
|
|
nop
|
|
la t0, 0x80000000 /* an idx op should use an unmappable address */
|
|
ori t1, t0, ICACHE_SIZE /* cache size */
|
|
reloc_icache_loop:
|
|
cache ICIndexInv, 0(t0) /* invalidate icache index */
|
|
addiu t0, t0, ICACHE_LINE_SIZE /* bytes per cache line */
|
|
bne t0, t1, reloc_icache_loop
|
|
nop
|
|
jr ra
|
|
nop
|
|
#endif
|