Skip to content
J. Neuschäfer edited this page Apr 10, 2026 · 11 revisions

HiSilicon SD5650T-V110 is the SoC used in the QIVICON Home Base 2.

Memory map and interrupts

Based on hi_map.h.

base length device IRQ description
0x00000000 0x200000 ROM -- Boot ROM
0x10100000 0x001000 SCTL system control
0x10102000 0x001000 DDRC DDR RAM controller
0x10104000 0x001000 TIMER01 47 timers 0 and 1
0x10105000 0x001000 TIMER23 48 timers 2 and 3
0x10106000 0x000100 GPIO0 49 GPIO bank 0
0x10107000 0x000100 GPIO1 50 GPIO bank 1
0x10108000 0x000100 GPIO2 51 GPIO bank 2
0x10109000 0x000100 GPIO3 52 GPIO bank 3
0x1010a000 0x000100 GPIO4 53 GPIO bank 4
0x1010b000 0x000100 GPIO5 54 GPIO bank 5
0x1010c000 0x000100 GPIO6 55 GPIO bank 6
0x1010d000 0x000100 GPIO7 56 GPIO bank 7
0x1010e000 0x001000 UART0 45 UART 0 (32-bit 8250)
0x1010f000 0x001000 UART1 46 UART 1
0x10180000 0x002000 A9_PERI -- Cortex-A9 peripherals:
0x10180000 0x000100 - SCU
0x10180100 0x000100 - GIC_CPU -- Generic Interrupt Controller, GIC v1
0x10180200 0x000100 - GLOBAL_TIMER
0x10180600 0x000100 - PRI_TIMER_WDT
0x10181000 0x001000 - GIC_DIST -- GIC distributor
0x10a00000 0x010000 PCIE0
0x10a10000 0x010000 PCIE1
0x10a20000 0x000100 SFC 40 Serial Flash Controller
0x10a30000 0x000100 NFC 41 NAND Flash Controller
0x10a40000 0x001000 EHCI 38 EHCI USB controller
0x10a50000 0x001000 OHCI 39 OHCI USB controller
0x10a50000 0x010000 XHCI 39 XHCI USB controller (same address?)
0x10a60000 0x010000 SD/MMC 57
0x10a70000 0x010000 ETH 120, 121 Ethernet MAC
0x11300000 0x080000 SRAM internal RAM (until 0x11380000)
0x14080000 0x001000 MACATTR0 Ethernet MAC(?) Attributes 0
0x14100000 0x001000 MACATTR1 Ethernet MAC(?) Attributes 1
0x14180000 0x001000 MACATTR2 Ethernet MAC(?) Attributes 2
0x14200000 0x001000 MACATTR3 Ethernet MAC(?) Attributes 3
0x14280000 0x001000 MACATTR4 Ethernet MAC(?) Attributes 4
0x14300000 0x001000 MACATTR5 Ethernet MAC(?) Attributes 5
0x14380000 0x001000 MDIO0 [MDIO] 0 (internal PHY)
0x14400000 0x001000 MDIO1 MDIO 1 (external PHY)
0x14880000 0x001000 CRG clock/reset generator
0x14900000 0x001000 IOMUX [I/O multiplexer]
0x16800000 0x001000 L2CACHE level 2 cache controller
0x18000000 64 MiB SFC CS0
0x1c000000 64 MiB SFC CS1
0x20000000 NAND -- NAND Flash Controller access window
0x40000000 0xa00000 PCIE0 mem -- PCIe 0 memory space
0x40a00000 0x600000 PCIE0 io -- PCIe 0 port I/O space
0x58000000 0xa00000 PCIE1 mem -- PCIe 1 memory space
0x58a00000 0x600000 PCIE1 io -- PCIe 1 port I/O space
0x80000000 DRAM -- external DDR3 RAM

Boot ROM

The bootrom is located at 0 in the address space. It's really just 16 KiB (0x4000 bytes) long, but it repeats to fill a 2 MiB window.

UART 1 is used as a debug port (at the usual 3.3V and 115200 baud). Hitting Ctrl-C early in boot spawns the bootrom shell:

