Rewrite the memory map-related code...

...other style fixes, etc.
This commit is contained in:
TuxSH 2018-02-26 22:09:35 +01:00
parent bda9dcbe73
commit c7d83c6eb6
26 changed files with 603 additions and 442 deletions

View File

@ -30,11 +30,11 @@ bool bootconfig_is_debug_mode(void) {
} }
uint64_t bootconfig_get_memory_arrangement(void) { uint64_t bootconfig_get_memory_arrangement(void) {
return 0ULL; return 0ull;
/* TODO */ /* TODO */
} }
uint64_t bootconfig_get_kernel_memory_configuration(void) { uint64_t bootconfig_get_kernel_memory_configuration(void) {
return 0ULL; return 0ull;
/* TODO */ /* TODO */
} }

View File

@ -18,10 +18,67 @@ extern void invalidate_icache_all_tzram_pa(void);
uintptr_t get_coldboot_crt0_stack_address(void); uintptr_t get_coldboot_crt0_stack_address(void);
static void identity_map_all_mappings(uintptr_t *mmu_l1_tbl, uintptr_t *mmu_l3_tbl) {
static const uintptr_t addrs[] = { TUPLE_FOLD_LEFT_0(EVAL(IDENTIY_MAPPING_ID_MAX), _MMAPID, COMMA) };
static const size_t sizes[] = { TUPLE_FOLD_LEFT_1(EVAL(IDENTIY_MAPPING_ID_MAX), _MMAPID, COMMA) };
static const uint64_t attribs[] = { TUPLE_FOLD_LEFT_2(EVAL(IDENTIY_MAPPING_ID_MAX), _MMAPID, COMMA) };
static const uint64_t is_block[] = { TUPLE_FOLD_LEFT_3(EVAL(IDENTIY_MAPPING_ID_MAX), _MMAPID, COMMA) };
for(size_t i = 0; i < IDENTIY_MAPPING_ID_MAX; i++) {
identity_map_mapping(mmu_l1_tbl, mmu_l3_tbl, addrs[i], sizes[i], attribs[i], is_block[i]);
}
}
static void mmio_map_all_devices(uintptr_t *mmu_l3_tbl) {
static const uintptr_t pas[] = { TUPLE_FOLD_LEFT_0(EVAL(MMIO_DEVID_MAX), _MMAPDEV, COMMA) };
static const size_t sizes[] = { TUPLE_FOLD_LEFT_1(EVAL(MMIO_DEVID_MAX), _MMAPDEV, COMMA) };
static const bool is_secure[] = { TUPLE_FOLD_LEFT_2(EVAL(MMIO_DEVID_MAX), _MMAPDEV, COMMA) };
for(size_t i = 0, offset = 0; i < MMIO_DEVID_MAX; i++) {
mmio_map_device(mmu_l3_tbl, MMIO_BASE + offset, pas[i], sizes[i], is_secure[i]);
offset += sizes[i];
offset += 0x1000;
}
}
static void lp0_entry_map_all_ram_segments(uintptr_t *mmu_l3_tbl) {
static const uintptr_t pas[] = { TUPLE_FOLD_LEFT_0(EVAL(LP0_ENTRY_RAM_SEGMENT_ID_MAX), _MMAPLP0ES, COMMA) };
static const size_t sizes[] = { TUPLE_FOLD_LEFT_1(EVAL(LP0_ENTRY_RAM_SEGMENT_ID_MAX), _MMAPLP0ES, COMMA) };
static const uint64_t attribs[] = { TUPLE_FOLD_LEFT_2(EVAL(LP0_ENTRY_RAM_SEGMENT_ID_MAX), _MMAPLP0ES, COMMA) };
for(size_t i = 0, offset = 0; i < LP0_ENTRY_RAM_SEGMENT_ID_MAX; i++) {
lp0_entry_map_ram_segment(mmu_l3_tbl, LP0_ENTRY_RAM_SEGMENT_BASE + offset, pas[i], sizes[i], attribs[i]);
offset += 0x10000;
}
}
static void warmboot_map_all_ram_segments(uintptr_t *mmu_l3_tbl) {
static const uintptr_t pas[] = { TUPLE_FOLD_LEFT_0(EVAL(WARMBOOT_RAM_SEGMENT_ID_MAX), _MMAPWBS, COMMA) };
static const size_t sizes[] = { TUPLE_FOLD_LEFT_1(EVAL(WARMBOOT_RAM_SEGMENT_ID_MAX), _MMAPWBS, COMMA) };
static const uint64_t attribs[] = { TUPLE_FOLD_LEFT_2(EVAL(WARMBOOT_RAM_SEGMENT_ID_MAX), _MMAPWBS, COMMA) };
for(size_t i = 0, offset = 0; i < WARMBOOT_RAM_SEGMENT_ID_MAX; i++) {
warmboot_map_ram_segment(mmu_l3_tbl, WARMBOOT_RAM_SEGMENT_BASE + offset, pas[i], sizes[i], attribs[i]);
offset += sizes[i];
}
}
static void tzram_map_all_segments(uintptr_t *mmu_l3_tbl) {
static const uintptr_t offs[] = { TUPLE_FOLD_LEFT_0(EVAL(TZRAM_SEGMENT_ID_MAX), _MMAPTZS, COMMA) };
static const size_t sizes[] = { TUPLE_FOLD_LEFT_1(EVAL(TZRAM_SEGMENT_ID_MAX), _MMAPTZS, COMMA) };
static const size_t increments[] = { TUPLE_FOLD_LEFT_2(EVAL(TZRAM_SEGMENT_ID_MAX), _MMAPTZS, COMMA) };
static const bool is_executable[] = { TUPLE_FOLD_LEFT_3(EVAL(TZRAM_SEGMENT_ID_MAX), _MMAPTZS, COMMA) };
for(size_t i = 0, offset = 0; i < TZRAM_SEGMENT_ID_MAX; i++) {
tzram_map_segment(mmu_l3_tbl, TZRAM_SEGMENT_BASE, 0x7C010000ull + offs[i], sizes[i], is_executable[i]);
offset += increments[i];
}
}
static void configure_ttbls(void) { static void configure_ttbls(void) {
uintptr_t *mmu_l1_tbl = (uintptr_t *)(tzram_get_segment_pa(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64); uintptr_t *mmu_l1_tbl = (uintptr_t *)(TZRAM_GET_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64);
uintptr_t *mmu_l2_tbl = (uintptr_t *)tzram_get_segment_pa(TZRAM_SEGMENT_ID_L2_TRANSLATION_TABLE); uintptr_t *mmu_l2_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_L2_TRANSLATION_TABLE);
uintptr_t *mmu_l3_tbl = (uintptr_t *)tzram_get_segment_pa(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE); uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
mmu_init_table(mmu_l1_tbl, 64); /* 33-bit address space */ mmu_init_table(mmu_l1_tbl, 64); /* 33-bit address space */
mmu_init_table(mmu_l2_tbl, 4096); mmu_init_table(mmu_l2_tbl, 4096);
@ -40,7 +97,7 @@ static void configure_ttbls(void) {
identity_map_all_mappings(mmu_l1_tbl, mmu_l3_tbl); identity_map_all_mappings(mmu_l1_tbl, mmu_l3_tbl);
mmio_map_all_devices(mmu_l3_tbl); mmio_map_all_devices(mmu_l3_tbl);
lp0_map_all_plaintext_ram_segments(mmu_l3_tbl); lp0_entry_map_all_ram_segments(mmu_l3_tbl);
warmboot_map_all_ram_segments(mmu_l3_tbl); warmboot_map_all_ram_segments(mmu_l3_tbl);
tzram_map_all_segments(mmu_l3_tbl); tzram_map_all_segments(mmu_l3_tbl);
} }
@ -48,7 +105,7 @@ static void configure_ttbls(void) {
#if 0 #if 0
static void copy_lma_to_vma(unsigned int segment_id, void *lma, size_t size, bool vma_is_pa) { static void copy_lma_to_vma(unsigned int segment_id, void *lma, size_t size, bool vma_is_pa) {
uintptr_t vma = vma_is_pa ? tzram_get_segment_pa(segment_id) : tzram_get_segment_address(segment_id); uintptr_t vma = vma_is_pa ? TZRAM_GET_SEGMENT_PA(segment_id) : TZRAM_GET_SEGMENT_ADDRESS(segment_id);
uintptr_t vma_offset = (uintptr_t)lma & 0xFFF; uintptr_t vma_offset = (uintptr_t)lma & 0xFFF;
uint64_t *p_vma = (uint64_t *)vma; uint64_t *p_vma = (uint64_t *)vma;
uint64_t *p_lma = (uint64_t *)lma; uint64_t *p_lma = (uint64_t *)lma;
@ -67,7 +124,7 @@ static void __libc_init_array(void) {
#endif #endif
uintptr_t get_coldboot_crt0_stack_address(void) { uintptr_t get_coldboot_crt0_stack_address(void) {
return tzram_get_segment_pa(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800; return TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800;
} }
void coldboot_init(void) { void coldboot_init(void) {

View File

@ -26,8 +26,8 @@ __attribute__((used)) static void __libc_fini_array(void) {
void coldboot_main(void) { void coldboot_main(void) {
#if 0 #if 0
uintptr_t *mmu_l3_table = (uintptr_t *)tzram_get_segment_address(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE); uintptr_t *mmu_l3_table = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
uintptr_t pk2ldr = tzram_get_segment_address(TZRAM_SEGMENT_ID_PK2LDR); uintptr_t pk2ldr = TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_PK2LDR);
/* Clear and unmap pk2ldr (which is reused as exception entry stacks) */ /* Clear and unmap pk2ldr (which is reused as exception entry stacks) */
memset((void *)pk2ldr, 0, __pk2ldr_end__ - __pk2ldr_start__); memset((void *)pk2ldr, 0, __pk2ldr_end__ - __pk2ldr_start__);

View File

@ -23,7 +23,7 @@ void fuse_init(void)
void fuse_make_regs_visible(void) void fuse_make_regs_visible(void)
{ {
/* TODO: Replace this with a proper CLKRST driver */ /* TODO: Replace this with a proper CLKRST driver */
volatile uint32_t* misc_clk_reg = (volatile uint32_t *)mmio_get_device_address(MMIO_DEVID_CLKRST) + 0x48; volatile uint32_t* misc_clk_reg = (volatile uint32_t *)MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_CLKRST) + 0x48;
uint32_t misc_clk_val = *misc_clk_reg; uint32_t misc_clk_val = *misc_clk_reg;
*misc_clk_reg = (misc_clk_val | (1 << 28)); *misc_clk_reg = (misc_clk_val | (1 << 28));
} }

View File

@ -168,8 +168,15 @@ typedef struct {
uint32_t FUSE_SPARE_BIT[0x20]; uint32_t FUSE_SPARE_BIT[0x20];
} fuse_chip_registers_t; } fuse_chip_registers_t;
#define FUSE_REGS ((volatile fuse_registers_t *)(mmio_get_device_address(MMIO_DEVID_FUSE) + 0x800)) static inline volatile fuse_registers_t *get_fuse_regs(void) {
#define FUSE_CHIP_REGS ((volatile fuse_chip_registers_t *)(mmio_get_device_address(MMIO_DEVID_FUSE) + 0x900)) return (volatile fuse_registers_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_FUSE) + 0x800);
}
static inline volatile fuse_chip_registers_t *get_fuse_chip_regs(void) {
return (volatile fuse_chip_registers_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_FUSE) + 0x900);
}
#define FUSE_REGS (get_fuse_regs())
#define FUSE_CHIP_REGS (get_fuse_chip_regs())
void fuse_init(void); void fuse_init(void);

View File

@ -18,7 +18,7 @@ static void shr_128(uint64_t *val) {
/* Shifts left a little endian 128-bit value. */ /* Shifts left a little endian 128-bit value. */
static void shl_128(uint64_t *val) { static void shl_128(uint64_t *val) {
val[1] <<= 1; val[1] <<= 1;
val[1] |= (val[0] & (1ULL << 63)) >> 63; val[1] |= (val[0] & (1ull << 63)) >> 63;
val[0] <<= 1; val[0] <<= 1;
} }

View File

@ -51,13 +51,20 @@ typedef struct {
uint32_t I2C_I2C_HS_INTERFACE_TIMING_1_0; uint32_t I2C_I2C_HS_INTERFACE_TIMING_1_0;
} i2c_registers_t; } i2c_registers_t;
static inline uintptr_t get_i2c_dtv_234_base(void) {
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DTV_I2C234);
}
#define I2C1_REGS ((volatile i2c_registers_t *)(mmio_get_device_address(MMIO_DEVID_DTV_I2C234) + 0x000)) static inline uintptr_t get_i2c56_spi2b_base(void) {
#define I2C2_REGS ((volatile i2c_registers_t *)(mmio_get_device_address(MMIO_DEVID_DTV_I2C234) + 0x400)) return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_I2C56_SPI2B);
#define I2C3_REGS ((volatile i2c_registers_t *)(mmio_get_device_address(MMIO_DEVID_DTV_I2C234) + 0x500)) }
#define I2C4_REGS ((volatile i2c_registers_t *)(mmio_get_device_address(MMIO_DEVID_DTV_I2C234) + 0x700))
#define I2C5_REGS ((volatile i2c_registers_t *)(mmio_get_device_address(MMIO_DEVID_I2C56_SPI2B) + 0x000)) #define I2C1_REGS ((volatile i2c_registers_t *)(get_i2c_dtv_234_base() + 0x000))
#define I2C6_REGS ((volatile i2c_registers_t *)(mmio_get_device_address(MMIO_DEVID_I2C56_SPI2B) + 0x100)) #define I2C2_REGS ((volatile i2c_registers_t *)(get_i2c_dtv_234_base() + 0x400))
#define I2C3_REGS ((volatile i2c_registers_t *)(get_i2c_dtv_234_base() + 0x500))
#define I2C4_REGS ((volatile i2c_registers_t *)(get_i2c_dtv_234_base() + 0x700))
#define I2C5_REGS ((volatile i2c_registers_t *)(get_i2c56_spi2b_base() + 0x000))
#define I2C6_REGS ((volatile i2c_registers_t *)(get_i2c56_spi2b_base() + 0x100))
void i2c_init(unsigned int id); void i2c_init(unsigned int id);

View File

@ -11,21 +11,29 @@
#define INTERRUPT_ID_SECURITY_ENGINE 0x5A #define INTERRUPT_ID_SECURITY_ENGINE 0x5A
#define INTERRUPT_ID_USER_SECURITY_ENGINE 0x2C #define INTERRUPT_ID_USER_SECURITY_ENGINE 0x2C
#define GICD_BASE (mmio_get_device_address(MMIO_DEVID_GICD)) static inline uintptr_t get_gicd_base(void) {
#define GICC_BASE (mmio_get_device_address(MMIO_DEVID_GICC)) return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_GICD);
}
#define GICD_IGROUPR ((volatile uint32_t *)(GICD_BASE + 0x080ULL)) static inline uintptr_t get_gicc_base(void) {
#define GICD_ISENABLER ((volatile uint32_t *)(GICD_BASE + 0x100ULL)) return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_GICC);
#define GICD_ISPENDR ((volatile uint32_t *)(GICD_BASE + 0x200ULL)) }
#define GICD_IPRIORITYR ((volatile uint8_t *)(GICD_BASE + 0x400ULL))
#define GICD_ITARGETSR ((volatile uint8_t *)(GICD_BASE + 0x800ULL))
#define GICD_ICFGR ((volatile uint32_t *)(GICD_BASE + 0xC00ULL))
#define GICC_CTLR (*((volatile uint32_t *)(GICC_BASE + 0x0000ULL))) #define GICD_BASE (get_gicd_base())
#define GICC_PMR (*((volatile uint32_t *)(GICC_BASE + 0x0004ULL))) #define GICC_BASE (get_gicc_base())
#define GICC_BPR (*((volatile uint32_t *)(GICC_BASE + 0x0008ULL)))
#define GICD_IGROUPR ((volatile uint32_t *)(GICD_BASE + 0x080ull))
#define GICD_ISENABLER ((volatile uint32_t *)(GICD_BASE + 0x100ull))
#define GICD_ISPENDR ((volatile uint32_t *)(GICD_BASE + 0x200ull))
#define GICD_IPRIORITYR ((volatile uint8_t *)(GICD_BASE + 0x400ull))
#define GICD_ITARGETSR ((volatile uint8_t *)(GICD_BASE + 0x800ull))
#define GICD_ICFGR ((volatile uint32_t *)(GICD_BASE + 0xC00ull))
#define GICC_CTLR (*((volatile uint32_t *)(GICC_BASE + 0x0000ull)))
#define GICC_PMR (*((volatile uint32_t *)(GICC_BASE + 0x0004ull)))
#define GICC_BPR (*((volatile uint32_t *)(GICC_BASE + 0x0008ull)))
#define GICC_IAR (*((volatile uint32_t *)(GICC_BASE + 0x000CULL))) #define GICC_IAR (*((volatile uint32_t *)(GICC_BASE + 0x000CULL)))
#define GICC_EOIR (*((volatile uint32_t *)(GICC_BASE + 0x0010ULL))) #define GICC_EOIR (*((volatile uint32_t *)(GICC_BASE + 0x0010ull)))
#define GIC_PRI_HIGHEST_SECURE 0x00 #define GIC_PRI_HIGHEST_SECURE 0x00
#define GIC_PRI_HIGHEST_NONSECURE 0x80 #define GIC_PRI_HIGHEST_NONSECURE 0x80

View File

@ -5,7 +5,7 @@
volatile security_carveout_t *get_carveout_by_id(unsigned int carveout) { volatile security_carveout_t *get_carveout_by_id(unsigned int carveout) {
if (CARVEOUT_ID_MIN <= carveout && carveout <= CARVEOUT_ID_MAX) { if (CARVEOUT_ID_MIN <= carveout && carveout <= CARVEOUT_ID_MAX) {
return (volatile security_carveout_t *)(MC_BASE + 0xC08ULL + 0x50 * (carveout - CARVEOUT_ID_MIN)); return (volatile security_carveout_t *)(MC_BASE + 0xC08ull + 0x50 * (carveout - CARVEOUT_ID_MIN));
} }
generic_panic(); generic_panic();
return NULL; return NULL;

View File

@ -6,7 +6,11 @@
/* Exosphere driver for the Tegra X1 Memory Controller. */ /* Exosphere driver for the Tegra X1 Memory Controller. */
#define MC_BASE (mmio_get_device_address(MMIO_DEVID_MC)) static inline uintptr_t get_mc_base(void) {
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_MC);
}
#define MC_BASE (get_mc_base())
#define CARVEOUT_ID_MIN 1 #define CARVEOUT_ID_MIN 1
#define CARVEOUT_ID_MAX 5 #define CARVEOUT_ID_MAX 5

View File

@ -2,86 +2,63 @@
#define EXOSPHERE_MEMORY_MAP_H #define EXOSPHERE_MEMORY_MAP_H
#include "mmu.h" #include "mmu.h"
#include "preprocessor.h"
#define ATTRIB_MEMTYPE_NORMAL MMU_PTE_BLOCK_MEMTYPE(0) #define ATTRIB_MEMTYPE_NORMAL MMU_PTE_BLOCK_MEMTYPE(0)
#define ATTRIB_MEMTYPE_DEVICE MMU_PTE_BLOCK_MEMTYPE(1) #define ATTRIB_MEMTYPE_DEVICE MMU_PTE_BLOCK_MEMTYPE(1)
static const struct { /* Identity mappings (addr, size, additional attributes, is block range) */
uintptr_t address; #define _MMAPID0 ( 0x40020000ull, 0x20000ull, 0ull, false ) /* iRAM-C+D (contains the secmon's coldboot crt0) */
uint64_t size; #define _MMAPID1 ( 0x7C010000ull, 0x10000ull, 0ull, false ) /* TZRAM (contains the secmon's warmboot crt0) */
uint64_t attributes; #define _MMAPID2 ( 0x80000000ull, 4ull << 30, MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_NS, true ) /* DRAM (4GB) */
bool is_block_range;
} g_identity_mappings[] = {
{ 0x40020000, 0x20000, 0, false }, /* iRAM-C+D (contains the secmon's coldboot crt0) */
{ 0x7C010000, 0x10000, 0, false }, /* TZRAM (contains the secmon's warmboot crt0) */
{ 0x80000000, 4u << 30, MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_NS, true }, /* DRAM (4GB) */
};
static const struct { /* MMIO (addr, size, is secure) */
uintptr_t pa; #define _MMAPDEV0 ( 0x50041000ull, 0x1000ull, true ) /* ARM Interrupt Distributor */
size_t size; #define _MMAPDEV1 ( 0x50042000ull, 0x2000ull, true ) /* Interrupt Controller Physical CPU interface */
bool is_secure; #define _MMAPDEV2 ( 0x70006000ull, 0x1000ull, false ) /* UART-A */
} g_devices[] = { #define _MMAPDEV3 ( 0x60006000ull, 0x1000ull, false ) /* Clock and Reset */
{ 0x50041000, 0x1000, true }, /* ARM Interrupt Distributor */ #define _MMAPDEV4 ( 0x7000E000ull, 0x1000ull, true ) /* RTC, PMC */
{ 0x50042000, 0x2000, true }, /* Interrupt Controller Physical CPU interface */ #define _MMAPDEV5 ( 0x60005000ull, 0x1000ull, true ) /* TMRs, WDTs */
{ 0x70006000, 0x1000, false }, /* UART-A */ #define _MMAPDEV6 ( 0x6000C000ull, 0x1000ull, true ) /* System Registers */
{ 0x60006000, 0x1000, false }, /* Clock and Reset */ #define _MMAPDEV7 ( 0x70012000ull, 0x2000ull, true ) /* SE */
{ 0x7000E000, 0x1000, true }, /* RTC, PMC */ #define _MMAPDEV8 ( 0x700F0000ull, 0x1000ull, true ) /* SYSCTR0 */
{ 0x60005000, 0x1000, true }, /* TMRs, WDTs */ #define _MMAPDEV9 ( 0x70019000ull, 0x1000ull, true ) /* MC */
{ 0x6000C000, 0x1000, true }, /* System Registers */ #define _MMAPDEV10 ( 0x7000F000ull, 0x1000ull, true ) /* FUSE (0x7000F800) */
{ 0x70012000, 0x2000, true }, /* SE */ #define _MMAPDEV11 ( 0x70000000ull, 0x4000ull, true ) /* MISC */
{ 0x700F0000, 0x1000, true }, /* SYSCTR0 */ #define _MMAPDEV12 ( 0x60007000ull, 0x1000ull, true ) /* Flow Controller */
{ 0x70019000, 0x1000, true }, /* MC */ #define _MMAPDEV13 ( 0x40002000ull, 0x1000ull, true ) /* NX bootloader mailbox page */
{ 0x7000F000, 0x1000, true }, /* FUSE (0x7000F800) */ #define _MMAPDEV14 ( 0x7000D000ull, 0x1000ull, true ) /* I2C-5,6 - SPI 2B-1 to 4 */
{ 0x70000000, 0x4000, true }, /* MISC */ #define _MMAPDEV15 ( 0x6000D000ull, 0x1000ull, true ) /* GPIO-1 - GPIO-8 */
{ 0x60007000, 0x1000, true }, /* Flow Controller */ #define _MMAPDEV16 ( 0x7000C000ull, 0x1000ull, true ) /* I2C-I2C4 */
{ 0x40002000, 0x1000, true }, /* NX bootloader mailbox page */ #define _MMAPDEV17 ( 0x6000F000ull, 0x1000ull, true ) /* Exception vectors */
{ 0x7000D000, 0x1000, true }, /* I2C-5,6 - SPI 2B-1 to 4 */
{ 0x6000D000, 0x1000, true }, /* GPIO-1 - GPIO-8 */
{ 0x7000C000, 0x1000, true }, /* I2C-I2C4 */
{ 0x6000F000, 0x1000, true }, /* Exception vectors */
};
static const struct { /* LP0 entry ram segments (addr, size, additional attributes) */
uintptr_t pa; #define _MMAPLP0ES0 ( 0x40020000ull, 0x10000ull, MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_DEVICE ) /* Encrypted TZRAM */
size_t size; #define _MMAPLP0ES1 ( 0x40003000ull, 0x01000ull, MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_DEVICE ) /* LP0 entry code */
uint64_t attributes; #define _MMAPLP0ES2 ( 0x7C010000ull, 0x10000ull, MMU_AP_PRIV_RO | ATTRIB_MEMTYPE_NORMAL ) /* TZRAM to encrypt */
} g_lp0_entry_ram_segments[] = {
{ 0x40020000, 0x10000, MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_DEVICE }, /* Encrypted TZRAM */
{ 0x40003000, 0x01000, MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_DEVICE }, /* LP0 entry code */
{ 0x7C010000, 0x10000, MMU_AP_PRIV_RO | ATTRIB_MEMTYPE_NORMAL }, /* TZRAM to encrypt */
};
static const struct { /* Warmboot data ram segments (addr, size, additional attributes) */
uintptr_t pa; #define _MMAPWBS0 ( 0x8000F000ull, 0x01000ull, MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_DEVICE ) /* Encrypted SE state for bootROM */
size_t size; #define _MMAPWBS1 ( 0x80010000ull, 0x10000ull, MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_DEVICE ) /* Encrypted TZRAM for warmboot.bin */
uint64_t attributes;
} g_warmboot_ram_segments[] = {
{ 0x8000F000, 0x01000, MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_DEVICE }, /* Encrypted SE state for bootROM */
{ 0x80010000, 0x10000, MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_DEVICE }, /* Encrypted TZRAM for warmboot.bin */
};
static const struct { /* TZRAM segments (offset, size, VA increment, is executable) */
size_t tzram_offset; #define _MMAPTZS0 ( 0x3000ull, 0x10000 - 0x2000 - 0x3000ull, 0x10000ull, true ) /* Warmboot crt0 sections and main code segment */
size_t map_size; #define _MMAPTZS1 ( 0x10000 - 0x2000ull, 0x2000ull, 0x04000ull, true ) /* pk2ldr segment */
size_t increment; /* for alignment, guard pages, etc. */ #define _MMAPTZS2 ( 0ull, 0ull, 0x02000ull, false ) /* SPL .bss buffer, NOT mapped at startup */
bool is_code_segment; /* note: code is RWX */ #define _MMAPTZS3 ( 0x10000 - 0x2000ull, 0x1000ull, 0x02000ull, false ) /* Core 0ull1,2 stack */
} g_tzram_segments[] = { #define _MMAPTZS4 ( 0x10000 - 0x1000ull, 0x1000ull, 0x02000ull, false ) /* Core 3 stack */
{ 0x3000, 0x10000 - 0x2000 - 0x3000, 0x10000, true }, /* Warmboot crt0 sections and main code segment */ #define _MMAPTZS5 ( 0ull, 0x1000ull, 0x02000ull, true ) /* Secure Monitor exception vectors, some init stacks */
{ 0x10000 - 0x2000, 0x2000, 0x04000, true }, /* pk2ldr segment */ #define _MMAPTZS6 ( 0x1000ull, 0x1000ull, 0x02000ull, false ) /* L2 translation table */
{ 0, 0, 0x02000, false }, /* SPL .bss buffer, NOT mapped at startup */ #define _MMAPTZS7 ( 0x2000ull, 0x1000ull, 0x02000ull, false ) /* L3 translation table */
{ 0x10000 - 0x2000, 0x1000, 0x02000, false }, /* Core 0,1,2 stack */
{ 0x10000 - 0x1000, 0x1000, 0x02000, false }, /* Core 3 stack */
{ 0, 0x1000, 0x02000, true }, /* Secure Monitor exception vectors, some init stacks */
{ 0x1000, 0x1000, 0x02000, false }, /* L2 translation table */
{ 0x2000, 0x1000, 0x02000, false }, /* L3 translation table */
};
#define MMIO_BASE 0x1F0080000ull #define MMIO_BASE 0x1F0080000ull
#define LP0_ENTRY_RAM_SEGMENT_BASE (MMIO_BASE + 0x000100000) #define LP0_ENTRY_RAM_SEGMENT_BASE (MMIO_BASE + 0x000100000ull)
#define WARMBOOT_RAM_SEGMENT_BASE (LP0_ENTRY_RAM_SEGMENT_BASE + 0x000047000) /* increment seems to be arbitrary ? */ #define WARMBOOT_RAM_SEGMENT_BASE (LP0_ENTRY_RAM_SEGMENT_BASE + 0x000047000ull) /* increment seems to be arbitrary ? */
#define TZRAM_SEGMENT_BASE (MMIO_BASE + 0x0001E0000) #define TZRAM_SEGMENT_BASE (MMIO_BASE + 0x0001E0000ull)
#define IDENTITY_MAPPING_IRAM_CD 0
#define IDENTITY_MAPPING_TZRAM 1
#define IDENTITY_MAPPING_DRAM 2
#define IDENTIY_MAPPING_ID_MAX 3 #define IDENTIY_MAPPING_ID_MAX 3
#define MMIO_DEVID_GICD 0 #define MMIO_DEVID_GICD 0
@ -123,194 +100,70 @@ static const struct {
#define TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE 7 #define TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE 7
#define TZRAM_SEGMENT_ID_MAX 8 #define TZRAM_SEGMENT_ID_MAX 8
/**********************************************************************************************/ #define IDENTITY_GET_MAPPING_ADDRESS(mapping_id) (TUPLE_ELEM_0(CAT(_MMAPID, EVAL(mapping_id))))
#define IDENTITY_GET_MAPPING_SIZE(mapping_id) (TUPLE_ELEM_1(CAT(_MMAPID, EVAL(mapping_id))))
#define IDENTITY_GET_MAPPING_ATTRIBS(mapping_id) (TUPLE_ELEM_2(CAT(_MMAPID, EVAL(mapping_id))))
#define IDENTITY_IS_MAPPING_BLOCK_RANGE(mapping_id) (TUPLE_ELEM_3(CAT(_MMAPID, EVAL(mapping_id))))
INLINE_UNROLL static inline void identity_map_all_mappings(uintptr_t *mmu_l1_tbl, uintptr_t *mmu_l3_tbl) { #define MMIO_GET_DEVICE_PA(device_id) (TUPLE_ELEM_0(CAT(_MMAPDEV, EVAL(device_id))))
static uint64_t base_attributes = MMU_PTE_BLOCK_INNER_SHAREBLE | ATTRIB_MEMTYPE_NORMAL; #define MMIO_GET_DEVICE_ADDRESS(device_id)\
for(size_t i = 0; i < IDENTIY_MAPPING_ID_MAX; i++) { (\
uint64_t attributes = base_attributes | g_identity_mappings[i].attributes; (TUPLE_FOLD_LEFT_1(EVAL(device_id), _MMAPDEV, PLUS) EVAL(MMIO_BASE)) +\
if(g_identity_mappings[i].is_block_range) { 0x1000ull * (device_id)\
mmu_map_block_range(1, mmu_l1_tbl, g_identity_mappings[i].address, g_identity_mappings[i].address, )
g_identity_mappings[i].size, attributes); #define MMIO_GET_DEVICE_SIZE(device_id) (TUPLE_ELEM_1(CAT(_MMAPDEV, EVAL(device_id))))
} #define MMIO_IS_DEVICE_SECURE(device_id) (TUPLE_ELEM_2(CAT(_MMAPDEV, EVAL(device_id))))
else {
mmu_map_page_range(mmu_l3_tbl, g_identity_mappings[i].address, g_identity_mappings[i].address,
g_identity_mappings[i].size, attributes);
}
}
}
INLINE_UNROLL static inline void identity_unmap_all_mappings(uintptr_t *mmu_l1_tbl, uintptr_t *mmu_l3_tbl) { #define LP0_ENTRY_GET_RAM_SEGMENT_PA(segment_id) (TUPLE_ELEM_0(CAT(_MMAPLP0ES, EVAL(segment_id))))
for(size_t i = 0; i < IDENTIY_MAPPING_ID_MAX; i++) { #define LP0_ENTRY_GET_RAM_SEGMENT_ADDRESS(segment_id) (EVAL(LP0_ENTRY_RAM_SEGMENT_BASE) + 0x10000ull * (segment_id))
if(g_identity_mappings[i].is_block_range) { #define LP0_ENTRY_GET_RAM_SEGMENT_SIZE(segment_id) (TUPLE_ELEM_1(CAT(_MMAPLP0ES, EVAL(segment_id))))
mmu_unmap_range(1, mmu_l1_tbl, g_identity_mappings[i].address, g_identity_mappings[i].size); #define LP0_ENTRY_GET_RAM_SEGMENT_ATTRIBS(segment_id) (TUPLE_ELEM_2(CAT(_MMAPLP0ES, EVAL(segment_id))))
}
else { #define WARMBOOT_GET_RAM_SEGMENT_PA(segment_id) (TUPLE_ELEM_0(CAT(_MMAPWBS, EVAL(segment_id))))
mmu_unmap_range(3, mmu_l3_tbl, g_identity_mappings[i].address, g_identity_mappings[i].size); #define WARMBOOT_GET_RAM_SEGMENT_ADDRESS(segment_id) (TUPLE_FOLD_LEFT_1(EVAL(segment_id), _MMAPWBS, PLUS) EVAL(WARMBOOT_RAM_SEGMENT_BASE))
} #define WARMBOOT_GET_RAM_SEGMENT_SIZE(segment_id) (TUPLE_ELEM_1(CAT(_MMAPWBS, EVAL(segment_id))))
} #define WARMBOOT_GET_RAM_SEGMENT_ATTRIBS(segment_id) (TUPLE_ELEM_2(CAT(_MMAPWBS, EVAL(segment_id))))
}
#define TZRAM_GET_SEGMENT_PA(segment_id) (0x7C010000ull + (TUPLE_ELEM_0(CAT(_MMAPTZS, EVAL(segment_id)))))
#define TZRAM_GET_SEGMENT_ADDRESS(segment_id) (TUPLE_FOLD_LEFT_2(EVAL(segment_id), _MMAPTZS, PLUS) EVAL(TZRAM_SEGMENT_BASE))
#define TZRAM_GET_SEGMENT_SIZE(segment_id) (TUPLE_ELEM_1(CAT(_MMAPTZS, EVAL(segment_id))))
#define TZRAM_IS_SEGMENT_EXECUTABLE(segment_id) (TUPLE_ELEM_3(CAT(_MMAPTZS, EVAL(segment_id))))
/**********************************************************************************************/ /**********************************************************************************************/
/* We don't need unmapping functions */
INLINE_UNROLL static inline uintptr_t mmio_get_device_pa(unsigned int device_id) { ALINLINE static inline void identity_map_mapping(uintptr_t *mmu_l1_tbl, uintptr_t *mmu_l3_tbl, uintptr_t addr, size_t size, uint64_t attribs, bool is_block_range) {
return g_devices[device_id].pa; if (is_block_range) {
} mmu_map_block_range(1, mmu_l1_tbl, addr, addr, size, attribs | MMU_PTE_BLOCK_INNER_SHAREBLE | ATTRIB_MEMTYPE_NORMAL);
}
#ifndef MEMORY_MAP_USE_IDENTIY_MAPPING else {
INLINE_UNROLL static inline uintptr_t mmio_get_device_address(unsigned int device_id) { mmu_map_page_range(mmu_l3_tbl, addr, addr, size, attribs | MMU_PTE_BLOCK_INNER_SHAREBLE | ATTRIB_MEMTYPE_NORMAL);
size_t offset = 0;
for(unsigned int i = 0; i < device_id; i++) {
offset += g_devices[i].size;
offset += 0x1000; /* guard page */
} }
return MMIO_BASE + offset;
} }
ALINLINE static inline void mmio_map_device(uintptr_t *mmu_l3_tbl, uintptr_t addr, uintptr_t pa, size_t size, bool is_secure) {
#else
INLINE_UNROLL static inline uintptr_t mmio_get_device_address(unsigned int device_id) {
return mmio_get_device_pa(device_id);
}
#endif
INLINE_UNROLL static inline void mmio_map_all_devices(uintptr_t *mmu_l3_tbl) {
static const uint64_t secure_device_attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | ATTRIB_MEMTYPE_DEVICE; static const uint64_t secure_device_attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | ATTRIB_MEMTYPE_DEVICE;
static const uint64_t device_attributes = MMU_PTE_BLOCK_NS | secure_device_attributes; static const uint64_t device_attributes = MMU_PTE_BLOCK_NS | secure_device_attributes;
for(size_t i = 0, offset = 0; i < MMIO_DEVID_MAX; i++) { uint64_t attributes = is_secure ? secure_device_attributes : device_attributes;
uint64_t attributes = g_devices[i].is_secure ? secure_device_attributes : device_attributes; mmu_map_page_range(mmu_l3_tbl, addr, pa, size, attributes);
mmu_map_page_range(mmu_l3_tbl, MMIO_BASE + offset, g_devices[i].pa, g_devices[i].size, attributes);
offset += g_devices[i].size;
offset += 0x1000; /* insert guard page */
}
} }
INLINE_UNROLL static inline void mmio_unmap_all_devices(uintptr_t *mmu_l3_tbl) { ALINLINE static inline void lp0_entry_map_ram_segment(uintptr_t *mmu_l3_tbl, uintptr_t addr, uintptr_t pa, size_t size, uint64_t attribs) {
for(size_t i = 0, offset = 0; i < MMIO_DEVID_MAX; i++) { uint64_t attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | attribs;
mmu_unmap_range(3, mmu_l3_tbl, MMIO_BASE + offset, g_devices[i].size);
offset += g_devices[i].size; mmu_map_page_range(mmu_l3_tbl, addr, pa, size, attributes);
offset += 0x1000; /* insert guard page */
}
} }
/**********************************************************************************************/ ALINLINE static inline void warmboot_map_ram_segment(uintptr_t *mmu_l3_tbl, uintptr_t addr, uintptr_t pa, size_t size, uint64_t attribs) {
uint64_t attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | attribs;
INLINE_UNROLL static inline uintptr_t lp0_get_plaintext_ram_segment_pa(unsigned int segment_id) { mmu_map_page_range(mmu_l3_tbl, addr, pa, size, attributes);
return g_lp0_entry_ram_segments[segment_id].pa;
} }
#ifndef MEMORY_MAP_USE_IDENTIY_MAPPING ALINLINE static inline void tzram_map_segment(uintptr_t *mmu_l3_tbl, uintptr_t addr, uintptr_t pa, size_t size, bool is_executable) {
INLINE_UNROLL static inline uintptr_t lp0_get_plaintext_ram_segment_address(unsigned int segment_id) { uint64_t attributes = (is_executable ? 0 : MMU_PTE_BLOCK_XN) | MMU_PTE_BLOCK_INNER_SHAREBLE | ATTRIB_MEMTYPE_NORMAL;
return LP0_ENTRY_RAM_SEGMENT_BASE + 0x10000 * segment_id;
}
#else
INLINE_UNROLL static inline uintptr_t lp0_get_plaintext_ram_segment_address(unsigned int segment_id) {
return lp0_get_plaintext_ram_segment_pa(segment_id);
}
#endif
INLINE_UNROLL static inline void lp0_map_all_plaintext_ram_segments(uintptr_t *mmu_l3_tbl) { mmu_map_page_range(mmu_l3_tbl, addr, pa, size, attributes);
for(size_t i = 0, offset = 0; i < LP0_ENTRY_RAM_SEGMENT_ID_MAX; i++) {
uint64_t attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | g_lp0_entry_ram_segments[i].attributes;
mmu_map_page_range(mmu_l3_tbl, LP0_ENTRY_RAM_SEGMENT_BASE + offset, g_lp0_entry_ram_segments[i].pa,
g_lp0_entry_ram_segments[i].size, attributes);
offset += 0x10000;
}
}
INLINE_UNROLL static inline void lp0_unmap_all_plaintext_ram_segments(uintptr_t *mmu_l3_tbl) {
for(size_t i = 0, offset = 0; i < LP0_ENTRY_RAM_SEGMENT_ID_MAX; i++) {
mmu_unmap_range(3, mmu_l3_tbl, LP0_ENTRY_RAM_SEGMENT_BASE + offset, g_lp0_entry_ram_segments[i].size);
offset += 0x10000;
}
}
/**********************************************************************************************/
INLINE_UNROLL static inline uintptr_t warmboot_get_ram_segment_pa(unsigned int segment_id) {
return g_warmboot_ram_segments[segment_id].pa;
}
#ifndef MEMORY_MAP_USE_IDENTIY_MAPPING
INLINE_UNROLL static inline uintptr_t warmboot_get_ram_segment_address(unsigned int segment_id) {
size_t offset = 0;
for(unsigned int i = 0; i < segment_id; i++) {
offset += g_warmboot_ram_segments[i].size;
}
return WARMBOOT_RAM_SEGMENT_BASE + offset;
}
#else
INLINE_UNROLL static inline uintptr_t warmboot_get_ram_segment_address(unsigned int segment_id) {
return warmboot_get_ram_segment_pa(segment_id);
}
#endif
INLINE_UNROLL static inline void warmboot_map_all_ram_segments(uintptr_t *mmu_l3_tbl) {
for(size_t i = 0, offset = 0; i < WARMBOOT_RAM_SEGMENT_ID_MAX; i++) {
uint64_t attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | g_warmboot_ram_segments[i].attributes;
mmu_map_page_range(mmu_l3_tbl, WARMBOOT_RAM_SEGMENT_BASE + offset, g_warmboot_ram_segments[i].pa,
g_warmboot_ram_segments[i].size, attributes);
offset += g_warmboot_ram_segments[i].size;
}
}
INLINE_UNROLL static inline void warmboot_unmap_all_ram_segments(uintptr_t *mmu_l3_tbl) {
for(size_t i = 0, offset = 0; i < WARMBOOT_RAM_SEGMENT_ID_MAX; i++) {
mmu_unmap_range(3, mmu_l3_tbl, WARMBOOT_RAM_SEGMENT_BASE + offset, g_warmboot_ram_segments[i].size);
offset += g_warmboot_ram_segments[i].size;
}
}
/**********************************************************************************************/
INLINE_UNROLL static inline uintptr_t tzram_get_segment_pa(unsigned int segment_id) {
return 0x7C010000 + g_tzram_segments[segment_id].tzram_offset;
}
#ifndef MEMORY_MAP_USE_IDENTIY_MAPPING
INLINE_UNROLL static inline uintptr_t tzram_get_segment_address(unsigned int segment_id) {
size_t offset = 0;
for(unsigned int i = 0; i < segment_id; i++) {
offset += g_tzram_segments[i].increment;
}
return TZRAM_SEGMENT_BASE + offset;
}
#else
INLINE_UNROLL static inline uintptr_t tzram_get_segment_address(unsigned int segment_id) {
return tzram_get_segment_pa(segment_id);
}
#endif
INLINE_UNROLL static inline void tzram_map_all_segments(uintptr_t *mmu_l3_tbl) {
/* Except the SPL userpage */
for(size_t i = 0, offset = 0; i < TZRAM_SEGMENT_ID_MAX; i++) {
uint64_t attributes = (g_tzram_segments[i].is_code_segment ? 0 : MMU_PTE_BLOCK_XN) | MMU_PTE_BLOCK_INNER_SHAREBLE | ATTRIB_MEMTYPE_NORMAL;
if(g_tzram_segments[i].map_size == 0) {
continue;
}
mmu_map_page_range(mmu_l3_tbl, TZRAM_SEGMENT_BASE + offset, 0x7C010000 + g_tzram_segments[i].tzram_offset,
g_tzram_segments[i].map_size, attributes);
offset += g_tzram_segments[i].increment;
}
}
INLINE_UNROLL static inline void tzram_unmap_all_segments(uintptr_t *mmu_l3_tbl) {
/* Except the SPL userpage */
for(size_t i = 0, offset = 0; i < TZRAM_SEGMENT_ID_MAX; i++) {
if(g_tzram_segments[i].map_size == 0) {
continue;
}
mmu_unmap_range(3, mmu_l3_tbl, TZRAM_SEGMENT_BASE + offset, g_tzram_segments[i].map_size);
offset += g_tzram_segments[i].increment;
}
} }
#endif #endif

View File

@ -13,14 +13,14 @@
#if MMU_GRANULE_TYPE == 0 #if MMU_GRANULE_TYPE == 0
#define MMU_Lx_SHIFT(x) (12 + 9 * (3 - (x))) #define MMU_Lx_SHIFT(x) (12 + 9 * (3 - (x)))
#define MMU_Lx_MASK(x) (BIT(9) - 1) #define MMU_Lx_MASK(x) (BITL(9) - 1)
#elif MMU_GRANULE_TYPE == 1 #elif MMU_GRANULE_TYPE == 1
/* 64 KB, no L0 here */ /* 64 KB, no L0 here */
#define MMU_Lx_SHIFT(x) (16 + 13 * (3 - (x))) #define MMU_Lx_SHIFT(x) (16 + 13 * (3 - (x)))
#define MMU_Lx_MASK(x) ((x) == 1 ? (BIT(5) - 1) : (BIT(13) - 1)) #define MMU_Lx_MASK(x) ((x) == 1 ? (BITL(5) - 1) : (BITL(13) - 1))
#elif MMU_GRANULE_TYPE == 2 #elif MMU_GRANULE_TYPE == 2
#define MMU_Lx_SHIFT(x) (14 + 11 * (3 - (x))) #define MMU_Lx_SHIFT(x) (14 + 11 * (3 - (x)))
#define MMU_Lx_MASK(x) ((x) == 0 ? 1 : (BIT(11) - 1)) #define MMU_Lx_MASK(x) ((x) == 0 ? 1 : (BITL(11) - 1))
#endif #endif
/* /*
@ -32,24 +32,24 @@
* SPDX-License-Identifier: GPL-2.0+ * SPDX-License-Identifier: GPL-2.0+
*/ */
#define MMU_MT_DEVICE_NGNRNE 0 #define MMU_MT_DEVICE_NGNRNE 0ull
#define MMU_MT_DEVICE_NGNRE 1 #define MMU_MT_DEVICE_NGNRE 1ull
#define MMU_MT_DEVICE_GRE 2 #define MMU_MT_DEVICE_GRE 2ull
#define MMU_MT_NORMAL_NC 3 #define MMU_MT_NORMAL_NC 3ull
#define MMU_MT_NORMAL 4 #define MMU_MT_NORMAL 4ull
/* /*
* Hardware page table definitions. * Hardware page table definitions.
* *
*/ */
#define MMU_PTE_TYPE_MASK 3 #define MMU_PTE_TYPE_MASK 3ull
#define MMU_PTE_TYPE_FAULT 0 #define MMU_PTE_TYPE_FAULT 0ull
#define MMU_PTE_TYPE_TABLE 3 #define MMU_PTE_TYPE_TABLE 3ull
#define MMU_PTE_TYPE_BLOCK 1 #define MMU_PTE_TYPE_BLOCK 1ull
/* L3 only */ /* L3 only */
#define MMU_PTE_TYPE_PAGE 3 #define MMU_PTE_TYPE_PAGE 3ull
#define MMU_PTE_TABLE_PXN BITL(59) #define MMU_PTE_TABLE_PXN BITL(59)
#define MMU_PTE_TABLE_XN BITL(60) #define MMU_PTE_TABLE_XN BITL(60)
@ -59,13 +59,13 @@
/* /*
* Block * Block
*/ */
#define MMU_PTE_BLOCK_MEMTYPE(x) ((x) << 2) #define MMU_PTE_BLOCK_MEMTYPE(x) ((uint64_t)((x) << 2))
#define MMU_PTE_BLOCK_NS BIT(5) #define MMU_PTE_BLOCK_NS BITL(5)
#define MMU_PTE_BLOCK_NON_SHAREABLE (0 << 8) #define MMU_PTE_BLOCK_NON_SHAREABLE (0ull << 8)
#define MMU_PTE_BLOCK_OUTER_SHAREABLE (2 << 8) #define MMU_PTE_BLOCK_OUTER_SHAREABLE (2ull << 8)
#define MMU_PTE_BLOCK_INNER_SHAREBLE (3 << 8) #define MMU_PTE_BLOCK_INNER_SHAREBLE (3ull << 8)
#define MMU_PTE_BLOCK_AF BIT(10) #define MMU_PTE_BLOCK_AF BITL(10)
#define MMU_PTE_BLOCK_NG BIT(11) #define MMU_PTE_BLOCK_NG BITL(11)
#define MMU_PTE_BLOCK_PXN BITL(53) #define MMU_PTE_BLOCK_PXN BITL(53)
#define MMU_PTE_BLOCK_UXN BITL(54) #define MMU_PTE_BLOCK_UXN BITL(54)
#define MMU_PTE_BLOCK_XN MMU_PTE_BLOCK_UXN #define MMU_PTE_BLOCK_XN MMU_PTE_BLOCK_UXN
@ -73,24 +73,24 @@
/* /*
* AP[2:1] * AP[2:1]
*/ */
#define MMU_AP_PRIV_RW (0 << 6) #define MMU_AP_PRIV_RW (0ull << 6)
#define MMU_AP_RW (1 << 6) #define MMU_AP_RW (1ull << 6)
#define MMU_AP_PRIV_RO (2 << 6) #define MMU_AP_PRIV_RO (2ull << 6)
#define MMU_AP_RO (3 << 6) #define MMU_AP_RO (3ull << 6)
/* /*
* S2AP[2:1] (for stage2 translations; secmon doesn't use it) * S2AP[2:1] (for stage2 translations; secmon doesn't use it)
*/ */
#define MMU_S2AP_NONE (0 << 6) #define MMU_S2AP_NONE (0ull << 6)
#define MMU_S2AP_RO (1 << 6) #define MMU_S2AP_RO (1ull << 6)
#define MMU_S2AP_WO (2 << 6) #define MMU_S2AP_WO (2ull << 6)
#define MMU_S2AP_RW (3 << 6) #define MMU_S2AP_RW (3ull << 6)
/* /*
* AttrIndx[2:0] * AttrIndx[2:0]
*/ */
#define MMU_PMD_ATTRINDX(t) ((t) << 2) #define MMU_PMD_ATTRINDX(t) ((uint64_t)((t) << 2))
#define MMU_PMD_ATTRINDX_MASK (7 << 2) #define MMU_PMD_ATTRINDX_MASK (7ull << 2)
/* /*
* TCR flags. * TCR flags.

View File

@ -21,7 +21,7 @@ static void setup_se(void) {
se_clear_interrupts(); se_clear_interrupts();
/* Perform some sanity initialization. */ /* Perform some sanity initialization. */
volatile security_engine_t *p_security_engine = get_security_engine_address(); volatile security_engine_t *p_security_engine = get_security_engine();
p_security_engine->_0x4 = 0; p_security_engine->_0x4 = 0;
p_security_engine->AES_KEY_READ_DISABLE_REG = 0; p_security_engine->AES_KEY_READ_DISABLE_REG = 0;
p_security_engine->RSA_KEY_READ_DISABLE_REG = 0; p_security_engine->RSA_KEY_READ_DISABLE_REG = 0;
@ -372,7 +372,7 @@ static void load_package2_sections(package2_meta_t *metadata, uint32_t master_ke
} }
uintptr_t get_pk2ldr_stack_address(void) { uintptr_t get_pk2ldr_stack_address(void) {
return tzram_get_segment_address(TZRAM_SEGMENT_ID_PK2LDR) + 0x2000; return TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_PK2LDR) + 0x2000;
} }
/* This function is called during coldboot init, and validates a package2. */ /* This function is called during coldboot init, and validates a package2. */

View File

@ -8,9 +8,13 @@
#include "memory_map.h" #include "memory_map.h"
/* Physaddr 0x40002EF8 */ /* Physaddr 0x40002EF8 */
#define MAILBOX_NX_BOOTLOADER_BASE (mmio_get_device_address(MMIO_DEVID_NXBOOTLOADER_MAILBOX)) static inline uintptr_t get_nx_bootloader_mailbox_base(void) {
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_NXBOOTLOADER_MAILBOX);
}
#define MAILBOX_NX_BOOTLOADER_SETUP_STATE (*((volatile uint32_t *)(MAILBOX_NX_BOOTLOADER_BASE + 0xEF8ULL))) #define MAILBOX_NX_BOOTLOADER_BASE (get_nx_bootloader_mailbox_base())
#define MAILBOX_NX_BOOTLOADER_SETUP_STATE (*((volatile uint32_t *)(MAILBOX_NX_BOOTLOADER_BASE + 0xEF8ull)))
#define NX_BOOTLOADER_STATE_INIT 0 #define NX_BOOTLOADER_STATE_INIT 0
#define NX_BOOTLOADER_STATE_MOVED_BOOTCONFIG 1 #define NX_BOOTLOADER_STATE_MOVED_BOOTCONFIG 1
@ -20,11 +24,11 @@
/* Physaddr 0x40002EFC */ /* Physaddr 0x40002EFC */
#define MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE (*((volatile uint32_t *)(MAILBOX_NX_BOOTLOADER_BASE + 0xEFCULL))) #define MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE (*((volatile uint32_t *)(MAILBOX_NX_BOOTLOADER_BASE + 0xEFCULL)))
#define NX_BOOTLOADER_BOOTCONFIG_POINTER ((void *)(0x4003D000ULL)) #define NX_BOOTLOADER_BOOTCONFIG_POINTER ((void *)(0x4003D000ull))
#define NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS ((void *)(0xA9800000ULL)) #define NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS ((void *)(0xA9800000ull))
#define DRAM_BASE_PHYSICAL (0x80000000ULL) #define DRAM_BASE_PHYSICAL (0x80000000ull)
#define MAGIC_PK21 (0x31324B50) #define MAGIC_PK21 (0x31324B50)
#define PACKAGE2_SIZE_MAX 0x7FC000 #define PACKAGE2_SIZE_MAX 0x7FC000

