Application Processor Boot ROM

From MILEDROPEDIA
Jump to: navigation, search

Booting Flow

OMAP3430

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

Starting of Boot ROM

OMAP3430

  1. int rom_start()
  2. {
  3.   if ( (*(OMAP3430_reg_CONTROL_STATUS + 1) & 7) == 3 && (OMAP3430_reg_CONTROL_STATUS & 0x1F) == 31 ) {
  4.     boot_fast_XIP();
  5.   }
  6.   __set_CPSR(0xD3);
  7.   __mcr(15, 0, (uint8_t)ROM_LOAD_START, 12, 0, 0);
  8.   prepare_tracing_data();
  9.   memory_buffer |= tracing_Reset;
  10.   __mcr(15, 0, __mrc(15, 0, 1, 0, 0) | 0x1800, 1, 0, 0); // set high exception vectors, enable instructions caching
  11.   return memory_init();
  12. }

OMAP3630

OMAP4430

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.

Invalid language.

You need to specify a language like this: <source lang="html4strict">...</source>

Supported languages for syntax highlighting:

4cs, 6502acme, 6502kickass, 6502tasm, 68000devpac, abap, actionscript, actionscript3, ada, algol68, apache, applescript, apt_sources, arm, asm, asp, asymptote, autoconf, autohotkey, autoit, avisynth, awk, bascomavr, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, c_loadrunner, c_mac, caddcl, cadlisp, cfdg, cfm, chaiscript, cil, clojure, cmake, cobol, coffeescript, cpp, cpp-qt, csharp, css, cuesheet, d, dcl, dcpu16, dcs, delphi, diff, div, dos, dot, e, ecmascript, eiffel, email, epc, erlang, euphoria, f1, falcon, fo, fortran, freebasic, freeswitch, fsharp, gambas, gdb, genero, genie, gettext, glsl, gml, gnuplot, go, groovy, gwbasic, haskell, haxe, hicest, hq9plus, html4strict, html5, icon, idl, ini, inno, intercal, io, j, java, java5, javascript, jquery, kixtart, klonec, klonecpp, latex, lb, ldif, lisp, llvm, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, mmix, modula2, modula3, mpasm, mxml, mysql, nagios, netrexx, newlisp, nsis, oberon2, objc, objeck, ocaml, ocaml-brief, octave, oobas, oorexx, oracle11, oracle8, oxygene, oz, parasail, parigp, pascal, pcre, per, perl, perl6, pf, php, php-brief, pic16, pike, pixelbender, pli, plsql, postgresql, povray, powerbuilder, powershell, proftpd, progress, prolog, properties, providex, purebasic, pycon, pys60, python, q, qbasic, rails, rebol, reg, rexx, robots, rpmspec, rsplus, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty, spark, sparql, sql, stonescript, systemverilog, tcl, teraterm, text, thinbasic, tsql, typoscript, unicon, upc, urbi, uscript, vala, vb, vbnet, vedit, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xbasic, xml, xorg_conf, xpp, yaml, z80, zxbasic