-------------------
- VER5610 bootrom -
-------------------
-
>> hit <ctrl+c> to stop autoboot: 1 
bootrom > help
cmd     - usage          - help
------------------------------------------------------------
boot    - boot           - read info from flash and boot
go      - go <addr>      - jump to application at 'addr'
help    - help           - print description of all commands
loady   - loady <addr>   - load file from the serial line
md      - md <addr>      - memory display
mw      - mw <addr>      - memory write
reset   - reset          - system reboot
run     - run <addr>     - execute application at 'addr'

(With proper command line editing and history support, btw!)

After 30 seconds, a watchdog kicks in and resets the board. Therefore it is necessary to occasionally re-enter the bootrom shell during longer sessions.

Commands

  • boot continues with the normal boot flow (loading code from flash, etc.)
  • reset performs a watchdog reset
  • md prints 64 bytes at once, in hex+ASCII format. Data can be reconstructed later
    • A suffix may be specified to indicate width: b for byte (8 bits), l for long (32 bits), w for word (16 bits); The default is 32 bits.
    • A length may be specified as the second argument; it is the number of bytes to print minus 16 (in other words, the first line of output isn't counted).
  • mw writes a value to memory. The arguments are address, value, repetitions. A width suffix may be specified as with md
  • loady accepts data over serial, using the YMODEM protocol, and places it at the address specified in the parameter, or the default address of 0x11346000
  • run executes code at the given address and passes extra arguments as argc/argv
  • go is very similar but first disables cache and MMU. Programs written using mw or loady will not run correctly when started with go.

Normal boot flow

----------------------------------
- Flash type .......... [  NAND  ]
- Boot mode ........... [ NONSEC ]
- Read page0 .......... [   OK   ]
- DDR ................. [   OK   ]
- bootloader .......... [   OK   ]
----------------------------------
-
>> startup bootloader...

After determining the flash type and security mode, the bootrom resets and initializes the appropriate flash controller. It then loads and runs the DDR init code at internal memory address 0x11346000 and finally loads the bootloader to DDR memory address 0x80010000, disables cache/MMU and runs it.

Locations and sizes of the DDR and bootloader images are stored in a parameter struct in the first flash page, which is read with ECC mode 0.

Zero-page data structures

Page 0 is organized into several chunks of data, which start with a common header of two little-endian 32-bit words. The first is a type, the second is the size of the contained data (not including the 8-byte header).

Chunk 0x1002: Device parameters (short match)

This is a table of supported flash devices. Each entry consists of four bytes, and the table is terminated by an all-zero entry:

offset type description NFC register bits
0 u8 Device ID --
1 u8 ECC type NFC_CON[9:11]
2 u8 page size shift NFC_CON[1:3]
3 u8 unknown NFC_BOOT_SET[0:1]
bootrom > md 0x20000000 0x2000
20000000: 00001002 00000038 000102f1 000102d1    ....8...........
20000010: 000102dc 000102a2 000102f2 000102a1    ................
20000020: 000102aa 000102da 000102ac 000102a3    ................
20000030: 000102d3 000102a5 000102d5 00000000    ................

The first (least-significant) byte is the Device ID, the second byte returned from the ONFI-defined flash command 90h.

For the Micron MT29F4G08ABDA (Device ID dc), the parameters are: ECC type = 2, page size shift = 1 (2048 bytes), bootset[0] = 0.

Chunk 0x1001: Device parameters (long match)

This chunk also contains a flash device table, but each entry is 12 bytes long:

offset type description
0 char[8] full flash ID
8 u8 length of the ID
9 u8 ECC type
10 u8 page size shift
11 u8 unknown, corresponding to NFC_BOOT_SET[0]
20000040: 00001001 00000108 1590d198 00001476    ............v...
20000050: 00010206 a690dc2c 00000054 00010205    ....,...T.......
20000060: 3294d598 00005576 01030406 9590dc01    ...2vU..........
20000070: 00000056 00010205 9510dcad 00000054    V...........T...
20000080: 00010105 2594d5ad 00004144 00010106    .......%DA......
20000090: 9a94d5ad 00004274 00010106 9a94d7ad    ....tB..........
200000a0: 00004274 00010206 a690dc2c 00000054    tB......,...T...
200000b0: 00020308 4604482c 00000085 02020308    ....,H.F........
200000c0: 4a04482c 000000a5 02020308 2600382c    ,H.J........,8.&
200000d0: 00000085 01020308 4b04882c 000000a9    ........,..K....
200000e0: 02030408 4604682c 00000089 02020308    ....,h.F........
200000f0: 29d5d7ec 00004138 00010206 7284d5ec    ...)8A.........r
20000100: 00004250 00010106 72c5d7ec 00004254    PB.........rTB..
20000110: 00010206 7284d3ec 00004250 00010106    .......rPB......
20000120: b655d7ec 00000078 01010205 1d80f0c2    ..U.x...........
20000130: 00000000 00010104 9790dc03 00000057    ............W...
20000140: 00010205 00000000 00000000 00010200    ................

