diff --git a/bdk/mem/mc_t210.h b/bdk/mem/mc_t210.h index ed96852..ff96b9d 100644 --- a/bdk/mem/mc_t210.h +++ b/bdk/mem/mc_t210.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2014, NVIDIA Corporation. All rights reserved. + * Copyright (c) 2014, NVIDIA Corporation. + * Copyright (c) 2018-2023, CTCaer * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -14,6 +15,22 @@ #ifndef _MC_T210_H_ #define _MC_T210_H_ +/*! MC SMMU registers */ +#define MC_SMMU_CONFIG 0x10 +#define MC_SMMU_TLB_CONFIG 0x14 +#define MC_SMMU_PTC_CONFIG 0x18 +#define MC_SMMU_PTB_ASID 0x1c +#define MC_SMMU_PTB_DATA 0x20 +#define MC_SMMU_TLB_FLUSH 0x30 +#define MC_SMMU_PTC_FLUSH 0x34 +#define MC_SMMU_ASID_SECURITY 0x38 +#define MC_SMMU_TRANSLATION_ENABLE_0 0x228 +#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c +#define MC_SMMU_TRANSLATION_ENABLE_2 0x230 +#define MC_SMMU_TRANSLATION_ENABLE_3 0x234 +#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98 + +/*! MC General registers */ #define MC_INTSTATUS 0x0 #define MC_INTMASK 0x4 #define MC_ERR_STATUS 0x8 @@ -464,7 +481,7 @@ #define MC_UNTRANSLATED_REGION_CHECK 0x948 #define MC_DA_CONFIG0 0x9dc -/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS0 */ +/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS0 */ #define SEC_CARVEOUT_CA0_R_PTCR BIT(0) #define SEC_CARVEOUT_CA0_R_DISPLAY0A BIT(1) #define SEC_CARVEOUT_CA0_R_DISPLAY0AB BIT(2) @@ -484,7 +501,7 @@ #define SEC_CARVEOUT_CA0_R_PPCSAHBSLV BIT(30) #define SEC_CARVEOUT_CA0_R_SATAR BIT(31) -/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS1 */ +/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS1 */ #define SEC_CARVEOUT_CA1_R_VDEBSEV BIT(2) #define SEC_CARVEOUT_CA1_R_VDEMBE BIT(3) #define SEC_CARVEOUT_CA1_R_VDEMCE BIT(4) @@ -504,7 +521,7 @@ #define SEC_CARVEOUT_CA1_W_VDEBSEV BIT(30) #define SEC_CARVEOUT_CA1_W_VDEDBG BIT(31) -/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS2 */ +/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS2 */ #define SEC_CARVEOUT_CA2_W_VDEMBE BIT(0) #define SEC_CARVEOUT_CA2_W_VDETPM BIT(1) #define SEC_CARVEOUT_CA2_R_ISPRA BIT(4) @@ -524,7 +541,7 @@ #define SEC_CARVEOUT_CA2_W_GPU BIT(25) #define SEC_CARVEOUT_CA2_R_DISPLAYT BIT(26) -/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS3 */ +/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS3 */ #define SEC_CARVEOUT_CA3_R_SDMMCA BIT(0) #define SEC_CARVEOUT_CA3_R_SDMMCAA BIT(1) #define SEC_CARVEOUT_CA3_R_SDMMC BIT(2) @@ -544,7 +561,7 @@ #define SEC_CARVEOUT_CA3_R_NVJPG BIT(30) #define SEC_CARVEOUT_CA3_W_NVJPG BIT(31) -/* MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS4 */ +/*! MC_SECURITY_CARVEOUTX_CLIENT_FORCE_INTERNAL_ACCESS4 */ #define SEC_CARVEOUT_CA4_R_SE BIT(0) #define SEC_CARVEOUT_CA4_W_SE BIT(1) #define SEC_CARVEOUT_CA4_R_AXIAP BIT(2) diff --git a/bdk/mem/smmu.c b/bdk/mem/smmu.c index 048203f..0128103 100644 --- a/bdk/mem/smmu.c +++ b/bdk/mem/smmu.c @@ -23,6 +23,23 @@ #include #include #include +#include + +#define SMMU_PAGE_SHIFT 12 +#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT) +#define SMMU_PDIR_COUNT 1024 +#define SMMU_PDIR_SIZE (sizeof(u32) * SMMU_PDIR_COUNT) +#define SMMU_PTBL_COUNT 1024 +#define SMMU_PTBL_SIZE (sizeof(u32) * SMMU_PTBL_COUNT) +#define SMMU_PDIR_SHIFT 12 +#define SMMU_PDE_SHIFT 12 +#define SMMU_PTE_SHIFT 12 +#define SMMU_PFN_MASK 0x000FFFFF +#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12) +#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22) +#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22) +#define SMMU_MK_PDIR(page, attr) (((page) >> SMMU_PDIR_SHIFT) | (attr)) +#define SMMU_MK_PDE(page, attr) (((page) >> SMMU_PDE_SHIFT) | (attr)) u8 *_pageheap = (u8 *)SMMU_HEAP_ADDR; @@ -37,7 +54,7 @@ u8 smmu_payload[] __attribute__((aligned(16))) = { 0x10, 0x90, 0x01, 0x70, // 0x18: MC_SMMU_CONFIG }; -void *page_alloc(u32 num) +void *smmu_page_zalloc(u32 num) { u8 *res = _pageheap; _pageheap += SZ_PAGE * num; @@ -45,15 +62,15 @@ void *page_alloc(u32 num) return res; } -u32 *smmu_alloc_pdir() +static u32 *_smmu_pdir_alloc() { - u32 *pdir = (u32 *)page_alloc(1); + u32 *pdir = (u32 *)smmu_page_zalloc(1); for (int pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++) pdir[pdn] = _PDE_VACANT(pdn); return pdir; } -void smmu_flush_regs() +static void _smmu_flush_regs() { (void)MC(MC_SMMU_PTB_DATA); } @@ -61,10 +78,10 @@ void smmu_flush_regs() void smmu_flush_all() { MC(MC_SMMU_PTC_FLUSH) = 0; - smmu_flush_regs(); + _smmu_flush_regs(); MC(MC_SMMU_TLB_FLUSH) = 0; - smmu_flush_regs(); + _smmu_flush_regs(); } void smmu_init() @@ -95,14 +112,14 @@ void smmu_enable() u32 *smmu_init_domain4(u32 dev_base, u32 asid) { - u32 *pdir = smmu_alloc_pdir(); + u32 *pdir = _smmu_pdir_alloc(); MC(MC_SMMU_PTB_ASID) = asid; MC(MC_SMMU_PTB_DATA) = SMMU_MK_PDIR((u32)pdir, _PDIR_ATTR); - smmu_flush_regs(); + _smmu_flush_regs(); MC(dev_base) = 0x80000000 | (asid << 24) | (asid << 16) | (asid << 8) | (asid); - smmu_flush_regs(); + _smmu_flush_regs(); return pdir; } @@ -117,7 +134,7 @@ u32 *smmu_get_pte(u32 *pdir, u32 iova) ptbl = (u32 *)((pdir[pdn] & SMMU_PFN_MASK) << SMMU_PDIR_SHIFT); else { - ptbl = (u32 *)page_alloc(1); + ptbl = (u32 *)smmu_page_zalloc(1); u32 addr = SMMU_PDN_TO_ADDR(pdn); for (int pn = 0; pn < SMMU_PTBL_COUNT; pn++, addr += SMMU_PAGE_SIZE) ptbl[pn] = _PTE_VACANT(addr); @@ -140,16 +157,16 @@ void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr) smmu_flush_all(); } -u32 *smmu_init_for_tsec() +u32 *smmu_init_domain(u32 asid) { - return smmu_init_domain4(MC_SMMU_TSEC_ASID, 1); + return smmu_init_domain4(asid, 1); } -void smmu_deinit_for_tsec() +void smmu_deinit_domain(u32 asid) { MC(MC_SMMU_PTB_ASID) = 1; MC(MC_SMMU_PTB_DATA) = 0; - MC(MC_SMMU_TSEC_ASID) = 0; - smmu_flush_regs(); + MC(asid) = 0; + _smmu_flush_regs(); } diff --git a/bdk/mem/smmu.h b/bdk/mem/smmu.h index 80ef66f..c0c765c 100644 --- a/bdk/mem/smmu.h +++ b/bdk/mem/smmu.h @@ -17,45 +17,13 @@ #include -#define SMMU_HEAP_ADDR 0xA0000000 - -#define MC_INTSTATUS 0x0 -#define MC_INTMASK 0x4 -#define MC_ERR_STATUS 0x8 -#define MC_ERR_ADR 0xc -#define MC_SMMU_CONFIG 0x10 -#define MC_SMMU_TLB_CONFIG 0x14 -#define MC_SMMU_PTC_CONFIG 0x18 -#define MC_SMMU_PTB_ASID 0x1c -#define MC_SMMU_PTB_DATA 0x20 -#define MC_SMMU_TLB_FLUSH 0x30 -#define MC_SMMU_PTC_FLUSH 0x34 -#define MC_SMMU_ASID_SECURITY 0x38 #define MC_SMMU_AVPC_ASID 0x23C #define MC_SMMU_TSEC_ASID 0x294 -#define MC_SMMU_TRANSLATION_ENABLE_0 0x228 -#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c -#define MC_SMMU_TRANSLATION_ENABLE_2 0x230 -#define MC_SMMU_TRANSLATION_ENABLE_3 0x234 -#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98 #define SMMU_PDE_NEXT_SHIFT 28 #define MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT 29 #define MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT 30 #define MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT 31 -#define SMMU_PAGE_SHIFT 12 -#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT) -#define SMMU_PDIR_COUNT 1024 -#define SMMU_PDIR_SIZE (sizeof(u32) * SMMU_PDIR_COUNT) -#define SMMU_PTBL_COUNT 1024 -#define SMMU_PTBL_SIZE (sizeof(u32) * SMMU_PTBL_COUNT) -#define SMMU_PDIR_SHIFT 12 -#define SMMU_PDE_SHIFT 12 -#define SMMU_PTE_SHIFT 12 -#define SMMU_PFN_MASK 0x000FFFFF -#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12) -#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22) -#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22) #define _READABLE (1 << MC_SMMU_PTB_DATA_0_ASID_READABLE_SHIFT) #define _WRITABLE (1 << MC_SMMU_PTB_DATA_0_ASID_WRITABLE_SHIFT) #define _NONSECURE (1 << MC_SMMU_PTB_DATA_0_ASID_NONSECURE_SHIFT) @@ -66,17 +34,13 @@ #define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR) #define _PTE_ATTR (_READABLE | _WRITABLE | _NONSECURE) #define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR) -#define SMMU_MK_PDIR(page, attr) (((page) >> SMMU_PDIR_SHIFT) | (attr)) -#define SMMU_MK_PDE(page, attr) (((page) >> SMMU_PDE_SHIFT) | (attr)) -void *page_alloc(u32 num); -u32 *smmu_alloc_pdir(); -void smmu_flush_regs(); -void smmu_flush_all(); -void smmu_init(); -void smmu_enable(); -u32 *smmu_init_domain4(u32 dev_base, u32 asid); -u32 *smmu_get_pte(u32 *pdir, u32 iova); -void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr); -u32 *smmu_init_for_tsec(); -void smmu_deinit_for_tsec(); +void *smmu_page_zalloc(u32 num); +void smmu_flush_all(); +void smmu_init(); +void smmu_enable(); +u32 *smmu_init_domain4(u32 dev_base, u32 asid); +u32 *smmu_get_pte(u32 *pdir, u32 iova); +void smmu_map(u32 *pdir, u32 addr, u32 page, int cnt, u32 attr); +u32 *smmu_init_domain(u32 asid); +void smmu_deinit_domain(u32 asid); diff --git a/bdk/memory_map.h b/bdk/memory_map.h index e24d924..c687f2c 100644 --- a/bdk/memory_map.h +++ b/bdk/memory_map.h @@ -50,7 +50,9 @@ /* Stack theoretical max: 33MB */ #define IPL_STACK_TOP 0x83100000 #define IPL_HEAP_START 0x84000000 -#define IPL_HEAP_SZ SZ_512M +#define IPL_HEAP_SZ (SZ_512M - SZ_64M) + +#define SMMU_HEAP_ADDR 0xA0000000 /* --- Gap: 1040MB 0xA4000000 - 0xE4FFFFFF --- */ // Virtual disk / Chainloader buffers. diff --git a/bdk/sec/tsec.c b/bdk/sec/tsec.c index 820a2d3..52f130e 100644 --- a/bdk/sec/tsec.c +++ b/bdk/sec/tsec.c @@ -145,20 +145,20 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt) if (type == TSEC_FW_TYPE_EMU) { // Init SMMU translation for TSEC. - pdir = smmu_init_for_tsec(); + pdir = smmu_init_domain(MC_SMMU_TSEC_ASID); smmu_init(); // Enable SMMU. smmu_enable(); // Clock reset controller. - car = page_alloc(1); + car = smmu_page_zalloc(1); memcpy(car, (void *)CLOCK_BASE, SZ_PAGE); car[CLK_RST_CONTROLLER_CLK_SOURCE_TSEC / 4] = 2; smmu_map(pdir, CLOCK_BASE, (u32)car, 1, _WRITABLE | _READABLE | _NONSECURE); // Fuse driver. - fuse = page_alloc(1); + fuse = smmu_page_zalloc(1); memcpy((void *)&fuse[0x800/4], (void *)FUSE_BASE, SZ_1K); fuse[0x82C / 4] = 0; fuse[0x9E0 / 4] = (1 << (TSEC_HOS_KB_620 + 2)) - 1; @@ -166,34 +166,34 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt) smmu_map(pdir, (FUSE_BASE - 0x800), (u32)fuse, 1, _READABLE | _NONSECURE); // Power management controller. - pmc = page_alloc(1); + pmc = smmu_page_zalloc(1); smmu_map(pdir, RTC_BASE, (u32)pmc, 1, _READABLE | _NONSECURE); // Flow control. - flowctrl = page_alloc(1); + flowctrl = smmu_page_zalloc(1); smmu_map(pdir, FLOW_CTLR_BASE, (u32)flowctrl, 1, _WRITABLE | _NONSECURE); // Security engine. - se = page_alloc(1); + se = smmu_page_zalloc(1); memcpy(se, (void *)SE_BASE, SZ_PAGE); smmu_map(pdir, SE_BASE, (u32)se, 1, _READABLE | _WRITABLE | _NONSECURE); // Memory controller. - mc = page_alloc(1); + mc = smmu_page_zalloc(1); memcpy(mc, (void *)MC_BASE, SZ_PAGE); mc[MC_IRAM_BOM / 4] = 0; mc[MC_IRAM_TOM / 4] = DRAM_START; smmu_map(pdir, MC_BASE, (u32)mc, 1, _READABLE | _NONSECURE); // IRAM - iram = page_alloc(0x30); + iram = smmu_page_zalloc(0x30); memcpy(iram, tsec_ctxt->pkg1, 0x30000); // PKG1.1 magic offset. pkg11_magic_off = (u32 *)(iram + ((tsec_ctxt->pkg11_off + 0x20) / 4)); smmu_map(pdir, 0x40010000, (u32)iram, 0x30, _READABLE | _WRITABLE | _NONSECURE); // Exception vectors - evec = page_alloc(1); + evec = smmu_page_zalloc(1); smmu_map(pdir, EXCP_VEC_BASE, (u32)evec, 1, _READABLE | _WRITABLE | _NONSECURE); } @@ -229,7 +229,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt) if (kidx != 8) { res = -6; - smmu_deinit_for_tsec(); + smmu_deinit_domain(MC_SMMU_TSEC_ASID); goto out_free; } @@ -240,7 +240,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt) memcpy(tsec_keys, &key, 0x20); memcpy(tsec_ctxt->pkg1, iram, 0x30000); - smmu_deinit_for_tsec(); + smmu_deinit_domain(MC_SMMU_TSEC_ASID); // for (int i = 0; i < kidx; i++) // gfx_printf("key %08X\n", key[i]); diff --git a/bdk/soc/irq.c b/bdk/soc/irq.c index 380cfe1..5ecfb58 100644 --- a/bdk/soc/irq.c +++ b/bdk/soc/irq.c @@ -194,7 +194,7 @@ void irq_wait_event(u32 irq) _irq_enable_source(irq); // Halt BPMP and wait for the IRQ. No need to use WAIT_EVENT + LIC_IRQ when BPMP serves the IRQ. - FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_COP_STOP_UNTIL_IRQ; + FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = HALT_MODE_STOP_UNTIL_IRQ; _irq_disable_source(irq); _irq_ack_source(irq);