From 056b65fbc08c2b04061a2fe692467bb4810e2d75 Mon Sep 17 00:00:00 2001 From: qianfan Zhao Date: Fri, 10 Feb 2023 17:29:34 +0800 Subject: [PATCH] fel: Introduce 'sid-dump' The sid memory maps are copied from allwinner 3.10 bsp. Next is a sample output from allwinner T3: $ sunxi-fel sid-dump chipid 1300000c 02c04700 79350400 30791acc in 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ssk 00000000 00000000 00000000 00000000 thermal 0823081c ft_zone 00000000 00000000 tvout 00ff02ad 00f8029e 00f0028d 00f902a2 rssk 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 hdcp_hash 00000000 00000000 00000000 00000000 reserved 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 00000000 00000000 00000000 Signed-off-by: qianfan Zhao --- fel.c | 35 +++++++++++++++++++++++++++++++++-- fel_lib.c | 9 +++++++++ fel_lib.h | 2 ++ soc_info.c | 14 ++++++++++++++ soc_info.h | 16 ++++++++++++++++ 5 files changed, 74 insertions(+), 2 deletions(-) diff --git a/fel.c b/fel.c index 2881587fb..ea641ac89 100644 --- a/fel.c +++ b/fel.c @@ -202,7 +202,7 @@ void *load_file(const char *name, size_t *size) perror("Failed to open input file"); exit(1); } - + while (true) { size_t len = bufsize - offset; size_t n = fread(buf+offset, 1, len, in); @@ -216,7 +216,7 @@ void *load_file(const char *name, size_t *size) exit(1); } } - if (size) + if (size) *size = offset; if (in != stdin) fclose(in); @@ -440,6 +440,35 @@ void aw_fel_print_sid(feldev_handle *dev, bool force_workaround) printf("%08x%c", key[i], i < 3 ? ':' : '\n'); } +void aw_fel_dump_sid(feldev_handle *dev) +{ + uint32_t buffer[2048 / sizeof(uint32_t)]; /* total SID size is 2K */ + soc_info_t *soc_info = dev->soc_info; + + if (!soc_info->sid_base || !soc_info->sid_sections) { + printf("SID memory maps for your SoC (%s) are unknown.\n", + dev->soc_name); + return; + } + + for (const sid_section *s = soc_info->sid_sections; s->name; s++) { + uint32_t count = s->size_bits / 32; + + if (!fel_get_sid(dev, buffer, s->offset, count)) { + fprintf(stderr, "Read sid:%s failed\n", s->name); + return; + } + + printf("%-15s", s->name); + for (uint32_t i = 0; i < count; i++) { + if (i > 0 && ((i % 8) == 0)) + printf("\n%-15s", ""); + printf(" %08x", buffer[i]); + } + putchar('\n'); + } +} + void aw_enable_l2_cache(feldev_handle *dev, soc_info_t *soc_info) { uint32_t arm_code[] = { @@ -1368,6 +1397,8 @@ int main(int argc, char **argv) aw_fel_print_sid(handle, false); } else if (strcmp(argv[1], "sid-registers") == 0) { aw_fel_print_sid(handle, true); /* enforce register access */ + } else if (strcmp(argv[1], "sid-dump") == 0) { + aw_fel_dump_sid(handle); } else if (strcmp(argv[1], "write") == 0 && argc > 3) { skip += 2 * file_upload(handle, 1, argc - 2, argv + 2, pflag_active ? progress_bar : NULL); diff --git a/fel_lib.c b/fel_lib.c index 2db6154b5..310e836b5 100644 --- a/fel_lib.c +++ b/fel_lib.c @@ -610,6 +610,15 @@ bool fel_get_sid_root_key(feldev_handle *dev, uint32_t *result, return true; } +bool fel_get_sid(feldev_handle *dev, uint32_t *result, uint32_t offset, + size_t count) +{ + fel_readl_n(dev, dev->soc_info->sid_base + + dev->soc_info->sid_offset + offset, result, count); + + return true; +} + /* general functions, "FEL device" management */ static int feldev_get_endpoint(feldev_handle *dev) diff --git a/fel_lib.h b/fel_lib.h index ddbc2f3b8..414f9d943 100644 --- a/fel_lib.h +++ b/fel_lib.h @@ -80,6 +80,8 @@ void fel_clrsetbits_le32(feldev_handle *dev, /* retrieve SID root key */ bool fel_get_sid_root_key(feldev_handle *dev, uint32_t *result, bool force_workaround); +bool fel_get_sid(feldev_handle *dev, uint32_t *result, uint32_t offset, + size_t count); bool aw_fel_remotefunc_prepare(feldev_handle *dev, size_t stack_size, diff --git a/soc_info.c b/soc_info.c index 18536f7b0..247de9a0b 100644 --- a/soc_info.c +++ b/soc_info.c @@ -187,6 +187,19 @@ const watchdog_info wd_v853_compat = { .reg_mode_value = 0x16aa0001, }; +const sid_section r40_sid_maps[] = { + SID_SECTION("chipid", 0x00, 128), + SID_SECTION("in", 0x10, 256), + SID_SECTION("ssk", 0x30, 128), + SID_SECTION("thermal", 0x40, 32), + SID_SECTION("ft_zone", 0x44, 64), + SID_SECTION("tvout", 0x4c, 128), + SID_SECTION("rssk", 0x5c, 256), + SID_SECTION("hdcp_hash",0x7c, 128), + SID_SECTION("reserved", 0x90, 896), + SID_SECTION(NULL, 0, 0), +}; + soc_info_t soc_info_table[] = { { .soc_id = 0x1623, /* Allwinner A10 */ @@ -335,6 +348,7 @@ soc_info_t soc_info_table[] = { .sram_size = 48 * 1024, .sid_base = 0x01C1B000, .sid_offset = 0x200, + .sid_sections = r40_sid_maps, .watchdog = &wd_a10_compat, },{ .soc_id = 0x1719, /* Allwinner A63 */ diff --git a/soc_info.h b/soc_info.h index f7ab8e5da..a7ae83e39 100644 --- a/soc_info.h +++ b/soc_info.h @@ -61,6 +61,21 @@ typedef struct { uint32_t reg_mode_value; } watchdog_info; +/* + * sunxi sid sections + */ +typedef struct { + const char *name; + uint32_t offset; + uint32_t size_bits; +} sid_section; + +#define SID_SECTION(_name, _offset, _size_bits) { \ + .name = _name, \ + .offset = _offset, \ + .size_bits = _size_bits, \ +} + /* * Each SoC variant may have its own list of memory buffers to be exchanged * and the information about the placement of the thunk code, which handles @@ -110,6 +125,7 @@ typedef struct { uint32_t mmu_tt_addr; /* MMU translation table address */ uint32_t sid_base; /* base address for SID registers */ uint32_t sid_offset; /* offset for SID_KEY[0-3], "root key" */ + const sid_section *sid_sections; /* sid memory maps */ uint32_t rvbar_reg; /* MMIO address of RVBARADDR0_L register */ const watchdog_info *watchdog; /* Used for reset */ bool sid_fix; /* Use SID workaround (read via register) */