Application Processor Boot ROM
Contents
Booting Flow
ROM table
The DAP (Debug Access Port, see CoreSight manual) provides an internal ROM table connected to the master Debug APB port of the APB-Mux. The Debug ROM table is loaded at address 0x00000000 and 0x80000000 of this bus and is accessible from both APB-AP and the system APB input. Bit [31] of the address bus is not connected to the ROM Table, ensuring that both views read the same value. The ROM table stores the locations of the components on the Debug APB. See the CoreSight Architecture Specification for more information. The ROM table has a standard APB interface except for the exclusion of PWRITEDBG and PWDATADBG. All transfers are assumed to be reads. The ROM table is a read-only device and writes are ignored.
ROM table registers
Offset | Type | Bits | Name | Function |
---|---|---|---|---|
0xFDC | - | [7:0] | Peripheral ID7 | Reserved SBZ. Read as 0x00. |
0xFD8 | - | [7:0] | Peripheral ID6 | Reserved SBZ. Read as 0x00. |
0xFD4 | - | [7:0] | Peripheral ID5 | Reserved SBZ. Read as 0x00. |
0xFD0 RO [7:4] Peripheral ID4 4KB count, set to 0x0. [3:0] 0xFEC RO [7:4] JEP106 continuation code, implementation defined. Peripheral ID3 [3:0] 0xFE8 RO [7:4] RevAnd, at top level, implementation defined. Customer Modified, implementation defined. Peripheral ID2 Revision number of Peripheral, implementation defined. [3] [2:0] 0xFE4 RO 1 = indicates that a JEDEC assigned value is used. 0 = indicates that a JEDEC assigned value is not used. JEP106 Identity Code [6:4], implementation defined. [7:4] Peripheral ID1 [3:0] 0xFE0 2-72 RO [7:0] JEP106 Identity Code [3:0], implementation defined. PartNumber1, implementation defined. Peripheral ID0 PartNumber0, implementation defined. 0xFF0 RO [7:0] Component ID0 Preamble. Set to 0x0D. 0xFF4 RO [7:0] Component ID1 Preamble. Set to 0x10. 0xFF8 RO [7:0] Component ID2 Preamble. Set to 0x05. 0xFFC RO [7:0] Component ID3 Preamble. Set to 0xB1.
The ROM table has a specific PrimeCell class. In all registers 0xFD0-0xFFC, bits [31:8] are reserved and should be read as zero. Locations 0xF00-0xFCC are reserved and should be read as zero.
ROM table entries
Table shows the ROM table entries bit assignments for each entry in the 0x000-0xEFC region:
Bits | Name | Description |
---|---|---|
[31:12] | Address offset | Base address of the component, relative to the ROM address. Negative values are permitted using two's complement. ComponentAddress = ROMAddress + (AddressOffset SHL 12). |
[11:2] | none | Reserved SBZ. |
[1] | Format | 1 = 32-bit format. In the DAP Debug ROM this is set to 1. 0 = 8-bit format. |
[0] | Entry present | Set HIGH to indicate an entry is present. |
The last entry in the ROM table has the value 0x00000000, which is reserved.If the
CoreSight component occupies several consecutive 4KB blocks, the base address of the
lowest block in memory is given. The locations of components are stored in sequential
locations with the ROM table. The entry following the last component in the table must
read 0x00000000, and subsequent locations are assumed to read as zero.
Public part of Application Boot ROM
Interesting concurrency loop
It is eventually found that in do_something_with_mmc@40016f88, a short loop expect changes in memory by external means.
R4 is never updated in the loop loc_ROM_40016FC0 but [R4+0x130] is expected to change by the following logics. So it is suspected that there is multi-thread operation or parallel operation with other processor like DSP or the like.
Since concurrency could be tricky, loops with this pattern should be found and further analysed.
40016FC0 loc_ROM_40016FC0 ; CODE XREF: do_something_with_mmc+3E�j 40016FC0 ; do_something_with_mmc+4A�j 40016FC0 00C D4 F8 30 21 LDR.W R2, [R4,#0x130] ; Load from Memory 40016FC4 00C 00 2A CMP R2, #0 ; Set cond. codes on Op1 - Op2 40016FC6 00C FB D0 BEQ loc_ROM_40016FC0 ; Branch 40016FC6 40016FC8 00C 15 04 LSLS R5, R2, #0x10 ; Logical Shift Left 40016FCA 00C 01 D5 BPL loc_ROM_40016FD0 ; Branch 40016FCA 40016FCC 00C 01 20 MOVS R0, #1 ; Rd = Op2 40016FCE 00C 30 BD POP {R4,R5,PC} ; Pop registers 40016FCE 40016FD0 ; --------------------------------------------------------------------------- 40016FD0 40016FD0 loc_ROM_40016FD0 ; CODE XREF: do_something_with_mmc+42�j
comment: in this example LDR.W R2, [R4,#0x130] really read not from memory, but from registers of mmc peripherals, so it can change as the state of that peripheral changes.. but there are also irq handlers, that interrupts the main thread and perform some actions that can change memory.
How to locate this kind of loop?
- Open rom3.idb, set "number of opcode bytes" to 4 then copy all the text and save as a text file.
- Use this RE to locate short loops(adjust the parameters as necessary):
grep -B 6 -E "[0-9]{3} F. D." rom3.txt
Sample snippet grep'ed
400144DE 000 01 61 STR R1, [R0,#0x10] 400144DE 400144E0 400144E0 loc_ROM_400144E0 400144E0 000 41 69 LDR R1, [R0,#0x14] 400144E2 000 C9 07 LSLS R1, R1, #0x1F 400144E4 000 FC D0 BEQ loc_ROM_400144E0 -- 400145F8 004 81 40 LSLS R1, R0 400145F8 400145FA 400145FA loc_ROM_400145FA 400145FA 004 50 6D LDR R0, [R2,#0x54] 400145FC 004 08 42 TST R0, R1 400145FE 004 FC D0 BEQ loc_ROM_400145FA --
Secure part of Application Processor Boot ROM
impossible to dump - fully hardware implemented in cortex-a8 core; used by some handlers in BootROM/mbmloader for SVC/SMC calling. and some wrappers for secure coprocessor operations
Power up reason
The boot ROM will pass the power up reason via atag. This info can be found from two places: 1) dmesg; 2) /proc/bootinfo .
See bootinfo.h for the interpretation of the power up reason:
#define PU_REASON_USB_CABLE 0x00000010 /* Bit 4 */ #define PU_REASON_FACTORY_CABLE 0x00000020 /* Bit 5 */ #define PU_REASON_PWR_KEY_PRESS 0x00000080 /* Bit 7 */ #define PU_REASON_CHARGER 0x00000100 /* Bit 8 */ #define PU_REASON_POWER_CUT 0x00000200 /* bit 9 */ #define PU_REASON_SW_AP_RESET 0x00004000 /* Bit 14 */ #define PU_REASON_WDOG_AP_RESET 0x00008000 /* Bit 15 */ #define PU_REASON_AP_KERNEL_PANIC 0x00020000 /* Bit 17 */