From 980dbbfe4c537b95f55ba0341a0d904370a609ef Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 21 Aug 2020 02:52:46 -0700 Subject: [PATCH] npdmtool: add compatibility for 8.0.0+ memory region capabilities --- src/elf2kip.c | 2 +- src/npdmtool.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/elf2kip.c b/src/elf2kip.c index a948d44..1e8e473 100644 --- a/src/elf2kip.c +++ b/src/elf2kip.c @@ -440,7 +440,7 @@ int ParseKipConfiguration(const char *json, KipHeader *kip_hdr) { capability |= ((regions[i] & 0x3F) | ((is_ro[i] & 1) << 6)) << (11 + 7 * i); } kip_hdr->Capabilities[cur_cap++] = capability; - } else if (!strcmp(type_str, "irq_pair")) { + } else if (!strcmp(type_str, "irq_pair")) { if (cur_cap + 1 > 0x20) { fprintf(stderr, "Error: Too many capabilities!\n"); status = 0; diff --git a/src/npdmtool.c b/src/npdmtool.c index 663980c..a4878cd 100644 --- a/src/npdmtool.c +++ b/src/npdmtool.c @@ -687,6 +687,47 @@ int CreateNpdm(const char *json, void **dst, u32 *dst_size) { } desc = (u32)((page_address >> 12) & 0x00FFFFFFULL); caps[cur_cap++] = (u32)((desc << 8) | (0x007F)); + } else if (!strcmp(type_str, "map_region")) { + if (cur_cap + 1 > 0x20) { + fprintf(stderr, "Error: Too many capabilities!\n"); + status = 0; + goto NPDM_BUILD_END; + } + if (!cJSON_IsArray(value)) { + fprintf(stderr, "Map Region capability value must be array!\n"); + status = 0; + goto NPDM_BUILD_END; + } + u8 regions[3] = {0}; + int is_ro[3] = {0}; + const cJSON *cur_region = NULL; + int index = 0; + cJSON_ArrayForEach(cur_region, value) { + if (index >= 3) { + fprintf(stderr, "Too many region descriptors!\n"); + status = 0; + goto NPDM_BUILD_END; + } + if (!cJSON_IsObject(cur_region)) { + fprintf(stderr, "Region descriptor value must be object!\n"); + status = 0; + goto NPDM_BUILD_END; + } + + if (!cJSON_GetU8(cur_region, "region_type", ®ions[index]) || + !cJSON_GetBoolean(cur_region, "is_ro", &is_ro[index])) { + status = 0; + goto NPDM_BUILD_END; + } + + index++; + } + + u32 capability = 0x3FF; + for (int i = 0; i < 3; ++i) { + capability |= ((regions[i] & 0x3F) | ((is_ro[i] & 1) << 6)) << (11 + 7 * i); + } + caps[cur_cap++] = capability; } else if (!strcmp(type_str, "irq_pair")) { if (!cJSON_IsArray(value) || cJSON_GetArraySize(value) != 2) { fprintf(stderr, "Error: IRQ Pairs must have size 2 array value.\n");