mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-23 02:42:09 +00:00
Rewrite the memory map-related code...
...other style fixes, etc.
This commit is contained in:
parent
bda9dcbe73
commit
c7d83c6eb6
26 changed files with 603 additions and 442 deletions
|
@ -58,7 +58,7 @@ $(dir_bpmpfw)/out/bpmpfw.bin: $(dir_bpmpfw)
|
||||||
$(dir_build)/bpmpfw.bin: $(dir_bpmpfw)/out/bpmpfw.bin
|
$(dir_build)/bpmpfw.bin: $(dir_bpmpfw)/out/bpmpfw.bin
|
||||||
@mkdir -p "$(@D)"
|
@mkdir -p "$(@D)"
|
||||||
@cp $< $(@D)
|
@cp $< $(@D)
|
||||||
|
|
||||||
$(dir_build)/%.bin.o: $(dir_build)/%.bin
|
$(dir_build)/%.bin.o: $(dir_build)/%.bin
|
||||||
@$(bin2o)
|
@$(bin2o)
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,68 @@ 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,12 +105,12 @@ 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;
|
||||||
for (size_t i = 0; i < size / 8; i++) {
|
for (size_t i = 0; i < size / 8; i++) {
|
||||||
p_vma[vma_offset / 8 + i] = p_lma[i];
|
p_vma[vma_offset / 8 + i] = p_lma[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
|
|
@ -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__);
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -162,9 +162,9 @@ uint64_t fuse_get_device_id(void) {
|
||||||
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
||||||
}
|
}
|
||||||
derived_lot_code &= 0x03FFFFFF;
|
derived_lot_code &= 0x03FFFFFF;
|
||||||
|
|
||||||
device_id |= y_coord << 0;
|
device_id |= y_coord << 0;
|
||||||
device_id |= x_coord << 9;
|
device_id |= x_coord << 9;
|
||||||
device_id |= wafer_id << 18;
|
device_id |= wafer_id << 18;
|
||||||
device_id |= derived_lot_code << 24;
|
device_id |= derived_lot_code << 24;
|
||||||
device_id |= fab_code << 50;
|
device_id |= fab_code << 50;
|
||||||
|
@ -200,7 +200,7 @@ uint32_t fuse_get_retail_type(void) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */
|
} else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 2; /* IS_RETAIL | DEV_UNIT */
|
return 2; /* IS_RETAIL | DEV_UNIT */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ void fuse_get_hardware_info(void *dst) {
|
||||||
uint32_t lot_code_1 = FUSE_CHIP_REGS->FUSE_LOT_CODE_1 & 0x0FFFFFFF;
|
uint32_t lot_code_1 = FUSE_CHIP_REGS->FUSE_LOT_CODE_1 & 0x0FFFFFFF;
|
||||||
uint32_t fab_code = FUSE_CHIP_REGS->FUSE_FAB_CODE & 0x3F;
|
uint32_t fab_code = FUSE_CHIP_REGS->FUSE_FAB_CODE & 0x3F;
|
||||||
uint32_t vendor_code = FUSE_CHIP_REGS->FUSE_VENDOR_CODE & 0xF;
|
uint32_t vendor_code = FUSE_CHIP_REGS->FUSE_VENDOR_CODE & 0xF;
|
||||||
|
|
||||||
/* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */
|
/* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */
|
||||||
hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse));
|
hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse));
|
||||||
hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2));
|
hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2));
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ static void gf128_mul(uint8_t *dst, const uint8_t *x, const uint8_t *y) {
|
||||||
uint64_t *p_x = (uint64_t *)(&x_work[0]);
|
uint64_t *p_x = (uint64_t *)(&x_work[0]);
|
||||||
uint64_t *p_y = (uint64_t *)(&y_work[0]);
|
uint64_t *p_y = (uint64_t *)(&y_work[0]);
|
||||||
uint64_t *p_dst = (uint64_t *)(&dst_work[0]);
|
uint64_t *p_dst = (uint64_t *)(&dst_work[0]);
|
||||||
|
|
||||||
/* Initialize buffers. */
|
/* Initialize buffers. */
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
for (unsigned int i = 0; i < 0x10; i++) {
|
||||||
x_work[i] = x[0xF-i];
|
x_work[i] = x[0xF-i];
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -16,7 +16,7 @@ void configure_default_carveouts(void) {
|
||||||
volatile security_carveout_t *carveout = get_carveout_by_id(1);
|
volatile security_carveout_t *carveout = get_carveout_by_id(1);
|
||||||
carveout->paddr_low = 0;
|
carveout->paddr_low = 0;
|
||||||
carveout->paddr_high = 0;
|
carveout->paddr_high = 0;
|
||||||
carveout->size_big_pages = 0;
|
carveout->size_big_pages = 0;
|
||||||
carveout->flags_0 = 0;
|
carveout->flags_0 = 0;
|
||||||
carveout->flags_1 = 0;
|
carveout->flags_1 = 0;
|
||||||
carveout->flags_2 = 0;
|
carveout->flags_2 = 0;
|
||||||
|
@ -45,7 +45,7 @@ void configure_default_carveouts(void) {
|
||||||
carveout->flags_8 = 0;
|
carveout->flags_8 = 0;
|
||||||
carveout->flags_9 = 0;
|
carveout->flags_9 = 0;
|
||||||
carveout->allowed_clients = 0x440167E;
|
carveout->allowed_clients = 0x440167E;
|
||||||
|
|
||||||
/* Configure Carveout 3 (UNUSED GPU) */
|
/* Configure Carveout 3 (UNUSED GPU) */
|
||||||
carveout = get_carveout_by_id(3);
|
carveout = get_carveout_by_id(3);
|
||||||
carveout->paddr_low = 0;
|
carveout->paddr_low = 0;
|
||||||
|
@ -62,12 +62,12 @@ void configure_default_carveouts(void) {
|
||||||
carveout->flags_8 = 0;
|
carveout->flags_8 = 0;
|
||||||
carveout->flags_9 = 0;
|
carveout->flags_9 = 0;
|
||||||
carveout->allowed_clients = 0x4401E7E;
|
carveout->allowed_clients = 0x4401E7E;
|
||||||
|
|
||||||
/* Configure default Kernel carveouts based on 2.0.0+. */
|
/* Configure default Kernel carveouts based on 2.0.0+. */
|
||||||
|
|
||||||
/* Configure Carveout 4 (KERNEL_BUILTINS) */
|
/* Configure Carveout 4 (KERNEL_BUILTINS) */
|
||||||
configure_kernel_carveout(5, 0x80060000, KERNEL_CARVEOUT_SIZE_MAX);
|
configure_kernel_carveout(5, 0x80060000, KERNEL_CARVEOUT_SIZE_MAX);
|
||||||
|
|
||||||
/* Configure Carveout 5 (KERNEL_UNUSED) */
|
/* Configure Carveout 5 (KERNEL_UNUSED) */
|
||||||
configure_kernel_carveout(5, 0, 0);
|
configure_kernel_carveout(5, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint6
|
||||||
if (carveout_id != 4 && carveout_id != 5) {
|
if (carveout_id != 4 && carveout_id != 5) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile security_carveout_t *carveout = get_carveout_by_id(carveout_id);
|
volatile security_carveout_t *carveout = get_carveout_by_id(carveout_id);
|
||||||
carveout->paddr_low = (uint32_t)(address & 0xFFFFFFFF);
|
carveout->paddr_low = (uint32_t)(address & 0xFFFFFFFF);
|
||||||
carveout->paddr_high = (uint32_t)(address >> 32);
|
carveout->paddr_high = (uint32_t)(address >> 32);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -2,87 +2,64 @@
|
||||||
#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 IDENTIY_MAPPING_ID_MAX 3
|
#define IDENTITY_MAPPING_IRAM_CD 0
|
||||||
|
#define IDENTITY_MAPPING_TZRAM 1
|
||||||
|
#define IDENTITY_MAPPING_DRAM 2
|
||||||
|
#define IDENTIY_MAPPING_ID_MAX 3
|
||||||
|
|
||||||
#define MMIO_DEVID_GICD 0
|
#define MMIO_DEVID_GICD 0
|
||||||
#define MMIO_DEVID_GICC 1
|
#define MMIO_DEVID_GICC 1
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -108,14 +108,14 @@ static bool rsa2048_pss_verify(const void *signature, size_t signature_size, con
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Constant lmask for rsa-2048-pss. */
|
/* Constant lmask for rsa-2048-pss. */
|
||||||
message[0] &= 0x7F;
|
message[0] &= 0x7F;
|
||||||
|
|
||||||
/* Validate DB is of the form 0000...0001. */
|
/* Validate DB is of the form 0000...0001. */
|
||||||
for (unsigned int i = 0; i < RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1; i++) {
|
for (unsigned int i = 0; i < RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1; i++) {
|
||||||
if (message[i] != 0) {
|
if (message[i] != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (message[RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1] != 1) {
|
if (message[RSA_2048_BYTES - 0x20 - 0x20 - 1 - 1] != 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -298,7 +298,7 @@ static uint32_t decrypt_and_validate_header(package2_header_t *header) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure we successfully decrypted the header. */
|
/* Ensure we successfully decrypted the header. */
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -351,7 +351,7 @@ static void load_package2_sections(package2_meta_t *metadata, uint32_t master_ke
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy each section to its appropriate location, decrypting if necessary. */
|
/* Copy each section to its appropriate location, decrypting if necessary. */
|
||||||
for (unsigned int section = 0; section < PACKAGE2_SECTION_MAX; section++) {
|
for (unsigned int section = 0; section < PACKAGE2_SECTION_MAX; section++) {
|
||||||
if (metadata->section_sizes[section] == 0) {
|
if (metadata->section_sizes[section] == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -359,7 +359,7 @@ static void load_package2_sections(package2_meta_t *metadata, uint32_t master_ke
|
||||||
void *dst_start = (void *)(DRAM_BASE_PHYSICAL + (uint64_t)metadata->section_offsets[section]);
|
void *dst_start = (void *)(DRAM_BASE_PHYSICAL + (uint64_t)metadata->section_offsets[section]);
|
||||||
void *src_start = load_buf + sizeof(package2_header_t) + metadata->section_offsets[section];
|
void *src_start = load_buf + sizeof(package2_header_t) + metadata->section_offsets[section];
|
||||||
size_t size = (size_t)metadata->section_sizes[section];
|
size_t size = (size_t)metadata->section_sizes[section];
|
||||||
|
|
||||||
if (bootconfig_is_package2_plaintext()) {
|
if (bootconfig_is_package2_plaintext()) {
|
||||||
memcpy(dst_start, src_start, size);
|
memcpy(dst_start, src_start, size);
|
||||||
} else {
|
} else {
|
||||||
|
@ -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. */
|
||||||
|
@ -380,7 +380,7 @@ uintptr_t get_pk2ldr_stack_address(void) {
|
||||||
void load_package2(void) {
|
void load_package2(void) {
|
||||||
/* Setup the Security Engine. */
|
/* Setup the Security Engine. */
|
||||||
setup_se();
|
setup_se();
|
||||||
|
|
||||||
/* TODO: bootup_misc_mmio(). */
|
/* TODO: bootup_misc_mmio(). */
|
||||||
/* This func will also be called on warmboot. */
|
/* This func will also be called on warmboot. */
|
||||||
/* And will verify stored SE Test Vector, clear keyslots, */
|
/* And will verify stored SE Test Vector, clear keyslots, */
|
||||||
|
@ -388,9 +388,9 @@ void load_package2(void) {
|
||||||
/* Configure the GPU uCode carveout, configure the Kernel default carveouts, */
|
/* Configure the GPU uCode carveout, configure the Kernel default carveouts, */
|
||||||
/* Initialize the PMC secure scratch registers, initialize MISC registers, */
|
/* Initialize the PMC secure scratch registers, initialize MISC registers, */
|
||||||
/* And assign "se_operation_completed" to Interrupt 0x5A. */
|
/* And assign "se_operation_completed" to Interrupt 0x5A. */
|
||||||
|
|
||||||
/* TODO: Read and save BOOTREASON stored by NX_BOOTLOADER at 0x1F009FE00 */
|
/* TODO: Read and save BOOTREASON stored by NX_BOOTLOADER at 0x1F009FE00 */
|
||||||
|
|
||||||
/* Initialize cache'd random bytes for kernel. */
|
/* Initialize cache'd random bytes for kernel. */
|
||||||
randomcache_init();
|
randomcache_init();
|
||||||
|
|
||||||
|
|
|
@ -8,23 +8,27 @@
|
||||||
#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
|
||||||
#define NX_BOOTLOADER_STATE_LOADED_PACKAGE2 2
|
#define NX_BOOTLOADER_STATE_LOADED_PACKAGE2 2
|
||||||
#define NX_BOOTLOADER_STATE_FINISHED 3
|
#define NX_BOOTLOADER_STATE_FINISHED 3
|
||||||
|
|
||||||
/* 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
|
||||||
|
|
|
@ -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)))
|
||||||
|
|
||||||
|
|
207
exosphere/src/preprocessor.h
Normal file
207
exosphere/src/preprocessor.h
Normal 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
|
|
@ -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);
|
||||||
|
|
||||||
|
@ -23,7 +20,7 @@ static unsigned int g_se_exp_sizes[KEYSLOT_RSA_MAX];
|
||||||
/* Initialize a SE linked list. */
|
/* Initialize a SE linked list. */
|
||||||
void ll_init(se_ll_t *ll, void *buffer, size_t size) {
|
void ll_init(se_ll_t *ll, void *buffer, size_t size) {
|
||||||
ll->num_entries = 0; /* 1 Entry. */
|
ll->num_entries = 0; /* 1 Entry. */
|
||||||
|
|
||||||
if (buffer != NULL) {
|
if (buffer != NULL) {
|
||||||
ll->addr_info.address = (uint32_t) get_physical_address(buffer);
|
ll->addr_info.address = (uint32_t) get_physical_address(buffer);
|
||||||
ll->addr_info.size = (uint32_t) size;
|
ll->addr_info.size = (uint32_t) size;
|
||||||
|
@ -39,7 +36,7 @@ void set_security_engine_callback(unsigned int (*callback)(void)) {
|
||||||
if (callback == NULL || g_se_callback != NULL) {
|
if (callback == NULL || g_se_callback != NULL) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
g_se_callback = callback;
|
g_se_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,12 +75,12 @@ void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) {
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Misc flags. */
|
/* Misc flags. */
|
||||||
if (flags & ~0x80) {
|
if (flags & ~0x80) {
|
||||||
SECURITY_ENGINE->AES_KEYSLOT_FLAGS[keyslot] = ~flags;
|
SECURITY_ENGINE->AES_KEYSLOT_FLAGS[keyslot] = ~flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable keyslot reads. */
|
/* Disable keyslot reads. */
|
||||||
if (flags & 0x80) {
|
if (flags & 0x80) {
|
||||||
SECURITY_ENGINE->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
|
SECURITY_ENGINE->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
|
||||||
|
@ -95,13 +92,13 @@ void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) {
|
||||||
if (keyslot >= KEYSLOT_RSA_MAX) {
|
if (keyslot >= KEYSLOT_RSA_MAX) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Misc flags. */
|
/* Misc flags. */
|
||||||
if (flags & ~0x80) {
|
if (flags & ~0x80) {
|
||||||
/* TODO: Why are flags assigned this way? */
|
/* TODO: Why are flags assigned this way? */
|
||||||
SECURITY_ENGINE->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
|
SECURITY_ENGINE->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable keyslot reads. */
|
/* Disable keyslot reads. */
|
||||||
if (flags & 0x80) {
|
if (flags & 0x80) {
|
||||||
SECURITY_ENGINE->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
|
SECURITY_ENGINE->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot);
|
||||||
|
@ -112,7 +109,7 @@ void clear_aes_keyslot(unsigned int keyslot) {
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zero out the whole keyslot and IV. */
|
/* Zero out the whole keyslot and IV. */
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
for (unsigned int i = 0; i < 0x10; i++) {
|
||||||
SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
|
SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
|
||||||
|
@ -124,7 +121,7 @@ void clear_rsa_keyslot(unsigned int keyslot) {
|
||||||
if (keyslot >= KEYSLOT_RSA_MAX) {
|
if (keyslot >= KEYSLOT_RSA_MAX) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zero out the whole keyslot. */
|
/* Zero out the whole keyslot. */
|
||||||
for (unsigned int i = 0; i < 0x40; i++) {
|
for (unsigned int i = 0; i < 0x40; i++) {
|
||||||
/* Select Keyslot Modulus[i] */
|
/* Select Keyslot Modulus[i] */
|
||||||
|
@ -142,7 +139,7 @@ void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) {
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || key_size > KEYSIZE_AES_MAX) {
|
if (keyslot >= KEYSLOT_AES_MAX || key_size > KEYSIZE_AES_MAX) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (key_size >> 2); i++) {
|
for (size_t i = 0; i < (key_size >> 2); i++) {
|
||||||
SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
|
SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | i;
|
||||||
SECURITY_ENGINE->AES_KEYTABLE_DATA = read32le(key, 4 * i);
|
SECURITY_ENGINE->AES_KEYTABLE_DATA = read32le(key, 4 * i);
|
||||||
|
@ -153,17 +150,17 @@ void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_
|
||||||
if (keyslot >= KEYSLOT_RSA_MAX || modulus_size > KEYSIZE_RSA_MAX || exp_size > KEYSIZE_RSA_MAX) {
|
if (keyslot >= KEYSLOT_RSA_MAX || modulus_size > KEYSIZE_RSA_MAX || exp_size > KEYSIZE_RSA_MAX) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (modulus_size >> 2); i++) {
|
for (size_t i = 0; i < (modulus_size >> 2); i++) {
|
||||||
SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i;
|
SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i;
|
||||||
SECURITY_ENGINE->RSA_KEYTABLE_DATA = read32be(modulus, 4 * i);
|
SECURITY_ENGINE->RSA_KEYTABLE_DATA = read32be(modulus, 4 * i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (exp_size >> 2); i++) {
|
for (size_t i = 0; i < (exp_size >> 2); i++) {
|
||||||
SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | i;
|
||||||
SECURITY_ENGINE->RSA_KEYTABLE_DATA = read32be(exponent, 4 * i);
|
SECURITY_ENGINE->RSA_KEYTABLE_DATA = read32be(exponent, 4 * i);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_se_modulus_sizes[keyslot] = modulus_size;
|
g_se_modulus_sizes[keyslot] = modulus_size;
|
||||||
g_se_exp_sizes[keyslot] = exp_size;
|
g_se_exp_sizes[keyslot] = exp_size;
|
||||||
}
|
}
|
||||||
|
@ -172,7 +169,7 @@ void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) {
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || iv_size > 0x10) {
|
if (keyslot >= KEYSLOT_AES_MAX || iv_size > 0x10) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (iv_size >> 2); i++) {
|
for (size_t i = 0; i < (iv_size >> 2); i++) {
|
||||||
SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i;
|
||||||
SECURITY_ENGINE->AES_KEYTABLE_DATA = read32le(iv, 4 * i);
|
SECURITY_ENGINE->AES_KEYTABLE_DATA = read32le(iv, 4 * i);
|
||||||
|
@ -183,7 +180,7 @@ void clear_aes_keyslot_iv(unsigned int keyslot) {
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (0x10 >> 2); i++) {
|
for (size_t i = 0; i < (0x10 >> 2); i++) {
|
||||||
SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | 8;
|
SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | 8;
|
||||||
SECURITY_ENGINE->AES_KEYTABLE_DATA = 0;
|
SECURITY_ENGINE->AES_KEYTABLE_DATA = 0;
|
||||||
|
@ -200,7 +197,7 @@ void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_sr
|
||||||
if (keyslot_dst >= KEYSLOT_AES_MAX || keyslot_src >= KEYSIZE_AES_MAX || wrapped_key_size > KEYSIZE_AES_MAX) {
|
if (keyslot_dst >= KEYSLOT_AES_MAX || keyslot_src >= KEYSIZE_AES_MAX || wrapped_key_size > KEYSIZE_AES_MAX) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB);
|
SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB);
|
||||||
SECURITY_ENGINE->CRYPTO_REG = keyslot_src << 24;
|
SECURITY_ENGINE->CRYPTO_REG = keyslot_src << 24;
|
||||||
SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
|
SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
|
||||||
|
@ -214,11 +211,11 @@ void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr,
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup Config register. */
|
/* Setup Config register. */
|
||||||
if (encrypt) {
|
if (encrypt) {
|
||||||
SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
|
SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
|
||||||
|
@ -249,7 +246,7 @@ void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr,
|
||||||
SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG;
|
SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG;
|
||||||
SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG;
|
SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG;
|
||||||
SECURITY_ENGINE->OPERATION_REG = 1;
|
SECURITY_ENGINE->OPERATION_REG = 1;
|
||||||
|
|
||||||
/* Ensure writes go through. */
|
/* Ensure writes go through. */
|
||||||
__asm__ __volatile__ ("dsb ish" : : : "memory");
|
__asm__ __volatile__ ("dsb ish" : : : "memory");
|
||||||
}
|
}
|
||||||
|
@ -266,7 +263,7 @@ void se_aes_cbc_encrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, ui
|
||||||
se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x44, true, callback);
|
se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x44, true, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_aes_cbc_decrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void)) {
|
void se_aes_cbc_decrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void)) {
|
||||||
set_aes_keyslot_iv(keyslot, iv, 0x10);
|
set_aes_keyslot_iv(keyslot, iv, 0x10);
|
||||||
se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x66, false, callback);
|
se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x66, false, callback);
|
||||||
}
|
}
|
||||||
|
@ -274,16 +271,16 @@ void se_aes_cbc_decrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, ui
|
||||||
|
|
||||||
void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*callback)(void)) {
|
void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*callback)(void)) {
|
||||||
uint8_t stack_buf[KEYSIZE_RSA_MAX];
|
uint8_t stack_buf[KEYSIZE_RSA_MAX];
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_RSA_MAX || size > KEYSIZE_RSA_MAX) {
|
if (keyslot >= KEYSLOT_RSA_MAX || size > KEYSIZE_RSA_MAX) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Endian swap the input. */
|
/* Endian swap the input. */
|
||||||
for (size_t i = size; i > 0; i--) {
|
for (size_t i = size; i > 0; i--) {
|
||||||
stack_buf[i] = *((uint8_t *)buf + size - i);
|
stack_buf[i] = *((uint8_t *)buf + size - i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SECURITY_ENGINE->CONFIG_REG = (ALG_RSA | DST_RSAREG);
|
SECURITY_ENGINE->CONFIG_REG = (ALG_RSA | DST_RSAREG);
|
||||||
SECURITY_ENGINE->RSA_CONFIG = keyslot << 24;
|
SECURITY_ENGINE->RSA_CONFIG = keyslot << 24;
|
||||||
|
@ -291,7 +288,7 @@ void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*cal
|
||||||
SECURITY_ENGINE->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
|
SECURITY_ENGINE->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
|
||||||
|
|
||||||
set_security_engine_callback(callback);
|
set_security_engine_callback(callback);
|
||||||
|
|
||||||
/* Enable SE Interrupt firing for async op. */
|
/* Enable SE Interrupt firing for async op. */
|
||||||
SECURITY_ENGINE->INT_ENABLE_REG = 0x10;
|
SECURITY_ENGINE->INT_ENABLE_REG = 0x10;
|
||||||
|
|
||||||
|
@ -303,7 +300,7 @@ void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*cal
|
||||||
|
|
||||||
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
||||||
uint8_t stack_buf[KEYSIZE_RSA_MAX];
|
uint8_t stack_buf[KEYSIZE_RSA_MAX];
|
||||||
|
|
||||||
if (keyslot >= KEYSLOT_RSA_MAX || src_size > KEYSIZE_RSA_MAX || dst_size > KEYSIZE_RSA_MAX) {
|
if (keyslot >= KEYSLOT_RSA_MAX || src_size > KEYSIZE_RSA_MAX || dst_size > KEYSIZE_RSA_MAX) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
@ -312,13 +309,13 @@ void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, co
|
||||||
for (size_t i = src_size; i > 0; i--) {
|
for (size_t i = src_size; i > 0; i--) {
|
||||||
stack_buf[i] = *((uint8_t *)src + src_size - i);
|
stack_buf[i] = *((uint8_t *)src + src_size - i);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECURITY_ENGINE->CONFIG_REG = (ALG_RSA | DST_RSAREG);
|
SECURITY_ENGINE->CONFIG_REG = (ALG_RSA | DST_RSAREG);
|
||||||
SECURITY_ENGINE->RSA_CONFIG = keyslot << 24;
|
SECURITY_ENGINE->RSA_CONFIG = keyslot << 24;
|
||||||
SECURITY_ENGINE->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1;
|
SECURITY_ENGINE->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1;
|
||||||
SECURITY_ENGINE->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
|
SECURITY_ENGINE->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
|
||||||
|
|
||||||
|
|
||||||
flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX);
|
flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX);
|
||||||
trigger_se_blocking_op(1, NULL, 0, stack_buf, src_size);
|
trigger_se_blocking_op(1, NULL, 0, stack_buf, src_size);
|
||||||
se_get_exp_mod_output(dst, dst_size);
|
se_get_exp_mod_output(dst, dst_size);
|
||||||
|
@ -329,10 +326,10 @@ void se_get_exp_mod_output(void *buf, size_t size) {
|
||||||
if (num_dwords < 1) {
|
if (num_dwords < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t *p_out = ((uint32_t *)buf) + num_dwords - 1;
|
uint32_t *p_out = ((uint32_t *)buf) + num_dwords - 1;
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
|
|
||||||
/* Copy endian swapped output. */
|
/* Copy endian swapped output. */
|
||||||
while (num_dwords) {
|
while (num_dwords) {
|
||||||
*p_out = read32be(SECURITY_ENGINE->RSA_OUTPUT, offset);
|
*p_out = read32be(SECURITY_ENGINE->RSA_OUTPUT, offset);
|
||||||
|
@ -347,13 +344,13 @@ 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;
|
||||||
SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG;
|
SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG;
|
||||||
SECURITY_ENGINE->OPERATION_REG = 1;
|
SECURITY_ENGINE->OPERATION_REG = 1;
|
||||||
|
|
||||||
/* Ensure writes go through. */
|
/* Ensure writes go through. */
|
||||||
__asm__ __volatile__ ("dsb ish" : : : "memory");
|
__asm__ __volatile__ ("dsb ish" : : : "memory");
|
||||||
}
|
}
|
||||||
|
@ -361,19 +358,19 @@ 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) {
|
||||||
se_ll_t in_ll;
|
se_ll_t in_ll;
|
||||||
se_ll_t out_ll;
|
se_ll_t out_ll;
|
||||||
|
|
||||||
ll_init(&in_ll, (void *)src, src_size);
|
ll_init(&in_ll, (void *)src, src_size);
|
||||||
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;
|
||||||
SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG;
|
SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG;
|
||||||
SECURITY_ENGINE->OPERATION_REG = op;
|
SECURITY_ENGINE->OPERATION_REG = op;
|
||||||
|
|
||||||
while (!(SECURITY_ENGINE->INT_STATUS_REG & 0x10)) { /* Wait a while */ }
|
while (!(SECURITY_ENGINE->INT_STATUS_REG & 0x10)) { /* Wait a while */ }
|
||||||
se_check_for_error();
|
se_check_for_error();
|
||||||
}
|
}
|
||||||
|
@ -394,7 +391,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src,
|
||||||
/* Trigger AES operation. */
|
/* Trigger AES operation. */
|
||||||
SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
|
SECURITY_ENGINE->BLOCK_COUNT_REG = 0;
|
||||||
trigger_se_blocking_op(1, block, sizeof(block), block, sizeof(block));
|
trigger_se_blocking_op(1, block, sizeof(block), block, sizeof(block));
|
||||||
|
|
||||||
/* Copy output data into dst. */
|
/* Copy output data into dst. */
|
||||||
flush_dcache_range(block, block + sizeof(block));
|
flush_dcache_range(block, block + sizeof(block));
|
||||||
memcpy(dst, block, dst_size);
|
memcpy(dst, block, dst_size);
|
||||||
|
@ -404,22 +401,22 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || ctr_size != 0x10) {
|
if (keyslot >= KEYSLOT_AES_MAX || ctr_size != 0x10) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int num_blocks = src_size >> 4;
|
unsigned int num_blocks = src_size >> 4;
|
||||||
|
|
||||||
/* Unknown what this write does, but official code writes it for CTR mode. */
|
/* Unknown what this write does, but official code writes it for CTR mode. */
|
||||||
SECURITY_ENGINE->_0x80C = 1;
|
SECURITY_ENGINE->_0x80C = 1;
|
||||||
SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
|
SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY);
|
||||||
SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x91E;
|
SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x91E;
|
||||||
set_se_ctr(ctr);
|
set_se_ctr(ctr);
|
||||||
|
|
||||||
/* Handle any aligned blocks. */
|
/* Handle any aligned blocks. */
|
||||||
size_t aligned_size = (size_t)num_blocks << 4;
|
size_t aligned_size = (size_t)num_blocks << 4;
|
||||||
if (aligned_size) {
|
if (aligned_size) {
|
||||||
SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 1;
|
SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 1;
|
||||||
trigger_se_blocking_op(1, dst, dst_size, src, aligned_size);
|
trigger_se_blocking_op(1, dst, dst_size, src, aligned_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle final, unaligned block. */
|
/* Handle final, unaligned block. */
|
||||||
if (aligned_size < dst_size && aligned_size < src_size) {
|
if (aligned_size < dst_size && aligned_size < src_size) {
|
||||||
size_t last_block_size = dst_size - aligned_size;
|
size_t last_block_size = dst_size - aligned_size;
|
||||||
|
@ -434,7 +431,7 @@ void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size,
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
|
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
|
/* Set configuration high (256-bit vs 128-bit) based on parameter. */
|
||||||
SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
|
SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16);
|
||||||
SECURITY_ENGINE->CRYPTO_REG = keyslot << 24;
|
SECURITY_ENGINE->CRYPTO_REG = keyslot << 24;
|
||||||
|
@ -455,7 +452,7 @@ void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size,
|
||||||
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
|
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
|
SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY);
|
||||||
SECURITY_ENGINE->CRYPTO_REG = keyslot << 24;
|
SECURITY_ENGINE->CRYPTO_REG = keyslot << 24;
|
||||||
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
se_perform_aes_block_operation(dst, 0x10, src, 0x10);
|
||||||
|
@ -466,7 +463,7 @@ void shift_left_xor_rb(uint8_t *key) {
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
for (unsigned int i = 0; i < 0x10; i++) {
|
||||||
uint8_t cur_byte = key[0xF - i];
|
uint8_t cur_byte = key[0xF - i];
|
||||||
key[0xF - i] = (cur_byte << 1) | (prev_high_bit);
|
key[0xF - i] = (cur_byte << 1) | (prev_high_bit);
|
||||||
prev_high_bit = cur_byte >> 7;
|
prev_high_bit = cur_byte >> 7;
|
||||||
}
|
}
|
||||||
if (prev_high_bit) {
|
if (prev_high_bit) {
|
||||||
key[0xF] ^= 0x87;
|
key[0xF] ^= 0x87;
|
||||||
|
@ -477,7 +474,7 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate the derived key, to be XOR'd with final output block. */
|
/* Generate the derived key, to be XOR'd with final output block. */
|
||||||
uint8_t derived_key[0x10];
|
uint8_t derived_key[0x10];
|
||||||
memset(derived_key, 0, sizeof(derived_key));
|
memset(derived_key, 0, sizeof(derived_key));
|
||||||
|
@ -486,11 +483,11 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
|
||||||
if (data_size & 0xF) {
|
if (data_size & 0xF) {
|
||||||
shift_left_xor_rb(derived_key);
|
shift_left_xor_rb(derived_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
|
SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16);
|
||||||
SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | (0x145);
|
SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | (0x145);
|
||||||
clear_aes_keyslot_iv(keyslot);
|
clear_aes_keyslot_iv(keyslot);
|
||||||
|
|
||||||
unsigned int num_blocks = (data_size + 0xF) >> 4;
|
unsigned int num_blocks = (data_size + 0xF) >> 4;
|
||||||
/* Handle aligned blocks. */
|
/* Handle aligned blocks. */
|
||||||
if (num_blocks > 1) {
|
if (num_blocks > 1) {
|
||||||
|
@ -498,26 +495,26 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
|
||||||
trigger_se_blocking_op(1, NULL, 0, data, data_size);
|
trigger_se_blocking_op(1, NULL, 0, data, data_size);
|
||||||
SECURITY_ENGINE->CRYPTO_REG |= 0x80;
|
SECURITY_ENGINE->CRYPTO_REG |= 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create final block. */
|
/* Create final block. */
|
||||||
uint8_t last_block[0x10];
|
uint8_t last_block[0x10];
|
||||||
memset(last_block, 0, sizeof(last_block));
|
memset(last_block, 0, sizeof(last_block));
|
||||||
if (data_size & 0xF) {
|
if (data_size & 0xF) {
|
||||||
|
|
||||||
memcpy(last_block, data + (data_size & ~0xF), data_size & 0xF);
|
memcpy(last_block, data + (data_size & ~0xF), data_size & 0xF);
|
||||||
last_block[data_size & 0xF] = 0x80; /* Last block = data || 100...0 */
|
last_block[data_size & 0xF] = 0x80; /* Last block = data || 100...0 */
|
||||||
} else if (data_size >= 0x10) {
|
} else if (data_size >= 0x10) {
|
||||||
memcpy(last_block, data + data_size - 0x10, 0x10);
|
memcpy(last_block, data + data_size - 0x10, 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 0x10; i++) {
|
for (unsigned int i = 0; i < 0x10; i++) {
|
||||||
last_block[i] ^= derived_key[i];
|
last_block[i] ^= derived_key[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform last operation. */
|
/* Perform last operation. */
|
||||||
flush_dcache_range(last_block, last_block + sizeof(last_block));
|
flush_dcache_range(last_block, last_block + sizeof(last_block));
|
||||||
trigger_se_blocking_op(1, NULL, 0, last_block, sizeof(last_block));
|
trigger_se_blocking_op(1, NULL, 0, last_block, sizeof(last_block));
|
||||||
|
|
||||||
/* Copy output CMAC. */
|
/* Copy output CMAC. */
|
||||||
for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
|
for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
|
||||||
((uint32_t *)cmac)[i] = read32le(SECURITY_ENGINE->HASH_RESULT_REG, i << 2);
|
((uint32_t *)cmac)[i] = read32le(SECURITY_ENGINE->HASH_RESULT_REG, i << 2);
|
||||||
|
@ -544,10 +541,10 @@ void se_calculate_sha256(void *dst, const void *src, size_t src_size) {
|
||||||
SECURITY_ENGINE->_0x21C = 0;
|
SECURITY_ENGINE->_0x21C = 0;
|
||||||
SECURITY_ENGINE->_0x220 = 0;
|
SECURITY_ENGINE->_0x220 = 0;
|
||||||
SECURITY_ENGINE->_0x224 = 0;
|
SECURITY_ENGINE->_0x224 = 0;
|
||||||
|
|
||||||
/* Trigger the operation. */
|
/* Trigger the operation. */
|
||||||
trigger_se_blocking_op(1, NULL, 0, src, src_size);
|
trigger_se_blocking_op(1, NULL, 0, src, src_size);
|
||||||
|
|
||||||
/* Copy output hash. */
|
/* Copy output hash. */
|
||||||
for (unsigned int i = 0; i < (0x20 >> 2); i++) {
|
for (unsigned int i = 0; i < (0x20 >> 2); i++) {
|
||||||
((uint32_t *)dst)[i] = read32be(SECURITY_ENGINE->HASH_RESULT_REG, i << 2);
|
((uint32_t *)dst)[i] = read32be(SECURITY_ENGINE->HASH_RESULT_REG, i << 2);
|
||||||
|
@ -559,11 +556,11 @@ void se_initialize_rng(unsigned int keyslot) {
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* To initialize the RNG, we'll perform an RNG operation into an output buffer. */
|
/* To initialize the RNG, we'll perform an RNG operation into an output buffer. */
|
||||||
/* This will be discarded, when done. */
|
/* This will be discarded, when done. */
|
||||||
uint8_t output_buf[0x10];
|
uint8_t output_buf[0x10];
|
||||||
|
|
||||||
SECURITY_ENGINE->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */
|
SECURITY_ENGINE->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */
|
||||||
SECURITY_ENGINE->RNG_RESEED_INTERVAL_REG = 70001;
|
SECURITY_ENGINE->RNG_RESEED_INTERVAL_REG = 70001;
|
||||||
SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_MEMORY);
|
SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_MEMORY);
|
||||||
|
@ -577,13 +574,13 @@ void se_generate_random(unsigned int keyslot, void *dst, size_t size) {
|
||||||
if (keyslot >= KEYSLOT_AES_MAX) {
|
if (keyslot >= KEYSLOT_AES_MAX) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t num_blocks = size >> 4;
|
uint32_t num_blocks = size >> 4;
|
||||||
size_t aligned_size = num_blocks << 4;
|
size_t aligned_size = num_blocks << 4;
|
||||||
SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_MEMORY);
|
SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_MEMORY);
|
||||||
SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x108;
|
SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x108;
|
||||||
SECURITY_ENGINE->RNG_CONFIG_REG = 4;
|
SECURITY_ENGINE->RNG_CONFIG_REG = 4;
|
||||||
|
|
||||||
if (num_blocks >= 1) {
|
if (num_blocks >= 1) {
|
||||||
SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 1;
|
SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 1;
|
||||||
trigger_se_blocking_op(1, dst, aligned_size, NULL, 0);
|
trigger_se_blocking_op(1, dst, aligned_size, NULL, 0);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ uint64_t try_set_smc_callback(uint32_t (*callback)(void *, uint64_t)) {
|
||||||
if (g_smc_callback_key) {
|
if (g_smc_callback_key) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
se_generate_random(KEYSLOT_SWITCH_RNGKEY, &key, sizeof(uint64_t));
|
se_generate_random(KEYSLOT_SWITCH_RNGKEY, &key, sizeof(uint64_t));
|
||||||
g_smc_callback_key = key;
|
g_smc_callback_key = key;
|
||||||
g_smc_callback = callback;
|
g_smc_callback = callback;
|
||||||
|
@ -160,33 +160,33 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
|
||||||
unsigned char smc_id;
|
unsigned char smc_id;
|
||||||
unsigned int result;
|
unsigned int result;
|
||||||
unsigned int (*smc_handler)(smc_args_t *args);
|
unsigned int (*smc_handler)(smc_args_t *args);
|
||||||
|
|
||||||
/* Validate top-level handler. */
|
/* Validate top-level handler. */
|
||||||
if (handler_id != SMC_HANDLER_USER && handler_id != SMC_HANDLER_PRIV) {
|
if (handler_id != SMC_HANDLER_USER && handler_id != SMC_HANDLER_PRIV) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate core is appropriate for handler. */
|
/* Validate core is appropriate for handler. */
|
||||||
if (handler_id == SMC_HANDLER_USER && get_core_id() != 3) {
|
if (handler_id == SMC_HANDLER_USER && get_core_id() != 3) {
|
||||||
/* USER SMCs must be called via svcCallSecureMonitor on core 3 (where spl runs) */
|
/* USER SMCs must be called via svcCallSecureMonitor on core 3 (where spl runs) */
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate sub-handler index */
|
/* Validate sub-handler index */
|
||||||
if ((smc_id = (unsigned char)args->X[0]) >= g_smc_tables[handler_id].num_handlers) {
|
if ((smc_id = (unsigned char)args->X[0]) >= g_smc_tables[handler_id].num_handlers) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate sub-handler */
|
/* Validate sub-handler */
|
||||||
if (g_smc_tables[handler_id].handlers[smc_id].id != args->X[0]) {
|
if (g_smc_tables[handler_id].handlers[smc_id].id != args->X[0]) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate handler. */
|
/* Validate handler. */
|
||||||
if ((smc_handler = g_smc_tables[handler_id].handlers[smc_id].handler) == NULL) {
|
if ((smc_handler = g_smc_tables[handler_id].handlers[smc_id].handler) == NULL) {
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call function. */
|
/* Call function. */
|
||||||
args->X[0] = smc_handler(args);
|
args->X[0] = smc_handler(args);
|
||||||
(void)result; /* FIXME: result unused */
|
(void)result; /* FIXME: result unused */
|
||||||
|
@ -244,13 +244,13 @@ uint32_t smc_check_status(smc_args_t *args) {
|
||||||
if (g_smc_callback_key == 0) {
|
if (g_smc_callback_key == 0) {
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args->X[1] != g_smc_callback_key) {
|
if (args->X[1] != g_smc_callback_key) {
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
args->X[1] = g_smc_callback(NULL, 0);
|
args->X[1] = g_smc_callback(NULL, 0);
|
||||||
|
|
||||||
g_smc_callback_key = 0;
|
g_smc_callback_key = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +261,7 @@ uint32_t smc_get_result(smc_args_t *args) {
|
||||||
upage_ref_t page_ref;
|
upage_ref_t page_ref;
|
||||||
|
|
||||||
void *user_address = (void *)args->X[2];
|
void *user_address = (void *)args->X[2];
|
||||||
|
|
||||||
if (g_smc_callback_key == 0) {
|
if (g_smc_callback_key == 0) {
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
@ -274,7 +274,7 @@ uint32_t smc_get_result(smc_args_t *args) {
|
||||||
if (args->X[3] > 0x400) {
|
if (args->X[3] > 0x400) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
args->X[1] = g_smc_callback(result_buf, args->X[3]);
|
args->X[1] = g_smc_callback(result_buf, args->X[3]);
|
||||||
g_smc_callback_key = 0;
|
g_smc_callback_key = 0;
|
||||||
|
|
||||||
|
@ -296,13 +296,13 @@ uint32_t smc_exp_mod_get_result(void *buf, uint64_t size) {
|
||||||
if (get_exp_mod_done() != 1) {
|
if (get_exp_mod_done() != 1) {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size != 0x100) {
|
if (size != 0x100) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
se_get_exp_mod_output(buf, 0x100);
|
se_get_exp_mod_output(buf, 0x100);
|
||||||
|
|
||||||
/* smc_exp_mod is done now. */
|
/* smc_exp_mod is done now. */
|
||||||
lock_release(&g_is_user_smc_in_progress);
|
lock_release(&g_is_user_smc_in_progress);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -371,24 +371,24 @@ uint32_t smc_unwrap_rsa_oaep_wrapped_titlekey_get_result(void *buf, uint64_t siz
|
||||||
if (get_exp_mod_done() != 1) {
|
if (get_exp_mod_done() != 1) {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size != 0x10) {
|
if (size != 0x10) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
se_get_exp_mod_output(rsa_wrapped_titlekey, 0x100);
|
se_get_exp_mod_output(rsa_wrapped_titlekey, 0x100);
|
||||||
if (tkey_rsa_oaep_unwrap(aes_wrapped_titlekey, 0x10, rsa_wrapped_titlekey, 0x100) != 0x10) {
|
if (tkey_rsa_oaep_unwrap(aes_wrapped_titlekey, 0x10, rsa_wrapped_titlekey, 0x100) != 0x10) {
|
||||||
/* Failed to extract RSA OAEP wrapped key. */
|
/* Failed to extract RSA OAEP wrapped key. */
|
||||||
lock_release(&g_is_user_smc_in_progress);
|
lock_release(&g_is_user_smc_in_progress);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
tkey_aes_unwrap(titlekey, 0x10, aes_wrapped_titlekey, 0x10);
|
tkey_aes_unwrap(titlekey, 0x10, aes_wrapped_titlekey, 0x10);
|
||||||
seal_titlekey(sealed_titlekey, 0x10, titlekey, 0x10);
|
seal_titlekey(sealed_titlekey, 0x10, titlekey, 0x10);
|
||||||
|
|
||||||
p_sealed_key[0] = sealed_titlekey[0];
|
p_sealed_key[0] = sealed_titlekey[0];
|
||||||
p_sealed_key[1] = sealed_titlekey[1];
|
p_sealed_key[1] = sealed_titlekey[1];
|
||||||
|
|
||||||
/* smc_unwrap_rsa_oaep_wrapped_titlekey is done now. */
|
/* smc_unwrap_rsa_oaep_wrapped_titlekey is done now. */
|
||||||
lock_release(&g_is_user_smc_in_progress);
|
lock_release(&g_is_user_smc_in_progress);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -475,10 +475,10 @@ 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,
|
||||||
0xCD, 0xFE, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00,
|
0xCD, 0xFE, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x03, 0x40, 0x73, 0x3E, 0x2F, 0x00, 0x00, 0x6E,
|
0x03, 0x40, 0x73, 0x3E, 0x2F, 0x00, 0x00, 0x6E,
|
||||||
|
@ -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. */
|
||||||
|
@ -510,7 +510,7 @@ uint32_t smc_read_write_register(smc_args_t *args) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform actual write. */
|
/* Perform actual write. */
|
||||||
if (p_mmio != NULL) {
|
if (p_mmio != NULL) {
|
||||||
uint32_t old_value;
|
uint32_t old_value;
|
||||||
|
@ -527,7 +527,7 @@ uint32_t smc_read_write_register(smc_args_t *args) {
|
||||||
args->X[1] = old_value;
|
args->X[1] = old_value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,22 +536,22 @@ uint32_t smc_configure_carveout(smc_args_t *args) {
|
||||||
if (args->X[0] > 1) {
|
if (args->X[0] > 1) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int carveout_id = (unsigned int)args->X[1];
|
unsigned int carveout_id = (unsigned int)args->X[1];
|
||||||
uint64_t address = args->X[2];
|
uint64_t address = args->X[2];
|
||||||
uint64_t size = args->X[3];
|
uint64_t size = args->X[3];
|
||||||
|
|
||||||
/* Ensure carveout isn't too big. */
|
/* Ensure carveout isn't too big. */
|
||||||
if (size > KERNEL_CARVEOUT_SIZE_MAX) {
|
if (size > KERNEL_CARVEOUT_SIZE_MAX) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configuration is one-shot, and cannot be done multiple times. */
|
/* Configuration is one-shot, and cannot be done multiple times. */
|
||||||
static bool configured_carveouts[2] = {false, false};
|
static bool configured_carveouts[2] = {false, false};
|
||||||
if (configured_carveouts[carveout_id]) {
|
if (configured_carveouts[carveout_id]) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
configure_kernel_carveout(carveout_id + 4, address, size);
|
configure_kernel_carveout(carveout_id + 4, address, size);
|
||||||
configured_carveouts[carveout_id] = true;
|
configured_carveouts[carveout_id] = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -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)))
|
||||||
|
|
||||||
|
|
|
@ -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)))
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue