-
Notifications
You must be signed in to change notification settings - Fork 3
SD5650T V110
HiSilicon SD5650T-V110 is the SoC used in the QIVICON Home Base 2.
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] |
0x11300000 |
0x080000 |
SRAM | internal RAM (until 0x11380000) |
|
0x14380000 |
0x001000 |
MDIO0 | [MDIO] 0 | |
0x14400000 |
0x001000 |
MDIO1 | MDIO 1 | |
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 |
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.
-
bootcontinues with the normal boot flow (loading code from flash, etc.) -
resetperforms a watchdog reset -
mdprints 64 bytes at once, in hex+ASCII format. Data can be reconstructed later- A suffix may be specified to indicate width:
bfor byte (8 bits),lfor long (32 bits),wfor 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).
- A suffix may be specified to indicate width:
-
mwwrites a value to memory. The arguments are address, value, repetitions. A width suffix may be specified as withmd -
loadyaccepts data over serial, using the YMODEM protocol, and places it at the address specified in the parameter, or the default address of0x11346000 -
runexecutes code at the given address and passes extra arguments as argc/argv -
gois very similar but first disables cache and MMU. Programs written usingmworloadywill not run correctly when started withgo.
----------------------------------
- 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.
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).
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.
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.
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.
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.
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).
| 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) |
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 |
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 |
The name IOMUX would imply that this block is configuring how peripheral controllers (SPI, etc.) are multiplexed onto pins of the chip.
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.
List of registers
| offset | name | description |
|---|---|---|
0x004 |
RX interrupt status (write 1 to clear) |
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 |
|---|---|---|
0x04 |
CMD |
initiate a transfer |
0x0c |
RDATA |
value read from register |
0x10 |
STATUS |
status of current transfer |
| 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 shoule be written to register, if WRITE
|
| bits | name | description |
|---|---|---|
| 0:2 | BUSY |
non-zero while a transfer is running |
| 3:4 | COMPLETE |
non-zero if a transfer completed successfully |
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.
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.
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 |
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 |
Notes:
- 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.
- 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.
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 |
| 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 |
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 |
| 42 | Ethernet RGMII |
| 54 | USB |
| 58 | Ethernet MII 0 |
| 59 | Ethernet MII 1 |
| 60 | Ethernet MII 2 |
| 61 | Ethernet MII 3 |
| 62 | Ethernet MII 4 |
Some firmware must be stored in flash in order for an SD56xx-based system to boot.
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.
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 #
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.
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
bootmcommand ("boot application image from memory"), abootdelayvariable, 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_initperforms some hardware initialization on the SD/MMC device (0x10a60000)
-
The bootloader can be patched in RAM to pass custom arguments to the Linux kernel.
PowerPC:
Servers/BMCs:
E-Book readers:
- Allwinner F1E200 based
- Kobo Aura (U-Boot, SD boot)
- Tolino Shine (SD boot), Shine2HD
- Netronix EC, eKTF2132 touchscreen
Cameras/DVRs:
- AHB780XTB DVR (Hi3520D), NBD8032
- Hi3518-based
Networking equipment:
TVs and set-top boxes:
Linux: