============ ARM CPU Core ============ - Probably some type of ARM7 - Supports 32-bit ARM and 16-bit Thumb - Might have a flash icache, not sure yet - Not Thumb-2 - No cp15 (not sure how to control cache, get CPU ID) - Not fast. About 2 MIPS running Thumb NOPs from DRAM. - Has blx - Has muls, mla, umull Vector Table ------------ The area from 10000 - 102ff is set aside by the bootloader protocol for interrupt vectors. The hardware IVT is at address 0, covered by a 0x400 byte SRAM mapping by the standard firmawre. 00: reset 04: ARM undefined instruction 08: ARM software interrupt -- hangs (infinite loop) 0c: ARM prefetch abort exception -- unused normally; we use this to implement %hook 10: ARM data abort exception -- unused normally 18: hardware interrupt - SCSI / inter-processor comms 1c: FIQ hardware interrupt - Eject button? Not sure if these are actually vectors or they just look similar: 40: Very complex (IPC?) message handler? 46: SCSI command handler? Cryptography ------------ Annoyingly but not necessarily suprisingly, I'm hitting cryptography already just in trying to understand the boot process. It's likely someone thought the firmware should include a chain of trust for something related to video DRM or possibly protecting intellectual property. It's annoying, and hopefully not very thorough. - Uses 128-bit blocks. It's likely AES, but I don't really know yet - A block cipher core lives at [4063000] - There also appears to be transparent decryption for code memory. The bootloader includes one encrypted region at 000:fff, but the application firmware includes many more. Unused areas at the end of these blocks exhibit a characteristic repeating 16-byte pattern, which seems like the transparent cipher would be using ECB mode. Every individually encrypted code block seems to use a different key. The blocks in the main app are prefixed with a NOP sled and an MSR instruction which enables supervisor mode. This hardware probably has a poweron default to be active for memory at 000:fff, hence the encrypted IVT in the bootloader. Hardware Memory Map ------------------- * 00000000 - 001fffff Flash (2MB) 00000000 - 0000ffff Write-protected bootloader flash (64kB) 00010000 - 001e1fff Loadable firmware image (1863 kB) 001e2000 - 001fffff Runtime storage and bootloader info (120 kB) * 01c08000 - 02007fff DRAM (4MB) 01c08000 - 01ffffff Shared DRAM 02000000 - 02001fff System DRAM (32 kB) 04000000 - 043fffff Memory mapped I/O DRAM ---- I'm not yet sure where DRAM is usually mapped in the ARM address space. It's usually accessed indirectly, via ref[20]. I've been referring to this space a lot as '8051' address space because I saw the ARM copy the 8051 firmware image there, but now that I've figured out how to dump it using undocumented SCSI command 3C02, the whole DRAM area can be examined. When dumping from the bootloader after cold boot, the characteristic noisy checkerboard patterns of DRAM's wiring show up in the uninitialized areas. 0 - fff [BOOT] uninitialized [TS01] Array with 8-byte records 1000 - 2fff 8051 program memory 3000 - 1f7fff [BOOT] uninitialized 1f8000 - 3fffff gobs of loosely structured data! It could be more code data here, but my hunch is that this is a ring buffer of command data structures. Many of the repeating blocks look like they could be arguments, and I feel like a sufficiently awesome tool could convert this into a log of recent transfers. All signs point to the DRAM region being 4MB in size. This is the size of the "cache memory" advertised for the device, and it looks like at 400000 and after, the same 2MB of memory mirrors over and over. Most of this memory seems to be dynamically allocated, so it often has useful tidbits in it but the overall structure varies wildly from run to run. Memory Mapped I/O ----------------- This processor has a substantial zoo of memory mapped peripherals. Very rough notes, may be wildly wrong. 4000000 Low level system control, interrupt enables 4000000 uint32 Flags 10 Global interrupt enable? 4001000 Reset control 4002000 GPIO, System Timer 4002004 uint32 Flags Read only 800 40 10 Eject button, 1=open, 0=pressed 8 4 Tray sensor nearest to edge, 1=open 0=closed - Both tray sensors affect other registers, probably because they have hardware power supply interlocks to prevent the laser from firing when open. But only the outermost switch is directly readable via GPIO. 2 NOTE: This may not be generated directly by hardware, this may be the result of some other software or SoC process. When pressing the tray button, reg [4002084] changes 80ms ahead of this one. 4002028 uint32 Interrupt flags? 400202c uint32 Interrupt vector pointer? 4002058 uint32 "App select", affects bootloader in many ways Fully read/write. May be intended for firmware use, perhaps this survives some forms of reset. 4002064 uint32 Used by ISR 1c 4002078 uint32 System tick counter, 512*1024 Hz 4002084 uint32 Flags Read only 1 2 4 8 400 Also changing frequently 800 1000 100000 2000000 8000000 10000000 Eject button 20000000 Tray sensor NOTE: Possibly a lower-level version of [4002004] 4002088 uint32 flags Outputs, a few bits not implemented wwww_00ww_wwww_wwww_wwww_wwww_wwww_0www 0 3 0 3 0 3 0 3 LED 1 2 Solenoid 100 200 Solenoid 10000 20000 1000000 \ LED enable, 1=off, 0=on 2000000 / LED control, 1=off, 0=on 4002108 uint32 - Clear upper half (ldrh/str) to ack interrupt 4002120 4003000 4004000 4004800 4010000 8051 Co-processor 4010000 uint8 write FIFO 4010008 uint32 Write-1-to-clear? 4010009 uint8 4011000 Coprocessor and encryption memory mapping control Possibly inter-processor message notification 4011000 uint32 Flags 80 Set at the top of bootloader app_main 4011008 uint32 Low 10 bits (count?) set to 1 in app_main 401100c uint32 Flags 4 Set after polling [4011088] 2 Set / op / clear in app_main 4011010 uint8 Flags 8 Wait for 0 (second) 4 Wait for 1 (first) 4011040 uint32 Flags 1 Set while booting app firmware, in bootloader 4011050 uint32 Flags 1 Cleared after polling [4011088] - Transparent 128-bit code decryption, possibly AES-ECB mode 4011064 uint32 Flags 4 Transparent encryption enabled 4011068 uint32 First address of transparent encryption region 401106c uint32 Last address in transparent encryption region - Status? 4011088 uint32 Flags 1 Poll for bit=1 after setting [4011000] |= 80 - Movable memory regions This register runs the show: 4011f04 uint32 Flags 800 Set by boot0 400 Enable flag 200 Enable flag, set by boot0 100 Enable flag, set by boot0 Then we have these pairs of first-address / last-address registers. Just the ones that are definitely addresses: 4011f08 / 4011f0c First 4k of address space 4011f10 / 4011f14 Function in app flash, cfbe4 Also seen at 400000:400bff:400c00:400fff for mapped memcpys This seems to be an SRAM page used by the firmware to accelerate specific functions in flash by copying them to RAM. 4011f20 / 4011f24 All of flash 4011f50 / 4011f54 In the firmware startup code, 1ec00:1efff 4011f58 / 4011f5c Much later in flash, 169220:16961f 4011f60 / 4011f64 Bootloader, 2800:2fff Mappings have a fixed source size, after which they repeat. Mappings work for any address below 800000 (First 8MB). So, these mappings it seems can't overwrite DRAM or MMIO space, but they can be in the address space accessible to DMA. 4020000 4020f00 Related to RAM region 2000000, set up during boot0 4020f04 uint32 Flags 800 Set by boot0 4030000 RAM region setup / DMA engine 40300e8 uint32 Mapped pointer for SCSI device-to-host transfer (DMA source address) 40300f4 uint32 = 1_ffff during boot0 (SRAM size?) 4030f04 uint32 = 2 during boot0, then =8802 at end of boot0 4030f20 uint32 DRAM mapping begin 4030f24 uint32 DRAM mapping end 4030f40 uint32 = 200_0000 during boot0 4030f44 uint32 = 200_19ff during boot0 4031000 - Vector 1019c 4031000 uint32 =4000_0800 during boot0 4031004 uint32 = 8 during boot0 4031140 4031180 4032040 4033000 - Vector 1019c 4033100 4033200 4033300 4040040 Related to commands (SCSI?) received via vector 10046 4041000 4042000 - SCSI response pipe 4040064 uint32 USB Interrupt Flags, write-to-clear checking for mask 0x3008 1000 SETUP completed 2000 IN completed 4040078 uint32 USB event interrupt 80000 OUT completed xx endpoint? 40400a5 uint8 Bits 1F cleared prior to PIO transfer 40400a8 uint32 Byte FIFO register for PIO (non-DMA) Used by cmd03 Request Sense and some others. 40400d4 uint32 Byte in bits 15:8, set prior to transfer. PIO: 0x01__ 4042154 uint32 Pre-initiation write DMA: size, after pointer written to [40300e8] PIO: Before other MMIO writes, &= 1 This one seems more protocol-related than to control the DMA/PIO hardware. It's a weird address (a header in a buffer somewhere) and the ordering is strange. In PIO, this is written prior to all error handling. 4050000 4062000 4063000 Crypto coprocessor. Seems to have a few different modes it can operate in. 128-bit block size, probably AES. Used by bootloader and app firmware for hashing. 4063000 uint32 Flags 1 Set before op (after 4063090:1) 4063004 uint8 Flags 2 Operation complete 4063008 uint32 Flags 4 Cleared before op 2 Cleared before op 4063010 uint128 Zero'ed before a hashing operation Conditionally zeroed by boot2 4063020 uint128 Key loaded from 10ff0 by boot2 Blocks loaded from regions we're checking. Simpler checker algo in cmd3B uses a key from 1ff000. 4063038 uint32 Result (boot2 expected a1b9d358) 406303c uint32 Result (boot2 expected 13201959) 4063084 uint32 Flags 4 Set during boot2 4063088 uint32 boot2 init: reg = 50 + (reg & ~70) 4063090 uint32 Flags 1 Set before op, after op 4070200 4070300 4070400 4070500 4081e00 4081f00 4082d00 40b0040 40d0200 4100000 Debug trace interface (Used by logging func f6024, verified non-essential to operation) 4010000 uint8 FIFO, byte output 4010008 uint32 Flags? (read before writing) 4010009 uint8 Acknowledge? (read after writing) 4100701 41f0000 8051 XDATA memory interface This looks like it might be an in-package serial bus. The registers at 41f4_ follow a protocol where [41f5c0c] is used for flow control and [41f5c08] performs delayed reads. This is probably how they cross clock domains. 41f4d50 uint8 Write to firmware memory 41f4d51 uint8 Flags 1 Force firmware address to 0 when asserted. Strobe high to reset address. 2 Disable firmware autoincrement? 4 0 during upload, 1 during normal operation (just before [41f4dcc]=0) 41f4d52 uint8 Read from firmware memory 41f4d91 uint8 Firmware boot status 41f4dcc uint8 Flags 8 Processor held in reset? (Set during firmware install) Bus control for registers in 41f4_ 41f5c08 uint8 Read data 41f5c0c uint8 Flags 8 Busy pre-result, wait for 0 4 Busy pre-result, wait for 0 1 Busy post-result, wait for 1 41f5c44 uint8 4200000 4201000 4204000 4206000 Stepper motor controller This seems to be a fairly high-level hardware motor controller, probably with a way to set up acceleration rates and such. The following commands, with the right initialization, on each issuance will cause the pickup sled to move about a centimeter away from the spindle motor. Possibly an auto-reset on error? After leaving in 500mA state for some seconds, the same commands will not produce motor movement. These commands seem fairly high-level, like they're executing something that's been set up elsewhere. %wr 4206000 a10200 %wr 4206010 c646 %wr 4206000 910200 <- Current up to 500mA, motor moves all at once %wr 4206010 c600 %wr 4206000 910200 <- Drops current from ~500mA to 270mA ---- 4206000 uint32 Flags + number in [23c, b60] 800000 400000 200000 100000 10000 4206004 4206010 uint32 number in [0, ffff] 4206014 uint32 number in [0, f500] 4206018 uint32 number in [17, b16e] 420601c uint32 number in [0, 3d00] 4206020 uint32 number in [0, 3000] 4206024 uint32 number in [0, 7dbe] 4206080 4206084 420608c 420610c uint32 508 4206114 4206204 4206208 4206280 4206284 42062a8 42062ac 4206300 4206308 420630c 4206310 4206314 4206318 420640c 420c000