0x40016FC0                 loc_ROM_40016FC0                                            ; CODE XREF: do_something_with_mmc+3E�j
0x40016FC0                                                                             ; do_something_with_mmc+4A�j
0x40016FC0 00C D4 F8 30 21                 LDR.W   R2, [R4,#0x130]                     ; Load from Memory
0x40016FC4 00C 00 2A                       CMP     R2, #0                              ; Set cond. codes on Op1 - Op2
0x40016FC6 00C FB D0                       BEQ     loc_ROM_40016FC0                    ; Branch
0x40016FC6
0x40016FC8 00C 15 04                       LSLS    R5, R2, #0x10                       ; Logical Shift Left
0x40016FCA 00C 01 D5                       BPL     loc_ROM_40016FD0                    ; Branch
0x40016FCA
0x40016FCC 00C 01 20                       MOVS    R0, #1                              ; Rd = Op2
0x40016FCE 00C 30 BD                       POP     {R4,R5,PC}                          ; Pop registers
0x40016FCE
0x40016FD0                 ; ---------------------------------------------------------------------------
0x40016FD0
0x40016FD0                 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

Invalid language.

You need to specify a language like this: <source lang="html4strict">...</source>

Supported languages for syntax highlighting:

4cs, 6502acme, 6502kickass, 6502tasm, 68000devpac, abap, actionscript, actionscript3, ada, algol68, apache, applescript, apt_sources, arm, asm, asp, asymptote, autoconf, autohotkey, autoit, avisynth, awk, bascomavr, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, c_loadrunner, c_mac, caddcl, cadlisp, cfdg, cfm, chaiscript, cil, clojure, cmake, cobol, coffeescript, cpp, cpp-qt, csharp, css, cuesheet, d, dcl, dcpu16, dcs, delphi, diff, div, dos, dot, e, ecmascript, eiffel, email, epc, erlang, euphoria, f1, falcon, fo, fortran, freebasic, freeswitch, fsharp, gambas, gdb, genero, genie, gettext, glsl, gml, gnuplot, go, groovy, gwbasic, haskell, haxe, hicest, hq9plus, html4strict, html5, icon, idl, ini, inno, intercal, io, j, java, java5, javascript, jquery, kixtart, klonec, klonecpp, latex, lb, ldif, lisp, llvm, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, mmix, modula2, modula3, mpasm, mxml, mysql, nagios, netrexx, newlisp, nsis, oberon2, objc, objeck, ocaml, ocaml-brief, octave, oobas, oorexx, oracle11, oracle8, oxygene, oz, parasail, parigp, pascal, pcre, per, perl, perl6, pf, php, php-brief, pic16, pike, pixelbender, pli, plsql, postgresql, povray, powerbuilder, powershell, proftpd, progress, prolog, properties, providex, purebasic, pycon, pys60, python, q, qbasic, rails, rebol, reg, rexx, robots, rpmspec, rsplus, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty, spark, sparql, sql, stonescript, systemverilog, tcl, teraterm, text, thinbasic, tsql, typoscript, unicon, upc, urbi, uscript, vala, vb, vbnet, vedit, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xbasic, xml, xorg_conf, xpp, yaml, z80, zxbasic


0x400144DE 000 01 61                       STR     R1, [R0,#0x10]
0x400144DE
0x400144E0
0x400144E0                 loc_ROM_400144E0
0x400144E0 000 41 69                       LDR     R1, [R0,#0x14]
0x400144E2 000 C9 07                       LSLS    R1, R1, #0x1F
0x400144E4 000 FC D0                       BEQ     loc_ROM_400144E0
--
0x400145F8 004 81 40                       LSLS    R1, R0
0x400145F8
0x400145FA
0x400145FA                 loc_ROM_400145FA
0x400145FA 004 50 6D                       LDR     R0, [R2,#0x54]
0x400145FC 004 08 42                       TST     R0, R1
0x400145FE 004 FC D0                       BEQ     loc_ROM_400145FA
--

ROM CRC check

  1. int ROM_CRC_check(int bits_mode, char *membuf)
  2. {
  3.   int result;
  4.   char *var_0;
  5.   int var_1;
  6.   char *pa;
  7.  
  8.   result = membuf[0];
  9.   if ( !membuf ) {
  10.     standard_memclr(membuf, 69);
  11.     membuf[1] = 1;
  12.     membuf[2] = 5;
  13.     membuf[3] = 1;
  14.     membuf[4] = 52;
  15.     membuf[5] = 48;
  16.     membuf[6] = 7;
  17.     membuf[7] = *(uint32_t)0x1BFFC;
  18.     membuf[8] = 19;
  19.     membuf[9] = 2;
  20.     membuf[10] = 1;
  21.     membuf[12] = 18;
  22.     membuf[13] = 21;
  23.     membuf[14] = 1;
  24.     membuf[35] = 20;
  25.     membuf[36] = 21;
  26.     membuf[37] = 1;
  27.     membuf[58] = 21;
  28.     membuf[59] = 9;
  29.     membuf[60] = 1;
  30.     standard_uwrite4(*(uint32_t)0x14020, membuf[61]);
  31.     result = security_check_GP_mode();
  32.     if ( result ) {
  33.       tbf[11] = security_check_HS_mode();
  34.       security_call_SSID_0x1E(membuf[15]);
  35.       security_call_SSID_0x1F(pa);
  36.       var_0 = standard_memmove(membuf[38], pa, 20);
  37.       var_1 = security_call_SSID_0x22(var_0);
  38.       result = standard_uwrite4(var_1, membuf[65]);
  39.     }
  40.   }
  41.   if ( bits_mode == 16 ) {
  42.     result = 4;
  43.     membuf[0] = 4;
  44.   } else {
  45.     membuf[0] = 5;
  46.   }
  47.   return result;
  48. }

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 */