View File

@ -6,7 +6,11 @@
/* Exosphere register definitions for the Tegra X1 PMC. */ /* Exosphere register definitions for the Tegra X1 PMC. */
#define PMC_BASE (mmio_get_device_address(MMIO_DEVID_RTC_PMC) + 0x400ULL) static inline uintptr_t get_pmc_base(void) {
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull;
}
#define PMC_BASE (get_pmc_base())
#define APBDEV_PMC_DPD_ENABLE_0 (*((volatile uint32_t *)(PMC_BASE + 0x24))) #define APBDEV_PMC_DPD_ENABLE_0 (*((volatile uint32_t *)(PMC_BASE + 0x24)))

View File

@ -0,0 +1,207 @@
/* TuxSH: I added INC/DEC_10 to INC/DEC_32; tuples */
#ifndef EXOSPHERE_PREPROCESSOR_H
#define EXOSPHERE_PREPROCESSOR_H
/*=============================================================================
Copyright (c) 2015 Paul Fultz II
cloak.h
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
/*#ifndef CLOAK_GUARD_H
#define CLOAK_GUARD_H*/
#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
#define COMPL(b) PRIMITIVE_CAT(COMPL_, b)
#define COMPL_0 1
#define COMPL_1 0
#define BITAND(x) PRIMITIVE_CAT(BITAND_, x)
#define BITAND_0(y) 0
#define BITAND_1(y) y
#define INC(x) PRIMITIVE_CAT(INC_, x)
#define INC_0 1
#define INC_1 2
#define INC_2 3
#define INC_3 4
#define INC_4 5
#define INC_5 6
#define INC_6 7
#define INC_7 8
#define INC_8 9
#define INC_9 10
#define INC_10 11
#define INC_11 12
#define INC_12 13
#define INC_13 14
#define INC_14 15
#define INC_15 16
#define INC_16 17
#define INC_17 18
#define INC_18 19
#define INC_19 20
#define INC_20 21
#define INC_21 22
#define INC_22 23
#define INC_23 24
#define INC_24 25
#define INC_25 26
#define INC_26 27
#define INC_27 28
#define INC_28 29
#define INC_29 30
#define INC_30 31
#define INC_31 32
#define INC_32 32
#define INC_33 33
#define DEC(x) PRIMITIVE_CAT(DEC_, x)
#define DEC_0 0
#define DEC_1 0
#define DEC_2 1
#define DEC_3 2
#define DEC_4 3
#define DEC_5 4
#define DEC_6 5
#define DEC_7 6
#define DEC_8 7
#define DEC_9 8
#define DEC_10 9
#define DEC_11 10
#define DEC_12 11
#define DEC_13 12
#define DEC_14 13
#define DEC_15 14
#define DEC_16 15
#define DEC_17 16
#define DEC_18 17
#define DEC_19 18
#define DEC_20 19
#define DEC_21 20
#define DEC_22 21
#define DEC_23 22
#define DEC_24 23
#define DEC_25 24
#define DEC_26 25
#define DEC_27 26
#define DEC_28 27
#define DEC_29 28
#define DEC_30 29
#define DEC_31 30
#define DEC_32 31
#define DEC_33 32
#define CHECK_N(x, n, ...) n
#define CHECK(...) CHECK_N(__VA_ARGS__, 0,)
#define PROBE(x) x, 1,
#define IS_PAREN(x) CHECK(IS_PAREN_PROBE x)
#define IS_PAREN_PROBE(...) PROBE(~)
#define NOT(x) CHECK(PRIMITIVE_CAT(NOT_, x))
#define NOT_0 PROBE(~)
#define COMPL(b) PRIMITIVE_CAT(COMPL_, b)
#define COMPL_0 1
#define COMPL_1 0
#define BOOL(x) COMPL(NOT(x))
#define IIF(c) PRIMITIVE_CAT(IIF_, c)
#define IIF_0(t, ...) __VA_ARGS__
#define IIF_1(t, ...) t
#define IF(c) IIF(BOOL(c))
#define EAT(...)
#define EXPAND(...) __VA_ARGS__
#define WHEN(c) IF(c)(EXPAND, EAT)
#define EMPTY()
#define DEFER(id) id EMPTY()
#define OBSTRUCT(id) id DEFER(EMPTY)()
#define EVAL(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__)))
#define EVAL1(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__)))
#define EVAL2(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__)))
#define EVAL3(...) EVAL4(EVAL4(EVAL4(__VA_ARGS__)))
#define EVAL4(...) EVAL5(EVAL5(EVAL5(__VA_ARGS__)))
#define EVAL5(...) __VA_ARGS__
#define REPEAT(count, macro, ...) \
WHEN(count) \
( \
OBSTRUCT(REPEAT_INDIRECT) () \
( \
DEC(count), macro, __VA_ARGS__ \
) \
OBSTRUCT(macro) \
( \
DEC(count), __VA_ARGS__ \
) \
)
#define REPEAT_INDIRECT() REPEAT
#define WHILE(pred, op, ...) \
IF(pred(__VA_ARGS__)) \
( \
OBSTRUCT(WHILE_INDIRECT) () \
( \
pred, op, op(__VA_ARGS__) \
), \
__VA_ARGS__ \
)
#define WHILE_INDIRECT() WHILE
#define PRIMITIVE_COMPARE(x, y) IS_PAREN \
( \
COMPARE_ ## x ( COMPARE_ ## y) (()) \
)
#define IS_COMPARABLE(x) IS_PAREN( CAT(COMPARE_, x) (()) )
#define NOT_EQUAL(x, y) \
IIF(BITAND(IS_COMPARABLE(x))(IS_COMPARABLE(y)) ) \
( \
PRIMITIVE_COMPARE, \
1 EAT \
)(x, y)
#define EQUAL(x, y) COMPL(NOT_EQUAL(x, y))
#define COMMA() ,
#define COMMA_IF(n) IF(n)(COMMA, EAT)()
#define PLUS() +
#define _TUPLE_ELEM_0(a, ...) a
#define _TUPLE_ELEM_1(a, b, ...) b
#define _TUPLE_ELEM_2(a, b, c, ...) c
#define _TUPLE_ELEM_3(a, b, c, d, ...) d
#define _TUPLE_ELEM_4(a, b, c, d, e, ...) e
#define TUPLE_ELEM_0(T) EVAL(_TUPLE_ELEM_0 T)
#define TUPLE_ELEM_1(T) EVAL(_TUPLE_ELEM_1 T)
#define TUPLE_ELEM_2(T) EVAL(_TUPLE_ELEM_2 T)
#define TUPLE_ELEM_3(T) EVAL(_TUPLE_ELEM_3 T)
#define TUPLE_ELEM_4(T) EVAL(_TUPLE_ELEM_4 T)
#define _TUPLE_FOLD_LEFT_0(i, T, op) (_TUPLE_ELEM_0 CAT(T,i)) op()
#define _TUPLE_FOLD_LEFT_1(i, T, op) (_TUPLE_ELEM_1 CAT(T,i)) op()
#define _TUPLE_FOLD_LEFT_2(i, T, op) (_TUPLE_ELEM_2 CAT(T,i)) op()
#define _TUPLE_FOLD_LEFT_3(i, T, op) (_TUPLE_ELEM_3 CAT(T,i)) op()
#define _TUPLE_FOLD_LEFT_4(i, T, op) (_TUPLE_ELEM_4 CAT(T,i)) op()
#define TUPLE_FOLD_LEFT_0(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_0, T, op))
#define TUPLE_FOLD_LEFT_1(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_1, T, op))
#define TUPLE_FOLD_LEFT_2(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_2, T, op))
#define TUPLE_FOLD_LEFT_3(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_3, T, op))
#define TUPLE_FOLD_LEFT_4(len, T, op) EVAL(REPEAT(len, _TUPLE_FOLD_LEFT_4, T, op))
#endif

