mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
Implement smcConfigureCarveout
This commit is contained in:
parent
b2dc858738
commit
f7598cb433
3 changed files with 172 additions and 0 deletions
104
exosphere/mc.c
Normal file
104
exosphere/mc.c
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "mmu.h"
|
||||||
|
#include "mc.h"
|
||||||
|
|
||||||
|
volatile security_carveout_t *get_carveout_by_id(unsigned int carveout) {
|
||||||
|
if (CARVEOUT_ID_MIN <= carveout <= CARVEOUT_ID_MAX) {
|
||||||
|
return (volatile security_carveout_t *)(MC_BASE + 0xC08ULL + 0x50 * (carveout - CARVEOUT_ID_MIN));
|
||||||
|
}
|
||||||
|
panic();
|
||||||
|
return NULL;
|
||||||
|
switch (carveout) {
|
||||||
|
case 4: /* Kernel carveout */
|
||||||
|
return (volatile security_carveout_t *)(MC_BASE + 0xCF8ULL);
|
||||||
|
case 5: /* Unused Kernel carveout */
|
||||||
|
return (volatile security_carveout_t *)(MC_BASE + 0xD48ULL);
|
||||||
|
default:
|
||||||
|
panic();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void configure_default_carveouts(void) {
|
||||||
|
/* Configure Carveout 1 (UNUSED) */
|
||||||
|
volatile security_carveout_t *carveout = get_carveout_by_id(1);
|
||||||
|
carveout->paddr_low = 0;
|
||||||
|
carveout->paddr_high = 0;
|
||||||
|
carveout->size_big_pages = 0;
|
||||||
|
carveout->flags_0 = 0;
|
||||||
|
carveout->flags_1 = 0;
|
||||||
|
carveout->flags_2 = 0;
|
||||||
|
carveout->flags_3 = 0;
|
||||||
|
carveout->flags_4 = 0;
|
||||||
|
carveout->flags_5 = 0;
|
||||||
|
carveout->flags_6 = 0;
|
||||||
|
carveout->flags_7 = 0;
|
||||||
|
carveout->flags_8 = 0;
|
||||||
|
carveout->flags_9 = 0;
|
||||||
|
carveout->allowed_clients = 0x04000006;
|
||||||
|
|
||||||
|
/* Configure Carveout 2 (GPU UCODE) */
|
||||||
|
carveout = get_carveout_by_id(2);
|
||||||
|
carveout->paddr_low = 0x80020000;
|
||||||
|
carveout->paddr_high = 0;
|
||||||
|
carveout->size_big_pages = 2; /* 0x40000 */
|
||||||
|
carveout->flags_0 = 0;
|
||||||
|
carveout->flags_1 = 0;
|
||||||
|
carveout->flags_2 = 0x3000000;
|
||||||
|
carveout->flags_3 = 0;
|
||||||
|
carveout->flags_4 = 0x300;
|
||||||
|
carveout->flags_5 = 0;
|
||||||
|
carveout->flags_6 = 0;
|
||||||
|
carveout->flags_7 = 0;
|
||||||
|
carveout->flags_8 = 0;
|
||||||
|
carveout->flags_9 = 0;
|
||||||
|
carveout->allowed_clients = 0x440167E;
|
||||||
|
|
||||||
|
/* Configure Carveout 3 (UNUSED GPU) */
|
||||||
|
carveout = get_carveout_by_id(3);
|
||||||
|
carveout->paddr_low = 0;
|
||||||
|
carveout->paddr_high = 0;
|
||||||
|
carveout->size_big_pages = 0;
|
||||||
|
carveout->flags_0 = 0;
|
||||||
|
carveout->flags_1 = 0;
|
||||||
|
carveout->flags_2 = 0x3000000;
|
||||||
|
carveout->flags_3 = 0;
|
||||||
|
carveout->flags_4 = 0x300;
|
||||||
|
carveout->flags_5 = 0;
|
||||||
|
carveout->flags_6 = 0;
|
||||||
|
carveout->flags_7 = 0;
|
||||||
|
carveout->flags_8 = 0;
|
||||||
|
carveout->flags_9 = 0;
|
||||||
|
carveout->allowed_clients = 0x4401E7E;
|
||||||
|
|
||||||
|
/* Configure default Kernel carveouts based on 2.0.0+. */
|
||||||
|
|
||||||
|
/* Configure Carveout 4 (KERNEL_BUILTINS) */
|
||||||
|
configure_kernel_carveout(5, 0x80060000, KERNEL_CARVEOUT_SIZE_MAX);
|
||||||
|
|
||||||
|
/* Configure Carveout 5 (KERNEL_UNUSED) */
|
||||||
|
configure_kernel_carveout(5, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint64_t size) {
|
||||||
|
if (carveout_id != 4 && carveout_id != 5) {
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
volatile security_carveout_t *carveout = get_carveout_by_id(carveout_id);
|
||||||
|
carveout->paddr_low = (uint32_t)(address & 0xFFFFFFFF);
|
||||||
|
carveout->paddr_high = (uint32_t)(address >> 32);
|
||||||
|
carveout->size_big_pages = (uint32_t)(size >> 17);
|
||||||
|
carveout->flags_0 = 0x70E3407F;
|
||||||
|
carveout->flags_1 = 0x1A620880;
|
||||||
|
carveout->flags_2 = 0x303C00;
|
||||||
|
carveout->flags_3 = 0xCF0830BB;
|
||||||
|
carveout->flags_4 = 0x3;
|
||||||
|
carveout->flags_5 = 0;
|
||||||
|
carveout->flags_6 = 0;
|
||||||
|
carveout->flags_7 = 0;
|
||||||
|
carveout->flags_8 = 0;
|
||||||
|
carveout->flags_9 = 0;
|
||||||
|
carveout->allowed_clients = 0x8B;
|
||||||
|
}
|
40
exosphere/mc.h
Normal file
40
exosphere/mc.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef EXOSPHERE_MC_H
|
||||||
|
#define EXOSPHERE_MC_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "mmu.h"
|
||||||
|
|
||||||
|
/* Exosphere driver for the Tegra X1 Memory Controller. */
|
||||||
|
|
||||||
|
#define MC_BASE (mmio_get_device_address(MMIO_DEVID_MC))
|
||||||
|
|
||||||
|
#define CARVEOUT_ID_MIN 1
|
||||||
|
#define CARVEOUT_ID_MAX 5
|
||||||
|
|
||||||
|
#define KERNEL_CARVEOUT_SIZE_MAX 0x1FFE0000
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t allowed_clients;
|
||||||
|
uint32_t paddr_low;
|
||||||
|
uint32_t paddr_high;
|
||||||
|
uint32_t size_big_pages;
|
||||||
|
uint32_t flags_0;
|
||||||
|
uint32_t flags_1;
|
||||||
|
uint32_t flags_2;
|
||||||
|
uint32_t flags_3;
|
||||||
|
uint32_t flags_4;
|
||||||
|
uint32_t flags_5;
|
||||||
|
uint32_t flags_6;
|
||||||
|
uint32_t flags_7;
|
||||||
|
uint32_t flags_8;
|
||||||
|
uint32_t flags_9;
|
||||||
|
uint8_t padding[0x28];
|
||||||
|
} security_carveout_t;
|
||||||
|
|
||||||
|
|
||||||
|
volatile security_carveout_t *get_carveout_by_id(unsigned int carveout);
|
||||||
|
void configure_default_carveouts(void);
|
||||||
|
void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint64_t size);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -3,6 +3,8 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "configitem.h"
|
#include "configitem.h"
|
||||||
#include "cpu_context.h"
|
#include "cpu_context.h"
|
||||||
|
#include "mc.h"
|
||||||
|
#include "mmu.h"
|
||||||
#include "smc_api.h"
|
#include "smc_api.h"
|
||||||
#include "smc_user.h"
|
#include "smc_user.h"
|
||||||
#include "se.h"
|
#include "se.h"
|
||||||
|
@ -478,3 +480,29 @@ uint32_t smc_read_write_register(smc_args_t *args) {
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t smc_configure_carveout(smc_args_t *args) {
|
||||||
|
if (args->X[0] > 1) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int carveout_id = (unsigned int)args->X[1];
|
||||||
|
uint64_t address = args->X[2];
|
||||||
|
uint64_t size = args->X[3];
|
||||||
|
|
||||||
|
/* Ensure carveout isn't too big. */
|
||||||
|
if (size > KERNEL_CARVEOUT_SIZE_MAX) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configuration is one-shot, and cannot be done multiple times. */
|
||||||
|
static bool configured_carveouts[2] = {false, false};
|
||||||
|
if (configured_carveouts[carveout_id]) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_kernel_carveout(carveout_id + 4, address, size);
|
||||||
|
configured_carveouts[carveout_id] = true;
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue