我来当小白鼠了,CHIP ID是可以改写的。在T113芯片上测试
先读取出厂的CHIP ID,前4个字节为93406000
$ xfel extra efuse dump
chipid:(0x0000 128-bits)
93406000 0c004814 01426250 48671b4b
将前4个字节修改为0xffffffff
$ xfel extra efuse write32 0x00 0xffffffff
再次查看芯片的CHIP ID,已经被修改为0xffffffff了。
$ xfel extra efuse dump
chipid:(0x0000 128-bits)
ffffffff 0c004814 01426250 48671b4b
结论,关于CHIP ID,你真的可以用xfel工具,自己重写一个。如果全志出厂时,CHIP ID全0的话,你是真的可以完美复制出两个一模一样的芯片。
我印象中,当时还在研究D1,手上拿到了一颗F133样片,里面的SID就是全0,当时还很奇怪,为何没有SID呢,原来仅仅是没烧写。
一转眼,距离离研究D1芯片,已经过去2年了, 这该死的时间,也不慢一点。
有厂家提前烧好的区域,比如chipid,thermal-sensor,但这些都还是可见的,全志在启用加密引导功能后,有部分EFUSE就不可见了,读取会直接返回0。
全志SOC,写EFUSE,必须通过SID控制器,通过寄存器操作来写入,但读取EFUSE,有两种方案,一种是比较简单的SRAM映射,直接用MMIO来访问就可以了,这里有个细节需要注意,仅支持word字访问,不支持byte字节访问,还有一种方案,就是用SID控制器来读取。
SRAM映射方案,只有在SOC重启时更新一次,所以,如果新写入了efuse,想不重启来查看的话,就需要用SID控制器来读取。
启用加密模式后,SID控制器访问也会受限,需要用SMC相关指令来访问,具体还没有研究加密后的SID控制器。
上面的验签过程,有两种应用场景,需求不同,思路也会不同。
第一种,自己的产品防盗版,没有升级需求,或者loader没有升级需求,也就是某部分固件,完全不变化,且需防盗版抄袭。
这种需求,你需要将CPU ID + 固件或者loader,两者所有信息进行sha256摘要运算,并用ECDSA256对SHA256的摘要进行签名,存储在EFUSE里。当别人复制产品时,复制了SPI NOR FLASH,复制了EFUSE 签名,因CPU ID不同,也无法正常验签。
第二种,自己是方案商仅出主控芯片,客户自行烧录生产,有固件及各种烧写工具。这种情况要求客户必须从你这里走芯片,而不能从市面上随便购买。
对于这种需求,仅需要对CPU ID 进行SHA256摘要运算,并用ECDSA256对SHA256的摘要进行签名,存储在EFUSE里,烧录好,出给客户就可以了。客户可以随便刷机,升级,但不能随便购买芯片。
当然,固件完整性,固件防逆向,这些需求,可结合坑网之前的讨论的帖子,来实现。
最后一句话,攻防手段千千万,但几千年来,唯一不变的,还是人心,人性。
在F133芯片上,烧写ECDSA256 64字节签名文件到EFUSE,偏移为0x00c0区域,也就是2048bit的最后面的512bit,efuse前面的bit有各种隐藏用途,需小心使用,但后面的bit就随便整了。无需担心变砖。
经验证,是可以通过efuse来存储签名文件,并能够验签通过。
1,通过write指令烧写64字节签名文件,烧写到0xc0这个偏移位置
xfel extra efuse write 0x00c0 sign.bin
2,查看烧写好的efuse,发现0xc0偏移,已经储存了签名文件,与sign.bin的内容保持一致
xfel extra efuse dump
chipid:(0x0000 128-bits)
93005c00 ac004814 01425a4c 1c5318cb
brom-conf-try:(0x0010 32-bits)
00000000
thermal-sensor:(0x0014 64-bits)
7906c10a 019db011
ft-zone:(0x001c 128-bits)
83883119 0ef00f02 2b06111c 87180a0b
tvout:(0x002c 32-bits)
00000285
tvout-gamma:(0x0030 64-bits)
00000000 00000000
oem-program:(0x0038 64-bits)
11223344 55667788
write-protect:(0x0040 32-bits)
00000000
read-protect:(0x0044 32-bits)
00000000
reserved1:(0x0048 64-bits)
00000000 00000000
huk:(0x0050 192-bits)
00000000 00000000 00000000 00000000 00000000 00000000
reserved2:(0x0068 64-bits)
00000000 00000000
rotpk:(0x0070 256-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ssk:(0x0090 256-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
rssk:(0x00b0 128-bits)
00000000 00000000 00000000 00000000
hdcp-hash:(0x00c0 128-bits)
e133aa93 7aaf3227 14b10f12 06b71c6c
nv1:(0x00d0 32-bits)
ef80e46e
nv2:(0x00d4 32-bits)
e0ba33d4
reserved3:(0x00d8 96-bits)
a6fe6c3c f65c2d60 915ae6c7
oem-program-secure:(0x00e4 224-bits)
90ce9b07 94906489 3e39dce8 d06473aa 1dda2501 1f940484 36a770d8
3, 验签,将efuse里的签名读出来,用ECDSA256公钥进行验签,这里是对CPU唯一序列号的SHA256摘要进行验签。经过这样的操作,只要你没有ECDSA256私钥,你是无法生成正确的签名文件的,那么验签就无法通过。当别人想抄板或更换CPU,因序列号变了,且没有正确的签名,就无法启动运行,实现放盗版保护。
扩展XFEL,支持V851/V853芯片的EFUSE读写操作
$ xfel extra efuse dump
chipid:(0x0000 128-bits)
62c07800 cc004820 0145c519 204e1a8c
brom-conf-try:(0x0010 32-bits)
00000000
thermal-sensor:(0x0014 64-bits)
2291c0f9 007c9279
ft-zone:(0x001c 128-bits)
100f1109 13210de2 00278600 00691510
reserved1:(0x002c 96-bits)
00000000 00000000 00000000
write-protect:(0x0038 32-bits)
00000000
read-protect:(0x003c 32-bits)
00000000
lcjs:(0x0040 32-bits)
00000000
reserved2:(0x0044 800-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000
rotpk:(0x00a8 256-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
reserved3:(0x00c8 448-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
写完会熔断吗?会不会因为写efuse不当导致芯片成砖
这个是可能的,比如你烧写了加密引导位,并且随便填了个rotpk的sha256值,那么你的芯片就永远无法启动了,没有合法的加密引导签名,谁都没辙,就变砖了。
但只要不碰到关键熔丝,还是没啥风险的,在操作之前,仔细确认EFUSE分配信息,就无伤大雅了。
efuse分配信息,其实也不是一成不变的,除了核心分配信息,基本都是随着SDK的而重新分配的,这些细节就只能去翻代码了。
有些efuse存储了全志出厂时的芯片校正信息,比如温度传感器校正参数,TVOUT校正,各种AD,DA,内部RC补偿等等,这些没有文档,只能自己去寻找蛛丝马迹了。
现在XFEL支持了D1 / D1s / F133芯片的EFUSE读写操作
1,dump efuse
$ xfel extra efuse dump
chipid:(0x0000 128-bits)
93005c00 ac004814 01425a4c 1c5318cb
brom-conf-try:(0x0010 32-bits)
00000000
thermal-sensor:(0x0014 64-bits)
7906c10a 019db011
ft-zone:(0x001c 128-bits)
83883119 0ef00f02 2b06111c 87180a0b
tvout:(0x002c 32-bits)
00000285
tvout-gamma:(0x0030 64-bits)
00000000 00000000
oem-program:(0x0038 64-bits)
00000000 00000000
write-protect:(0x0040 32-bits)
00000000
read-protect:(0x0044 32-bits)
00000000
reserved1:(0x0048 64-bits)
00000000 00000000
huk:(0x0050 192-bits)
00000000 00000000 00000000 00000000 00000000 00000000
reserved2:(0x0068 64-bits)
00000000 00000000
rotpk:(0x0070 256-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ssk:(0x0090 256-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
rssk:(0x00b0 128-bits)
00000000 00000000 00000000 00000000
hdcp-hash:(0x00c0 128-bits)
00000000 00000000 00000000 00000000
nv1:(0x00d0 32-bits)
00000000
nv2:(0x00d4 32-bits)
00000000
reserved3:(0x00d8 96-bits)
00000000 00000000 00000000
oem-program-secure:(0x00e4 224-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000
2, write oem-program 1
$ xfel extra efuse write32 0x0038 0x11223344
$ xfel extra efuse dump
chipid:(0x0000 128-bits)
93005c00 ac004814 01425a4c 1c5318cb
brom-conf-try:(0x0010 32-bits)
00000000
thermal-sensor:(0x0014 64-bits)
7906c10a 019db011
ft-zone:(0x001c 128-bits)
83883119 0ef00f02 2b06111c 87180a0b
tvout:(0x002c 32-bits)
00000285
tvout-gamma:(0x0030 64-bits)
00000000 00000000
oem-program:(0x0038 64-bits)
11223344 00000000
write-protect:(0x0040 32-bits)
00000000
read-protect:(0x0044 32-bits)
00000000
reserved1:(0x0048 64-bits)
00000000 00000000
huk:(0x0050 192-bits)
00000000 00000000 00000000 00000000 00000000 00000000
reserved2:(0x0068 64-bits)
00000000 00000000
rotpk:(0x0070 256-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ssk:(0x0090 256-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
rssk:(0x00b0 128-bits)
00000000 00000000 00000000 00000000
hdcp-hash:(0x00c0 128-bits)
00000000 00000000 00000000 00000000
nv1:(0x00d0 32-bits)
00000000
nv2:(0x00d4 32-bits)
00000000
reserved3:(0x00d8 96-bits)
00000000 00000000 00000000
oem-program-secure:(0x00e4 224-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000
3, write oem-program 2
$ xfel extra efuse write32 0x003c 0x55667788
$ xfel extra efuse dump
chipid:(0x0000 128-bits)
93005c00 ac004814 01425a4c 1c5318cb
brom-conf-try:(0x0010 32-bits)
00000000
thermal-sensor:(0x0014 64-bits)
7906c10a 019db011
ft-zone:(0x001c 128-bits)
83883119 0ef00f02 2b06111c 87180a0b
tvout:(0x002c 32-bits)
00000285
tvout-gamma:(0x0030 64-bits)
00000000 00000000
oem-program:(0x0038 64-bits)
11223344 55667788
write-protect:(0x0040 32-bits)
00000000
read-protect:(0x0044 32-bits)
00000000
reserved1:(0x0048 64-bits)
00000000 00000000
huk:(0x0050 192-bits)
00000000 00000000 00000000 00000000 00000000 00000000
reserved2:(0x0068 64-bits)
00000000 00000000
rotpk:(0x0070 256-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ssk:(0x0090 256-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
rssk:(0x00b0 128-bits)
00000000 00000000 00000000 00000000
hdcp-hash:(0x00c0 128-bits)
00000000 00000000 00000000 00000000
nv1:(0x00d0 32-bits)
00000000
nv2:(0x00d4 32-bits)
00000000
reserved3:(0x00d8 96-bits)
00000000 00000000 00000000
oem-program-secure:(0x00e4 224-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000
4, reboot and dump efuse again
$ xfel extra efuse dump
chipid:(0x0000 128-bits)
93005c00 ac004814 01425a4c 1c5318cb
brom-conf-try:(0x0010 32-bits)
00000000
thermal-sensor:(0x0014 64-bits)
7906c10a 019db011
ft-zone:(0x001c 128-bits)
83883119 0ef00f02 2b06111c 87180a0b
tvout:(0x002c 32-bits)
00000285
tvout-gamma:(0x0030 64-bits)
00000000 00000000
oem-program:(0x0038 64-bits)
11223344 55667788
write-protect:(0x0040 32-bits)
00000000
read-protect:(0x0044 32-bits)
00000000
reserved1:(0x0048 64-bits)
00000000 00000000
huk:(0x0050 192-bits)
00000000 00000000 00000000 00000000 00000000 00000000
reserved2:(0x0068 64-bits)
00000000 00000000
rotpk:(0x0070 256-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ssk:(0x0090 256-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
rssk:(0x00b0 128-bits)
00000000 00000000 00000000 00000000
hdcp-hash:(0x00c0 128-bits)
00000000 00000000 00000000 00000000
nv1:(0x00d0 32-bits)
00000000
nv2:(0x00d4 32-bits)
00000000
reserved3:(0x00d8 96-bits)
00000000 00000000 00000000
oem-program-secure:(0x00e4 224-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000
efuse分配信息如下:
static const struct sid_section_t {
char * name;
uint32_t offset;
uint32_t size_bits;
} sids[] = {
{ "chipid", 0x0000, 128 },
{ "brom-conf-try", 0x0010, 32 },
{ "thermal-sensor", 0x0014, 64 },
{ "ft-zone", 0x001c, 128 },
{ "tvout", 0x002c, 32 },
{ "tvout-gamma", 0x0030, 64 },
{ "oem-program", 0x0038, 64 },
{ "write-protect", 0x0040, 32 },
{ "read-protect", 0x0044, 32 },
{ "reserved1", 0x0048, 64 },
{ "huk", 0x0050, 192 },
{ "reserved2", 0x0068, 64 },
{ "rotpk", 0x0070, 256 },
{ "ssk", 0x0090, 256 },
{ "rssk", 0x00b0, 128 },
{ "hdcp-hash", 0x00c0, 128 },
{ "nv1", 0x00d0, 32 },
{ "nv2", 0x00d4, 32 },
{ "reserved3", 0x00d8, 96 },
{ "oem-program-secure", 0x00e4, 224 },
};
这是根据全志SDK总结而来。
全志的SOC,只要不是太老旧的芯片,里面都集成了2048bit的EFUSE,但此熔丝位的很多细节,并没有相关描述文档,这导致大家很难在实际项目中应用此功能,而且也缺乏灵活的烧写工具,基于此问题,我花了点时间扩展了下XFEL工具。
扩展的命令如下:
usage:
xfel extra efuse dump - Dump all of the efuse information
xfel extra efuse read32 <offset> - Read 32-bits value from efuse
xfel extra efuse write32 <offset> <value> - Write 32-bits value to efuse
xfel extra efuse write <offset> <file> - Write file to efuse
执行dump指令,显示如下信息:
xfel extra efuse dump
chipid:(0x0000 128-bits)
93406000 0c004814 01426250 48671b4b
brom-conf-try:(0x0010 32-bits)
00000000
thermal-sensor:(0x0014 64-bits)
88fbc11a 01e9080f
ft-zone:(0x001c 128-bits)
898f1919 0f760f6c 3108126c 811a0a0e
tvout:(0x002c 32-bits)
0000028f
tvout-gamma:(0x0030 64-bits)
00000000 00000000
oem-program:(0x0038 64-bits)
00000000 00000000
write-protect:(0x0040 32-bits)
00000000
read-protect:(0x0044 32-bits)
00000000
reserved1:(0x0048 64-bits)
00000000 00000000
huk:(0x0050 192-bits)
00000000 00000000 00000000 00000000 00000000 00000000
reserved2:(0x0068 64-bits)
00000000 00000000
rotpk:(0x0070 256-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ssk:(0x0090 256-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
rssk:(0x00b0 128-bits)
00000000 00000000 00000000 00000000
hdcp-hash:(0x00c0 128-bits)
00000000 00000000 00000000 00000000
nv1:(0x00d0 32-bits)
00000000
nv2:(0x00d4 32-bits)
00000000
reserved3:(0x00d8 96-bits)
00000000 00000000 00000000
oem-program-secure:(0x00e4 224-bits)
00000000 00000000 00000000 00000000 00000000 00000000 00000000
可以通过write32 或者write指令来烧写熔丝。
全志加密引导功能可以通过烧写熔丝来启用,当然你也可以烧写自己的序列号,或者mac地址之类的,当然这个efuse还可以用来做防盗版,来实现一机一固件,简要说明下,就是在efuse里烧录本机固件的签名文件,而这个签名文件又是跟cpu序列号关联,可以采用ECDSA256签名算法,签名大小为512bit,64字节,比RSA的签名要小很多,而且强度够。
全志T113的TVD模块,测试下来,发现是这德行。估计又是哪里配置错误了。
驱动文件在这里
https://github.com/xboot/xboot/blob/master/src/arch/arm32/mach-t113s3/driver/cam-t113-tvd.c
站在微凉大侠的肩膀上,编写F1C100S平台的CVBS IN驱动, 也就是驱动完全找不到北的TVD模块。
https://whycan.com/t_6902.html
F133平台做了自动探测处理,T113平台没有实现。
enum {
BOOT_DEVICE_SPINOR,
BOOT_DEVICE_SPINAND,
BOOT_DEVICE_SDCARD,
};
static int get_boot_device(void)
{
uint8_t s = *((volatile uint8_t *)(0x00020000 + 0x28));
if(s == 0x3)
return BOOT_DEVICE_SPINOR;
else if(s == 0x4)
return BOOT_DEVICE_SPINAND;
else if(s == 0x0)
return BOOT_DEVICE_SDCARD;
return BOOT_DEVICE_SPINOR;
}
想研究的,看这个代码,不贴代码的都是耍流氓。
{
// The Hotplug Flag Register is 0x070005DC.
// The Soft Entry Address Register is 0x070005E0.
// la a0, 0x02500000
// la a1, 0x23
// sb a1, 0 (a0)
// xxx: j xxx
// Test: write byte to 0x02500000 = UART0 data tegister
static const uint32_t code [] = {
0x02500537, // 37 05 50 02
0x0230059B, // 9B 05 30 02 │
0x00B50023, // 23 00 B5 00
0x0000006F, // 6F 00 00 00,
};
* (volatile uint32_t *) 0x070005DC = 0*0xFA50392Fu; // Hotplug Flag Register
* (volatile uint32_t *) 0x070005E0 = (uintptr_t) code; // Soft Entry Address Register
dcache_clean_all();
printhex(0x06000000, (void *) 0x06000000, 0x10000);
//CCU->RISC_GATING_REG
CCU->RISC_CFG_BGR_REG |= (1u << 16) | (1u << 0);
(void) CCU->RISC_CFG_BGR_REG;
PRINTF("CCU->RISC_CFG_BGR_REG=%08" PRIX32 "\n", CCU->RISC_CFG_BGR_REG);
RISC_CFG->RISC_STA_ADD0_REG = (uintptr_t) code;
RISC_CFG->RISC_STA_ADD1_REG = 0;//(uint32_t) (uintptr_t) code >> 32;
//memset(RISC_CFG, ~ 0u, sizeof * RISC_CFG);
PRINTF("CCU->RISC_GATING_REG=%08" PRIX32 ", CCU->RISC_CFG_BGR_REG=%08" PRIX32 "\n", CCU->RISC_GATING_REG, CCU->RISC_CFG_BGR_REG);
PRINTF("RISC_CFG->RISC_STA_ADD0_REG=%08" PRIX32 ", RISC_CFG->RISC_STA_ADD1_REG=%08" PRIX32 "\n", RISC_CFG->RISC_STA_ADD0_REG, RISC_CFG->RISC_STA_ADD1_REG);
//printhex32(RISC_CFG_BASE, RISC_CFG, sizeof * RISC_CFG);
local_delay_ms(3000);
//PRINTF("CCU->RISC_RST_REG=%08" PRIX32 "\n", CCU->RISC_RST_REG);
CCU->RISC_RST_REG = 0x16AA0001u;
(void) CCU->RISC_RST_REG;
//PRINTF("CCU->RISC_RST_REG=%08" PRIX32 "\n", CCU->RISC_RST_REG);
//ASSERT(CCU->RISC_RST_REG & 0x01u);
for (;;)
;
}
xfel-windows-v1.3.1.7z
上传一个已编译好的V1.3.1版本,windows平台。
贴一个采用xfel直接引导xboot的完整log,可以是空片直接启动。
xfel ddr r128-s2;
xfel write 0x08200000 xboot.bin;
xfel extra exec riscv 0x08200000;
[2]set pll end
[3]board init ok
[5]fake dram ok
[7]heap: 0x40a0000 size:0xe000
[9]lpsram init
[11]lspsram init aps64
[13]lspsram dqs:0x011a01a0
[18]psram chip APS64 init ok!, freq 1920000000
[22]Init psram controller ok
[24]hpsram init
[26]DRAM DQS gate is PD mode.
[29]DRAM BOOT DRIVE INFO: V2.00
[32]DRAM CLK = 800 MHZ
[34]dram_tpr11 = 0x0 , dram_tpr12 =0x0
[37]dram_tpr9 = 0x2020
[86]DRAM simple test OK.
[88]DRAM SIZE =8 MB
[100]fes1 done
█████████████████████████████████
██ ▄▄▄▄▄ █ ▀███▀ ▄█▀█ ▄█ ▄▄▄▄▄ ██
██ █ █ █ ▀▄█▄▄▀▄▀█▄▀ █ █ █ ██
██ █▄▄▄█ █▄ ▄▄▀█▄▀█ ▄█ █▄▄▄█ ██
██▄▄▄▄▄▄▄█ █ █▄▀▄█▄▀▄▀▄█▄▄▄▄▄▄▄██
███▄▄█▄█▄▄▀█ ▀ ▀ ▀ ███ ▀▄ ▄▄ ██
██▀ ▄▄ ▄▄█▄▄ ▀ ▄▄▀▄▀▄█ ▀▄▀▄▀▄██
██▄▀▄█▄█▄ ▄▄█▀▄▀ ▀ ███ ██ ██ ██
███ ▄▄▄▄▄▄ ▄▄▀▀▄▄█▀▀▄▀▄▀▄▀▄▀▄▀▄██
██▄▄█▀▄▄▄ ▄ ▀▀▄▄▄▀▄ ███ █ ██ ██
██▄▀▄▄█ ▄▀▀▄▀▄ ▄▀▀▄▀▄▀▄▀▄▀▄▀▄▀▄██
██▄██▄█▄▄█▀▀▀▄█ ███ █ ▄▄▄ ██ ██
██ ▄▄▄▄▄ █▄ ██▀ ▀▀▄▀▄ █▄█ ▀▄▀▄██
██ █ █ █▄▀██▀█▄██ ▀▄ ▄▄ █▀ ██
██ █▄▄▄█ █ ▀▀▄▄██▀▄▀▄█ █▀▄▀▄▀▄██
██▄▄▄▄▄▄▄███▄▄▄▄▄██▄▄█▄█▄█▄▄█▄▄██
█████████████████████████████████
_ _
_ _ | |___ _____ _____ _| |_
\ \/ /| _ | _ | _ |_ _| (C) 2007-2023
) ( | |_| | |_| | |_| | | |____JIANJUN.JIANG__
/_/\_\|_____|_____|_____| |_____________________|
V3.0.0 (May 24 2023 - 09:30:05) - [yuzuki][Yuzuki Based On Allwinner R128 SOC]
[ 0.000020]Probe device 'blk-romdisk.0' with blk-romdisk
[ 0.000800]Probe device 'fix-losc' with clk-fixed
[ 0.000810]Probe device 'rc-16m' with clk-fixed
[ 0.000820]Probe device 'rcosc-clk' with clk-fixed
[ 0.000830]Probe device 'ext-32k' with clk-fixed
[ 0.000840]Probe device 'rc-hf' with clk-fixed
[ 0.000850]Probe device 'rccal-fake-parent' with clk-fixed
[ 0.000860]Probe device 'osc26m' with clk-fixed
[ 0.000870]Probe device 'osc40m' with clk-fixed
[ 0.000880]Probe device 'osc24m' with clk-fixed
[ 0.000890]Probe device 'osc32m' with clk-fixed
[ 0.000900]Probe device 'osc24.576m' with clk-fixed
[ 0.000910]Probe device 'hosc' with clk-mux
[ 0.000920]Probe device 'hosc-div32k' with clk-fixed-factor
[ 0.000930]Probe device 'rcosc-div32k' with clk-fixed-factor
[ 0.000940]Probe device 'hosc-div2' with clk-fixed-factor
[ 0.000950]Probe device 'dpll1' with clk-r128-pll
[ 0.000960]Probe device 'dpll2' with clk-r128-pll
[ 0.000970]Probe device 'dpll3' with clk-r128-pll
[ 0.000980]Probe device 'pll-audio' with clk-r128-pll
[ 0.000990]Probe device 'rfip0-dpll' with clk-fixed-factor
[ 0.001000]Probe device 'rfip1-dpll' with clk-fixed-factor
[ 0.001010]Probe device 'pll-audio2x' with clk-fixed-factor
[ 0.001020]Probe device 'pll-audio1x' with clk-fixed-factor
[ 0.001030]Probe device 'dpll1-div4' with clk-fixed-factor
[ 0.001040]Probe device 'dpll1-div5' with clk-fixed-factor
[ 0.001050]Probe device 'dpll1-div6' with clk-fixed-factor
[ 0.001060]Probe device 'dpll1-div7' with clk-fixed-factor
[ 0.001070]Probe device 'dpll1-div8' with clk-fixed-factor
[ 0.001080]Probe device 'dpll1-div39' with clk-fixed-factor
[ 0.001090]Probe device 'dpll1-div85' with clk-fixed-factor
[ 0.001100]Probe device 'dpll3-div4' with clk-fixed-factor
[ 0.001110]Probe device 'dpll3-div5' with clk-fixed-factor
[ 0.001120]Probe device 'dpll3-div6' with clk-fixed-factor
[ 0.001130]Probe device 'dpll3-div7' with clk-fixed-factor
[ 0.001140]Probe device 'dpll3-div8' with clk-fixed-factor
[ 0.001150]Probe device 'ck1-usb' with clk-gate
[ 0.001160]Probe device 'mux-ck1-aud' with clk-mux
[ 0.001170]Probe device 'ck1-aud' with clk-gate
[ 0.001180]Probe device 'mux-ck1-dev' with clk-mux
[ 0.001190]Probe device 'ck1-dev' with clk-gate
[ 0.001200]Probe device 'mux-ck1-m33' with clk-mux
[ 0.001210]Probe device 'ck1-m33' with clk-gate
[ 0.001220]Probe device 'mux-ck3-dev' with clk-mux
[ 0.001230]Probe device 'ck3-dev' with clk-gate
[ 0.001240]Probe device 'mux-ck3-m33' with clk-mux
[ 0.001250]Probe device 'ck3-m33' with clk-gate
[ 0.001260]Probe device 'ck-dev' with clk-mux
[ 0.001270]Probe device 'device-clk' with clk-divider
[ 0.001280]Probe device 'ck-m33' with clk-mux
[ 0.001290]Probe device 'sys' with clk-divider
[ 0.001300]Probe device 'aud-rco-div' with clk-divider
[ 0.001310]Probe device 'ar200a-f' with clk-mux
[ 0.001320]Probe device 'hfclk-div' with clk-ratio
[ 0.001330]Probe device 'lfclk-div' with clk-ratio
[ 0.001340]Probe device 'ahb-div' with clk-ratio
[ 0.001350]Probe device 'apb' with clk-mux
[ 0.001360]Probe device 'ble-32m' with clk-gate
[ 0.001370]Probe device 'ble-48m' with clk-gate
[ 0.001380]Probe device 'gpio-gate' with clk-gate
[ 0.001390]Probe device 'bus-codec-dac' with clk-gate
[ 0.001400]Probe device 'rccal' with clk-gate
[ 0.001410]Probe device 'bus-codec-adc' with clk-gate
[ 0.001420]Probe device 'dmic-bus' with clk-gate
[ 0.001430]Probe device 'gpadc' with clk-gate
[ 0.001440]Probe device 'lpuart1-wkup' with clk-gate
[ 0.001450]Probe device 'lpuart0-wkup' with clk-gate
[ 0.001460]Probe device 'osc32k-en' with clk-gate
[ 0.001470]Probe device 'rc32k-en' with clk-gate
[ 0.001480]Probe device 'rc-hf-en' with clk-gate
[ 0.001490]Probe device 'rccal-32k' with clk-gate
[ 0.001500]Probe device 'rco-wup-en' with clk-gate
[ 0.001510]Probe device 'lf-sel' with clk-mux
[ 0.001520]Probe device 'sys-32k-sel' with clk-mux
[ 0.001530]Probe device 'ble-sel' with clk-mux
[ 0.001540]Probe device 'sysrtc32k' with clk-mux
[ 0.001550]Probe device 'pad' with clk-mux
[ 0.001560]Probe device 'div-pad' with clk-divider
[ 0.001570]Probe device 'pad-out' with clk-gate
[ 0.001580]Probe device 'div' with clk-mux
[ 0.001590]Probe device '32k-auto-en-switch' with clk-gate
[ 0.001600]Probe device 'bus-ehci0' with clk-gate
[ 0.001610]Probe device 'bus-ohci0' with clk-gate
[ 0.001620]Probe device 'bus-csi-jpe' with clk-gate
[ 0.001630]Probe device 'bus-ledc' with clk-gate
[ 0.001640]Probe device 'bus-otg' with clk-gate
[ 0.001650]Probe device 'bus-smcard' with clk-gate
[ 0.001660]Probe device 'bus-hspsram-ctrl' with clk-gate
[ 0.001670]Probe device 'bus-irrx' with clk-gate
[ 0.001680]Probe device 'bus-irtx' with clk-gate
[ 0.001690]Probe device 'bus-pwm' with clk-gate
[ 0.001700]Probe device 'bus-twi1' with clk-gate
[ 0.001710]Probe device 'bus-twi0' with clk-gate
[ 0.001720]Probe device 'bus-uart2' with clk-gate
[ 0.001730]Probe device 'bus-uart1' with clk-gate
[ 0.001740]Probe device 'bus-uart0' with clk-gate
[ 0.001750]Probe device 'bus-sdc0' with clk-gate
[ 0.001760]Probe device 'bus-spi1' with clk-gate
[ 0.001770]Probe device 'bus-spi0' with clk-gate
[ 0.001780]Probe device 'bus-monitor' with clk-gate
[ 0.001790]Probe device 'bus-g2d' with clk-gate
[ 0.001800]Probe device 'bus-de' with clk-gate
[ 0.001810]Probe device 'bus-display' with clk-gate
[ 0.001820]Probe device 'bus-lcd' with clk-gate
[ 0.001830]Probe device 'bus-bt-core' with clk-gate
[ 0.001840]Probe device 'bus-wlan-ctrl' with clk-gate
[ 0.001850]Probe device 'bus-trng' with clk-gate
[ 0.001860]Probe device 'bus-spc' with clk-gate
[ 0.001870]Probe device 'bus-ss' with clk-gate
[ 0.001880]Probe device 'bus-timer' with clk-gate
[ 0.001890]Probe device 'bus-spinlock' with clk-gate
[ 0.001900]Probe device 'bus-dma1' with clk-gate
[ 0.001910]Probe device 'bus-dma0' with clk-gate
[ 0.001920]Probe device 'bus-spdif' with clk-gate
[ 0.001930]Probe device 'bus-i2s' with clk-gate
[ 0.001940]Probe device 'riscv-cfg' with clk-gate
[ 0.001950]Probe device 'riscv-msgbox' with clk-gate
[ 0.001960]Probe device 'dsp-cfg' with clk-gate
[ 0.001970]Probe device 'dsp-msgbox' with clk-gate
[ 0.001980]Probe device 'cpu-msgbox' with clk-gate
[ 0.001990]Probe device 'mbus-de' with clk-gate
[ 0.002000]Probe device 'mbus-g2d' with clk-gate
[ 0.002010]Probe device 'mbus-csi' with clk-gate
[ 0.002020]Probe device 'mbus-dma1' with clk-gate
[ 0.002030]Probe device 'mbus-dma0' with clk-gate
[ 0.002040]Probe device 'mbus-usb' with clk-gate
[ 0.002050]Probe device 'mbus-ce' with clk-gate
[ 0.002060]Probe device 'mbus-dsp' with clk-gate
[ 0.002070]Probe device 'mbus-riscv' with clk-gate
[ 0.002080]Probe device 'mbus-cpu' with clk-gate
[ 0.002090]Probe device 'mux-pclk-spc' with clk-mux
[ 0.002100]Probe device 'div-pclk-spc' with clk-divider
[ 0.002110]Probe device 'pclk-spc' with clk-ratio
[ 0.002120]Probe device 'mux-spi0' with clk-mux
[ 0.002130]Probe device 'div-spi0' with clk-divider
[ 0.002140]Probe device 'ratio-spi0' with clk-ratio
[ 0.002150]Probe device 'spi0' with clk-gate
[ 0.002160]Probe device 'mux-spi1' with clk-mux
[ 0.002170]Probe device 'div-spi1' with clk-divider
[ 0.002180]Probe device 'ratio-spi1' with clk-ratio
[ 0.002190]Probe device 'spi1' with clk-gate
[ 0.002200]Probe device 'mux-sdc0' with clk-mux
[ 0.002210]Probe device 'div-sdc0' with clk-divider
[ 0.002220]Probe device 'ratio-sdc0' with clk-ratio
[ 0.002230]Probe device 'sdc0' with clk-gate
[ 0.002240]Probe device 'mux-ss' with clk-mux
[ 0.002250]Probe device 'div-ss' with clk-divider
[ 0.002260]Probe device 'ratio-ss' with clk-ratio
[ 0.002270]Probe device 'ss' with clk-gate
[ 0.002280]Probe device 'mux-csi-jpe' with clk-mux
[ 0.002290]Probe device 'div-csi-jpe' with clk-divider
[ 0.002300]Probe device 'ratio-csi-jpe' with clk-ratio
[ 0.002310]Probe device 'csi-jpe' with clk-gate
[ 0.002320]Probe device 'mux-ledc' with clk-mux
[ 0.002330]Probe device 'div-ledc' with clk-divider
[ 0.002340]Probe device 'ratio-ledc' with clk-ratio
[ 0.002350]Probe device 'ledc' with clk-gate
[ 0.002360]Probe device 'mux-irrx' with clk-mux
[ 0.002370]Probe device 'div-irrx' with clk-divider
[ 0.002380]Probe device 'ratio-irrx' with clk-ratio
[ 0.002390]Probe device 'irrx' with clk-gate
[ 0.002400]Probe device 'mux-irtx' with clk-mux
[ 0.002410]Probe device 'div-irtx' with clk-divider
[ 0.002420]Probe device 'ratio-irtx' with clk-ratio
[ 0.002430]Probe device 'irtx' with clk-gate
[ 0.002440]Probe device 'mux-systick-ref' with clk-mux
[ 0.002450]Probe device 'div-systick-ref' with clk-divider
[ 0.002460]Probe device 'ratio-systick-ref' with clk-ratio
[ 0.002470]Probe device 'systick-ref' with clk-gate
[ 0.002480]Probe device 'systick-noref' with clk-gate
[ 0.002490]Probe device 'systick-skew' with clk-gate
[ 0.002500]Probe device 'mux-csi-mclk' with clk-mux
[ 0.002510]Probe device 'div-csi-mclk' with clk-divider
[ 0.002520]Probe device 'ratio-csi-mclk' with clk-ratio
[ 0.002530]Probe device 'csi-mclk' with clk-gate
[ 0.002540]Probe device 'mux-flash-spi' with clk-mux
[ 0.002550]Probe device 'div-flash-spi' with clk-divider
[ 0.002560]Probe device 'ratio-flash-spi' with clk-ratio
[ 0.002570]Probe device 'flash-spi' with clk-gate
[ 0.002580]Probe device 'mux-g2d' with clk-mux
[ 0.002590]Probe device 'div-g2d' with clk-divider
[ 0.002600]Probe device 'ratio-g2d' with clk-ratio
[ 0.002610]Probe device 'g2d' with clk-gate
[ 0.002620]Probe device 'mux-de' with clk-mux
[ 0.002630]Probe device 'div-de' with clk-divider
[ 0.002640]Probe device 'ratio-de' with clk-ratio
[ 0.002650]Probe device 'de' with clk-gate
[ 0.002660]Probe device 'mux-lcd' with clk-mux
[ 0.002670]Probe device 'div-lcd' with clk-divider
[ 0.002680]Probe device 'ratio-lcd' with clk-ratio
[ 0.002690]Probe device 'lcd' with clk-gate
[ 0.002700]Probe device 'timer0' with clk-link
[ 0.002710]Probe device 'timer1' with clk-link
[ 0.002720]Probe device 'uart0' with clk-link
[ 0.002730]Probe device 'uart1' with clk-link
[ 0.002740]Probe device 'uart2' with clk-link
[ 0.002750]Probe device 'wdg' with clk-fixed
[ 0.002760]Probe device 'reset-r128.0' with reset-r128
[ 0.002770]Probe device 'reset-r128.1' with reset-r128
[ 0.002780]Probe device 'reset-r128.2' with reset-r128
[ 0.002790]Probe device 'reset-r128.3' with reset-r128
[ 0.002800]Probe device 'reset-r128.4' with reset-r128
[ 0.002810]Probe device 'reset-r128.5' with reset-r128
[ 0.002820]Probe device 'reset-r128.6' with reset-r128
[ 0.002830]Probe device 'irq-r128.0' with irq-r128
[ 0.002840]Probe device 'irq-r128-gpio.0' with irq-r128-gpio
[ 0.002850]Probe device 'irq-r128-gpio.1' with irq-r128-gpio
[ 0.002860]Probe device 'gpio-r128.0' with gpio-r128
[ 0.002870]Probe device 'gpio-r128.1' with gpio-r128
[ 0.002880]Probe device 'ce-r128-timer.0' with ce-r128-timer
[ 0.000089]Probe device 'cs-r128-timer.0' with cs-r128-timer
[ 0.005967]Probe device 'uart-16550.0' with uart-16550
[ 0.011228]Probe device 'uart-16550.1' with uart-16550
[ 0.016569]Probe device 'i2c-r128.0' with i2c-r128
[ 0.021506]Probe device 'i2c-r128.1' with i2c-r128
[ 0.026445]Probe device 'spi-r128.0' with spi-r128
[ 0.040882]Found spi nor flash 'SFDP' with 16.000MB
[ 0.045752]Found partition:
[ 0.048569] 0x0000000000000000 ~ 0x0000000000ffffff 16.000MB - blk-spinor.0
[ 0.055880] 0x0000000000000000 ~ 0x00000000005fffff 6.000MB - blk-spinor.0.xboot
[ 0.063687] 0x0000000000600000 ~ 0x00000000007fffff 2.000MB - blk-spinor.0.reserve
[ 0.071651] 0x0000000000800000 ~ 0x0000000000ffffff 8.000MB - blk-spinor.0.private
[ 0.079508]Probe device 'blk-spinor.0' with blk-spinor
[ 0.084811]Probe device 'wdg-r128.0' with wdg-r128
[ 0.089669]Probe device 'console-uart.0' with console-uart
[ 0.098777]mount /private with 'ram' filesystem
Press any key to stop auto boot: 0.260
xboot: /#
xboot: /#
xboot: /#
xfel升级到V1.3.1版本,此版本已完整支持R128,楼上计划的所有功能均以实现,包括烧写SPI NOR FLASH,通过fel启动RISCV核心,启动DSP核心。
这里扩展了一个extra命令,可以启动RISCV和DSP核,后面的地址,就是核心的入口地址。
usage:
xfel extra exec riscv <address> - Boot riscv and jump to address
xfel extra exec dsp <address> - Boot dsp and jump to address
现在运行xboot有两种方案:
1,直接用xfel来运行RISCV程序
xfel ddr r128-s2;
xfel write 0x08200000 xboot.bin;
xfel extra exec riscv 0x08200000;
2,利用全志SDK里的m33.bin程序来引导riscv
xfel ddr r128-s2;
xfel write 0x08004000 lichee/rtos/build/r128s2_pro_m33/img/rt_system.bin;
xfel write 0x08200000 xboot.bin;
xfel exec 0x08004001;
严谨点说,就是多做3个操作,R128芯片内部spi nor flash必挂
1, 全局解锁SPI NOR FLASH
2, 将状态寄存器2,清零
3,将状态寄存器3,清零
具体是哪一个操作导致的,还是3个操作共同导致的,就不得而知了,每实验一次,一个芯片就报废了,我手上的三颗芯片,全处于搞残的状态,已经没有新芯片了,这些实验代价有点高。
除了这三个操作,xfel在操作spi nor时,还会执行两个动作
1,复位SPI NOR FLASH
2, 将状态寄存器1,清零
这两个动作是不会产生任何副作用的,在R128上已测试通过,就是最上面的三个步骤,会导致问题,而且百分百必现。
再去锁定下SPI NOR FLASH,可以救活被搞残的芯片?
已实现xfel烧写R128内部SPI NOR FLASH,但出现了一个超级超级大的坑。
只要用xfel访问过的R128芯片,哪怕仅仅是探测下spi nor flash,就会导致全志的固件无法正常运行,而且这个时候想用Phoenixsuit工具去刷机也不给刷了,提示找不到spi nor flash,但用xfel是可以正常读写spi nor flash的,这坑坑。。。。
换句话说,xfel能将R128搞残,而且是永久性的,这。。。。
全志固件启动的提示:
[2]BOOT0 commit : 7de04b7c
[5]set pll end
[6]board init ok
[8]boot reason: SUNXI_BOOT_REASON_COLD_BOOT
[26]heap: 0x40a0000 size:0xe000
[29]lspsram init aps64
[31]lspsram dqs:0x01190190
[36]psram chip APS64 init ok!, freq 1920000000
[40]Init psram controller ok
[43]hpsram init
[44]DRAM DQS gate is PD mode.
[47]DRAM BOOT DRIVE INFO: V2.00
[50]DRAM CLK = 800 MHZ
[52]dram_tpr11 = 0x0 , dram_tpr12 =0x0
[56]dram_tpr9 = 0x2121
[86]DRAM simple test OK.
[88]DRAM SIZE =8 MB
[90]boot package base:0xc600000
[93]prcm: 0x1
[94]init pins for sip nor
[96]nor read id ret:0x0, id[0]:0x0
[100]spinor init fail
[102]load gpt fail
[103]init gpt fail
[115]go to usb efex!
手上仅有的2片R128都被搞残了。再贴个xfel烧写spi nor 的log吧,读写spi nor完全正常,校验也可以通过。
xfel spinor
Found spi nor flash 'SFDP' with 16777216 bytes
xfel spinor read 0 16777216 dump4.bin
100% [================================================] 16.000 MB, 383.050 KB/s
xfel spinor write 0 dump.bin
100% [================================================] 16.000 MB, 193.715 KB/s
针对R128,现已实现了中断驱动,GPIO驱动,TIMER驱动,SPI驱动,I2C驱动,时钟等驱动,打印log如下:
[0]fes begin commit:7de04b7c
[2]set pll end
[3]board init ok
[5]fake dram ok
[7]heap: 0x40a0000 size:0xe000
[9]lpsram init
[11]lspsram init aps64
[13]lspsram dqs:0x011c01c0
[18]psram chip APS64 init ok!, freq 1920000000
[22]Init psram controller ok
[24]hpsram init
[26]DRAM DQS gate is PD mode.
[29]DRAM BOOT DRIVE INFO: V2.00
[32]DRAM CLK = 800 MHZ
[34]dram_tpr11 = 0x0 , dram_tpr12 =0x0
[37]dram_tpr9 = 0x2424
[86]DRAM simple test OK.
[88]DRAM SIZE =8 MB
[100]fes1 done
Warning: clk ck1-m33 enable_count is 2, parent is dpll1, parent rate is 1920000000, should not be changed from 480000000 to 384000000, please recheck whether the operation is correct
Warning: clk ck1-dev enable_count is 2, parent is dpll1, parent rate is 1920000000, should not be changed from 1920000000 to 384000000, please recheck whether the operation is correct
M33 CPU Clock Freq: 192 MHz
*******************************************
** Welcome to R128 FreeRTOS V1.5.0 **
** Copyright (C) 2019-2022 AllwinnerTech **
** **
** starting armv8m FreeRTOS V0.7 **
*******************************************
Date:May 10 2023, Time:14:01:58
flash not ready, skip mount
---boot dsp(start_addr: 0x0c000660)---
---boot
█████████████████████████████████
██ ▄▄▄▄▄ █ ▀███▀ ▄█▀█ ▄█ ▄▄▄▄▄ ██
██ █ █ █ ▀▄█▄▄▀▄▀█▄▀ █ █ █ ██
██ █▄▄▄█ █▄ ▄▄▀█▄▀█ ▄█ █▄▄▄█ ██
██▄▄▄▄▄▄▄█ █ █▄▀▄█▄▀▄▀▄█▄▄▄▄▄▄▄██
███▄▄█▄█▄▄▀█ ▀ ▀ ▀ ███ ▀▄ ▄▄ ██
██▀ ▄▄ ▄▄█▄▄ ▀ ▄▄▀▄▀▄█ ▀▄▀▄▀▄██
██▄▀▄█▄█▄ ▄▄█▀▄▀ ▀ ███ ██ ██ ██
███ ▄▄▄▄▄▄ ▄▄▀▀▄▄█▀▀▄▀▄▀▄▀▄▀▄▀▄██
██▄▄█▀▄▄▄ ▄ ▀▀▄▄▄▀▄ ███ █ ██ ██
██▄▀▄▄█ ▄▀▀▄▀▄ ▄▀▀▄▀▄▀▄▀▄▀▄▀▄▀▄██
██▄██▄█▄▄█▀▀▀▄█ ███ █ ▄▄▄ ██ ██
██ ▄▄▄▄▄ █▄ ██▀ ▀▀▄▀▄ █▄█ ▀▄▀▄██
██ █ █ █▄▀██▀█▄██ ▀▄ ▄▄ █▀ ██
██ █▄▄▄█ █ ▀▀▄▄██▀▄▀▄█ █▀▄▀▄▀▄██
██▄▄▄▄▄▄▄███▄▄▄▄▄██▄▄█▄█▄█▄▄█▄▄██
█████████████████████████████████
_ _
_ _ | |___ _____ _____ _| |_
\ \/ /| _ | _ | _ |_ _| (C) 2007-2023
) ( | |_| | |_| | |_| | | |____JIANJUN.JIANG__
/_/\_\|_____|_____|_____| |_____________________|
V3.0.0 (May 22 2023 - 17:17:57) - [yuzuki][Yuzuki Based On Allwinner R128 SOC]
[ 0.000020]Probe device 'blk-romdisk.0' with blk-romdisk
[ 0.000800]Probe device 'fix-losc' with clk-fixed
[ 0.000810]Probe device 'rc-16m' with clk-fixed
[ 0.000820]Probe device 'rcosc-clk' with clk-fixed
[ 0.000830]Probe device 'ext-32k' with clk-fixed
[ 0.000840]Probe device 'rc-hf' with clk-fixed
[ 0.000850]Probe device 'rccal-fake-parent' with clk-fixed
[ 0.000860]Probe device 'osc26m' with clk-fixed
[ 0.000870]Probe device 'osc40m' with clk-fixed
[ 0.000880]Probe device 'osc24m' with clk-fixed
[ 0.000890]Probe device 'osc32m' with clk-fixed
[ 0.000900]Probe device 'osc24.576m' with clk-fixed
[ 0.000910]Probe device 'hosc' with clk-mux
[ 0.000920]Probe device 'hosc-div32k' with clk-fixed-factor
[ 0.000930]Probe device 'rcosc-div32k' with clk-fixed-factor
[ 0.000940]Probe device 'hosc-div2' with clk-fixed-factor
[ 0.000950]Probe device 'dpll1' with clk-r128-pll
[ 0.000960]Probe device 'dpll2' with clk-r128-pll
[ 0.000970]Probe device 'dpll3' with clk-r128-pll
[ 0.000980]Probe device 'pll-audio' with clk-r128-pll
[ 0.000990]Probe device 'rfip0-dpll' with clk-fixed-factor
[ 0.001000]Probe device 'rfip1-dpll' with clk-fixed-factor
[ 0.001010]Probe device 'pll-audio2x' with clk-fixed-factor
[ 0.001020]Probe device 'pll-audio1x' with clk-fixed-factor
[ 0.001030]Probe device 'dpll1-div4' with clk-fixed-factor
[ 0.001040]Probe device 'dpll1-div5' with clk-fixed-factor
[ 0.001050]Probe device 'dpll1-div6' with clk-fixed-factor
[ 0.001060]Probe device 'dpll1-div7' with clk-fixed-factor
[ 0.001070]Probe device 'dpll1-div8' with clk-fixed-factor
[ 0.001080]Probe device 'dpll1-div39' with clk-fixed-factor
[ 0.001090]Probe device 'dpll1-div85' with clk-fixed-factor
[ 0.001100]Probe device 'dpll3-div4' with clk-fixed-factor
[ 0.001110]Probe device 'dpll3-div5' with clk-fixed-factor
[ 0.001120]Probe device 'dpll3-div6' with clk-fixed-factor
[ 0.001130]Probe device 'dpll3-div7' with clk-fixed-factor
[ 0.001140]Probe device 'dpll3-div8' with clk-fixed-factor
[ 0.001150]Probe device 'ck1-usb' with clk-gate
[ 0.001160]Probe device 'mux-ck1-aud' with clk-mux
[ 0.001170]Probe device 'ck1-aud' with clk-gate
[ 0.001180]Probe device 'mux-ck1-dev' with clk-mux
[ 0.001190]Probe device 'ck1-dev' with clk-gate
[ 0.001200]Probe device 'mux-ck1-m33' with clk-mux
[ 0.001210]Probe device 'ck1-m33' with clk-gate
[ 0.001220]Probe device 'mux-ck3-dev' with clk-mux
[ 0.001230]Probe device 'ck3-dev' with clk-gate
[ 0.001240]Probe device 'mux-ck3-m33' with clk-mux
[ 0.001250]Probe device 'ck3-m33' with clk-gate
[ 0.001260]Probe device 'ck-dev' with clk-mux
[ 0.001270]Probe device 'device-clk' with clk-divider
[ 0.001280]Probe device 'ck-m33' with clk-mux
[ 0.001290]Probe device 'sys' with clk-divider
[ 0.001300]Probe device 'aud-rco-div' with clk-divider
[ 0.001310]Probe device 'ar200a-f' with clk-mux
[ 0.001320]Probe device 'hfclk-div' with clk-ratio
[ 0.001330]Probe device 'lfclk-div' with clk-ratio
[ 0.001340]Probe device 'ahb-div' with clk-ratio
[ 0.001350]Probe device 'apb' with clk-mux
[ 0.001360]Probe device 'ble-32m' with clk-gate
[ 0.001370]Probe device 'ble-48m' with clk-gate
[ 0.001380]Probe device 'gpio-gate' with clk-gate
[ 0.001390]Probe device 'bus-codec-dac' with clk-gate
[ 0.001400]Probe device 'rccal' with clk-gate
[ 0.001410]Probe device 'bus-codec-adc' with clk-gate
[ 0.001420]Probe device 'dmic-bus' with clk-gate
[ 0.001430]Probe device 'gpadc' with clk-gate
[ 0.001440]Probe device 'lpuart1-wkup' with clk-gate
[ 0.001450]Probe device 'lpuart0-wkup' with clk-gate
[ 0.001460]Probe device 'osc32k-en' with clk-gate
[ 0.001470]Probe device 'rc32k-en' with clk-gate
[ 0.001480]Probe device 'rc-hf-en' with clk-gate
[ 0.001490]Probe device 'rccal-32k' with clk-gate
[ 0.001500]Probe device 'rco-wup-en' with clk-gate
[ 0.001510]Probe device 'lf-sel' with clk-mux
[ 0.001520]Probe device 'sys-32k-sel' with clk-mux
[ 0.001530]Probe device 'ble-sel' with clk-mux
[ 0.001540]Probe device 'sysrtc32k' with clk-mux
[ 0.001550]Probe device 'pad' with clk-mux
[ 0.001560]Probe device 'div-pad' with clk-divider
[ 0.001570]Probe device 'pad-out' with clk-gate
[ 0.001580]Probe device 'div' with clk-mux
[ 0.001590]Probe device '32k-auto-en-switch' with clk-gate
[ 0.001600]Probe device 'bus-ehci0' with clk-gate
[ 0.001610]Probe device 'bus-ohci0' with clk-gate
[ 0.001620]Probe device 'bus-csi-jpe' with clk-gate
[ 0.001630]Probe device 'bus-ledc' with clk-gate
[ 0.001640]Probe device 'bus-otg' with clk-gate
[ 0.001650]Probe device 'bus-smcard' with clk-gate
[ 0.001660]Probe device 'bus-hspsram-ctrl' with clk-gate
[ 0.001670]Probe device 'bus-irrx' with clk-gate
[ 0.001680]Probe device 'bus-irtx' with clk-gate
[ 0.001690]Probe device 'bus-pwm' with clk-gate
[ 0.001700]Probe device 'bus-twi1' with clk-gate
[ 0.001710]Probe device 'bus-twi0' with clk-gate
[ 0.001720]Probe device 'bus-uart2' with clk-gate
[ 0.001730]Probe device 'bus-uart1' with clk-gate
[ 0.001740]Probe device 'bus-uart0' with clk-gate
[ 0.001750]Probe device 'bus-sdc0' with clk-gate
[ 0.001760]Probe device 'bus-spi1' with clk-gate
[ 0.001770]Probe device 'bus-spi0' with clk-gate
[ 0.001780]Probe device 'bus-monitor' with clk-gate
[ 0.001790]Probe device 'bus-g2d' with clk-gate
[ 0.001800]Probe device 'bus-de' with clk-gate
[ 0.001810]Probe device 'bus-display' with clk-gate
[ 0.001820]Probe device 'bus-lcd' with clk-gate
[ 0.001830]Probe device 'bus-bt-core' with clk-gate
[ 0.001840]Probe device 'bus-wlan-ctrl' with clk-gate
[ 0.001850]Probe device 'bus-trng' with clk-gate
[ 0.001860]Probe device 'bus-spc' with clk-gate
[ 0.001870]Probe device 'bus-ss' with clk-gate
[ 0.001880]Probe device 'bus-timer' with clk-gate
[ 0.001890]Probe device 'bus-spinlock' with clk-gate
[ 0.001900]Probe device 'bus-dma1' with clk-gate
[ 0.001910]Probe device 'bus-dma0' with clk-gate
[ 0.001920]Probe device 'bus-spdif' with clk-gate
[ 0.001930]Probe device 'bus-i2s' with clk-gate
[ 0.001940]Probe device 'riscv-cfg' with clk-gate
[ 0.001950]Probe device 'riscv-msgbox' with clk-gate
[ 0.001960]Probe device 'dsp-cfg' with clk-gate
[ 0.001970]Probe device 'dsp-msgbox' with clk-gate
[ 0.001980]Probe device 'cpu-msgbox' with clk-gate
[ 0.001990]Probe device 'mbus-de' with clk-gate
[ 0.002000]Probe device 'mbus-g2d' with clk-gate
[ 0.002010]Probe device 'mbus-csi' with clk-gate
[ 0.002020]Probe device 'mbus-dma1' with clk-gate
[ 0.002030]Probe device 'mbus-dma0' with clk-gate
[ 0.002040]Probe device 'mbus-usb' with clk-gate
[ 0.002050]Probe device 'mbus-ce' with clk-gate
[ 0.002060]Probe device 'mbus-dsp' with clk-gate
[ 0.002070]Probe device 'mbus-riscv' with clk-gate
[ 0.002080]Probe device 'mbus-cpu' with clk-gate
[ 0.002090]Probe device 'mux-pclk-spc' with clk-mux
[ 0.002100]Probe device 'div-pclk-spc' with clk-divider
[ 0.002110]Probe device 'pclk-spc' with clk-ratio
[ 0.002120]Probe device 'mux-spi0' with clk-mux
[ 0.002130]Probe device 'div-spi0' with clk-divider
[ 0.002140]Probe device 'ratio-spi0' with clk-ratio
[ 0.002150]Probe device 'spi0' with clk-gate
[ 0.002160]Probe device 'mux-spi1' with clk-mux
[ 0.002170]Probe device 'div-spi1' with clk-divider
[ 0.002180]Probe device 'ratio-spi1' with clk-ratio
[ 0.002190]Probe device 'spi1' with clk-gate
[ 0.002200]Probe device 'mux-sdc0' with clk-mux
[ 0.002210]Probe device 'div-sdc0' with clk-divider
[ 0.002220]Probe device 'ratio-sdc0' with clk-ratio
[ 0.002230]Probe device 'sdc0' with clk-gate
[ 0.002240]Probe device 'mux-ss' with clk-mux
[ 0.002250]Probe device 'div-ss' with clk-divider
[ 0.002260]Probe device 'ratio-ss' with clk-ratio
[ 0.002270]Probe device 'ss' with clk-gate
[ 0.002280]Probe device 'mux-csi-jpe' with clk-mux
[ 0.002290]Probe device 'div-csi-jpe' with clk-divider
[ 0.002300]Probe device 'ratio-csi-jpe' with clk-ratio
[ 0.002310]Probe device 'csi-jpe' with clk-gate
[ 0.002320]Probe device 'mux-ledc' with clk-mux
[ 0.002330]Probe device 'div-ledc' with clk-divider
[ 0.002340]Probe device 'ratio-ledc' with clk-ratio
[ 0.002350]Probe device 'ledc' with clk-gate
[ 0.002360]Probe device 'mux-irrx' with clk-mux
[ 0.002370]Probe device 'div-irrx' with clk-divider
[ 0.002380]Probe device 'ratio-irrx' with clk-ratio
[ 0.002390]Probe device 'irrx' with clk-gate
[ 0.002400]Probe device 'mux-irtx' with clk-mux
[ 0.002410]Probe device 'div-irtx' with clk-divider
[ 0.002420]Probe device 'ratio-irtx' with clk-ratio
[ 0.002430]Probe device 'irtx' with clk-gate
[ 0.002440]Probe device 'mux-systick-ref' with clk-mux
[ 0.002450]Probe device 'div-systick-ref' with clk-divider
[ 0.002460]Probe device 'ratio-systick-ref' with clk-ratio
[ 0.002470]Probe device 'systick-ref' with clk-gate
[ 0.002480]Probe device 'systick-noref' with clk-gate
[ 0.002490]Probe device 'systick-skew' with clk-gate
[ 0.002500]Probe device 'mux-csi-mclk' with clk-mux
[ 0.002510]Probe device 'div-csi-mclk' with clk-divider
[ 0.002520]Probe device 'ratio-csi-mclk' with clk-ratio
[ 0.002530]Probe device 'csi-mclk' with clk-gate
[ 0.002540]Probe device 'mux-flash-spi' with clk-mux
[ 0.002550]Probe device 'div-flash-spi' with clk-divider
[ 0.002560]Probe device 'ratio-flash-spi' with clk-ratio
[ 0.002570]Probe device 'flash-spi' with clk-gate
[ 0.002580]Probe device 'mux-g2d' with clk-mux
[ 0.002590]Probe device 'div-g2d' with clk-divider
[ 0.002600]Probe device 'ratio-g2d' with clk-ratio
[ 0.002610]Probe device 'g2d' with clk-gate
[ 0.002620]Probe device 'mux-de' with clk-mux
[ 0.002630]Probe device 'div-de' with clk-divider
[ 0.002640]Probe device 'ratio-de' with clk-ratio
[ 0.002650]Probe device 'de' with clk-gate
[ 0.002660]Probe device 'mux-lcd' with clk-mux
[ 0.002670]Probe device 'div-lcd' with clk-divider
[ 0.002680]Probe device 'ratio-lcd' with clk-ratio
[ 0.002690]Probe device 'lcd' with clk-gate
[ 0.002700]Probe device 'timer0' with clk-link
[ 0.002710]Probe device 'timer1' with clk-link
[ 0.002720]Probe device 'wdg' with clk-fixed
[ 0.002730]Probe device 'uart0' with clk-fixed
[ 0.002740]Probe device 'uart1' with clk-fixed
[ 0.002750]Probe device 'uart2' with clk-fixed
[ 0.002760]Probe device 'reset-r128.0' with reset-r128
[ 0.002770]Probe device 'reset-r128.1' with reset-r128
[ 0.002780]Probe device 'reset-r128.2' with reset-r128
[ 0.002790]Probe device 'reset-r128.3' with reset-r128
[ 0.002800]Probe device 'reset-r128.4' with reset-r128
[ 0.002810]Probe device 'reset-r128.5' with reset-r128
[ 0.002820]Probe device 'reset-r128.6' with reset-r128
[ 0.002830]Probe device 'irq-r128.0' with irq-r128
[ 0.002840]Probe device 'irq-r128-gpio.0' with irq-r128-gpio
[ 0.002850]Probe device 'irq-r128-gpio.1' with irq-r128-gpio
[ 0.002860]Probe device 'gpio-r128.0' with gpio-r128
[ 0.002870]Probe device 'gpio-r128.1' with gpio-r128
[ 0.002880]Probe device 'ce-r128-timer.0' with ce-r128-timer
[ 0.000046]Probe device 'cs-r128-timer.0' with cs-r128-timer
[ 0.005696]Probe device 'uart-16550.0' with uart-16550
[ 0.010808]Probe device 'uart-16550.1' with uart-16550
[ 0.015957]Probe device 'i2c-r128.0' with i2c-r128
[ 0.020727]Probe device 'i2c-r128.1' with i2c-r128
[ 0.025489]Probe device 'spi-r128.0' with spi-r128
[ 0.039591]Found spi nor flash 'SFDP' with 16.000MB
[ 0.044374]Found partition:
[ 0.047151] 0x0000000000000000 ~ 0x0000000000ffffff 16.000MB - blk-spinor.0
[ 0.054304] 0x0000000000000000 ~ 0x00000000005fffff 6.000MB - blk-spinor.0.xboot
[ 0.061925] 0x0000000000600000 ~ 0x00000000007fffff 2.000MB - blk-spinor.0.reserve
[ 0.069725] 0x0000000000800000 ~ 0x0000000000ffffff 8.000MB - blk-spinor.0.private
[ 0.077480]Probe device 'blk-spinor.0' with blk-spinor
[ 0.082645]Probe device 'wdg-r128.0' with wdg-r128
[ 0.087402]Probe device 'console-uart.0' with console-uart
[ 0.094821]mount /private with 'ram' filesystem
Press any key to stop auto boot: 0.120
xboot: /#
补充一个手册上没有的信息,R128内置SPI NOR FLASH,此Flash接在GPIOB8,GPIOB9,GPIOB10,GPIOB11,GPIOB12,GPIOB13 Pin脚上,功能3为SPI0 pinmux
"spi-r128:0@0x40009000": {
"clock-name": "spi0",
"reset": 0,
"sclk-gpio": 45,
"sclk-gpio-config": 3,
"mosi-gpio": 42,
"mosi-gpio-config": 3,
"miso-gpio": 43,
"miso-gpio-config": 3,
"cs-gpio": 44,
"cs-gpio-config": 3
},
通过xfel工具,R128现在已可以运行xboot,LOG记录如下,下面就可以愉快的编写R128驱动了。
█████████████████████████████████
██ ▄▄▄▄▄ █ ▀███▀ ▄█▀█ ▄█ ▄▄▄▄▄ ██
██ █ █ █ ▀▄█▄▄▀▄▀█▄▀ █ █ █ ██
██ █▄▄▄█ █▄ ▄▄▀█▄▀█ ▄█ █▄▄▄█ ██
██▄▄▄▄▄▄▄█ █ █▄▀▄█▄▀▄▀▄█▄▄▄▄▄▄▄██
███▄▄█▄█▄▄▀█ ▀ ▀ ▀ ███ ▀▄ ▄▄ ██
██▀ ▄▄ ▄▄█▄▄ ▀ ▄▄▀▄▀▄█ ▀▄▀▄▀▄██
██▄▀▄█▄█▄ ▄▄█▀▄▀ ▀ ███ ██ ██ ██
███ ▄▄▄▄▄▄ ▄▄▀▀▄▄█▀▀▄▀▄▀▄▀▄▀▄▀▄██
██▄▄█▀▄▄▄ ▄ ▀▀▄▄▄▀▄ ███ █ ██ ██
██▄▀▄▄█ ▄▀▀▄▀▄ ▄▀▀▄▀▄▀▄▀▄▀▄▀▄▀▄██
██▄██▄█▄▄█▀▀▀▄█ ███ █ ▄▄▄ ██ ██
██ ▄▄▄▄▄ █▄ ██▀ ▀▀▄▀▄ █▄█ ▀▄▀▄██
██ █ █ █▄▀██▀█▄██ ▀▄ ▄▄ █▀ ██
██ █▄▄▄█ █ ▀▀▄▄██▀▄▀▄█ █▀▄▀▄▀▄██
██▄▄▄▄▄▄▄███▄▄▄▄▄██▄▄█▄█▄█▄▄█▄▄██
█████████████████████████████████
_ _
_ _ | |___ _____ _____ _| |_
\ \/ /| _ | _ | _ |_ _| (C) 2007-2023
) ( | |_| | |_| | |_| | | |____JIANJUN.JIANG__
/_/\_\|_____|_____|_____| |_____________________|
V3.0.0 (May 17 2023 - 23:25:28) - [yuzuki][Yuzuki Based On Allwinner R128 SOC]
[ 0.000020]Probe device 'blk-romdisk.0' with blk-romdisk
[ 0.000800]Probe device 'osc48m' with clk-fixed
[ 0.000810]Probe device 'osc32k' with clk-fixed
[ 0.000820]Probe device 'bus-uart0' with clk-fixed
[ 0.000830]Probe device 'wdg' with clk-fixed
[ 0.000840]Probe device 'uart-16550.0' with uart-16550
[ 0.000850]Probe device 'wdg-r128.0' with wdg-r128
[ 0.000860]Probe device 'console-uart.0' with console-uart
[ 0.000970]mount /private with 'ram' filesystem
Press any key to stop auto boot: 0.330
xboot: /#
用xfel指令加载sdk默认镜像试验。
#初始化DDR
xfel ddr r128-s2;
#加载M33核程序到0x08004000
xfel write 0x08004000 lichee/rtos/build/r128s2_pro_m33/img/rt_system.bin;
#加载C906程序到0x08200000,注意此程序是SPI NOR XIP的,光加载到RAM中是无法完整运行的,这里仅做引导C906试验。
xfel write 0x08200000 lichee/rtos/build/r128s2_pro_c906/img/rt_system.bin;
#运行M33核心程序,M33核心运行时,会自动的运行C906以及DSP程序。所以,将C906和DSP程序准备好,可以随着M33核一起启动。
xfel exec 0x08004001
现象如下:
[0]fes begin commit:7de04b7c
[2]set pll end
[3]board init ok
[5]fake dram ok
[7]heap: 0x40a0000 size:0xe000
[9]lpsram init
[11]lspsram init aps64
[13]lspsram dqs:0x011a01a0
[18]psram chip APS64 init ok!, freq 1920000000
[22]Init psram controller ok
[24]hpsram init
[26]DRAM DQS gate is PD mode.
[29]DRAM BOOT DRIVE INFO: V2.00
[32]DRAM CLK = 800 MHZ
[34]dram_tpr11 = 0x0 , dram_tpr12 =0x0
[37]dram_tpr9 = 0x2020
[86]DRAM simple test OK.
[88]DRAM SIZE =8 MB
[100]fes1 done
[0]fes begin commit:7de04b7c
[2]set pll end
[3]board init ok
[5]fake dram ok
[7]heap: 0x40a0000 size:0xe000
[9]lpsram init
[11]lspsram init aps64
[13]lspsram dqs:0x01060060
[18]psram chip APS64 init ok!, freq 1920000000
[22]Init psram controller ok
[24]hpsram init
[26]DRAM DQS gate is PD mode.
[29]DRAM BOOT DRIVE INFO: V2.00
[32]DRAM CLK = 800 MHZ
[34]dram_tpr11 = 0x0 , dram_tpr12 =0x0
[37]dram_tpr9 = 0x2020
[86]DRAM simple test OK.
[88]DRAM SIZE =8 MB
[100]fes1 done
Warning: clk ck1-m33 enable_count is 2, parent is dpll1, parent rate is 1920000000, should not be changed from 480000000 to 384000000, please recheck whether the operation is correct
Warning: clk ck1-dev enable_count is 2, parent is dpll1, parent rate is 1920000000, should not be changed from 1920000000 to 384000000, please recheck whether the operation is correct
] not support in sys_config
M33 CPU Clock Freq: 192 MHz
*******************************************
** Welcome to R128 FreeRTOS V1.5.0 **
** Copyright (C) 2019-2022 AllwinnerTech **
** **
** starting armv8m FreeRTOS V0.7 **
*******************************************
Date:May 10 2023, Time:14:01:58
[E(m33)] get dram_para dram_no_lpsram failed, skip LSPSRAM standby
[E(m33)] get dram_para dram_clk failed, skip HSPSRAM standby
flash not ready, skip mount
---boot dsp(start_addr: 0x0c000660)---
---boot c906---
C906 CPU Freq: 480 MHz
*******************************************
** Welcome to R128 FreeRTOS V1.5.0 **
** Copyright (C) 2019-2022 AllwinnerTech **
** **
** starting riscv FreeRTOS V0.7 **
*******************************************
Date:May 10 2023, Time:14:09:34
devfs: mount devfs to /dev ok
use default flash chip mJedec 0x0
[FD I]: Enter 32 Bit Address Mode
[FD I]: mode: 0x20, freq: 96000000Hz, drv: 0
[FD I]: jedec: 0x0, suspend_support: 1
no flash, skip init nor
=====================================================================================================
EXC_LOAD_ACCESS
=====================================================================================================
gprs:
x0:0x0000000000000000 ra:0x0000000008255c2e sp:0x000000000830dfe0 gp:0x00000000082c5420
tp:0x0000000000000000 t0:0x0000000000000030 t1:0x0000000000000000 t2:0x0000000000000009
s0:0x00000000082fca78 s1:0x00000000082b3df8 a0:0xffffffffffffffff a1:0x0000000000000000
a2:0x0000000000000000 a3:0x000000000830e070 a4:0x0000000000000000 a5:0x0000000000000000
a6:0x0000000000000002 a7:0x000000004004707c s2:0x00000000082b3df8 s3:0x0000000008336b70
s5:0xa5a5a5a5a5a5a5a5 s5:0xa5a5a5a5a5a5a5a5 s6:0xa5a5a5a5a5a5a5a5 s7:0xa5a5a5a5a5a5a5a5
s8:0xa5a5a5a5a5a5a5a5 s9:0xa5a5a5a5a5a5a5a5 s10:0xa5a5a5a5a5a5a5a5 s11:0xa5a5a5a5a5a5a5a5
t3:0x0000000000000000 t4:0x0000000000000000 t5:0x0000000000000020 t6:0x0000000000000000
other:
mepc :0x0000000008255c40
mcause :0x0000000000000005
mtval :0x0000000000000000
mstatus :0x0000000a00003980
mscratch:0x0000000000000000
-------backtrace-----------
backtrace : 0X08255C40
backtrace : 0X0825EFB6
backtrace : 0X0825EE76
---------------------------
再接再厉,利用读写payload操作M33核的看门狗,实现reset功能。
static int chip_reset(struct xfel_ctx_t * ctx)
{
payload_write32(ctx, 0x40020400 + 0x14, (0x16aa << 16) | (0x1 << 0));
payload_write32(ctx, 0x40020400 + 0x18, (0x16aa << 16) | (1 << 0));
payload_write32(ctx, 0x40020400 + 0x10, (0xa57 << 1) | (1 << 0));
return 1;
}
有了上面的研究,我们就可以编写一个纯粹的针对cortex-m33核的read32以及write32的payload了,为何要自己编写这两个payload,而不采用fel协议自带的读写R32,W32实现,是因为fel协议本身在读写内存时,是基于字节访问的,而某些控制器的寄存器是不支持字节访问,只支持word字访问,因为有这种限制,那fel自带的读写函数,是不适合操作芯片寄存器的。
read32.S
.syntax unified
.global _start
_start:
dsb.w sy
isb.w sy
ldr.w r0, _iciallu
mov.w r1, #0x0
str.w r1, [r0]
dsb.w sy
isb.w sy
b.w reset
.align 2
_iciallu:
.word 0xe000ef50
reset:
ldr.w r0, _adr
adr.w r1, _val
ldr.w r2, [r0]
str.w r2, [r1]
bx lr
.align 2
_adr:
.word 0x11223344
_val:
.word 0x55667788
write32.S
.syntax unified
.global _start
_start:
dsb.w sy
isb.w sy
ldr.w r0, _iciallu
mov.w r1, #0x0
str.w r1, [r0]
dsb.w sy
isb.w sy
b.w reset
.align 2
_iciallu:
.word 0xe000ef50
reset:
ldr.w r0, _adr
ldr.w r1, _val
str.w r1, [r0]
bx lr
.align 2
_adr:
.word 0x11223344
_val:
.word 0x55667788
封装读写payload
static uint32_t payload_read32(struct xfel_ctx_t * ctx, uint32_t addr)
{
static const uint8_t payload[] = {
0xbf, 0xf3, 0x4f, 0x8f, 0xbf, 0xf3, 0x6f, 0x8f, 0xdf, 0xf8, 0x14, 0x00,
0x4f, 0xf0, 0x00, 0x01, 0xc0, 0xf8, 0x00, 0x10, 0xbf, 0xf3, 0x4f, 0x8f,
0xbf, 0xf3, 0x6f, 0x8f, 0x00, 0xf0, 0x02, 0xb8, 0x50, 0xef, 0x00, 0xe0,
0xdf, 0xf8, 0x10, 0x00, 0x0f, 0xf2, 0x10, 0x01, 0xd0, 0xf8, 0x00, 0x20,
0xc1, 0xf8, 0x00, 0x20, 0x70, 0x47, 0x00, 0xbf
};
uint32_t adr = cpu_to_le32(addr);
uint32_t val;
fel_write(ctx, ctx->version.scratchpad, (void *)payload, sizeof(payload));
fel_write(ctx, ctx->version.scratchpad + sizeof(payload), (void *)&adr, sizeof(adr));
fel_exec(ctx, ctx->version.scratchpad);
fel_read(ctx, ctx->version.scratchpad + sizeof(payload) + sizeof(adr), (void *)&val, sizeof(val));
return le32_to_cpu(val);
}
static void payload_write32(struct xfel_ctx_t * ctx, uint32_t addr, uint32_t val)
{
static const uint8_t payload[] = {
0xbf, 0xf3, 0x4f, 0x8f, 0xbf, 0xf3, 0x6f, 0x8f, 0xdf, 0xf8, 0x14, 0x00,
0x4f, 0xf0, 0x00, 0x01, 0xc0, 0xf8, 0x00, 0x10, 0xbf, 0xf3, 0x4f, 0x8f,
0xbf, 0xf3, 0x6f, 0x8f, 0x00, 0xf0, 0x02, 0xb8, 0x50, 0xef, 0x00, 0xe0,
0xdf, 0xf8, 0x0c, 0x00, 0xdf, 0xf8, 0x0c, 0x10, 0xc0, 0xf8, 0x00, 0x10,
0x70, 0x47, 0x00, 0xbf
};
uint32_t params[2] = {
cpu_to_le32(addr),
cpu_to_le32(val),
};
fel_write(ctx, ctx->version.scratchpad, (void *)payload, sizeof(payload));
fel_write(ctx, ctx->version.scratchpad + sizeof(payload), (void *)params, sizeof(params));
fel_exec(ctx, ctx->version.scratchpad);
}
利用读写payload实现使能jtag的pinmux功能
static int chip_jtag(struct xfel_ctx_t * ctx)
{
uint32_t addr;
uint32_t val;
/* Config PA16 and PA17 to SWD-TMS and SWD-TCK */
addr = 0x4004a400 + 0x08;
val = payload_read32(ctx, addr);
val &= ~(0xf << ((0 & 0xf) << 2));
val |= ((0x8 & 0xf) << ((0 & 0xf) << 2));
payload_write32(ctx, addr, val);
val = payload_read32(ctx, addr);
val &= ~(0xf << ((1 & 0xf) << 2));
val |= ((0x8 & 0xf) << ((1 & 0xf) << 2));
payload_write32(ctx, addr, val);
return 1;
}
关于exec指令如何可靠稳定的执行自己写的测试程序的问题,经过深入研究,定位是M33核指令缓存相关问题。
我们编写的payload,如果上传到某个地址,然后在这个地址执行后,这部分代码就被缓存了,如果这个时候,我们在更新另外一个payload,通过write指令写入内存,SRAM或者LSPSRAM或者HSPSRAM中,然后新payload的执行地址如果跟原先的地址相同的话,这个时候就会出现不可预见的现象,执行的指令有可能是原先被缓存过payload。
既然分析到问题点了,解决手段,有两种方案:
一种是粗暴的关闭指令缓存,这种方案影响后续的执行效率,就不考虑了
另一种方案就是现在采用的方案,每一个payload保证开始的指令都是一致的,而且这些一致的指令里,首先做的动作就是清理指令,这样就能保证每个payload都能有效执行了,避免不可以预见的现象。
payload头指令
.syntax unified
.global _start
_start:
dsb.w sy
isb.w sy
ldr.w r0, _iciallu
mov.w r1, #0x0
str.w r1, [r0]
dsb.w sy
isb.w sy
b.w reset
.align 2
_iciallu:
.word 0xe000ef50
reset:
push.w { lr }
/* ... */
pop.w { lr }
bx lr
经过以上处理后,就可以解决之前感觉怪意的问题,同时也验证了,payload放在LSPSRAM或在HSPRSRAM空间,都是可以正常执行的,不是必须是内部的SRAM。这就为后续的全RAM中执行程序,打下基础。什么M33程序,C906程序,DSP程序,理论上都是可以执行的。
虽然算是搞了exec指令,但如何可靠稳定的执行自己写的测试程序,现在测试下来,感觉还是有点怪意,初步分析,可能M33核心里面指令或者数据cache了,还没玩过M33,对这个核里面的细节不清楚,先不枉下结论了,但这个问题,是有必要去深究的。
R128里面有PSRAM,有nor flash。初步计划,针对R128芯片,后续xfel需要开发以下功能:
1,读写SRAM,(已完成)
2,执行运行在M33核的payload指令(已完成)
3,读取R128的SID(已完成)
4,初始化M33核心的jtag接口,此接口跟调试串口复用(已开发,未测试)
5,实现reset操作
6,初始化LSPRAM以及HSPSRAM
7, 支持启动C906核心,加载并执行通过write命令写入到RAM中的C906程序
8, 支持启动DSP核心,加载并执行通过write命令写入到RAM中的DSP程序 (优先级低,估计没手段验证)
9,支持烧写NOR FLASH
如果完美实现了这些功能,通过xfel来开发R128,估计要爽到飞起,开发验证都是足够便捷的。
全志R128里面有三个核心,一个M33,一个C906,还有一个DSP。
M33核主要负责引导,启动,安全,休眠,唤醒,低功耗,WIFI/BT等相关功能。
C906主要负责运行各种APP,控制各种外设驱动
DSP主要负责音频算法处理
现在手上拿到了一个有异常的板子,无法正常烧录,刷机,但fel模式是可以运行的。所以先尝试开发xfel对R128芯片的支持。
适配xfel,前面比较顺利,可以顺利读写SRAM,但exec命令被卡壳了,无法运行ARM payload,经过不断尝试,终于可以执行exec指令了,原来M33核的payload每一条指令不一定都是32位,有可能存在16位的,M33核无法编译出全32位指令。
花了点时间研究了下全志的2D加速模块,这个2D加速,其实就是DE2模块,现在测试了矩形填充,以及bitblit操作。
驱动代码在这里。
https://gitee.com/xboot/xboot/blob/master/src/arch/arm32/mach-t113s3/driver/g2d-t113.c
时隔一年,一个偶然的发现,搞定了T113的中断, _vector 需要32字节对齐,补丁如下:
diff --git a/src/arch/arm32/mach-t113s3/start.S b/src/arch/arm32/mach-t113s3/start.S
index 39d83e78a..4415adea1 100644
--- a/src/arch/arm32/mach-t113s3/start.S
+++ b/src/arch/arm32/mach-t113s3/start.S
@@ -86,7 +86,7 @@
.global _start
_start:
/* Boot head information for BROM */
- .long 0xea000016
+ .long 0xea00000e
.byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0'
.long 0x12345678 /* checksum */
.long __spl_size /* spl size */
@@ -97,7 +97,9 @@ _start:
.long 0x0 /* eGON version */
.byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */
.byte 0x34, 0x2e, 0x30, 0x00
+ .long 0, 0, 0, 0 /* reserve */
+ .align 5
_vector:
b reset
ldr pc, _undefined_instruction
补充一个准确的说明文件,上面的偏移有些错误
# Rockchip RV1106
## Compile source code and generate the target files at the output directory
```shell
make clean
make CROSS_COMPILE=/path/to/arm-none-linux-gnueabihf- PLATFORM=arm32-rv1106
```
## Enter maskrom mode and using xrock for burning spi nor flash (offset = 0x00010000, sector = 128)
```shell
sudo xrock maskrom rv1106_ddr_924MHz_v1.09.bin rv1106_usbplug_v1.06.bin --rc4-off;
sleep 3;
sudo xrock flash write 128 xbootpak.bin;
sudo xrock reset;
```
## Enter maskrom mode and using xrock for burning spi nand flash (offset = 0x00040000, sector = 512)
```shell
sudo xrock maskrom rv1106_ddr_924MHz_v1.09.bin rv1106_usbplug_v1.06.bin --rc4-off;
sleep 3;
sudo xrock flash write 512 xbootpak.bin;
sudo xrock reset;
```
## Enter maskrom mode and using xrock for burning emmc (offset = 0x00008000, sector = 64)
```shell
sudo xrock maskrom rv1106_ddr_924MHz_v1.09.bin rv1106_usbplug_v1.06.bin --rc4-off;
sleep 3;
sudo xrock flash write 64 xbootpak.bin;
sudo xrock reset;
```
## Download xrock source code
```shell
git clone https://github.com/xboot/xrock.git
```
## Make and install xrock
```shell
make
sudo make install
```
现在已添加了不少裸机驱动,启动log如下:
DDR Version V1.09 20220630
f947
F
DDRConf2
DDR3, BW=16 Col=10 Bk=8 CS0 Row=13 CS=1 Die BW=16 Size=128MB
924MHz
DDR bin out
█████████████████████████
██ ▄▄▄▄▄ ██▄▀▀▀█ ▄▄▄▄▄ ██
██ █ █ █ ▀▄█ █ █ █ ██
██ █▄▄▄█ ██▄ ██ █▄▄▄█ ██
██▄▄▄▄▄▄▄█▄█ █ █▄▄▄▄▄▄▄██
████▀▄ ▀▄▄█ ▀█▄▀█▀▀ █▀██
███▀▄▀ ▀▄ ▄█▀▀▄▀█ ▀█ ▄███
███▄█▄█▄▄▄▀▀ ▄ ▀ ▄▄ ▀ ██
██ ▄▄▄▄▄ █▄ ▄█▄▀▄████▄▄██
██ █ █ █ ▀█▄█▄▄█ ▄▀█▄██
██ █▄▄▄█ ██▀ █ ▄▄▄▄█▄ ██
██▄▄▄▄▄▄▄███▄██▄▄▄▄▄▄▄███
█████████████████████████
_ _
_ _ | |___ _____ _____ _| |_
\ \/ /| _ | _ | _ |_ _| (C) 2007-2022
) ( | |_| | |_| | |_| | | |____JIANJUN.JIANG__
/_/\_\|_____|_____|_____| |_____________________|
V3.0.0 (Aug 19 2022 - 10:43:57) - [x1106][X1106 Based On RV1106 SOC]
[ 0.000020]Probe device 'blk-romdisk.0' with blk-romdisk
[ 0.000800]Probe device 'xin24m' with clk-fixed
[ 0.000810]Probe device 'xin32k' with clk-fixed
[ 0.000820]Probe device 'clk_rtc_32k' with clk-link
[ 0.000830]Probe device 'apll' with clk-rv1106-pll
[ 0.000840]Probe device 'cpll' with clk-rv1106-pll
[ 0.000850]Probe device 'dpll' with clk-rv1106-pll
[ 0.000860]Probe device 'gpll' with clk-rv1106-pll
[ 0.000870]Probe device 'clk_pvtm_core' with clk-rv1106-gate
[ 0.000880]Probe device 'clk_core_mcu_rtc' with clk-rv1106-gate
[ 0.000890]Probe device 'clk_timer_root' with clk-rv1106-gate
[ 0.000900]Probe device 'hclk_cpu' with clk-rv1106-comp
[ 0.000910]Probe device 'clk_core_mcu' with clk-rv1106-comp
[ 0.000920]Probe device 'clk_50m_src' with clk-rv1106-comp
[ 0.000930]Probe device 'clk_100m_src' with clk-rv1106-comp
[ 0.000940]Probe device 'clk_150m_src' with clk-rv1106-comp
[ 0.000950]Probe device 'clk_200m_src' with clk-rv1106-comp
[ 0.000960]Probe device 'clk_250m_src' with clk-rv1106-comp
[ 0.000970]Probe device 'clk_300m_src' with clk-rv1106-comp
[ 0.000980]Probe device 'clk_339m_src' with clk-rv1106-comp
[ 0.000990]Probe device 'clk_400m_src' with clk-rv1106-comp
[ 0.001000]Probe device 'clk_450m_src' with clk-rv1106-comp
[ 0.001010]Probe device 'clk_500m_src' with clk-rv1106-comp
[ 0.001020]Probe device 'pclk_top_root' with clk-rv1106-comp
[ 0.001030]Probe device 'pclk_peri_root' with clk-rv1106-comp
[ 0.001040]Probe device 'clk_100m_pmu' with clk-rv1106-divider
[ 0.001050]Probe device 'pclk_pmu_root' with clk-rv1106-comp
[ 0.001060]Probe device 'pclk_vi_rtc_root' with clk-rv1106-comp
[ 0.001070]Probe device 'pclk_vi_rtc_phy' with clk-rv1106-gate
[ 0.001080]Probe device 'pclk_vi_rtc_test' with clk-rv1106-gate
[ 0.001090]Probe device 'pclk_i2c0' with clk-rv1106-gate
[ 0.001100]Probe device 'clk_i2c0' with clk-rv1106-comp
[ 0.001110]Probe device 'pclk_i2c1' with clk-rv1106-gate
[ 0.001120]Probe device 'clk_i2c1' with clk-rv1106-comp
[ 0.001130]Probe device 'pclk_i2c2' with clk-rv1106-gate
[ 0.001140]Probe device 'clk_i2c2' with clk-rv1106-comp
[ 0.001150]Probe device 'pclk_i2c3' with clk-rv1106-gate
[ 0.001160]Probe device 'clk_i2c3' with clk-rv1106-comp
[ 0.001170]Probe device 'pclk_i2c4' with clk-rv1106-gate
[ 0.001180]Probe device 'clk_i2c4' with clk-rv1106-comp
[ 0.001190]Probe device 'pclk_timer' with clk-rv1106-gate
[ 0.001200]Probe device 'clk_timer0' with clk-rv1106-gate
[ 0.001210]Probe device 'clk_timer1' with clk-rv1106-gate
[ 0.001220]Probe device 'clk_timer2' with clk-rv1106-gate
[ 0.001230]Probe device 'clk_timer3' with clk-rv1106-gate
[ 0.001240]Probe device 'clk_timer4' with clk-rv1106-gate
[ 0.001250]Probe device 'clk_timer5' with clk-rv1106-gate
[ 0.001260]Probe device 'pclk_stimer' with clk-rv1106-gate
[ 0.001270]Probe device 'clk_stimer0' with clk-rv1106-gate
[ 0.001280]Probe device 'clk_stimer1' with clk-rv1106-gate
[ 0.001290]Probe device 'pclk_saradc' with clk-rv1106-gate
[ 0.001300]Probe device 'clk_saradc' with clk-rv1106-comp
[ 0.001310]Probe device 'clk_uart0_src' with clk-rv1106-comp
[ 0.001320]Probe device 'gate-clk_uart0_src' with clk-rv1106-gate
[ 0.001330]Probe device 'clk_uart0_frac' with clk-rv1106-factor
[ 0.001340]Probe device 'clk_uart0' with clk-rv1106-mux
[ 0.001350]Probe device 'link-uart0' with clk-link
[ 0.001360]Probe device 'link-uart1' with clk-link
[ 0.001370]Probe device 'link-uart2' with clk-link
[ 0.001380]Probe device 'link-uart3' with clk-link
[ 0.001390]Probe device 'link-uart4' with clk-link
[ 0.001400]Probe device 'link-uart5' with clk-link
[ 0.001410]Probe device 'link-wdt' with clk-link
[ 0.001420]Probe device 'reset-rv1106.0' with reset-rv1106
[ 0.001430]Probe device 'reset-rv1106.1' with reset-rv1106
[ 0.001440]Probe device 'reset-rv1106.2' with reset-rv1106
[ 0.001450]Probe device 'reset-rv1106.3' with reset-rv1106
[ 0.001460]Probe device 'reset-rv1106.4' with reset-rv1106
[ 0.001470]Probe device 'reset-rv1106.5' with reset-rv1106
[ 0.001480]Probe device 'reset-rv1106.6' with reset-rv1106
[ 0.001490]Probe device 'reset-rv1106.7' with reset-rv1106
[ 0.001500]Probe device 'reset-rv1106.8' with reset-rv1106
[ 0.001510]Probe device 'reset-rv1106.9' with reset-rv1106
[ 0.001520]Probe device 'reset-rv1106.10' with reset-rv1106
[ 0.001530]Probe device 'reset-rv1106.11' with reset-rv1106
[ 0.001540]Probe device 'reset-rv1106.12' with reset-rv1106
[ 0.001550]Probe device 'reset-rv1106.13' with reset-rv1106
[ 0.001560]Probe device 'reset-rv1106.14' with reset-rv1106
[ 0.001570]Probe device 'reset-rv1106.15' with reset-rv1106
[ 0.001580]Probe device 'reset-rv1106.16' with reset-rv1106
[ 0.001590]Probe device 'reset-rv1106.17' with reset-rv1106
[ 0.001600]Probe device 'reset-rv1106.18' with reset-rv1106
[ 0.001610]Probe device 'reset-rv1106.19' with reset-rv1106
[ 0.001620]Probe device 'reset-rv1106.20' with reset-rv1106
[ 0.001630]Probe device 'reset-rv1106.21' with reset-rv1106
[ 0.001640]Probe device 'reset-rv1106.22' with reset-rv1106
[ 0.001650]Probe device 'reset-rv1106.23' with reset-rv1106
[ 0.001660]Probe device 'reset-rv1106.24' with reset-rv1106
[ 0.001670]Probe device 'reset-rv1106.25' with reset-rv1106
[ 0.001680]Probe device 'reset-rv1106.26' with reset-rv1106
[ 0.001690]Probe device 'irq-gic400.0' with irq-gic400
[ 0.001700]Probe device 'irq-rv1106-gpio.0' with irq-rv1106-gpio
[ 0.001710]Probe device 'irq-rv1106-gpio.1' with irq-rv1106-gpio
[ 0.001720]Probe device 'irq-rv1106-gpio.2' with irq-rv1106-gpio
[ 0.001730]Probe device 'irq-rv1106-gpio.3' with irq-rv1106-gpio
[ 0.001740]Probe device 'irq-rv1106-gpio.4' with irq-rv1106-gpio
[ 0.001750]Probe device 'gpio-rv1106.0' with gpio-rv1106
[ 0.001760]Probe device 'gpio-rv1106.1' with gpio-rv1106
[ 0.001770]Probe device 'gpio-rv1106.2' with gpio-rv1106
[ 0.001780]Probe device 'gpio-rv1106.3' with gpio-rv1106
[ 0.001790]Probe device 'gpio-rv1106.4' with gpio-rv1106
[ 0.001840]Probe device 'adc-rv1106.0' with adc-rv1106
[ 0.001850]Probe device 'ce-armv7-timer.0' with ce-armv7-timer
[ 0.000026]Probe device 'cs-armv7-timer.0' with cs-armv7-timer
[ 0.005833]Probe device 'uart-8250.0' with uarn & SS&S%"٥:ѵr:ѡѵj & SSS%"٥:ѵr:ѡѵj & SS0
[ 0.024936]Probe device 'uart-8250.5' with uart-8250
[ 0.029878]Probe device 'i2c-rv1106.0' with i2c-rv1106
[ 0.034987]Probe device 'i2c-rv1106.1' with i2c-rv1106
[ 0.040098]Probe device 'i2c-rv1106.2' with i2c-rv1106
[ 0.045215]Probe device 'i2c-rv1106.3' with i2c-rv1106
[ 0.050331]Probe device 'i2c-rv1106.4' with i2c-rv1106
[ 0.055455]Probe device 'rtc-rv1106.0' with rtc-rv1106
[ 0.060545]Probe device 'wdg-rv1106.0' with wdg-rv1106
[ 0.065660]Probe device 'key-adc.0' with key-adc
[ 0.070257]Probe device 'led-gpio.0' with led-gpio
[ 0.075014]Probe device 'led-gpio.1' with led-gpio
[ 0.079784]Probe device 'led-gpio.2' with led-gpio
[ 0.084554]Probe device 'ledtrigger-heartbeat.0' with ledtrigger-heartbeat
[ 0.091395]Probe device 'ledtrigger-heartbeat.1' with ledtrigger-heartbeat
[ 0.098242]Probe device 'ledtrigger-heartbeat.2' with ledtrigger-heartbeat
[ 0.105088]Probe device 'console-uart.0' with console-uart
[ 0.111138]mount /private with 'ram' filesystem
xboot: /#
xboot: /#
xboot: /#
xboot: /#
xboot: /#
实现RV1106的RTC驱动
/*
* driver/rtc-rv1106.c
*
* Copyright(c) 2007-2022 Jianjun Jiang <8192542@qq.com>
* Official site: http://xboot.org
* Mobile phone: +86-18665388956
* QQ: 8192542
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#include <xboot.h>
#include <clk/clk.h>
#include <rtc/rtc.h>
enum {
RTC_SET_SECONDS = 0x00,
RTC_SET_MINUTES = 0x04,
RTC_SET_HOURS = 0x08,
RTC_SET_DAYS = 0x0c,
RTC_SET_MONTHS = 0x10,
RTC_SET_YEARL = 0x14,
RTC_SET_YEARH = 0x18,
RTC_SET_WEEKS = 0x1c,
RTC_ALARM_SECONDS = 0x20,
RTC_ALARM_MINUTES = 0x24,
RTC_ALARM_HOURS = 0x28,
RTC_ALARM_DAYS = 0x2c,
RTC_ALARM_MONTHS = 0x30,
RTC_ALARM_YEARL = 0x34,
RTC_ALARM_YEARH = 0x38,
RTC_CTRL = 0x3C,
RTC_STATUS0 = 0x40,
RTC_STATUS1 = 0x44,
RTC_INT0_EN = 0x48,
RTC_INT1_EN = 0x4c,
RTC_MSEC_CTRL = 0x50,
RTC_MSEC_CNT = 0x54,
RTC_COMP_H = 0x58,
RTC_COMP_D = 0x5c,
RTC_COMP_M = 0x60,
RTC_ANALOG_CTRL = 0x64,
RTC_ANALOG_TEST = 0x68,
RTC_LDO_CTRL = 0x6c,
RTC_XO_TRIM0 = 0x70,
RTC_XO_TRIM1 = 0x74,
RTC_VPTAT_TRIM = 0x78,
RTC_ANALOG_EN = 0x7c,
RTC_CLK32K_TEST = 0x80,
RTC_TEST_ST = 0x84,
RTC_TEST_LEN = 0x88,
RTC_CNT_0 = 0x8c,
RTC_CNT_1 = 0x90,
RTC_CNT_2 = 0x94,
RTC_CNT_3 = 0x98,
};
struct rtc_rv1106_pdata_t {
virtual_addr_t virt;
char * clk;
};
static void rtc_update_bits(virtual_addr_t virt, u32_t offset, u32_t mask, u32_t set)
{
u32_t val;
val = read32(virt + offset);
write32(virt + offset, (val & ~mask) | set | 0xc4522900);
}
static bool_t rtc_rv1106_settime(struct rtc_t * rtc, struct rtc_time_t * time)
{
struct rtc_rv1106_pdata_t * pdat = (struct rtc_rv1106_pdata_t *)rtc->priv;
u32_t rtc_data[8];
u32_t status;
int yearh, yearl;
int i;
rtc_data[0] = bin2bcd(time->second) | 0xc4522900;
rtc_data[1] = bin2bcd(time->minute) | 0xc4522900;
rtc_data[2] = bin2bcd(time->hour) | 0xc4522900;
rtc_data[3] = bin2bcd(time->day) | 0xc4522900;
rtc_data[4] = bin2bcd(time->month) | 0xc4522900;
if(time->year > 199)
{
yearh = (time->year - 100) / 100;
yearl = time->year - 100 - yearh * 100;
}
else
{
yearh = 0;
yearl = time->year - 100 - yearh * 100;
}
rtc_data[5] = bin2bcd(yearl) | 0xc4522900;
rtc_data[6] = bin2bcd(yearh) | 0xc4522900;
rtc_data[7] = bin2bcd(time->week) | 0xc4522900;
rtc_update_bits(pdat->virt, RTC_CTRL, (1 << 0), 0);
do {
status = read32(pdat->virt + RTC_STATUS1);
udelay(1);
} while(status & (1 << 0));
for(i = 0; i < 8; i++)
write32(pdat->virt + RTC_SET_SECONDS + (i << 2), rtc_data[i]);
rtc_update_bits(pdat->virt, RTC_CTRL, (1 << 7) | (1 << 0), (1 << 7) | (1 << 0));
do {
status = read32(pdat->virt + RTC_STATUS1);
udelay(1);
} while(!(status & (1 << 0)));
return TRUE;
}
static bool_t rtc_rv1106_gettime(struct rtc_t * rtc, struct rtc_time_t * time)
{
struct rtc_rv1106_pdata_t * pdat = (struct rtc_rv1106_pdata_t *)rtc->priv;
u32_t rtc_data[8];
int i;
for(i = 0; i < 8; i++)
rtc_data[i] = read32(pdat->virt + RTC_SET_SECONDS + (i << 2));
for(i = 0; i < 8; i++)
rtc_data[i] = read32(pdat->virt + RTC_SET_SECONDS + (i << 2));
for(i = 0; i < 8; i++)
rtc_data[i] = read32(pdat->virt + RTC_SET_SECONDS + (i << 2));
time->second = bcd2bin(rtc_data[0] & 0x7f);
time->minute = bcd2bin(rtc_data[1] & 0x7f);
time->hour = bcd2bin(rtc_data[2] & 0x3f);
time->day = bcd2bin(rtc_data[3] & 0x3f);
time->month = bcd2bin(rtc_data[4] & 0x1f);
time->year = (bcd2bin(rtc_data[6] & 0xff)) * 100 + (bcd2bin(rtc_data[5] & 0xff)) + 100;
time->week = bcd2bin(rtc_data[7] & 0x07);
return TRUE;
}
static struct device_t * rtc_rv1106_probe(struct driver_t * drv, struct dtnode_t * n)
{
struct rtc_rv1106_pdata_t * pdat;
struct rtc_t * rtc;
struct device_t * dev;
virtual_addr_t virt = phys_to_virt(dt_read_address(n));
char * clk = dt_read_string(n, "clock-name", NULL);
if(!search_clk(clk))
return NULL;
pdat = malloc(sizeof(struct rtc_rv1106_pdata_t));
if(!pdat)
return NULL;
rtc = malloc(sizeof(struct rtc_t));
if(!rtc)
{
free(pdat);
return NULL;
}
pdat->virt = virt;
pdat->clk = strdup(clk);
rtc->name = alloc_device_name(dt_read_name(n), -1);
rtc->settime = rtc_rv1106_settime;
rtc->gettime = rtc_rv1106_gettime;
rtc->priv = pdat;
clk_enable(pdat->clk);
write32(phys_to_virt(0xff000000) + 0x50000, ((1 << 6) << 16) | (1 << 6));
rtc_update_bits(pdat->virt, RTC_VPTAT_TRIM, (1 << 4), (4 << 1));
rtc_update_bits(pdat->virt, RTC_ANALOG_EN, (1 << 1), 0x00);
rtc_update_bits(pdat->virt, RTC_LDO_CTRL, (1 << 0), (1 << 0));
rtc_update_bits(pdat->virt, RTC_ANALOG_EN, (1 << 5), (1 << 5));
rtc_update_bits(pdat->virt, RTC_CTRL, (1 << 0) | (1 << 7), (1 << 0) | (1 << 7));
if(!(dev = register_rtc(rtc, drv)))
{
clk_disable(pdat->clk);
free(pdat->clk);
free_device_name(rtc->name);
free(rtc->priv);
free(rtc);
return NULL;
}
return dev;
}
static void rtc_rv1106_remove(struct device_t * dev)
{
struct rtc_t * rtc = (struct rtc_t *)dev->priv;
struct rtc_rv1106_pdata_t * pdat = (struct rtc_rv1106_pdata_t *)rtc->priv;
if(rtc)
{
unregister_rtc(rtc);
clk_disable(pdat->clk);
free(pdat->clk);
free_device_name(rtc->name);
free(rtc->priv);
free(rtc);
}
}
static void rtc_rv1106_suspend(struct device_t * dev)
{
}
static void rtc_rv1106_resume(struct device_t * dev)
{
}
static struct driver_t rtc_rv1106 = {
.name = "rtc-rv1106",
.probe = rtc_rv1106_probe,
.remove = rtc_rv1106_remove,
.suspend = rtc_rv1106_suspend,
.resume = rtc_rv1106_resume,
};
static __init void rtc_rv1106_driver_init(void)
{
register_driver(&rtc_rv1106);
}
static __exit void rtc_rv1106_driver_exit(void)
{
unregister_driver(&rtc_rv1106);
}
driver_initcall(rtc_rv1106_driver_init);
driver_exitcall(rtc_rv1106_driver_exit);
基于ADC驱动,添加ADC按键驱动,添加如下设备树即可。
"key-adc@0": {
"adc-name": "adc-rv1106.0",
"adc-channel": 0,
"poll-interval-ms": 100,
"keys": [
{ "min-voltage": 0, "max-voltage": 100000, "key-code": 11 }
]
},
xboot: /# event
[key-adc.0]: [KeyDown] [11]
[key-adc.0]: [KeyUp] [11]
[key-adc.0]: [KeyDown] [11]
[key-adc.0]: [KeyUp] [11]
[key-adc.0]: [KeyDown] [11]
[key-adc.0]: [KeyUp] [11]
[key-adc.0]: [KeyDown] [11]
[key-adc.0]: [KeyUp] [11]
[key-adc.0]: [KeyDown] [11]
[key-adc.0]: [KeyUp] [11]
[key-adc.0]: [KeyDown] [11]
[key-adc.0]: [KeyUp] [11]
[key-adc.0]: [KeyDown] [11]
[key-adc.0]: [KeyUp] [11]
[key-adc.0]: [KeyDown] [11]
[key-adc.0]: [KeyUp] [11]
[key-adc.0]: [KeyDown] [11]
[key-adc.0]: [KeyUp] [11]
编写SARADC驱动,测试通过,其寄存器跟RK3588一致。
https://github.com/xboot/xboot/blob/master/src/arch/arm32/mach-rv1106/driver/adc-rv1106.c
RV1106内部自带的6个timer不可见,其还带了两个加密模式的stimer,严重怀疑当前CPU工作在加密模式,导致其不可见,当然加密模式的stimer,现在不知道其基地址,所以也无从确认起。
关于搜寻timer基地址,本来是想通过 TIMER_REVISION_6CH = 0x11970006 或 TIMER_REVISION_2CH = 0x11970002 这两个关键信息,写了个程序来遍历的,但访问某些地址空间,触发访问异常,无法继续搜寻,所以,这个思路就没有继续了。
理论上是可以对异常进行处理后,再继续搜寻的。这个问题先放弃了,采用CORTEX-A7内部自带的,也更通用点,实现功能就行,不纠结了。
关于timer的运行模式,看linux内核,有些平台4个中断全部一起注册,额,这是增强适应性吧。
timer {
compatible = "arm,armv7-timer";
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
clock-frequency = <24000000>;
};
PPI 中断号从16开始,对应就是上面的26,27,29,30,四个中断号
已实现timer的中断支持,还算利用cortex-a7的timer了,核心代码如下:
#define armv7_read_cntpctl() ({ u32_t val; __asm__ __volatile__("mrc p15, 0, %0, c14, c2, 1" : "=r" (val)); val; })
#define armv7_write_cntpctl(val) __asm__ __volatile__("mcr p15, 0, %0, c14, c2, 1\nisb sy\n" : : "r" (val));
static inline void armv7_timer_start(void)
{
u32_t ctrl = armv7_read_cntpctl();
if(!(ctrl & (1 << 0)))
{
ctrl |= (1 << 0);
armv7_write_cntpctl(ctrl);
}
}
static inline void armv7_timer_stop(void)
{
u32_t ctrl = armv7_read_cntpctl();
if((ctrl & (1 << 0)))
{
ctrl &= ~(1 << 0);
armv7_write_cntpctl(ctrl);
}
}
static inline void armv7_timer_interrupt_enable(void)
{
u32_t ctrl = armv7_read_cntpctl();
if(ctrl & (1 << 1))
{
ctrl &= ~(1 << 1);
armv7_write_cntpctl(ctrl);
}
}
static inline void armv7_timer_interrupt_disable(void)
{
u32_t ctrl = armv7_read_cntpctl();
if(!(ctrl & (1 << 1)))
{
ctrl |= (1 << 1);
armv7_write_cntpctl(ctrl);
}
}
static inline u64_t armv7_timer_frequecy(void)
{
u32_t v;
__asm__ __volatile__("mrc p15, 0, %0, c14, c0, 0" : "=r" (v));
return (v != 0) ? (u64_t)v : 1000000;
}
static inline u64_t armv7_timer_read(void)
{
u32_t l, h;
__asm__ __volatile__("mrrc p15, 0, %0, %1, c14" : "=r" (l), "=r" (h));
return ((u64_t)h << 32) | l;
}
static inline void armv7_timer_compare(uint64_t interval)
{
u64_t last = armv7_timer_read() + interval;
__asm__ __volatile__("mcrr p15, 2, %Q0, %R0, c14" : : "r" (last));
}
PPI里面timer中断有4个
#define RV1106_IRQ_HYPERVISOR_TIMER (26)
#define RV1106_IRQ_VIRTUAL_TIMER (27)
#define RV1106_IRQ_SECURE_PHYSICAL_TIMER (29)
#define RV1106_IRQ_NONSECURE_PHYSICAL_TIMER (30)
现在需要申请29号中断才可以触发,仅申请30号中断,无法触发,从这一点来看,现在代码运行在加密模式?
引导过程大概如下:
BOOTROM -> DDR.BIN -> XBOOT
BOOTROM 和 DDR.BIN,前在运行在加密模式的可能性比较低,后者很有可能。现在还没有对当前CPU运行模式摸个底。
继续RV1106的裸奔,在编写看门狗驱动,发现时间到了后,并不能复位芯片,有一个机关,必须在启动时执行如下代码
/*
* Release the watchdog
*/
write32(0xff000000 + 0x0004, 0x2000200);
write32(0xff3b0000 + 0x0c10, 0x400040);
现在没TRM手册,也搞不清是啥意思,先能用就行,顺便来个sys_cpu_init函数吧,start.S里调用下,免得后面还有一堆未知的依赖。
void sys_cpu_init(void)
{
/*
* Set all devices to Non-secure
*/
write32(0xff070000 + 0x0020, 0xffff0000);
write32(0xff070000 + 0x0024, 0xffff0000);
write32(0xff070000 + 0x0028, 0xffff0000);
write32(0xff070000 + 0x002c, 0xffff0000);
write32(0xff070000 + 0x0030, 0xffff0000);
write32(0xff070000 + 0x00bc, 0x000f0000);
write32(0xff076000 + 0x0020, 0xffff0000);
write32(0xff076000 + 0x0024, 0xffff0000);
write32(0xff076000 + 0x0028, 0xffff0000);
write32(0xff076000 + 0x002c, 0xffff0000);
write32(0xff076000 + 0x0030, 0xffff0000);
write32(0xff076000 + 0x0040, 0x00030002);
write32(0xff080000, 0x20000000);
/*
* Set the emmc and fspi to access secure area
*/
write32(0xff900000 + 0x4c, 0x00000000);
write32(0xff910000 + 0x44, 0xff00ffff);
/*
* Set fspi clk 6mA
*/
write32(0xff568000 + 0x0030, 0x0f000700);
/*
* Set the USB2 PHY in suspend mode and turn off the
* USB2 PHY FS/LS differential receiver to save power
*/
write32(0xff000000 + 0x0050, 0x01ff01d1);
write32(0xff3e0000 + 0x0100, 0x00000000);
/*
* Release the watchdog
*/
write32(0xff000000 + 0x0004, 0x2000200);
write32(0xff3b0000 + 0x0c10, 0x400040);
/*
* When venc/npu use pvtpll, reboot will fail, because
* pvtpll is reset before venc/npu reset, so venc/npu
* is not completely reset, system will block when access
* NoC in SPL.
*/
write32(0xff3b0000 + 0x1008, 0xffff0018);
write32(0xff3b0000 + 0x1000, 0x00030003);
write32(0xff3b0000 + 0x1038, 0xffff0018);
write32(0xff3b0000 + 0x1030, 0x00030003);
sdelay(20);
/*
* Limits npu max transport packets to 4 for route to scheduler,
* give much more chance for other controllers to access memory.
*/
write32(0xff140080 + 0x0008, 0x4);
/*
* Improve VENC QOS PRIORITY
*/
write32(0xff150000 + 0x0008, 0x303);
}
RV1103 / RV1106 裸奔已支持SPI NOR FLASH以及SPI NAND FLASH引导
SPI NOR FLASH烧录指令 (offset = 0x00020000, sector = 256)
sudo xrock maskrom rv1106_ddr_924MHz_v1.09.bin rv1106_usbplug_v1.03.bin --rc4-off;
sleep 3;
sudo xrock flash write 256 xbootpak.bin;
sudo xrock reset;
SPI NAND FLASH烧录指令 (offset = 0x00040000, sector = 512)
sudo xrock maskrom rv1106_ddr_924MHz_v1.09.bin rv1106_usbplug_v1.03.bin --rc4-off;
sleep 3;
sudo xrock flash write 512 xbootpak.bin;
sudo xrock reset;
先DUMP整个时种树,以便裸奔时参考。
# cat clk_summary
enable prepare protect duty
clock count count count rate accuracy phase cycle
---------------------------------------------------------------------------------------------
xin24m 18 18 0 24000000 0 0 50000
pclk_vi_rtc_root 2 2 0 24000000 0 0 50000
pclk_vi_rtc_phy 1 1 0 24000000 0 0 50000
pclk_vi_rtc_test 1 1 0 24000000 0 0 50000
clk_tsadc_tsen 1 1 0 12000000 0 0 50000
clk_tsadc 1 1 0 1000000 0 0 50000
clk_user_otpc_s 0 0 0 12000000 0 0 50000
clk_sbpi_otpc_s 0 0 0 24000000 0 0 50000
clk_pmc_otp 0 0 0 24000000 0 0 50000
clk_user_otpc_ns 0 0 0 12000000 0 0 50000
clk_sbpi_otpc_ns 0 0 0 24000000 0 0 50000
clk_otpc_arb 0 0 0 24000000 0 0 50000
clk_macphy 1 1 0 24000000 0 0 50000
dbclk_gpio2 0 0 0 24000000 0 0 50000
clk_sdmmc_detn_flt 0 0 0 24000000 0 0 50000
cclk_src_sdmmc 1 1 0 800000 0 0 50000
sdmmc_sample 0 0 0 400000 0 0 50000
sdmmc_drv 0 0 0 400000 0 90 50000
dbclk_gpio3 0 0 0 24000000 0 0 50000
dbclk_gpio1 0 0 0 24000000 0 0 50000
clk_uart_detn_flt 0 0 0 24000000 0 0 50000
tclk_pmu_wdt 0 0 0 24000000 0 0 50000
clk_refout 0 0 0 24000000 0 0 50000
clk_pvtm_pmu 0 0 0 24000000 0 0 50000
clk_pmu_mcu_rtc 0 0 0 24000000 0 0 50000
dbclk_pmu_gpio0 0 0 0 24000000 0 0 50000
clk_pmu 1 1 0 24000000 0 0 50000
clk_ddr_fail_safe 0 0 0 24000000 0 0 50000
clk_rtc32k_frac 0 0 0 32768 0 0 50000
clk_rtc_32k 0 0 0 32768 0 0 50000
tclk_wdt_s 0 0 0 24000000 0 0 50000
tclk_wdt_ns 0 0 0 24000000 0 0 50000
clk_ref_usbphy 2 2 0 24000000 0 0 50000
clk_usbphy_480m 1 1 0 480000000 0 0 50000
clk_ref_usbotg 1 1 0 24000000 0 0 50000
clk_saradc 1 1 0 3000000 0 0 50000
clk_capture_pwm2_peri 0 0 0 24000000 0 0 50000
clk_capture_pwm1_peri 0 0 0 24000000 0 0 50000
clk_timer_root 2 2 0 24000000 0 0 50000
clk_timer5 1 1 0 24000000 0 0 50000
clk_timer4 0 0 0 24000000 0 0 50000
clk_timer3 0 0 0 24000000 0 0 50000
clk_timer2 0 0 0 24000000 0 0 50000
clk_timer1 0 0 0 24000000 0 0 50000
clk_timer0 0 0 0 24000000 0 0 50000
clk_stimer1 0 0 0 24000000 0 0 50000
clk_stimer0 0 0 0 24000000 0 0 50000
clk_capture_pwm0_peri 0 0 0 24000000 0 0 50000
dbclk_gpio4 0 0 0 24000000 0 0 50000
cclk_src_emmc 0 0 0 400000 0 0 50000
emmc_sample 0 0 0 200000 0 0 50000
emmc_drv 0 0 0 200000 0 180 50000
clk_timer_ddrmon 0 0 0 24000000 0 0 50000
clk_vicap_m1 1 1 0 24000000 0 0 50000
sclk_vicap_m1 1 1 0 24000000 0 0 50000
clk_vicap_m0 1 1 0 24000000 0 0 50000
sclk_vicap_m0 1 1 0 24000000 0 0 50000
clk_uart5 0 0 0 24000000 0 0 50000
sclk_uart5 0 0 0 24000000 0 0 50000
clk_uart4 0 0 0 24000000 0 0 50000
sclk_uart4 0 0 0 24000000 0 0 50000
clk_uart3 0 0 0 24000000 0 0 50000
sclk_uart3 0 0 0 24000000 0 0 50000
clk_uart2 1 1 0 24000000 0 0 50000
sclk_uart2 1 1 0 24000000 0 0 50000
clk_uart1 0 0 0 24000000 0 0 50000
sclk_uart1 0 0 0 24000000 0 0 50000
clk_uart0 0 0 0 24000000 0 0 50000
sclk_uart0 0 0 0 24000000 0 0 50000
clk_ref_mipi1 0 0 0 24000000 0 0 50000
mclk_ref_mipi1 0 0 0 24000000 0 0 50000
clk_core_mcu_rtc 1 1 0 24000000 0 0 50000
clk_pvtm_core 0 0 0 24000000 0 0 50000
xin_osc0_half 0 0 0 12000000 0 0 50000
i2s0_8ch_mclkout 0 0 0 12000000 0 0 50000
pll_gpll 1 1 0 1188000000 0 0 50000
gpll 12 12 0 1188000000 0 0 50000
clk_vicap_m1_src 0 0 0 594000000 0 0 50000
clk_vicap_m1_frac 0 0 0 12000000 0 0 50000
clk_vicap_m0_src 0 0 0 594000000 0 0 50000
clk_vicap_m0_frac 0 0 0 12000000 0 0 50000
clk_uart5_src 0 0 0 594000000 0 0 50000
clk_uart5_frac 0 0 0 12000000 0 0 50000
clk_uart4_src 0 0 0 594000000 0 0 50000
clk_uart4_frac 0 0 0 12000000 0 0 50000
clk_uart3_src 0 0 0 594000000 0 0 50000
clk_uart3_frac 0 0 0 12000000 0 0 50000
clk_uart2_src 0 0 0 594000000 0 0 50000
clk_uart2_frac 0 0 0 12000000 0 0 50000
clk_uart1_src 0 0 0 594000000 0 0 50000
clk_uart1_frac 0 0 0 12000000 0 0 50000
clk_uart0_src 0 0 0 594000000 0 0 50000
clk_uart0_frac 0 0 0 12000000 0 0 50000
clk_ref_mipi1_src 0 0 0 594000000 0 0 50000
clk_ref_mipi1_frac 0 0 0 12000000 0 0 50000
clk_ref_mipi0_src 1 1 0 594000000 0 0 50000
clk_ref_mipi0_frac 1 1 0 27000000 0 0 50000
clk_ref_mipi0 1 1 0 27000000 0 0 50000
mclk_ref_mipi0 1 1 0 27000000 0 0 50000
clk_i2s0_8ch_rx_src 1 1 0 594000000 0 0 50000
clk_i2s0_8ch_rx_frac 1 1 0 2048000 0 0 50000
clk_i2s0_8ch_rx 1 1 0 2048000 0 0 50000
mclk_i2s0_8ch_rx 1 1 0 2048000 0 0 50000
clk_i2s0_8ch_tx_src 1 1 0 594000000 0 0 50000
clk_i2s0_8ch_tx_frac 1 1 0 2048000 0 0 50000
clk_i2s0_8ch_tx 1 1 0 2048000 0 0 50000
mclk_i2s0_8ch_tx 2 2 0 2048000 0 0 50000
mclk_sai 0 0 0 2048000 0 0 50000
mclk_dsm 0 0 0 2048000 0 0 50000
mclk_acodec_tx 1 1 0 2048000 0 0 50000
clk_450m_src 1 1 0 475200000 0 0 50000
clk_400m_src 4 4 0 396000000 0 0 50000
cclk_src_sdio 0 0 0 396000000 0 0 50000
sdio_sample 0 0 0 198000000 0 0 50000
sdio_drv 0 0 0 198000000 0 180 50000
clk_core_rga2e 0 0 0 396000000 0 0 50000
aclk_vo_root 1 1 0 396000000 0 0 50000
aclk_rga2e 0 0 0 396000000 0 0 50000
aclk_vepu_com_root 1 1 0 396000000 0 0 50000
dclk_decom 0 0 0 396000000 0 0 50000
aclk_peri_root 1 1 0 396000000 0 0 50000
aclk_ive 0 0 0 396000000 0 0 50000
aclk_decom 0 0 0 396000000 0 0 50000
clk_339m_src 4 4 0 339428572 0 0 50000
clk_core_isp3p2 1 1 0 339428572 0 0 50000
dclk_vicap 1 1 0 339428572 0 0 50000
aclk_vi_root 3 3 0 339428572 0 0 50000
aclk_vicap 1 1 0 339428572 0 0 50000
aclk_isp3p2 1 1 0 339428572 0 0 50000
clk_300m_src 5 5 0 297000000 0 0 50000
sclk_sfc 0 0 0 74250000 0 0 50000
aclk_vop_root 1 1 0 297000000 0 0 50000
aclk_vop 1 1 0 297000000 0 0 50000
aclk_mac_root 1 1 0 297000000 0 0 50000
aclk_mac 1 1 0 297000000 0 0 50000
aclk_vepu_root 2 2 0 297000000 0 0 50000
aclk_vepu_pp 0 0 0 297000000 0 0 50000
aclk_vepu 1 1 0 297000000 0 0 50000
clk_pka_crypto 0 0 0 297000000 0 0 50000
clk_core_crypto 0 0 0 297000000 0 0 50000
aclk_bus_root 3 3 0 297000000 0 0 50000
aclk_usbotg 1 1 0 297000000 0 0 50000
aclk_dmac 1 1 0 297000000 0 0 50000
aclk_crypto 0 0 0 297000000 0 0 50000
clk_200m_src 6 8 0 198000000 0 0 50000
hclk_vo_root 2 2 0 198000000 0 0 50000
hclk_vop 1 1 0 198000000 0 0 50000
hclk_sdio 0 0 0 198000000 0 0 50000
hclk_rga2e 0 0 0 198000000 0 0 50000
clk_core_vepu_dvbm 0 0 0 198000000 0 0 50000
clk_spi0 0 0 0 198000000 0 0 50000
hclk_vepu_root 2 2 0 198000000 0 0 50000
hclk_vepu_pp 0 0 0 198000000 0 0 50000
hclk_vepu 1 1 0 198000000 0 0 50000
clk_i2c1 0 1 0 198000000 0 0 50000
hclk_pmu_root 1 1 0 198000000 0 0 50000
hclk_pmu_sram 0 0 0 198000000 0 0 50000
clk_pmu_mcu 0 0 0 198000000 0 0 50000
clk_100m_pmu 1 1 0 99000000 0 0 50000
pclk_pmu_root 3 4 0 99000000 0 0 50000
pclk_pmu_wdt 0 0 0 99000000 0 0 50000
pclk_pvtm_pmu 0 0 0 99000000 0 0 50000
pclk_pmu_mailbox 0 0 0 99000000 0 0 50000
pclk_i2c1 0 1 0 99000000 0 0 50000
pclk_pmu_gpio0 1 1 0 99000000 0 0 50000
pclk_pmu 1 1 0 99000000 0 0 50000
clk_i2c4 0 1 0 198000000 0 0 50000
clk_i2c3 0 0 0 198000000 0 0 50000
clk_i2c2 0 0 0 198000000 0 0 50000
clk_i2c0 0 0 0 198000000 0 0 50000
hclk_peri_root 2 2 0 198000000 0 0 50000
hclk_trng_s 0 0 0 198000000 0 0 50000
hclk_trng_ns 0 0 0 198000000 0 0 50000
hclk_sai 0 0 0 198000000 0 0 50000
hclk_bootrom 0 0 0 198000000 0 0 50000
hclk_sfc 0 0 0 198000000 0 0 50000
hclk_ive 0 0 0 198000000 0 0 50000
hclk_i2s0 1 1 0 198000000 0 0 50000
hclk_emmc 0 0 0 198000000 0 0 50000
hclk_crypto 0 0 0 198000000 0 0 50000
clk_150m_src 5 5 0 148500000 0 0 50000
pclk_vo_root 4 4 0 148500000 0 0 50000
pclk_tsadc 1 1 0 148500000 0 0 50000
pclk_otp_mask 0 0 0 148500000 0 0 50000
pclk_otpc_s 0 0 0 148500000 0 0 50000
pclk_otpc_ns 0 0 0 148500000 0 0 50000
pclk_mac 2 2 0 148500000 0 0 50000
pclk_gpio2 1 1 0 148500000 0 0 50000
pclk_vi_root 4 4 0 148500000 0 0 50000
pclk_mipicsiphy 1 1 0 148500000 0 0 50000
pclk_gpio3 1 1 0 148500000 0 0 50000
pclk_csihost1 0 0 0 148500000 0 0 50000
pclk_csihost0 1 1 0 148500000 0 0 50000
hclk_vi_root 4 4 0 148500000 0 0 50000
hclk_vicap 1 1 0 148500000 0 0 50000
hclk_sdmmc 1 1 0 148500000 0 0 50000
hclk_isp3p2 1 1 0 148500000 0 0 50000
hclk_npu_root 2 2 0 148500000 0 0 50000
hclk_rknn 1 1 0 148500000 0 0 50000
clk_core_mcu 1 1 0 297000000 0 0 50000
hclk_cpu 1 1 0 198000000 0 0 50000
pll_cpll 1 1 0 1000000000 0 0 50000
cpll 5 5 0 1000000000 0 0 50000
dclk_vop_src 1 1 0 50000000 0 0 50000
dclk_vop 1 1 0 50000000 0 0 50000
clk_500m_src 2 2 0 500000000 0 0 50000
aclk_ddr_root 2 2 0 500000000 0 0 50000
aclk_sys_shrm 1 1 0 500000000 0 0 50000
clk_250m_src 1 1 0 250000000 0 0 50000
clk_100m_src 7 7 0 100000000 0 0 50000
pclk_vepu_root 2 2 0 100000000 0 0 50000
pclk_gpio1 1 1 0 100000000 0 0 50000
pclk_spi0 0 0 0 100000000 0 0 50000
clk_pwm2_peri 0 0 0 100000000 0 0 50000
clk_pwm1_peri 0 0 0 100000000 0 0 50000
clk_pwm0_peri 2 2 0 100000000 0 0 50000
pclk_peri_root 7 9 0 100000000 0 0 50000
pclk_wdt_s 0 0 0 100000000 0 0 50000
pclk_wdt_ns 0 0 0 100000000 0 0 50000
pclk_usbphy 1 1 0 100000000 0 0 50000
pclk_uart5 0 0 0 100000000 0 0 50000
pclk_uart4 0 0 0 100000000 0 0 50000
pclk_uart3 0 0 0 100000000 0 0 50000
pclk_uart2 1 1 0 100000000 0 0 50000
pclk_timer 1 1 0 100000000 0 0 50000
pclk_stimer 0 0 0 100000000 0 0 50000
pclk_spi1 0 0 0 100000000 0 0 50000
pclk_saradc 1 1 0 100000000 0 0 50000
pclk_pwm2_peri 0 0 0 100000000 0 0 50000
pclk_pwm1_peri 0 0 0 100000000 0 0 50000
pclk_uart1 0 0 0 100000000 0 0 50000
pclk_uart0 0 0 0 100000000 0 0 50000
pclk_pwm0_peri 0 2 0 100000000 0 0 50000
pclk_dft2apb 0 0 0 100000000 0 0 50000
pclk_i2c4 0 1 0 100000000 0 0 50000
pclk_i2c3 0 0 0 100000000 0 0 50000
pclk_i2c2 0 0 0 100000000 0 0 50000
pclk_i2c0 0 0 0 100000000 0 0 50000
pclk_gpio4 1 1 0 100000000 0 0 50000
pclk_dsm 0 0 0 100000000 0 0 50000
pclk_decom 0 0 0 100000000 0 0 50000
pclk_acodec 1 1 0 100000000 0 0 50000
pclk_npu_root 1 1 0 100000000 0 0 50000
pclk_ddr_root 2 2 0 100000000 0 0 50000
pclk_dfictrl 1 1 0 100000000 0 0 50000
pclk_ddrc 0 0 0 100000000 0 0 50000
pclk_ddrmon 0 0 0 100000000 0 0 50000
pclk_ddr_hwlp 0 0 0 100000000 0 0 50000
pclk_ddrphy 0 0 0 100000000 0 0 50000
pclk_top_root 1 1 0 100000000 0 0 50000
clk_50m_src 2 2 0 50000000 0 0 50000
clk_gmac0_50m_o 2 2 0 50000000 0 0 50000
clk_gmac0_tx_50m_o 1 1 0 50000000 0 0 50000
clk_gmac0_ref_50m 1 1 0 50000000 0 0 50000
clk_spi1 0 0 0 50000000 0 0 50000
pll_dpll 1 1 0 924000000 0 0 50000
dpll 1 1 0 924000000 0 0 50000
clk_core_ddrc_src 2 2 0 462000000 0 0 50000
clk_core_ddrc 1 1 0 462000000 0 0 50000
aclk_ddrc 1 1 0 462000000 0 0 50000
clk_ddr_phy 0 0 0 462000000 0 0 50000
clk_ddrmon 0 0 0 462000000 0 0 50000
clk_dfictrl 0 0 0 462000000 0 0 50000
pll_apll 1 1 0 1608000000 0 0 50000
apll 1 1 0 1608000000 0 0 50000
armclk 1 1 0 1608000000 0 0 50000
pclk_dbg 2 2 0 201000000 0 0 50000
pclk_cpu_root 2 2 0 201000000 0 0 50000
pclk_mailbox 1 1 0 201000000 0 0 50000
clk_pvtpll_1 1 1 0 420000000 0 0 50000
aclk_npu_root 2 2 0 420000000 0 0 50000
aclk_rknn 1 1 0 420000000 0 0 50000
clk_pvtpll_0 1 1 0 410000000 0 0 50000
clk_core_vepu 1 1 0 410000000 0 0 50000
clk_utmi_usbotg 1 1 0 0 0 0 50000
sclk_in_spi0 0 0 0 0 0 0 50000
pclk_vicap_vepu 1 1 0 0 0 0 50000
clk_rxbyteclkhs_1 0 0 0 0 0 0 50000
clk_rxbyteclkhs_0 1 1 0 0 0 0 50000
pclk_vicap 1 1 0 0 0 0 50000
i1clk_vicap 1 1 0 0 0 0 50000
i0clk_vicap 1 1 0 0 0 0 50000
isp0clk_vicap 2 2 0 0 0 0 50000
rx1pclk_vicap 1 1 0 0 0 0 50000
rx0pclk_vicap 1 1 0 0 0 0 50000
为了烧写裸奔镜像,这里对xrock工具进行了扩展,支持了RV1103/RV1106芯片
https://github.com/xboot/xrock
烧写指令:
sudo xrock maskrom rv1106_ddr_924MHz_v1.07.bin rv1106_usbplug_v1.03.bin --rc4-off;
sleep 3;
sudo xrock flash write 512 xbootpak.bin;
sudo xrock reset;
RV1103 / RV1106开始裸奔了,要搞定裸奔必须研究透RK的引导机制,经过一整天的深入研究,在没有任何TRM手册的情况下,搞定了RV1106的SPI NAND FLASH引导启动。
下面是启动日记
DDR Version V1.07 20220523
f947
F
DDRConf2
DDR3, BW=16 Col=10 Bk=8 CS0 Row=13 CS=1 Die BW=16 Size=128MB
924MHz
DDR bin out
█████████████████████████
██ ▄▄▄▄▄ ██▄▀▀▀█ ▄▄▄▄▄ ██
██ █ █ █ ▀▄█ █ █ █ ██
██ █▄▄▄█ ██▄ ██ █▄▄▄█ ██
██▄▄▄▄▄▄▄█▄█ █ █▄▄▄▄▄▄▄██
████▀▄ ▀▄▄█ ▀█▄▀█▀▀ █▀██
███▀▄▀ ▀▄ ▄█▀▀▄▀█ ▀█ ▄███
███▄█▄█▄▄▄▀▀ ▄ ▀ ▄▄ ▀ ██
██ ▄▄▄▄▄ █▄ ▄█▄▀▄████▄▄██
██ █ █ █ ▀█▄█▄▄█ ▄▀█▄██
██ █▄▄▄█ ██▀ █ ▄▄▄▄█▄ ██
██▄▄▄▄▄▄▄███▄██▄▄▄▄▄▄▄███
█████████████████████████
_ _
_ _ | |___ _____ _____ _| |_
\ \/ /| _ | _ | _ |_ _| (C) 2007-2022
) ( | |_| | |_| | |_| | | |____JIANJUN.JIANG__
/_/\_\|_____|_____|_____| |_____________________|
V3.0.0 (Jul 29 2022 - 16:59:22) - [x1106][X1106 Based On RV1106 SOC]
[ 0.000020]Probe device 'blk-romdisk.0' with blk-romdisk
[ 0.000800]Probe device 'usbphy480m' with clk-fixed
[ 0.000810]Probe device 'xin24m' with clk-fixed
[ 0.000820]Probe device 'xin32k' with clk-fixed
[ 0.000830]Probe device 'link-uart0' with clk-link
[ 0.000840]Probe device 'link-uart1' with clk-link
[ 0.000850]Probe device 'link-uart2' with clk-link
[ 0.000860]Probe device 'link-uart3' with clk-link
[ 0.000870]Probe device 'link-uart4' with clk-link
[ 0.000880]Probe device 'link-uart5' with clk-link
[ 0.000890]Probe device 'uart-8250.0' with uar & S&LWobe device 'uart-8250.2' with uart-8250
[ 0.000920]Probe device 'uart-8250.3' with uart-8250
[ 0.000930]Probe device 'uart-8250.4' with uart-8250
[ 0.000940]Probe device 'uart-8250.5' with uart-8250
[ 0.000950]Probe device 'console-uart.0' with console-uart
[ 0.001060]mount /private with 'ram' filesystem
xboot: /#
xboot: /#
RV1106 裸奔
DDR Version V1.07 20220523
f947
F
DDRConf2
DDR3, BW=16 Col=10 Bk=8 CS0 Row=13 CS=1 Die BW=16 Size=128MB
924MHz
DDR bin out
█████████████████████████
██ ▄▄▄▄▄ ██▄▀▀▀█ ▄▄▄▄▄ ██
██ █ █ █ ▀▄█ █ █ █ ██
██ █▄▄▄█ ██▄ ██ █▄▄▄█ ██
██▄▄▄▄▄▄▄█▄█ █ █▄▄▄▄▄▄▄██
████▀▄ ▀▄▄█ ▀█▄▀█▀▀ █▀██
███▀▄▀ ▀▄ ▄█▀▀▄▀█ ▀█ ▄███
███▄█▄█▄▄▄▀▀ ▄ ▀ ▄▄ ▀ ██
██ ▄▄▄▄▄ █▄ ▄█▄▀▄████▄▄██
██ █ █ █ ▀█▄█▄▄█ ▄▀█▄██
██ █▄▄▄█ ██▀ █ ▄▄▄▄█▄ ██
██▄▄▄▄▄▄▄███▄██▄▄▄▄▄▄▄███
█████████████████████████
_ _
_ _ | |___ _____ _____ _| |_
\ \/ /| _ | _ | _ |_ _| (C) 2007-2022
) ( | |_| | |_| | |_| | | |____JIANJUN.JIANG__
/_/\_\|_____|_____|_____| |_____________________|
V3.0.0 (Jul 29 2022 - 16:59:22) - [x1106][X1106 Based On RV1106 SOC]
[ 0.000020]Probe device 'blk-romdisk.0' with blk-romdisk
[ 0.000800]Probe device 'usbphy480m' with clk-fixed
[ 0.000810]Probe device 'xin24m' with clk-fixed
[ 0.000820]Probe device 'xin32k' with clk-fixed
[ 0.000830]Probe device 'link-uart0' with clk-link
[ 0.000840]Probe device 'link-uart1' with clk-link
[ 0.000850]Probe device 'link-uart2' with clk-link
[ 0.000860]Probe device 'link-uart3' with clk-link
[ 0.000870]Probe device 'link-uart4' with clk-link
[ 0.000880]Probe device 'link-uart5' with clk-link
[ 0.000890]Probe device 'uart-8250.0' with uar & S&LWobe device 'uart-8250.2' with uart-8250
[ 0.000920]Probe device 'uart-8250.3' with uart-8250
[ 0.000930]Probe device 'uart-8250.4' with uart-8250
[ 0.000940]Probe device 'uart-8250.5' with uart-8250
[ 0.000950]Probe device 'console-uart.0' with console-uart
[ 0.001060]mount /private with 'ram' filesystem
xboot: /#
一年前,写了个帖子https://whycan.com/t_6507.html在全志芯片F1C100S/V3S/V831上实现裸机加密方案,防盗版进行时(不采用专用加密芯片)。
用于解决防盗版问题,这种方案是保护整个产品。
但如果我们的诉求变化了,不是保护完整的产品,仅要保证客户必须从我这里采购芯片,即使客户不从我们这里采购芯片,也能运行,只不过有个恶心的“未授权”提示,体验功能不受任何影响,那么该如何实现呢。同样,不采用任何加密芯片(一个主芯片配一个加密芯片,这种算常规方案,不考虑)
归纳下:
1,要求客户必须从你这里买主芯片,如果是从其他渠道购买的,所有功能都是正常的,但有屏幕有恶心提示,或显示我司联系方式。
2,不采用加密芯片,
3,镜像或者源码可以提供给客户(部分闭源)。
看了下eggos,里面实现如下syscall,不是全部linux syscall, 这些syscall,绝大部分还是用go写的。
kernelCalls = [...]uintptr{
syscall.SYS_ARCH_PRCTL,
syscall.SYS_MMAP,
syscall.SYS_MUNMAP,
syscall.SYS_CLOCK_GETTIME,
syscall.SYS_RT_SIGPROCMASK,
syscall.SYS_SIGALTSTACK,
syscall.SYS_RT_SIGACTION,
syscall.SYS_GETTID,
syscall.SYS_CLONE,
syscall.SYS_FUTEX,
syscall.SYS_NANOSLEEP,
syscall.SYS_SCHED_YIELD,
syscall.SYS_MADVISE,
syscall.SYS_EXIT_GROUP,
// TODO: real random
unix.SYS_GETRANDOM,
// may removed in the future
syscall.SYS_EPOLL_CREATE1,
syscall.SYS_EPOLL_CTL,
syscall.SYS_EPOLL_WAIT,
syscall.SYS_EPOLL_PWAIT,
syscall.SYS_PIPE2,
SYS_WAIT_IRQ,
SYS_WAIT_SYSCALL,
SYS_FIXED_MMAP,
SYS_EPOLL_NOTIFY,
}
生成串口二维码的代码,不复杂,就4种字符,其中一个是空格,其他是UTF8字符。支持反显,大部分linux终端,都是黑底白字,所有需要反色显示,当然对于微信,无所谓,正反都可以,但阿里的app,就不支持反显扫码了,这一点,还是微信做的好点。
/* ▀▄█ */
#define UTF8_EMPTY(inv) do{ if(inv) { *p++ = 0xe2; *p++ = 0x96; *p++ = 0x88; } else { *p++ = 0x20; } } while(0)
#define UTF8_TOPHALF(inv) do{ if(inv) { *p++ = 0xe2; *p++ = 0x96; *p++ = 0x84; } else { *p++ = 0xe2; *p++ = 0x96; *p++ = 0x80; } } while(0)
#define UTF8_BOTTOMHALF(inv) do{ if(inv) { *p++ = 0xe2; *p++ = 0x96; *p++ = 0x80; } else { *p++ = 0xe2; *p++ = 0x96; *p++ = 0x84; } } while(0)
#define UTF8_FULL(inv) do{ if(inv) { *p++ = 0x20; } else { *p++ = 0xe2; *p++ = 0x96; *p++ = 0x88; } } while(0)
#define UTF8_NEWLINE() do{ *p++ = '\r'; *p++ = '\n'; } while(0)
#define UTF8_END() do{ *p++ = '\0'; } while(0)
char * qrcgen_tostring(const char * txt, int invert)
{
uint8_t qrc[QRCGEN_BUFFER_LEN_MAX];
uint8_t tmp[QRCGEN_BUFFER_LEN_MAX];
int qrs, x, y, i;
int t, b;
char *s, *p;
if(qrcgen_encode_text(txt, tmp, qrc, QRCGEN_ECC_MEDIUM, QRCGEN_VERSION_MIN, QRCGEN_VERSION_MAX, QRCGEN_MASK_AUTO, 1))
{
qrs = qrcgen_get_size(qrc);
if(qrs > 0)
{
p = s = malloc(((qrs + 4) * 3 + 2) * (qrs / 2 + 1 + 2) + 1);
if(s)
{
for(i = 0; i < qrs + 4; ++i)
UTF8_EMPTY(invert);
UTF8_NEWLINE();
for(y = 0; y < qrs; y += 2)
{
UTF8_EMPTY(invert);
UTF8_EMPTY(invert);
for(x = 0; x < qrs; x++)
{
t = qrcgen_get_pixel(qrc, x, y);
b = 0;
if(y + 1 < qrs)
b = qrcgen_get_pixel(qrc, x, y + 1);
if(t)
{
if(b)
UTF8_FULL(invert);
else
UTF8_TOPHALF(invert);
}
else
{
if(b)
UTF8_BOTTOMHALF(invert);
else
UTF8_EMPTY(invert);
}
}
UTF8_EMPTY(invert);
UTF8_EMPTY(invert);
UTF8_NEWLINE();
}
for(i = 0; i < qrs + 4; i++)
UTF8_EMPTY(invert);
UTF8_NEWLINE();
UTF8_END();
return s;
}
}
}
return NULL;
}
坑网LinjieGuo发布了一个帖子,用SPI来驱动WS2811这种灯带,基于此研究成果,我编写了一个WS2812的通用驱动,原贴路径https://whycan.com/t_7742.html
因为此驱动需要4M的SPI时钟,在测试后发现,程序直接卡死,实验了3M同样如此,但2M,及5M,或者50M这些都没有任何问题,SPI驱动一直沿用之前的,什么F1C100S,V3S,V831,都是这一个,因为从来没有在F133上实验过如此低的频率,所以,也一直没有发现问题。现在突然发现这个问题,就有必要去深入研究一下了,初步比较芯片手册,之前的SPI_CCR寄存器没有了。发现多了SPI_BA_CCR之类的寄存器,但虽然SPI_CCR寄存器没有了,但还是可以通过这个寄存器来控制分频。那问题来了这个消失的寄存器,是如何控制分频的,难道是SPI_BA_CCR的马甲寄存器?
有谁研究过F133的SPI控制器驱动吗?可以去linux内核里翻翻,看能否找到蛛丝马迹。
更新了下WS2812的驱动,添加缓存支持,提升刷新效率。
26a11c1820cdb4e202a99876c37971684c4634e5
src/driver/led/ledstrip-ws2812.c | 37 ++++++++++++++++++++-----------------
1 file changed, 20 insertions(+), 17 deletions(-)
diff --git a/src/driver/led/ledstrip-ws2812.c b/src/driver/led/ledstrip-ws2812.c
index 6f598bb3e..bc0736ef4 100644
--- a/src/driver/led/ledstrip-ws2812.c
+++ b/src/driver/led/ledstrip-ws2812.c
@@ -47,9 +47,11 @@ struct ledstrip_ws2812_pdata_t {
struct spi_device_t * spidev;
int count;
struct color_t * color;
+ int buflen;
+ unsigned char * buffer;
};
-static const unsigned char ws2812_table[256][5]={
+static const unsigned char ws2812_map[256][5]={
{ 0x84, 0x21, 0x08, 0x42, 0x10, },
{ 0x84, 0x21, 0x08, 0x42, 0x1e, },
{ 0x84, 0x21, 0x08, 0x43, 0xd0, },
@@ -308,12 +310,6 @@ static const unsigned char ws2812_table[256][5]={
{ 0xf7, 0xbd, 0xef, 0x7b, 0xde, },
};
-static void ledstrip_ws2812_send(struct ledstrip_t * strip, unsigned char byte)
-{
- struct ledstrip_ws2812_pdata_t * pdat = (struct ledstrip_ws2812_pdata_t *)strip->priv;
- spi_device_write_then_read(pdat->spidev, (void *)&ws2812_table[byte][0], 5, NULL, 0);
-}
-
static void ledstrip_ws2812_set_count(struct ledstrip_t * strip, int n)
{
struct ledstrip_ws2812_pdata_t * pdat = (struct ledstrip_ws2812_pdata_t *)strip->priv;
@@ -322,9 +318,20 @@ static void ledstrip_ws2812_set_count(struct ledstrip_t * strip, int n)
{
if(pdat->color)
free(pdat->color);
+ if(pdat->buffer)
+ free(pdat->buffer);
pdat->count = n;
pdat->color = malloc(pdat->count * sizeof(struct color_t));
memset(pdat->color, 0, pdat->count * sizeof(struct color_t));
+ pdat->buflen = n * 3 * 5 + 150;
+ pdat->buffer = malloc(pdat->buflen);
+ for(int i = 0; i < n; i++)
+ {
+ memcpy(&pdat->buffer[(i * 3 + 0) * 5], (void *)&ws2812_map[0][0], 5);
+ memcpy(&pdat->buffer[(i * 3 + 1) * 5], (void *)&ws2812_map[0][0], 5);
+ memcpy(&pdat->buffer[(i * 3 + 2) * 5], (void *)&ws2812_map[0][0], 5);
+ }
+ memset(&pdat->buffer[n * 3 * 5], 0, 150);
}
}
@@ -338,6 +345,9 @@ static void ledstrip_ws2812_set_color(struct ledstrip_t * strip, int i, struct c
{
struct ledstrip_ws2812_pdata_t * pdat = (struct ledstrip_ws2812_pdata_t *)strip->priv;
memcpy(&pdat->color[i], c, sizeof(struct color_t));
+ memcpy(&pdat->buffer[(i * 3 + 0) * 5], (void *)&ws2812_map[pdat->color[i].g][0], 5);
+ memcpy(&pdat->buffer[(i * 3 + 1) * 5], (void *)&ws2812_map[pdat->color[i].r][0], 5);
+ memcpy(&pdat->buffer[(i * 3 + 2) * 5], (void *)&ws2812_map[pdat->color[i].b][0], 5);
}
static void ledstrip_ws2812_get_color(struct ledstrip_t * strip, int i, struct color_t * c)
@@ -349,16 +359,7 @@ static void ledstrip_ws2812_get_color(struct ledstrip_t * strip, int i, struct c
static void ledstrip_ws2812_refresh(struct ledstrip_t * strip)
{
struct ledstrip_ws2812_pdata_t * pdat = (struct ledstrip_ws2812_pdata_t *)strip->priv;
- int i;
-
- for(i = 0; i < 150; i++)
- ledstrip_ws2812_send(strip, 0x00);
- for(i = 0; i < pdat->count; i++)
- {
- ledstrip_ws2812_send(strip, pdat->color[i].g);
- ledstrip_ws2812_send(strip, pdat->color[i].r);
- ledstrip_ws2812_send(strip, pdat->color[i].b);
- }
+ spi_device_write_then_read(pdat->spidev, pdat->buffer, pdat->buflen, NULL, 0);
}
static struct device_t * ledstrip_ws2812_probe(struct driver_t * drv, struct dtnode_t * n)
@@ -386,6 +387,8 @@ static struct device_t * ledstrip_ws2812_probe(struct driver_t * drv, struct dtn
pdat->spidev = spidev;
pdat->count = 0;
pdat->color = NULL;
+ pdat->buflen = 0;
+ pdat->buffer = NULL;
strip->name = alloc_device_name(dt_read_name(n), dt_read_id(n));
strip->set_count = ledstrip_ws2812_set_count;
void cg_set_operator(struct cg_ctx_t * ctx, enum cg_operator_t op);
enum cg_operator_t {
CG_OPERATOR_SRC = 0, /* r = s * ca + d * cia */
CG_OPERATOR_SRC_OVER = 1, /* r = (s + d * sia) * ca + d * cia */
CG_OPERATOR_DST_IN = 2, /* r = d * sa * ca + d * cia */
CG_OPERATOR_DST_OUT = 3, /* r = d * sia * ca + d * cia */
};
调用cg_set_operator可以设定合成模式,测试用例没有覆盖所有模式。
用xfel工具,很容易读取BROM
https://whycan.com/t_6546.html#p72836
全志T113-S3编译烧写步骤
https://xboot.org/xboot/#/guide-allwinner-t113s3
编译源码,生成的目标文件在output目录下
make clean
make CROSS_COMPILE=/path/to/arm-none-linux-gnueabihf- PLATFORM=arm32-t113s3
烧写到RAM中并运行
sudo xfel ddr t113-s3; sudo xfel write 0x40000000 xboot.bin; sudo xfel exec 0x40000000;
烧写普通镜像到SPI Nor Flash
sudo xfel spinor write 0 xboot.bin
烧写压缩镜像到SPI Nor Flash
sudo xfel spinor write 0 xboot.bin.z
烧写普通镜像到SPI Nand Flash
sudo xfel spinand splwrite 2048 1048576 xboot.bin
烧写压缩镜像到SPI Nand Flash
sudo xfel spinand splwrite 2048 1048576 xboot.bin.z
现在T113还没有实现get_boot_device函数,默认引导介质为SPI NOR FLASH,F133, D1这些已实现get_boot_device函数。
这是坑网网友mengxp逆向R328-S3 fes1 工程里的相关代码,有一个bond_id_check函数,这个看名字是芯片邦定相关检测函数,感觉没啥大用,理论上全志应该会有一套自己的马甲管理方案的,也便于自己做产品控制,相关信息也一定会在封装时写入了efuse之类的地方,包括开哪个核,等等,这些细节有可能研究出来吗?
uint32_t crc_16(uint16_t reg, uint8_t data_crc)
{
uint32_t ret;
uint16_t v3;
uint16_t v4;
ret = reg ^ (data_crc << 8);
v3 = 8;
do {
v4 = 2 * ret;
v3--;
if ((ret << 16) >= 0)
ret = v4;
else
ret = v4 ^ 0x8005;
} while (v3);
return ret;
}
uint32_t disturb_coding(uint16_t disturb_code, uint8_t id_num)
{
return (disturb_code + id_num) | (crc_16(disturb_code, id_num) << 16);
}
uint32_t id_judge_fun(uint16_t disturb_code)
{
uint32_t chipId;
uint8_t v5;
uint32_t ret;
chipId = MEMORY(0x3006200) & 0xF;
printf("the chip id is 0x%x\n", chipId);
if (chipId == 3)
{
v5 = 7;
ret = disturb_coding(disturb_code, v5);
}
else
{
v5 = 1;
ret = 0;
}
return ret;
}
int bond_id_check(void)
{
uint8_t v0;
uint32_t v1;
uint16_t v3;
uint32_t v4;
v0 = 1;
v1 = id_judge_fun(0);
while (v1 != disturb_coding(0, v0))
{
v0++;
if (v0 == 17)
return 0;
}
v3 = 1;
while (1)
{
v4 = id_judge_fun(v3);
if (v4 != disturb_coding(v3, v0))
break;
v3++;
if (v3 == 5)
return 1;
}
return 0;
}
int chip_id_check(void)
{
uint32_t chipId = MEMORY(0x3006200) & 0xF;
if(chipId != 3)
return 0;
return 1;
}
现在有个棘手的问题,fel模式下如果通过代码的方式区分这些马甲,已知有两类,RISCV单核一类,ARM双核一类。
RISCV 单核,D1/F133,检测代码
static int chip_detect(struct xfel_ctx_t * ctx, uint32_t id)
{
if(id == 0x00185900)
{
/*
* XuanTie C906 RISC-V
*/
if(R32(0x00000000) == 0x43014281)
return 1;
}
return 0;
}
ARM双核,R528/T113,检测代码
static int chip_detect(struct xfel_ctx_t * ctx, uint32_t id)
{
if(id == 0x00185900)
{
/*
* Dual-Core ARM Cortex-A7
*/
if(R32(0x00000000) == 0xea000019)
return 1;
}
return 0;
}
这里通过读取0地址的机器码来判断是开启的是RISCV还是ARM核,但如何进一步区分,这马甲是R528还是T113呢?或者更近一步,能区分出马甲的尾缀,比如R528-S2,R528-S3,T113-S2,T113-S3这些马甲呢?
有没有相关解决这个问题的思路呢,大家来点脑洞吧,也许真能找到完美解决方案。
只要关心这个配置,填如GPIO编号即可,中断号无需关心,系统会通过gpio_to_irq来获取具体的中断号
"interrupt-gpio": 137,
"interrupt-gpio-config": 6,
"reset-gpio": 138,
"reset-gpio-config": 1
GPIO 编号如下:
#define F1C100S_GPIOA0 (0)
#define F1C100S_GPIOA1 (1)
#define F1C100S_GPIOA2 (2)
#define F1C100S_GPIOA3 (3)
#define F1C100S_GPIOC0 (64)
#define F1C100S_GPIOC1 (65)
#define F1C100S_GPIOC2 (66)
#define F1C100S_GPIOC3 (67)
#define F1C100S_GPIOD0 (96)
#define F1C100S_GPIOD1 (97)
#define F1C100S_GPIOD2 (98)
#define F1C100S_GPIOD3 (99)
#define F1C100S_GPIOD4 (100)
#define F1C100S_GPIOD5 (101)
#define F1C100S_GPIOD6 (102)
#define F1C100S_GPIOD7 (103)
#define F1C100S_GPIOD8 (104)
#define F1C100S_GPIOD9 (105)
#define F1C100S_GPIOD10 (106)
#define F1C100S_GPIOD11 (107)
#define F1C100S_GPIOD12 (108)
#define F1C100S_GPIOD13 (109)
#define F1C100S_GPIOD14 (110)
#define F1C100S_GPIOD15 (111)
#define F1C100S_GPIOD16 (112)
#define F1C100S_GPIOD17 (113)
#define F1C100S_GPIOD18 (114)
#define F1C100S_GPIOD19 (115)
#define F1C100S_GPIOD20 (116)
#define F1C100S_GPIOD21 (117)
#define F1C100S_GPIOE0 (128)
#define F1C100S_GPIOE1 (129)
#define F1C100S_GPIOE2 (130)
#define F1C100S_GPIOE3 (131)
#define F1C100S_GPIOE4 (132)
#define F1C100S_GPIOE5 (133)
#define F1C100S_GPIOE6 (134)
#define F1C100S_GPIOE7 (135)
#define F1C100S_GPIOE8 (136)
#define F1C100S_GPIOE9 (137)
#define F1C100S_GPIOE10 (138)
#define F1C100S_GPIOE11 (139)
#define F1C100S_GPIOE12 (140)
#define F1C100S_GPIOF0 (160)
#define F1C100S_GPIOF1 (161)
#define F1C100S_GPIOF2 (162)
#define F1C100S_GPIOF3 (163)
#define F1C100S_GPIOF4 (164)
#define F1C100S_GPIOF5 (165)
D1芯片的SVD寄存器文件,有什么好用的工具去看这玩意吗?
开发xrock已有近半年了,因RK裸奔玩家较少,故更新频率较低,最近因为要解决某些问题,增加了对RK3566, RK3568芯片的支持,新芯片采用New IDB,包括未来的RK3588旗舰芯片,这里扩展了maskrom指令,增加--rc4-off参数。
RK3566
sudo xrock maskrom rk3566_ddr_1056MHz_v1.11.bin rk356x_usbplug_v1.13.bin --rc4-off
sudo xrock version
RK3568
sudo xrock maskrom rk3568_ddr_1560MHz_v1.11.bin rk356x_usbplug_v1.13.bin --rc4-off
sudo xrock version
https://gitee.com/xboot/xboot/blob/master/src/arch/riscv64/mach-f133/romdisk/boot/mangopi.json
modify json device tree.
"fb-f133-rgb@0x05000000": {
"clock-name-de": "link-de",
"clock-name-tconlcd": "link-tconlcd",
"reset-de": 16,
"reset-tconlcd": 912,
"width": 800,
"height": 480,
"physical-width": 216,
"physical-height": 135,
"bits-per-pixel": 18,
"clock-frequency": 33000000,
"hfront-porch": 40,
"hback-porch": 87,
"hsync-len": 1,
"vfront-porch": 13,
"vback-porch": 31,
"vsync-len": 1,
"hsync-active": false,
"vsync-active": false,
"den-active": true,
"clk-active": true,
"backlight": null
},
因RK3568旧芯片存在flash兼容问题,在完全擦除后,出现无法下载boot的异常现象,处理方法如下。
本处理方法仅以linux系统为例,对于window系统理论上也是可行的,但windows上驱动安装比较麻烦,不推荐。建议在linux系统上操作,不需要安装任何驱动程序。
第一步,确认板子运行在maskrom模式
如果板子运行在loader模式,需要通过短接EMMC重新上电,或者运行如下指令进入maskrom模式
sudo xrock reset maskrom
第二步,运行xrock的maskrom指令,进入loader模式
sudo xrock maskrom rk3568_ddr_920MHz_v1.05.bin rk356x_usbplug_v1.05.bin --rc4-off
第三步,写入16MB头文件
sudo xrock flash write 0 16MB.bin
经过这三步处理后,就可以正常烧录。
sprite_test命令进入fes模式后,就可以通过FES协议来烧录了。
跟烧录FLASH相关的几个FES命令,如下:
FEX_CMD_fes_down
FEX_CMD_fes_up
FEX_CMD_fes_flash_size_probe
FEX_CMD_fes_flash_set_on
FEX_CMD_fes_flash_set_off
具体哪个命令干了哪些事,看uboot代码就能明白个大概,FES协议有2个版本,现在的SDK应该都是2.0版本,之前的1.0版本貌似是13年之前的。
FES跟FEL协议差异有多大,这个还需要进一步确认下,USB传输上应该精简了些,效率高一些。
一些命令操作记录,F133平台,如何通过XFEL进入FES模式
方式1,
对uboot打补丁,默认设置WORK_MODE_USB_PRODUCT启动模式。
diff --git a/lichee/brandy-2.0/u-boot-2018/board/sunxi/board_common.c b/lichee/brandy-2.0/u-boot-2018/board/sunxi/board_common.c
index 327238b86..319623ab8 100644
--- a/lichee/brandy-2.0/u-boot-2018/board/sunxi/board_common.c
+++ b/lichee/brandy-2.0/u-boot-2018/board/sunxi/board_common.c
@@ -67,7 +67,8 @@ void set_boot_work_mode(int work_mode)
int get_boot_work_mode(void)
{
- return uboot_spare_head.boot_data.work_mode;
+ return WORK_MODE_USB_PRODUCT;
+// return uboot_spare_head.boot_data.work_mode;
}
在FEL模式下,执行如下命令,就可以让F133进入FES模式了。
xfel ddr ddr2; xfel write 0x42000000 lichee/brandy-2.0/u-boot-2018/u-boot-dtb.bin; xfel exec 0x42000000;
方式2,不打补丁,通过xfel,修改uboot头,工作模式设置放置在uboot头,可以简单研究下,操作命令同上。
方式3,进入uboot命令行,敲sprite_test
进入FES模式后,就可以执行高阶烧录命令了。
#define FEX_CMD_fes_trans 0x0201
#define FEX_CMD_fes_run 0x0202
#define FEX_CMD_fes_down 0x0206
#define FEX_CMD_fes_up 0x0207
#define FEX_CMD_fes_verify 0x0208
#define FEX_CMD_fes_query_storage 0x0209
#define FEX_CMD_fes_probe_hardware 0x020A
#define FEX_CMD_fes_flash_set_on 0x020A
#define FEX_CMD_fes_flash_set_off 0x020B
#define FEX_CMD_fes_verify_value 0x020C
#define FEX_CMD_fes_verify_status 0x020D
#define FEX_CMD_fes_flash_size_probe 0x020E
#define FEX_CMD_fes_tool_mode 0x020F
#define FEX_CMD_fes_memset 0x0210
#define FEX_CMD_fes_pmu 0x0211
#define FEX_CMD_fes_unseqmem_read 0x0212
#define FEX_CMD_fes_unseqmem_write 0x0213
#define FEX_CMD_fes_force_erase 0x0220
#define FEX_CMD_fes_force_erase_key 0x0221
#define FEX_CMD_fes_reset_cpu 0x0214
#define FEX_CMD_fes_low_power_manger 0x0215
#define FEX_CMD_fes_query_secure 0x0230
#define FEX_CMD_fes_query_info 0x0231
你的代码需要拷贝到sys-copyself.c里,大概率是链接脚本没修改正确。添加一下就可以解决你的问题了。
.text :
{
PROVIDE(__image_start = .);
PROVIDE(__text_start = .);
PROVIDE(__spl_start = .);
.obj/arch/arm32/mach-f1c100s/start.o (.text*)
.obj/arch/arm32/lib/memcpy.o (.text*)
.obj/arch/arm32/lib/memset.o (.text*)
.obj/arch/arm32/mach-f1c100s/sys-jtag.o (.text*)
.obj/arch/arm32/mach-f1c100s/sys-uart.o (.text*)
.obj/arch/arm32/mach-f1c100s/sys-clock.o (.text*)
.obj/arch/arm32/mach-f1c100s/sys-dram.o (.text*)
.obj/arch/arm32/mach-f1c100s/sys-mmu.o (.text*)
.obj/arch/arm32/mach-f1c100s/sys-decompress.o (.text*)
.obj/arch/arm32/mach-f1c100s/sys-hash.o (.text*)
.obj/arch/arm32/mach-f1c100s/sys-verify.o (.text*)
.obj/arch/arm32/mach-f1c100s/sys-spinor.o (.text*)
.obj/arch/arm32/mach-f1c100s/sys-copyself.o (.text*)
PROVIDE(__spl_end = .);
*(.text*)
*(.init.text)
*(.exit.text)
*(.glue*)
*(.note.gnu.build-id)
PROVIDE(__text_end = .);
} > ram
贴一段之前的总结:
不是对齐问题,这种sys-开头的文件,是需要用特别的编程手段的,因为这些程序的链接地址都是在DDR中,而实际运行地址是在SRAM中,需要实现成地址无关的程序,而系统刚启动,什么环境都不具备,C执行环境,更是不完整的,所以只能用特别编程手段。
一般有一下注意点:
1,不要使用已初始化数据段
2,不要使用未初始化数据段
3,不要使用switch case语句,可以用if elseif 代替
4,不要使用全局变量,仅使用局部变量
5,局部变量的初始化,用代码实现,会编译成立即数赋值
6,只能使用栈空间,其他什么都不可以使用
7,不要调用任何外部库,比如工具链里的C库等。
只要按这种要求,编程,编译出来的代码,都是地址无关的,SPL代码是很特殊的,谨记运行地址不是链接地址,就明白为何需要这样处理了。
当然,这种限制,也导致编程要求较高,如果不想挑战自己,就链接两次,做两个程序吧,BL1->BL2,这种,你看某些芯片的引导链,那么长,就是因为这种原因。
独立的一个程序,支持引导,自举,换到DDR空间,要求是很高的。这种编程技巧,算挑战性编程。
还有一个需要注意的地方自拷贝完整镜像放在1MB偏移的地方,只要注意这些细节,spi nand 就可以引导了。
else if(d == BOOT_DEVICE_SPINAND)
{
struct zdesc_t * z = (struct zdesc_t *)__heap_start;
void * mem = (void *)__image_start;
void * tmp = (void *)z + sizeof(struct zdesc_t);
uint32_t size = __image_end - __image_start;
sys_spinand_init();
sys_spinand_read(1048576 + 65536, z, sizeof(struct zdesc_t));
sys_spinand_exit();
if((z->magic[0] == 'Z') && (z->magic[1] == 'B') && (z->magic[2] == 'L') && (z->magic[3] == '!'))
{
//if(sys_verify((char *)z->pubkey, (char *)z->sha256, (char *)z->signature))
{
uint32_t csize = (z->csize[0] << 24) | (z->csize[1] << 16) | (z->csize[2] << 8) | (z->csize[3] << 0);
uint32_t dsize = (z->dsize[0] << 24) | (z->dsize[1] << 16) | (z->dsize[2] << 8) | (z->dsize[3] << 0);
sys_spinand_init();
sys_spinand_read(1048576 + 65536 + sizeof(struct zdesc_t), tmp, csize);
sys_spinand_exit();
//if(sys_hash((char *)(&z->majoy), (sizeof(struct zdesc_t) - 100) + csize, (char *)z->sha256))
{
sys_decompress(tmp, csize, mem, dsize);
}
}
}
else
{
sys_spinand_init();
sys_spinand_read(1048576, mem, size);
sys_spinand_exit();
}
}
发现了一个机关,全志烧录工具,本质上是利用FES模式,FES模式是uboot提供的一个命令,叫做sprite_test,当你手动执行这个命令时,就可以进入FES模式,或者改变get_boot_work_mode函数的返回值为WORK_MODE_USB_PRODUCT,则uboot启动时会自动运行sprite_test命令进入FES模式。FES模式下的USB传输协议与FEL基本一致,一些命令的ID做了改变,并扩展了FLASH相关的指令,也就是说,XFEL仅需增加对FES模式的支持后,就可以实现实现flash烧写了。而且,FES模式下FES_PLATFORM_HW_ID永远是0x00161000,不管是哪种芯片。
FES,FEL模式公共命令:
#define APP_LAYER_COMMEN_CMD_VERIFY_DEV 0x0001
#define APP_LAYER_COMMEN_CMD_SWITCH_ROLE 0x0002
#define APP_LAYER_COMMEN_CMD_IS_READY 0x0003
#define APP_LAYER_COMMEN_CMD_GET_CMD_SET_VER 0x0004
#define APP_LAYER_COMMEN_CMD_DISCONNECT 0x0010
FES模式特有的命令:
#define FEX_CMD_fes_trans 0x0201
#define FEX_CMD_fes_run 0x0202
#define FEX_CMD_fes_down 0x0206
#define FEX_CMD_fes_up 0x0207
#define FEX_CMD_fes_verify 0x0208
#define FEX_CMD_fes_query_storage 0x0209
#define FEX_CMD_fes_probe_hardware 0x020A
#define FEX_CMD_fes_flash_set_on 0x020A
#define FEX_CMD_fes_flash_set_off 0x020B
#define FEX_CMD_fes_verify_value 0x020C
#define FEX_CMD_fes_verify_status 0x020D
#define FEX_CMD_fes_flash_size_probe 0x020E
#define FEX_CMD_fes_tool_mode 0x020F
#define FEX_CMD_fes_memset 0x0210
#define FEX_CMD_fes_pmu 0x0211
#define FEX_CMD_fes_unseqmem_read 0x0212
#define FEX_CMD_fes_unseqmem_write 0x0213
#define FEX_CMD_fes_force_erase 0x0220
#define FEX_CMD_fes_force_erase_key 0x0221
#define FEX_CMD_fes_reset_cpu 0x0214
#define FEX_CMD_fes_low_power_manger 0x0215
#define FEX_CMD_fes_query_secure 0x0230
#define FEX_CMD_fes_query_info 0x0231
理论上是可以实现用xfel来烧录全志image的,也就是说可以代替全志的PhoenixSuit工具的,但这个工作有多大意义就得打个问号了。