View File

@ -7,9 +7,6 @@
#include "cache.h" #include "cache.h"
#include "se.h" #include "se.h"
/* Macro for the SE registers. */
#define SECURITY_ENGINE ((volatile security_engine_t *)(mmio_get_device_address(MMIO_DEVID_SE)))
void trigger_se_rsa_op(void *buf, size_t size); void trigger_se_rsa_op(void *buf, size_t size);
void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size); void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size);
@ -347,7 +344,7 @@ void trigger_se_rsa_op(void *buf, size_t size) {
ll_init(&in_ll, (void *)buf, size); ll_init(&in_ll, (void *)buf, size);
/* Set the input LL. */ /* Set the input LL. */
SECURITY_ENGINE->IN_LL_ADDR_REG = get_physical_address(&in_ll); SECURITY_ENGINE->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll);
/* Set registers for operation. */ /* Set registers for operation. */
SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG; SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG;
@ -366,8 +363,8 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v
ll_init(&out_ll, dst, dst_size); ll_init(&out_ll, dst, dst_size);
/* Set the LLs. */ /* Set the LLs. */
SECURITY_ENGINE->IN_LL_ADDR_REG = get_physical_address(&in_ll); SECURITY_ENGINE->IN_LL_ADDR_REG = (uint32_t) get_physical_address(&in_ll);
SECURITY_ENGINE->OUT_LL_ADDR_REG = get_physical_address(&out_ll); SECURITY_ENGINE->OUT_LL_ADDR_REG = (uint32_t) get_physical_address(&out_ll);
/* Set registers for operation. */ /* Set registers for operation. */
SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG; SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG;

