问题
I am booting Android on an IMX53 Sabre tablet. The last few lines seen on serial port as android boots up normally is as follows:
warning: `rild' uses 32-bit capabilities (legacy support in use)
pmem: request for physical address of pmem region from process 2262.
request_suspend_state: on (3->0) at 12032459753 (2000-01-03
01:08:28.336600001 U
TC)
Unhandled fault: external abort on non-linefetch (0x1018) at 0x40a85054
Unhandled fault: external abort on non-linefetch (0x1018) at 0x40a85054
Note, these external aborts do not stop the boot process and Android boots normally. Now I want to use these external aborts to test my monitor abort handler code. I want the ability to trap external aborts to monitor.
In initialization of secure monitor, I do the following:
mrc p15, 0, r4, c1, c1, 0
bic r4, #0x66 @ clear AW, IRQ, FIQ
orr r4, #0x19 @ set FW, EA, NS
//orr r4, #0x01 @ previously, just set NS
mcr p15, 0, r4, c1, c1, 0
My monitor vector table looks as follows:
.global tz_monitor
.align 5
tz_monitor:
@ Monitor
b _monitor_reset @ Reset
b _monitor_undef @ Undef
b smc_handler @ SMC
b _monitor_prefetch @ Prefetch
b _monitor_da @ Data abort
nop @ RESERVED
b _monitor_irq @IRQ
b _monitor_fiq @FIQ
An example exception handler function just prints a statement and looks as follows: In assembly:
.global _monitor_prefetch
_monitor_prefetch:
push {lr}
bl monitor_prefetch
pop {lr}
movs pc, lr
In C:
void monitor_prefetch(void) {
printf("In Monitor's Prefetch Handler\n");
}
I add this vector table in initialization of secure monitor as follows:
ldr r0, =tz_monitor @ Get address of Monitors vector table
mcr p15, 0, r0, c12, c0, 1 @ Write Monitor Vector Address Register
There is change with these modifications, namely kernel crashes at the point of external abort. But I do not get the print statement in the monitor handler. I get the following output on serial now, when booting Android:
warning: `rild' uses 32-bit capabilities (legacy support in use)
pmem: request for physical address of pmem region from process 2262.
request_suspend_state: on (3->0) at 12005333628 (2000-01-03
00:38:52.322241626 UTC)
Bad mode in prefetch abort handler detected
Internal error: Oops - bad mode: 0 [#1] PREEMPT
last sysfs file: /sys/devices/platform/pwm-backlight.0/backlight/pwm-
backlight.0/brightness
Modules linked in:
CPU: 0 Not tainted (2.6.35.3-01265-g8f56f17 #6)
PC is at 0x77802570
LR is at 0xafd0bf6c
pc : [<77802570>] lr : [<afd0bf6c>] psr: 200001d6
sp : ce0e7fb0 ip : 8151c780 fp : 00000001
r10: 00000000 r9 : 40a85000 r8 : 00000002
r7 : 4090ae64 r6 : 8151c890 r5 : 00000018 r4 : 40207000
r3 : 40a85000 r2 : 00000001 r1 : 60000010 r0 : 00000000
Flags: nzCv IRQs off FIQs off Mode UK6_32 ISA ARM Segment user
Control: 10c5387d Table: 83668019 DAC: 00000015
Process Binder Thread # (pid: 2307, stack limit = 0xce0e62e8)
Stack: (0xce0e7fb0 to 0xce0e8000)
7fa0: 00000000 60000010 00000001
40a85000
7fc0: 40207000 00000018 8151c890 4090ae64 00000002 40a85000 00000000
00000001
7fe0: 8151c780 ce0e7fb0 afd0bf6c 77802570 200001d6 ffffffff ffc75a9a
dfd4eed7
Code: bad PC value
---[ end trace d8447dd37d1d45d8 ]---
Kernel panic - not syncing: Fatal exception
[<c003e58c>] (unwind_backtrace+0x0/0xf0) from [<c04862f0>]
(panic+0x6c/0xe0)
[<c04862f0>] (panic+0x6c/0xe0) from [<c003d420>] (die+0x2b4/0x304)
[<c003d420>] (die+0x2b4/0x304) from [<c003d4ac>] (bad_mode+0x3c/0x5c)
[<c003d4ac>] (bad_mode+0x3c/0x5c) from [<afd0bf6c>] (0xafd0bf6c)
Do I need some other setting to trap the abort to monitor mode? Eventually I will set CSU to make peripherals like I2C0/IPU secure and trap and emulate aborts for those peripherals. But I need to do this first step of directing an abort to a monitor handler function. Can someone please help?
EDIT
First let me try the prefetch abort handler without any printf (to reduce where errors are coming from). So the goal is: abort comes to the monitor, and the monitor just gives back control to the NW again, as this abort is not of interest.
Essentially, there is only one bit in SCR to specify what should happen to any abort. But I might be interested only in data aborts (that also when access happens for some particular peripheral). So this first step is to just give back control to NW, when the prefetch abort happens.
The following code as prefetch handler has the same output: crash with "Bad mode in prefetch abort handler detected".
.global tz_monitor
.align 5
tz_monitor:
@ Monitor
nop @ Reset - not used by Monitor
nop @ Undef - not used by Monitor
b smc_handler
b pabort_handler @ Prefetch - can by used by Monitor
b dabort_handler @ Data abort - can by used by Monitor
nop @ RESERVED
nop @ IRQ - can by used by Monitor
nop @ FIQ - can by used by Monitor
.global pabort_handler
pabort_handler:
sub r14, r14, #4 @ on excpetion, processor stores current pc to r14 or link register (lr), decrement by 4 for prefetch abort
stmfd sp!, {r14} @ save lr, to know where to return from exception
mrs r14, spsr @ on exception, processor stores current cpsr to spsr, read this to r14
stmfd sp!, {r0-r12, r14} @ save r14 and therefore spsr, also store general purpose registers r0-r12
mrc p15, 0, r4, c1, c1, 0 @ Read Secure Configuration Register data
bic r4, #NS_BIT @ clear NS bit
mcr p15, 0, r4, c1, c1, 0 @ Write Secure Configuration Register data
//bl monitor_prefetch @no printing for now
mrc p15, 0, r4, c1, c1, 0 @ Read Secure Configuration Register data
orr r4, #NS_BIT @ Set NS bit
mcr p15, 0, r4, c1, c1, 0 @ Write Secure Configuration Register data
ldmfd sp!,{r0-r12, r14} @ restore from stack general purpose registers and read spsr value to r14
msr spsr, r14 @ restore spsr from r14
ldmfd sp!, {pc}^ @ restore from stack lr-4 and set pc, the ^ denotes cpsr to be set with spsr
.global dabort_handler
dabort_handler:
sub r14, r14, #8 @ on excpetion, processor stores current pc to r14 or link register (lr), decrement by 8 for data abort
stmfd sp!, {r14} @ save lr, to know where to return from exception
mrs r14, spsr @ on exception, processor stores current cpsr to spsr, read this to r14
stmfd sp!, {r0-r12, r14} @ save r14 and therefore spsr, also store general purpose registers r0-r12
mrc p15, 0, r4, c1, c1, 0 @ Read Secure Configuration Register data
bic r4, #NS_BIT @ clear NS bit
mcr p15, 0, r4, c1, c1, 0 @ Write Secure Configuration Register data
//bl monitor_prefetch @no printing for now
mrc p15, 0, r4, c1, c1, 0 @ Read Secure Configuration Register data
orr r4, #NS_BIT @ Set NS bit
mcr p15, 0, r4, c1, c1, 0 @ Write Secure Configuration Register data
ldmfd sp!,{r0-r12, r14} @ restore from stack general purpose registers and read spsr value to r14
msr spsr, r14 @ restore spsr from r14
ldmfd sp!, {pc}^ @ restore from stack lr-4 and set pc, the ^ denotes cpsr to be set with spsr
来源:https://stackoverflow.com/questions/43100405/imx53-external-abort