The flash page size is calculated as 1024 << shift.

For example, for the Micron MT29F4G08ABADA (ID 2c dc 90 95 56), the precise ID isn't listed in the table that I found on my machine. This is ok, because it's already covered by chunk 0x1002.

Chunk 0x2001: DDR init

This chunk contains the size of the DDR init code, for example (show below), 0x1000 (4096) bytes.

20000150: 00002001 00000028 00001000 00000000    . ..(...........
20000160: 00000000 00000000 00000000 00000000    ................
20000170: 00000000 00000000 00000000 00000000    ................

The DDR init code is found in the second page, located, for example, at offset 2048 (given a page size shift parameter of 1). Note that anything beyond page 0 is read with the ECC mode specified in the device parameters.

Chunk 0x2002: Bootloader

Similar to the previous one, this chunk contains the size of the bootloader, for example (show below), 0x1e800 bytes (122 KiB).

20000180: 00002002 00000028 0001e800 00000000    . ..(...........
20000190: 00000000 00000000 00000000 00000000    ................
200001a0: 00000000 00000000 00000000 00000000    ................

The bootloader is found directly after the DDR init code.

SMP boot

All of the above happens only for the primary CPU. Secondary CPUs (of which there is presumably one) are held in the bootrom until the register at address 0x1010011c has the value 0xc0ddffff. They may then jump to 0x80010000 (the bootloader's entry point in DRAM).

System control

offset description
0x000 some clock source bits
0x008 boot flags:
0x008 x & 3: boot medium (ROM=0, SPI=1, NAND=2)
0x018 PCIE0_STAT0
0x038 PCIE0_STAT4
0x0a0 PERCTRL1
0x0a4
0x11c SMP release signal
0x130 TESTREG1, relevant for SMP bringup
0x800 chip ID (variants: H=0x56100100, T=0x56102100)

Timers

The memory map for the four timers is listed in hi_map.h and used in hi_mach.c. Timer 1 and 3 are located 0x20 bytes after Timer 0 and 2, respectively.

offset name description
0x00 RELOAD
0x04 VALUE
0x08 CONTROL
0x0C INTCLR
0x10 RIS interrupt status?
0x14 MIS
0x18 BGLOAD

GPIO

The relevant symbols like sd5610x_gpio_bit_attr_set are not in the GPL release. Each bank (GPIO0 at 0x10106000, GPIO1 at 0x10107000, etc.) has the following layout, housing up to 32 GPIO lines:

offset name description
0x00 OUT write bit to set output level
0x04 DIR direction (0: input, 1: output)
0x08 FUNC enable special function (0: GPIO, 1: function)
0x50 IN read bit to get input level

I/O Multiplexer

The name IOMUX would imply that this block is configuring how peripheral controllers (SPI, etc.) are multiplexed onto pins of the chip.

offset name description
0x198 IOSEL set bits to use pins in peripheral mode
0x1a0 MUX? multiplex config (including PCIe)
0x1ac GPIOSEL set bits to use pins as GPIO
0x200 EXT_EN GPIO extention: enable
0x204 EXT_OUT GPIO extention: output
0x20c EXT_IN GPIO extention: input

Ethernet

The defconfig indicates that a Marvell Sky2 Ethernet chip is used, but this is a distraction. The SoC has a built-in Ethernet MAC and PHY.

The Ethernet MAC consists of eight channels (numbered 0-7), each of which correspond to one receive (RX) queue and one transmit (TX) queue. If interrupt reporting is enabled, events on channels 0-3 raise IRQ 120 at the SoC's Generic Interrupt Controller, events on channels 4-7 raise IRQ 121.

The internal PHY is controlled through [MDIO] 0.

List of registers
offset name description
0x004 RX_INT RX interrupt status (write 1 to clear)
0x008 TX_INT TX interrupt status
...
0x01c CHAN0_RX_STOP Channel 0, RX stop (clear bit 0 to start channel)
0x020 CHAN1_RX_STOP Channel 1, RX stop
0x024 CHAN2_RX_STOP Channel 2, RX stop
0x028 CHAN3_RX_STOP Channel 3, RX stop
0x02c CHAN4_RX_STOP Channel 4, RX stop
0x030 CHAN5_RX_STOP Channel 5, RX stop
0x034 CHAN6_RX_STOP Channel 6, RX stop
0x038 CHAN7_RX_STOP Channel 7, RX stop
0x03c CHAN0_TX_STOP Channel 0, TX stop (clear bit 0 to start channel)
0x040 CHAN1_TX_STOP Channel 1, TX stop
0x044 CHAN2_TX_STOP Channel 2, TX stop
0x048 CHAN3_TX_STOP Channel 3, TX stop
0x04c CHAN4_TX_STOP Channel 4, TX stop
0x050 CHAN5_TX_STOP Channel 5, TX stop
0x054 CHAN6_TX_STOP Channel 6, TX stop
0x058 CHAN7_TX_STOP Channel 7, TX stop
...
0x100 CHAN0_RX_RING Channel 0, RX descriptor ring (0x10 bytes each)
0x110 CHAN1_RX_RING Channel 1, RX descriptor ring
0x120 CHAN2_RX_RING Channel 2, RX descriptor ring
0x130 CHAN3_RX_RING Channel 3, RX descriptor ring
0x140 CHAN4_RX_RING Channel 4, RX descriptor ring
0x150 CHAN5_RX_RING Channel 5, RX descriptor ring
0x160 CHAN6_RX_RING Channel 6, RX descriptor ring
0x170 CHAN7_RX_RING Channel 7, RX descriptor ring
0x180 RX_FLAGS RX flags
...
0x194 MAGIC write 0x5500 here
...
0x200 CHAN0_TX_RING Channel 0, TX descriptor ring (0x10 bytes each)
...
0x250 CHAN1_TX_RING Channel 1, TX descriptor ring
0x260 CHAN2_TX_RING Channel 2, TX descriptor ring
0x270 CHAN3_TX_RING Channel 3, TX descriptor ring
0x280 CHAN4_TX_RING Channel 4, TX descriptor ring
0x290 CHAN5_TX_RING Channel 5, TX descriptor ring
0x2a0 CHAN6_TX_RING Channel 6, TX descriptor ring
0x2b0 CHAN7_TX_RING Channel 7, TX descriptor ring

0x100/0x200: RX/TX descriptor ring registers (0x10 bytes per channel):

offset name description
0x0 BASE physical address of first descriptor in ring
0x4 MODE initialize to 4 (RX) or 8 (TX), log2 of size?
0x8 ACTION highest index of submitted descriptor
0xc STATUS progress status

The progress status field appears to work as follows:

bit mask description
16:31 0xffff0000 index of last submitted descriptor
0:15 0x0000ffff index of last descriptor returned to software control

The MAC will at most recognise four descriptors at once as submitted, resulting in readings such as 0x60002 (six submitted, two returned), when in reality 15 descriptors are currently in flight.

0x180: RX flags

bit mask name description
9 0x00000200 unknown
12 0x00001000 enable reception
19 0x00080000 unknown

Descriptors

Packets are managed through descriptor queues, as in many other NICs. Each descriptor is 0x10 bytes long:

offset TX desc RX desc
0x00 length (0x3fff), status (0xc000) flags?
0x04 buffer address buffer address
0x08 ? zero
0x0c ? zero

The status flags are:

mask bit description
0x8000 15 1: owned by hardware (ready to send/receive), 0: owned by software
0x4000 14 1: transmit buffer, 0: receive

MDIO

In addition to an Ethernet MAC, there is also an MDIO controller, to initiate communication with PHYs. The two instances of it are at 0x14380000 (conntected to internal PHY) and 0x14400000 (connected externally).

offset name description
0x00 MODE should be 1 before making transfers
0x04 CMD initiate a transfer
0x0c RDATA value read from register
0x10 STATUS status of current transfer

CMD

bits name description
0 GO set to 1 to start a transfer
1 WRITE transfer direction (0: read, 1: write)
2:6 PHY_ADDR PHY address
7:11 REG_ADDR register address
12:27 DATA value that should be written to register, if WRITE

STATUS

bits name description
0:2 BUSY non-zero while a transfer is running
3:4 COMPLETE non-zero if a transfer completed successfully

Ethernet Attributes

This is another kind of MMIO window that occurs 6 times on the SD56xxT:

index address
0 0x14080000
1 0x14100000
2 0x14180000
3 0x14200000
4 0x14280000
5 0x14300000
List of registers
offset name description
0x000 MAC_CONFIG MAC configuration
...
0x014 MAC_STATUS MAC status
...
0x018 MAC_RESET MAC reset (1: assert)
0x01c MAC_CTRL MAC control (1: enable)
0x020 mask 3 init'd to 1
...
0x040 mask 0xff0000 init'd to 0xc0000
...
0x06c LOOPBACK_CTRL Loopback control
0x070 EEE_CTRL Energy Efficient Ethernet control register (1: enable)
0x074 EEE_TIME0 Energy Efficient Ethernet time 0
0x078 EEE_TIME1 Energy Efficient Ethernet time 1
0x07c EEE_TIME2 Energy Efficient Ethernet time 2
...
0x100 MTU Maximum transmission unit, aka max. frame size
...
0x400 FRAMES_TOTAL0 total count of frames (part 0)
0x404 FRAMES_TOTAL1 total count of frames (part 1)
...
0x4a0 FRAMES_ERROR0 count of frames with error (part 0)
0x4a4 FRAMES_ERROR1 count of frames with error (part 1)
...
0x4d0 TXPKT_LO transmitted packets (count?), first (low?) 32 bits
0x4d4 TXPKT_HI transmitted packets (count?), second (high?) 32 bits
...
0x560 TXLATE_LO
0x564 TXLATE_HI
...

USB

The EHCI/OHCI base addresses are known, so the problem seems simple at first, but there are some extra bits, belonging to the clock/reset generator. Also, an XHCI is listed at the same address as the OHCI.

NAND Flash Controller

The NAND flash controller's MMIO interface is at address 0x10a30000. Flash content can be accessed through a mapping at address 0x20000000. The register layout is listed in hi_nand_drv.h.

Clock/Reset Generator

The CRG can be found at MMIO address 0x14880000 (the resemblence to a racist dogwhistle is hopefully accidental). Registers are listed in hi_wdg.h, hi_crg_reg_s. Uses within the GPL source dump are rare, and spread out between hi_common.c, hi_mach.c, hi_pcie.c, and hi_wdg.c; search for HI_REG_BASE_CRG and g_pst_crg_reg.

List of registers
offset name desc.(zh), from GPL src. description (en)
0x000 SC_SYSSTAT 软复位控制寄存器 soft reset control, Ethernet mode
0x004 ECSPLLL_CTRL0 ECS PLL控制寄存器 ECS PLL control
0x008 ECSPLLL_CTRL1 ECS PLL频率控制寄存器 ECS PLL frequency control
0x00c ETHPLLL_CTRL0 ETH PLL控制寄存器 [Ethernet] PLL control
0x010 ETHPLLL_CTRL1 ETH PLL频率控制寄存器 Ethernet frequency control
0x014 SC_PEREN0 外设时钟使能寄存器0 peripheral clock enable 0
0x018 SC_PERDIS0 外设时钟禁止寄存器0 peripheral clock disable 0
0x01c SC_PERCLKST0 外设时钟使能状态寄存器 peripheral clock enable status 0
0x020 SC_PEREN1 外设时钟使能寄存器1 peripheral clock enable 0
0x024 SC_PERDIS1 外设时钟禁止寄存器1 peripheral clock disable 1
0x028 SC_PERCLKST1 外设时钟使能状态寄存器1 peripheral clock enable status 1
0x02c SC_RST_CTRL0 外设复位控制寄存器0 reset control 0, (active low)
0x030 SC_RST_CTRL1 外设复位控制寄存器1 " 1
0x034 SC_RST_CTRL2 外设复位控制寄存器2 " 2
0x038 CPU_CFG CPU控制寄存器 CPU control
0x03c HW_CFG HW控制寄存器 HW(?) control
0x040 SC_PERCTRL0 外设控制寄存器0 peripheral control 0
0x044 SC_PERCTRL1 ~1 " 1
0x048 SC_PERCTRL2 ~2 " 2, GEMAC
0x04c reserved 保留 --
0x050 SC_PERCTRL3 外设控制寄存器3 peripheral control 3
0x054 SC_PERCTRL4 ~4 " 4
0x058 SC_PERCTRL5 ~5 " 5
0x05c SC_PERCTRL6 ~6 " 6
0x060 SC_PERCTRL7 ~7 " 7
0x064 SC_PERCTRL8 ~8 (硬件看门狗使能控制) " 8, watchdog enable control
0x068 RAM_CTRL_BUS RAM控制寄存器 RAM control
0x06c WDG_INIT_CFG 看门狗初始化配置信号 watchdog reset ("feed") register
0x070 OSC_CFG 晶振配置信号 crystal oscillator config signal
0x074 reserved (7) 保留 --
0x090 CRG_STAT0 CRG状态寄存器0 CRG state 0
0x094 DYING_GASP_PRE_INT DYING_GASP中断寄存器 DYING_GASP interrupt
0x098 DYING_GASP_INT_MASK DYING_GASP中断掩码寄存器 DYING_GASP interrupt mask
0x09c DYING_GASP_INT_INSERT DYING_GASP中断插入寄存器 DYING_GASP interrupt insertion
0x0a0 reserved (24) 保留 --
0x100 SC_CHIP_ID 芯片ID寄存器 chip ID (same as in [SCTL])
0x104 CRG_REV0 ECO预留寄存器0 CRG revision / reserved

0x000: SC_SYSSTAT

bits mask description
31:8 0xffffff00 soft reset control
3 0x00000008 Ethernet full duplex (otherwise you get half duplex)
2 0x00000004 Ethernet at 1000 Mbit/s
1 0x00000002 Ethernet at ≥ 100 Mbit/s
0 0x00000001 RGMII enable

To initiate a soft reset, write the chip ID masked with 0xffffff00 to SC_SYSSTAT, followed by the same but bit-inverted. For example, that would be 0x56102100 and 0xa9efdeff.

0x048: SC_PERCTRL2

The bits in SC_PERCTRL2 can be characterized by whether they are set in the different link modes (10/100/1000 Mbit/s and MII/RGMII):

bit mask 10(M) 100(M) 10(R) 100(R) 1000(R) description
21 0x00200000 yes no yes no no 10 Mbit
20 0x00100000 yes yes no yes no 100 Mbit or MII
19 0x00080000 yes no yes no no 10 Mbit
18 0x00040000 yes yes no no no MII
17 0x00020000 yes no yes no no 10 Mbit
16 0x00010000 yes yes no no no MII
1 0x00000002 yes yes no no no MII
0 0x00000001 no no - - -

Notes:

  • To enable the watchdog, write 0x4F4E5452 ('ONTR') followed by 0x12345610 to SC_PERCTRL8. To disable the watchdog, write 0xabcd5610 and 0xed574447 ('\xedWDG').
  • To reset (or "feed") the watchdog, write 0x55AA5A5A and 0xAA55A5A5 to WDG_INIT_CFG.

Reset signals

Resets are controlled by the bits in SC_RST_CTRL0..2, numbered LSB-first, allowing for up to 96 resets. For example, reset 0 the LSB of SC_RST_CTRL0, reset 63 is the MSB of SC_RST_CTRL1. The reset bits are active low: To assert a reset, clear the corresponding bit, to release a reset (let the hardware run), set the corresponding bit.

List of reset signals
reset peripheral
15 USB
16 USB
17 USB
18 USB
26 Ethernet PHY
27 Ethernet PHY
29 Ethernet (all modes)
33 Ethernet MAC
36 Ethernet MAC
38 Ethernet MAC/RGMII
40 Ethernet MAC
42 Ethernet MAC
44 Ethernet MAC
48 Ethernet MII 0
49 Ethernet MII 1
50 Ethernet MII 2
51 Ethernet MII 3
52 NAND Flash Controller
54 Ethernet RGMII
59 Ethernet MII 4
68 Ethernet RGMII
69 Ethernet RGMII

Clocks

Peripherl clocks are controlled by two sets of registers of enable, disable and status registers, allowing for up to 64 clocks. Clocks are enabled by setting the corresponding bit in SC_PERENx and disabled by setting the corresponding bit in SC_PERDISx. The current status is indicated by the corresponding bit in SC_PERCLKSTx.

List of clock signals
clock peripheral
16 USB
22 Ethernet MAC (RGMII)
23 Ethernet MAC
24 Ethernet MAC
25 Ethernet MAC
26 Ethernet MAC
37 NAND Flash Controller
41 MDIO0
42 MDIO1 (RGMII)
54 USB
58 Ethernet MII 0
59 Ethernet MII 1
60 Ethernet MII 2
61 Ethernet MII 3
62 Ethernet MII 4

Firmware

Some firmware must be stored in flash in order for an SD56xx-based system to boot.

DDR init

The DDR memory controller initialization code is a short program (2.6 KiB) that doesn't do any function calls and culminates in a single mov pc, lr instruction.

Bootloader

The bootloader is significantly larger, and for this reason, compressed.

>> startup bootloader...

DRAM       : 512MB       SYS        : 0xc0c00000 
STACK DATA : 0xc0020000  STACK SVC  : 0xc0030000 
STACK FIQ  : 0xc0040000  STACK ABT  : 0xc0050000 
STACK UND  : 0xc0060000  STACK IRQ  : 0xc0070000 
Memory     : total 511.5MB
Memory     : start 0xc2000000 available 64MB
Memory     : code 177KB bss 95KB highmem 416MB 0xc6000000

hi # 

Preloader (aka. SPL)

Before decompressing anything, the "pre-bootloader" stage does a bunch of initialization. Notably, it also brings up the secondary CPU core(s) by writing 0xc0ddffff to 0x1010011c. It sets up virtual memory (in the 0xc0000000 range) before calling into the main stage.

The preloader relocates itself from 0x80010000 to 0xc0080000.

Main stage

The main stage is LZMA-decompressed and loaded at virtual address 0xc4000000.

A few impressions:

  • Interestingly, there seems to be a web interface for firmware updates, which identifies the device as a DSL Router. I guess that's correct most of the time
  • Based on strings alone, the bootloader looks a lot like U-Boot. It has a bootm command ("boot application image from memory"), a bootdelay variable, it says things like Unknown command '%s' - try 'help' without arguments for list of all known commands
  • It hints at a JFFS2 root filesystem: args_nand=mem=492M console=null,115200 root=mtd:rootfs ro rootfstype=jffs2
  • The bootloader finally contains an Ethernet driver (previous stages didn't). It has code to load the OS image via TFTP, but the Ethernet link isn't detected fast enough
  • The list of commands has been stripped down to just three:
    • bootm <address> interprets the data found at the given address as a uImage
    • sec_test <address> checks the validity of the page 0 data structures at
    • sec_init performs some hardware initialization on the SD/MMC device (0x10a60000)

The bootloader can be patched in RAM to pass custom arguments to the Linux kernel.

Clone this wiki locally