View File

@ -137,11 +137,12 @@ typedef struct {
/* WIP, API subject to change. */ /* WIP, API subject to change. */
static inline volatile security_engine_t *get_security_engine(void) {
static inline volatile security_engine_t *get_security_engine_address(void) { return (volatile security_engine_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_SE));
return (volatile security_engine_t *)(mmio_get_device_address(MMIO_DEVID_SE));
} }
#define SECURITY_ENGINE (get_security_engine())
/* This function MUST be registered to fire on the appropriate interrupt. */ /* This function MUST be registered to fire on the appropriate interrupt. */
void se_operation_completed(void); void se_operation_completed(void);

View File

@ -112,16 +112,16 @@ static atomic_flag g_is_user_smc_in_progress = ATOMIC_FLAG_INIT;
static atomic_flag g_is_priv_smc_in_progress = ATOMIC_FLAG_INIT; static atomic_flag g_is_priv_smc_in_progress = ATOMIC_FLAG_INIT;
uintptr_t get_smc_core012_stack_address(void) { uintptr_t get_smc_core012_stack_address(void) {
return tzram_get_segment_address(TZRAM_SEGMENT_ID_CORE012_STACK) + 0x1000; return TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_CORE012_STACK) + 0x1000;
} }
uintptr_t get_exception_entry_stack_address(unsigned int core_id) { uintptr_t get_exception_entry_stack_address(unsigned int core_id) {
/* For core3, this is also the smc stack */ /* For core3, this is also the smc stack */
if (core_id == 3) { if (core_id == 3) {
return tzram_get_segment_address(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x1000; return TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x1000;
} }
else { else {
return tzram_get_segment_address(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x80 * (core_id + 1); return TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x80 * (core_id + 1);
} }
} }
@ -475,8 +475,8 @@ uint32_t smc_read_write_register(smc_args_t *args) {
} else { } else {
return 2; return 2;
} }
} else if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT && mmio_get_device_pa(MMIO_DEVID_MC) <= address && } else if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT && MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) <= address &&
address < mmio_get_device_pa(MMIO_DEVID_MC) + 0x1000) { address < MMIO_GET_DEVICE_PA(MMIO_DEVID_MC) + MMIO_GET_DEVICE_SIZE(MMIO_DEVID_MC)) {
/* Memory Controller RW supported only on 4.0.0+ */ /* Memory Controller RW supported only on 4.0.0+ */
const uint8_t mc_whitelist[0x68] = { const uint8_t mc_whitelist[0x68] = {
0x9F, 0x31, 0x30, 0x00, 0xF0, 0xFF, 0xF7, 0x01, 0x9F, 0x31, 0x30, 0x00, 0xF0, 0xFF, 0xF7, 0x01,
@ -497,7 +497,7 @@ uint32_t smc_read_write_register(smc_args_t *args) {
uint32_t wl_ind = (offset >> 5); uint32_t wl_ind = (offset >> 5);
/* If address is whitelisted, allow write. */ /* If address is whitelisted, allow write. */
if (wl_ind < sizeof(mc_whitelist) && (mc_whitelist[wl_ind] & (1 << ((offset >> 2) & 0x7)))) { if (wl_ind < sizeof(mc_whitelist) && (mc_whitelist[wl_ind] & (1 << ((offset >> 2) & 0x7)))) {
p_mmio = (volatile uint32_t *)(mmio_get_device_address(MMIO_DEVID_MC) + offset); p_mmio = (volatile uint32_t *)(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_MC) + offset);
} else { } else {
/* These addresses are not allowed by the whitelist. */ /* These addresses are not allowed by the whitelist. */
/* They correspond to SMMU DISABLE for the BPMP, and for APB-DMA. */ /* They correspond to SMMU DISABLE for the BPMP, and for APB-DMA. */

View File

@ -6,7 +6,11 @@
/* Exosphere driver for the Tegra X1 Timers. */ /* Exosphere driver for the Tegra X1 Timers. */
#define TIMERS_BASE (mmio_get_device_address(MMIO_DEVID_TMRs_WDTs)) static inline uintptr_t get_timers_base(void) {
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_TMRs_WDTs);
}
#define TIMERS_BASE (get_timers_base())
#define TIMERUS_CNTR_1US_0 (*((volatile uint32_t *)(TIMERS_BASE + 0x10))) #define TIMERUS_CNTR_1US_0 (*((volatile uint32_t *)(TIMERS_BASE + 0x10)))

View File

@ -8,7 +8,11 @@
/* TODO: Should we bother with support UARTB-D? */ /* TODO: Should we bother with support UARTB-D? */
#define UARTA_BASE (mmio_get_device_address(MMIO_DEVID_UART_A)) static inline uintptr_t get_uarta_base(void) {
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_UART_A);
}
#define UARTA_BASE (get_uarta_base())
#define UART_THR_DLAB_0_0 (*((volatile uint32_t *)(UARTA_BASE + 0x0))) #define UART_THR_DLAB_0_0 (*((volatile uint32_t *)(UARTA_BASE + 0x0)))
#define UART_IER_DLAB_0_0 (*((volatile uint32_t *)(UARTA_BASE + 0x4))) #define UART_IER_DLAB_0_0 (*((volatile uint32_t *)(UARTA_BASE + 0x4)))

View File

@ -5,7 +5,7 @@
#include "memory_map.h" #include "memory_map.h"
#include "cache.h" #include "cache.h"
static uintptr_t g_user_page_user_address = 0ULL; static uintptr_t g_user_page_user_address = 0ull;
static inline uintptr_t get_page_for_address(void *address) { static inline uintptr_t get_page_for_address(void *address) {
return ((uintptr_t)(address)) & ~0xFFFULL; return ((uintptr_t)(address)) & ~0xFFFULL;
@ -15,9 +15,9 @@ static inline uintptr_t get_page_for_address(void *address) {
/* Returns 1 on success, 0 on failure. */ /* Returns 1 on success, 0 on failure. */
bool upage_init(upage_ref_t *upage, void *user_address) { bool upage_init(upage_ref_t *upage, void *user_address) {
upage->user_address = get_page_for_address(user_address); upage->user_address = get_page_for_address(user_address);
upage->secure_monitor_address = 0ULL; upage->secure_monitor_address = 0ull;
if (g_user_page_user_address != 0ULL) { if (g_user_page_user_address != 0ull) {
/* Different physical address indicate SPL was rebooted, or another process got access to svcCallSecureMonitor. Panic. */ /* Different physical address indicate SPL was rebooted, or another process got access to svcCallSecureMonitor. Panic. */
if (g_user_page_user_address != upage->user_address) { if (g_user_page_user_address != upage->user_address) {
generic_panic(); generic_panic();
@ -27,7 +27,7 @@ bool upage_init(upage_ref_t *upage, void *user_address) {
/* Weakly validate SPL's physically random address is in DRAM. */ /* Weakly validate SPL's physically random address is in DRAM. */
if (upage->user_address >> 31) { if (upage->user_address >> 31) {
static const uint64_t userpage_attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_NORMAL; static const uint64_t userpage_attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_NORMAL;
uintptr_t *mmu_l3_tbl = (uintptr_t *)tzram_get_segment_address(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE); uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
g_user_page_user_address = upage->user_address; g_user_page_user_address = upage->user_address;
mmu_map_page(mmu_l3_tbl, USER_PAGE_SECURE_MONITOR_ADDR, upage->user_address, userpage_attributes); mmu_map_page(mmu_l3_tbl, USER_PAGE_SECURE_MONITOR_ADDR, upage->user_address, userpage_attributes);
tlb_invalidate_page_inner_shareable((void *)USER_PAGE_SECURE_MONITOR_ADDR); tlb_invalidate_page_inner_shareable((void *)USER_PAGE_SECURE_MONITOR_ADDR);
@ -35,7 +35,7 @@ bool upage_init(upage_ref_t *upage, void *user_address) {
} }
} }
return upage->secure_monitor_address != 0ULL; return upage->secure_monitor_address != 0ull;
} }
bool user_copy_to_secure(upage_ref_t *upage, void *secure_dst, void *user_src, size_t size) { bool user_copy_to_secure(upage_ref_t *upage, void *secure_dst, void *user_src, size_t size) {

View File

@ -4,7 +4,11 @@
#include "utils.h" #include "utils.h"
#include "memory_map.h" #include "memory_map.h"
#define USER_PAGE_SECURE_MONITOR_ADDR (tzram_get_segment_address(TZRAM_SEGMENT_ID_USERPAGE)) static inline uintptr_t get_user_page_secure_monitor_addr(void) {
return TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_USERPAGE);
}
#define USER_PAGE_SECURE_MONITOR_ADDR (get_user_page_secure_monitor_addr())
typedef struct { typedef struct {
uintptr_t user_address; uintptr_t user_address;

View File

@ -11,7 +11,7 @@
#define ALIGN(m) __attribute__((aligned(m))) #define ALIGN(m) __attribute__((aligned(m)))
#define PACKED __attribute__((packed)) #define PACKED __attribute__((packed))
#define INLINE_UNROLL __attribute__((always_inline, optimize("unroll-all-loops"))) #define ALINLINE __attribute__((always_inline))
void panic(uint32_t code); void panic(uint32_t code);
void generic_panic(void); void generic_panic(void);
@ -21,7 +21,7 @@ static inline uintptr_t get_physical_address(const void *vaddr) {
uintptr_t PAR; uintptr_t PAR;
__asm__ __volatile__ ("at s1e3r, %0" :: "r"(vaddr)); __asm__ __volatile__ ("at s1e3r, %0" :: "r"(vaddr));
__asm__ __volatile__ ("mrs %0, par_el1" : "=r"(PAR)); __asm__ __volatile__ ("mrs %0, par_el1" : "=r"(PAR));
return (PAR & 1) ? 0ULL : (PAR & 0x00000FFFFFFFF000ULL) | ((uintptr_t)vaddr & 0xFFF); return (PAR & 1) ? 0ull : (PAR & 0x00000FFFFFFFF000ull) | ((uintptr_t)vaddr & 0xFFF);
} }
static inline uint32_t read32le(const volatile void *dword, size_t offset) { static inline uint32_t read32le(const volatile void *dword, size_t offset) {

View File

@ -12,5 +12,5 @@ void invalidate_icache_all_tzram_pa(void) {
} }
uintptr_t get_warmboot_crt0_stack_address(void) { uintptr_t get_warmboot_crt0_stack_address(void) {
return tzram_get_segment_pa(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800; return TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800;
} }