mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
Fix emunand SMC behaviors
This commit is contained in:
parent
40b838c896
commit
6dd366cb22
4 changed files with 13 additions and 4 deletions
|
@ -286,7 +286,8 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
|
||||||
break;
|
break;
|
||||||
case CONFIGITEM_EMUNAND_CONFIG:
|
case CONFIGITEM_EMUNAND_CONFIG:
|
||||||
/* UNOFFICIAL: Gets configuration meta for emunand. */
|
/* UNOFFICIAL: Gets configuration meta for emunand. */
|
||||||
*p_outvalue = exosphere_get_emunand_config();
|
*p_outvalue = 1; //exosphere_get_emunand_config();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
result = 2;
|
result = 2;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -159,11 +159,12 @@ uint32_t ams_iram_copy(smc_args_t *args) {
|
||||||
uint32_t ams_write_address(smc_args_t *args) {
|
uint32_t ams_write_address(smc_args_t *args) {
|
||||||
/* Implements a write to a DRAM page. */
|
/* Implements a write to a DRAM page. */
|
||||||
/* This operation can be used to write to read-only pages. */
|
/* This operation can be used to write to read-only pages. */
|
||||||
/* args->X[1] = DRAM address (translated by kernel), must be size-bytes aligned. */
|
/* args->X[1] = Virtual address, must be size-bytes aligned and readable by EL0. */
|
||||||
/* args->X[2] = Value. */
|
/* args->X[2] = Value. */
|
||||||
/* args->X[3] = size (must be 1, 2, 4, or 8). */
|
/* args->X[3] = size (must be 1, 2, 4, or 8). */
|
||||||
|
|
||||||
const uintptr_t dram_address = (uintptr_t)args->X[1];
|
const uintptr_t el0_virtual_address = (uintptr_t)args->X[1];
|
||||||
|
const uintptr_t dram_address = get_physical_address_el0(el0_virtual_address);
|
||||||
const uintptr_t dram_page_offset = (dram_address & 0xFFFULL);
|
const uintptr_t dram_page_offset = (dram_address & 0xFFFULL);
|
||||||
const size_t size = (size_t)(args->X[3]);
|
const size_t size = (size_t)(args->X[3]);
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ static smc_table_entry_t g_smc_ams_table[] = {
|
||||||
{0, 4, NULL},
|
{0, 4, NULL},
|
||||||
{0xF0000201, 0, smc_ams_iram_copy},
|
{0xF0000201, 0, smc_ams_iram_copy},
|
||||||
{0xF0000002, 0, smc_read_write_register},
|
{0xF0000002, 0, smc_read_write_register},
|
||||||
{0xF0000203, 0, smc_ams_write_address},
|
{0xF0000003, 0, smc_ams_write_address},
|
||||||
};
|
};
|
||||||
#define SMC_AMS_HANDLERS (sizeof(g_smc_ams_table) / sizeof(g_smc_ams_table[0]))
|
#define SMC_AMS_HANDLERS (sizeof(g_smc_ams_table) / sizeof(g_smc_ams_table[0]))
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,13 @@ static inline uintptr_t get_physical_address(const void *vaddr) {
|
||||||
return (PAR & 1) ? 0ull : (PAR & MASK2L(40, 12)) | ((uintptr_t)vaddr & MASKL(12));
|
return (PAR & 1) ? 0ull : (PAR & MASK2L(40, 12)) | ((uintptr_t)vaddr & MASKL(12));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uintptr_t get_physical_address_el0(const uintptr_t el0_vaddr) {
|
||||||
|
uintptr_t PAR;
|
||||||
|
__asm__ __volatile__ ("at s1e0r, %0" :: "r"(el0_vaddr));
|
||||||
|
__asm__ __volatile__ ("mrs %0, par_el1" : "=r"(PAR));
|
||||||
|
return (PAR & 1) ? 0ull : (PAR & MASK2L(40, 12)) | ((uintptr_t)el0_vaddr & MASKL(12));
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint32_t read32le(const volatile void *dword, size_t offset) {
|
static inline uint32_t read32le(const volatile void *dword, size_t offset) {
|
||||||
return *(uint32_t *)((uintptr_t)dword + offset);
|
return *(uint32_t *)((uintptr_t)dword + offset);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue