Application Processor Boot ROM

Revision as of 20:07, 22 March 2011 by Nothize (Talk | contribs)

Jump to: navigation, search

Booting Flow

Omap bootrom boot.png

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
40016FC8 00C 15 04                       LSLS    R5, R2, #0x10                       ; Logical Shift Left
40016FCA 00C 01 D5                       BPL     loc_ROM_40016FD0                    ; Branch
40016FCC 00C 01 20                       MOVS    R0, #1                              ; Rd = Op2
40016FCE 00C 30 BD                       POP     {R4,R5,PC}                          ; Pop registers
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?

  1. Open rom3.idb, set "number of opcode bytes" to 4 then copy all the text and save as a text file.
  2. 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]
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
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 */