Created
January 5, 2024 01:28
-
-
Save chris-pcguy/dc5ce4a0e5de9a024892554f21f2fd8d to your computer and use it in GitHub Desktop.
Here with enabled trace buffer.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Here with enabled trace buffer. Some workarounds were needed, because of the shmbuf mapping-way the first 0x4000 bytes won't reach the register handler. Additionally, SEPOS has the position pointer on offset 0x4 (unaligned), and that makes CASAL (locking opcode) hang indefinitely. | |
diff --git a/hw/arm/apple_a13.c b/hw/arm/apple_a13.c | |
index cc333a0049..b7460ee975 100644 | |
--- a/hw/arm/apple_a13.c | |
+++ b/hw/arm/apple_a13.c | |
@@ -131,6 +131,20 @@ void apple_a13_cpu_start(AppleA13State *tcpu) | |
} | |
} | |
+void apple_a13_cpu_reset(AppleA13State *tcpu) | |
+{ | |
+ int ret = QEMU_ARM_POWERCTL_RET_SUCCESS; | |
+ | |
+ if (ARM_CPU(tcpu)->power_state != PSCI_OFF) { | |
+ ret = arm_reset_cpu(tcpu->mpidr); | |
+ } | |
+ | |
+ if (ret != QEMU_ARM_POWERCTL_RET_SUCCESS) { | |
+ error_report("%s: failed to reset CPU %d: err %d", __func__, | |
+ tcpu->cpu_id, ret); | |
+ } | |
+} | |
+ | |
void apple_a13_cpu_off(AppleA13State *tcpu) | |
{ | |
int ret = QEMU_ARM_POWERCTL_RET_SUCCESS; | |
@@ -494,7 +508,9 @@ static const ARMCPRegInfo apple_a13_cp_reginfo_tcg[] = { | |
A13_CPREG_DEF(ARM64_REG_HID13, 3, 0, 15, 14, 0, PL1_RW, 0), | |
A13_CPREG_DEF(ARM64_REG_HID14, 3, 0, 15, 15, 0, PL1_RW, 0), | |
A13_CPREG_DEF(ARM64_REG_HID16, 3, 0, 15, 15, 2, PL1_RW, 0), | |
- A13_CPREG_DEF(ARM64_REG_LSU_ERR_STS, 3, 3, 15, 0, 0, PL1_RW, 0), | |
+ A13_CPREG_DEF(ARM64_REG_LSU_ERR_STS, 3, 3, 15, 0, 0, PL1_RW, 0), // A14 SYS_LSU_ERR_STS | |
+ A13_CPREG_DEF(SYS_E_LSU_ERR_STS, 3, 3, 15, 2, 0, PL1_RW, 0), // A16 SYS_E_LSU_ERR_STS | |
+ A13_CPREG_DEF(SYS_E_FED_ERR_STS, 3, 4, 15, 0, 2, PL1_RW, 0), // A16 SYS_E_FED_ERR_STS | |
A13_CPREG_DEF(IMP_BARRIER_LBSY_BST_SYNC_W0_EL0, 3, 3, 15, 15, 0, PL1_RW, 0), | |
A13_CPREG_DEF(IMP_BARRIER_LBSY_BST_SYNC_W1_EL0, 3, 3, 15, 15, 1, PL1_RW, 0), | |
A13_CPREG_DEF(ARM64_REG_3_3_15_7, 3, 3, 15, 7, 0, PL1_RW, | |
@@ -510,6 +526,9 @@ static const ARMCPRegInfo apple_a13_cp_reginfo_tcg[] = { | |
A13_CPREG_DEF(ARM64_REG_CYC_OVRD, 3, 5, 15, 5, 0, PL1_RW, 0), | |
A13_CPREG_DEF(ARM64_REG_ACC_CFG, 3, 5, 15, 4, 0, PL1_RW, 0), | |
A13_CPREG_DEF(S3_5_c15_c10_1, 3, 5, 15, 10, 1, PL0_RW, 0), | |
+ A13_CPREG_DEF(SYS_PRE_LLCFLUSH_TMR, 3, 5, 15, 7, 0, PL1_RW, 0), | |
+ A13_CPREG_DEF(SYS_ACC_PWR_DN_SAVE, 3, 7, 15, 2, 0, PL1_RW, 0), | |
+ A13_CPREG_DEF(SYS_AON_CNT_CTL, 3, 7, 15, 4, 0, PL1_RW, 0), | |
A13_CPREG_DEF(UPMPCM, 3, 7, 15, 5, 4, PL1_RW, 0), | |
A13_CPREG_DEF(UPMCR0, 3, 7, 15, 0, 4, PL1_RW, 0), | |
A13_CPREG_DEF(UPMSR, 3, 7, 15, 6, 4, PL1_RW, 0), | |
@@ -708,7 +727,7 @@ AppleA13State *apple_a13_cpu_create(DTBNode *node, char *name, uint32_t cpu_id, | |
} | |
} | |
- if (tcpu->cpu_id == 0 || node == NULL) { | |
+ if (tcpu->cpu_id == 0) { | |
if (node) { | |
set_dtb_prop(node, "state", 8, "running"); | |
} | |
@@ -807,6 +826,8 @@ static const VMStateDescription vmstate_apple_a13 = { | |
VMSTATE_A13_CPREG(ARM64_REG_HID14), | |
VMSTATE_A13_CPREG(ARM64_REG_HID16), | |
VMSTATE_A13_CPREG(ARM64_REG_LSU_ERR_STS), | |
+ VMSTATE_A13_CPREG(SYS_E_LSU_ERR_STS), | |
+ VMSTATE_A13_CPREG(SYS_E_FED_ERR_STS), | |
VMSTATE_A13_CPREG(PMC0), | |
VMSTATE_A13_CPREG(PMC1), | |
VMSTATE_A13_CPREG(PMCR0), | |
@@ -818,6 +839,9 @@ static const VMStateDescription vmstate_apple_a13 = { | |
VMSTATE_A13_CPREG(ARM64_REG_CYC_OVRD), | |
VMSTATE_A13_CPREG(ARM64_REG_ACC_CFG), | |
VMSTATE_A13_CPREG(S3_5_c15_c10_1), | |
+ VMSTATE_A13_CPREG(SYS_PRE_LLCFLUSH_TMR), | |
+ VMSTATE_A13_CPREG(SYS_ACC_PWR_DN_SAVE), | |
+ VMSTATE_A13_CPREG(SYS_AON_CNT_CTL), | |
VMSTATE_A13_CPREG(UPMPCM), | |
VMSTATE_A13_CPREG(UPMCR0), | |
VMSTATE_A13_CPREG(UPMSR), | |
diff --git a/hw/arm/apple_sep.c b/hw/arm/apple_sep.c | |
index 9c83c57399..d81bacbc7e 100644 | |
--- a/hw/arm/apple_sep.c | |
+++ b/hw/arm/apple_sep.c | |
@@ -22,12 +22,163 @@ | |
#include "hw/arm/apple_a13.h" | |
#include "hw/arm/apple_a9.h" | |
#include "hw/arm/apple_sep.h" | |
+#include "hw/misc/apple_mbox.h" | |
#include "hw/arm/xnu.h" | |
#include "hw/core/cpu.h" | |
#include "qapi/error.h" | |
#include "qemu/error-report.h" | |
#include "qemu/log.h" | |
#include "qemu/units.h" | |
+#include "hw/arm/t8030.h" | |
+#include "exec/address-spaces.h" | |
+#include "hw/irq.h" | |
+#include "sysemu/dma.h" | |
+#include "hw/gpio/apple_gpio.h" | |
+#include "hw/i2c/apple_i2c.h" | |
+ | |
+//#define DO_SECUREROM 1 | |
+ | |
+//DeviceState *apple_custom_gpio_create(char *name, uint64_t mmio_size, uint32_t gpio_pins, uint32_t gpio_int_groups, uint32_t phandle); | |
+ | |
+ | |
+ | |
+ | |
+static void debug_trace_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ AddressSpace *nsas = &address_space_memory; | |
+ uint32_t offset = 0; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ //g_assert(addr >= 0x4000); // some qemu/dart-mapping bug | |
+ //addr -= 0x4000; | |
+ //g_assert(addr >= 0x4004); // some qemu/dart-mapping bug and a CASAL freeze | |
+ //addr -= 0x4004; | |
+ addr += 0x4000; | |
+ //offset = ((uint32_t*)s->debug_trace_regs)[0x40 / 4] << 6; | |
+ //offset = ((uint32_t*)s->debug_trace_regs)[0x40 / 4] << 6; | |
+ address_space_read(nsas, 0x80c000 + 0x10000 + 0x4, MEMTXATTRS_UNSPECIFIED, &offset, sizeof(offset)); | |
+ if (offset == 0x0) { | |
+ offset = 0x100; | |
+ address_space_write(nsas, 0x80c000 + 0x10000 + 0x4, MEMTXATTRS_UNSPECIFIED, &offset, sizeof(offset)); | |
+ } | |
+ offset -= 1; | |
+ offset <<= 6; | |
+ | |
+#if 1 | |
+ switch (addr) { | |
+ default: | |
+#endif | |
+ memcpy(&s->debug_trace_regs[addr], &data, size); | |
+#if 1 | |
+ if ( | |
+ addr != 0x40 && // offset register | |
+ (addr - offset) != 0xa0 && | |
+ (addr - offset) != 0xa8 && | |
+ (addr - offset) != 0x80 && | |
+ (addr - offset) != 0x88 && | |
+ (addr - offset) != 0x90 && | |
+ (addr - offset) != 0x98 && | |
+ (addr - offset) != 0xb0 | |
+ ) | |
+#endif | |
+ { | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "DEBUG_TRACE: Unknown write at 0x" HWADDR_FMT_plx | |
+ " of value 0x" HWADDR_FMT_plx " size=%u offset==0x%08x\n", | |
+ addr, data, size, offset); | |
+ } | |
+ // Might not include SEPOS output, as it's not initialized like e.g. SEPD. | |
+#if 0 | |
+ //if ((addr & 0x1f) == 0x0) | |
+ //if ((addr & 0x1f) == 0x1c) | |
+ //if ((addr & 0x1f) == 0x18) | |
+ // It looks like the writes aren't always sequentially, so always print this. | |
+ { | |
+ hwaddr base_addr = addr & ~0x1f; | |
+#if 0 | |
+ qemu_log_mask(LOG_UNIMP, "DEBUG_TRACE: Debug: 0x" HWADDR_FMT_plx ": 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n" | |
+ , base_addr | |
+ , ((uint32_t*)s->debug_trace_regs)[(base_addr + 0x00) / 4] | |
+ , ((uint32_t*)s->debug_trace_regs)[(base_addr + 0x04) / 4] | |
+ , ((uint32_t*)s->debug_trace_regs)[(base_addr + 0x08) / 4] | |
+ , ((uint32_t*)s->debug_trace_regs)[(base_addr + 0x0c) / 4] | |
+ , ((uint32_t*)s->debug_trace_regs)[(base_addr + 0x10) / 4] | |
+ , ((uint32_t*)s->debug_trace_regs)[(base_addr + 0x14) / 4] | |
+ , ((uint32_t*)s->debug_trace_regs)[(base_addr + 0x18) / 4] | |
+ , ((uint32_t*)s->debug_trace_regs)[(base_addr + 0x1c) / 4] | |
+ ); | |
+#else | |
+ qemu_log_mask(LOG_UNIMP, "DEBUG_TRACE: Debug: 0x" HWADDR_FMT_plx ": 0x" HWADDR_FMT_plx " 0x" HWADDR_FMT_plx " 0x" HWADDR_FMT_plx " 0x" HWADDR_FMT_plx "\n" | |
+ , base_addr | |
+ , ((uint64_t*)s->debug_trace_regs)[(base_addr + 0x00) / 8] | |
+ , ((uint64_t*)s->debug_trace_regs)[(base_addr + 0x08) / 8] | |
+ , ((uint64_t*)s->debug_trace_regs)[(base_addr + 0x10) / 8] | |
+ , ((uint64_t*)s->debug_trace_regs)[(base_addr + 0x18) / 8] | |
+ ); | |
+#endif | |
+ } | |
+#endif | |
+#if 1 | |
+ //if (addr == 0x40) | |
+ if ((addr - offset) == 0xb0) | |
+ { | |
+ qemu_log_mask(LOG_UNIMP, "DEBUG_TRACE: Debug:" | |
+ " 0x" HWADDR_FMT_plx " 0x" HWADDR_FMT_plx " 0x" HWADDR_FMT_plx " 0x" HWADDR_FMT_plx | |
+ " 0x" HWADDR_FMT_plx " 0x" HWADDR_FMT_plx " 0x" HWADDR_FMT_plx "\n" | |
+ , ((uint64_t*)s->debug_trace_regs)[(offset + 0x80) / 8] // arg1 | |
+ , ((uint64_t*)s->debug_trace_regs)[(offset + 0x88) / 8] // arg2 | |
+ , ((uint64_t*)s->debug_trace_regs)[(offset + 0x90) / 8] // arg3 | |
+ , ((uint64_t*)s->debug_trace_regs)[(offset + 0x98) / 8] // arg4 | |
+ , ((uint64_t*)s->debug_trace_regs)[(offset + 0xa0) / 8] // arg5 | |
+ , ((uint64_t*)s->debug_trace_regs)[(offset + 0xa8) / 8] // tid | |
+ , ((uint64_t*)s->debug_trace_regs)[(offset + 0xb0) / 8] // CNTPCT_EL0 | |
+ ); | |
+ } | |
+#endif | |
+#if 1 | |
+ break; | |
+ } | |
+#endif | |
+} | |
+ | |
+static uint64_t debug_trace_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ uint64_t ret = 0; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ //g_assert(addr >= 0x4000); // some qemu/dart-mapping bug | |
+ //addr -= 0x4000; | |
+ //g_assert(addr >= 0x4004); // some qemu/dart-mapping bug and a CASAL freeze | |
+ //addr -= 0x4004; | |
+ addr += 0x4000; | |
+ ((uint32_t*)s->debug_trace_regs)[0x00 / 4] = 0xffffffff; // negated trace exclusion mask for wrapper | |
+ ((uint32_t*)s->debug_trace_regs)[0x1c / 4] = 0x0; // disable trace mask for inner function | |
+ ((uint32_t*)s->debug_trace_regs)[0x20 / 4] = 0xffffffff; // trace mask for inner function | |
+ | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&ret, &s->debug_trace_regs[addr], size); | |
+ qemu_log_mask(LOG_UNIMP, "DEBUG_TRACE: Unknown read at 0x" HWADDR_FMT_plx " size=%u ret==0x" HWADDR_FMT_plx "\n", | |
+ addr, size, ret); | |
+ } | |
+ return ret; | |
+} | |
+ | |
+static const MemoryRegionOps debug_trace_reg_ops = { | |
+ .write = debug_trace_reg_write, | |
+ .read = debug_trace_reg_read, | |
+ .endianness = DEVICE_NATIVE_ENDIAN, | |
+ .valid.min_access_size = 4, | |
+ .valid.max_access_size = 8, | |
+ .impl.min_access_size = 4, | |
+ .impl.max_access_size = 8, | |
+ .valid.unaligned = false, | |
+}; | |
+ | |
+ | |
#define REG_TRNG_FIFO_OUTPUT_BASE (0x00) | |
#define REG_TRNG_FIFO_OUTPUT_END (0x0C) | |
@@ -41,71 +192,688 @@ | |
#define REG_TRNG_ECID_LOW (0x60) | |
#define REG_TRNG_ECID_HI (0x64) | |
-static void trng_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
- unsigned size) | |
-{ | |
- AppleTRNGState *s; | |
+static void trng_regs_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ MachineState *machine = MACHINE(qdev_get_machine()); | |
+ T8030MachineState *tms = T8030_MACHINE(machine); | |
+ AppleSEPState *sep; | |
+ AppleTRNGState *s; | |
+ | |
+ sep = APPLE_SEP(object_property_get_link(OBJECT(machine), "sep", &error_fatal)); | |
+ cpu_dump_state(CPU(sep->cpu), stderr, CPU_DUMP_CODE); | |
+ | |
+ s = (AppleTRNGState *)opaque; | |
+ | |
+ switch (addr) { | |
+ case REG_TRNG_CONFIG: | |
+ s->config = (uint32_t)data; | |
+ break; | |
+ case REG_TRNG_AES_KEY_BASE ... REG_TRNG_AES_KEY_END: | |
+ memcpy(s->key + (addr - REG_TRNG_AES_KEY_BASE), &data, size); | |
+ break; | |
+ case REG_TRNG_ECID_LOW: | |
+ s->ecid &= 0xFFFFFFFF00000000; | |
+ s->ecid |= data & 0xFFFFFFFF; | |
+ break; | |
+ case REG_TRNG_ECID_HI: | |
+ s->ecid &= 0x00000000FFFFFFFF; | |
+ s->ecid |= (data & 0xFFFFFFFF) << 32; | |
+ break; | |
+#if 1 | |
+ case 0x20: | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "TRNG_REGS: OFFSET_0x20 write at 0x" HWADDR_FMT_plx | |
+ " of value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ if (data == 0xffffff) { | |
+ apple_mbox_set_custom0(sep->mbox, 0x40003); | |
+ //apple_mbox_set_custom0(sep->mbox, 0x40001); | |
+ //apple_mbox_set_custom0(sep->mbox, 0x40002); | |
+ ////apple_mbox_set_custom0(sep->mbox, 0x40000); | |
+ ////apple_mbox_set_custom0(sep->mbox, 0x0); | |
+ } | |
+ break; | |
+#endif | |
+#if 0 | |
+ case 0x1c: | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "TRNG_REGS: OFFSET_0x1c write at 0x" HWADDR_FMT_plx | |
+ " of value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ if (data == 0x600ff) { | |
+ //apple_mbox_set_custom0(sep->mbox, 0x40003); | |
+ apple_mbox_set_custom0(sep->mbox, 0x40001); | |
+ //apple_mbox_set_custom0(sep->mbox, 0x40002); | |
+ } else { | |
+ //apple_mbox_set_custom0(sep->mbox, 0x0); | |
+ } | |
+ break; | |
+#endif | |
+ default: | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "TRNG_REGS: Unknown write at 0x" HWADDR_FMT_plx | |
+ " of value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ break; | |
+ } | |
+} | |
+ | |
+static uint64_t trng_regs_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+{ | |
+ MachineState *machine = MACHINE(qdev_get_machine()); | |
+ T8030MachineState *tms = T8030_MACHINE(machine); | |
+ AppleSEPState *sep; | |
+ AppleTRNGState *s; | |
+ uint64_t ret; | |
+ | |
+ sep = APPLE_SEP(object_property_get_link(OBJECT(machine), "sep", &error_fatal)); | |
+ cpu_dump_state(CPU(sep->cpu), stderr, CPU_DUMP_CODE); | |
+ | |
+ s = (AppleTRNGState *)opaque; | |
+ | |
+ switch (addr) { | |
+ case REG_TRNG_FIFO_OUTPUT_BASE ... REG_TRNG_FIFO_OUTPUT_END: { | |
+ uint64_t ret = 0; | |
+ qcrypto_random_bytes(&ret, size, NULL); | |
+ return ret; | |
+ } | |
+ case REG_TRNG_STATUS: | |
+ return TRNG_STATUS_FILLED; | |
+ case REG_TRNG_CONFIG: | |
+ //return s->config; | |
+ return 0x100000; | |
+ case 0x78: // (value & 0x180000) == 0 == panic | |
+ return 0x180000; | |
+ case REG_TRNG_AES_KEY_BASE ... REG_TRNG_AES_KEY_END: | |
+ memcpy(&ret, s->key + (addr - REG_TRNG_AES_KEY_BASE), size); | |
+ return ret; | |
+ case REG_TRNG_ECID_LOW: | |
+ return s->ecid & 0xFFFFFFFF; | |
+ case REG_TRNG_ECID_HI: | |
+ return (s->ecid & 0xFFFFFFFF00000000) >> 32; | |
+ default: | |
+ qemu_log_mask(LOG_UNIMP, "TRNG_REGS: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
+ addr); | |
+ return 0; | |
+ } | |
+} | |
+ | |
+static const MemoryRegionOps trng_regs_reg_ops = { | |
+ .write = trng_regs_reg_write, | |
+ .read = trng_regs_reg_read, | |
+ .endianness = DEVICE_NATIVE_ENDIAN, | |
+ .valid.min_access_size = 4, | |
+ .valid.max_access_size = 4, | |
+ .impl.min_access_size = 4, | |
+ .impl.max_access_size = 4, | |
+ .valid.unaligned = false, | |
+}; | |
+ | |
+ | |
+//// | |
+ | |
+ | |
+ | |
+static void pmgr_base_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ case 0x28: | |
+ case 0x58: | |
+ data |= (data & 0xf) << 4; | |
+ goto jump_default; | |
+ default: | |
+ jump_default: | |
+ memcpy(&s->pmgr_base_regs[addr], &data, size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP PMGR_BASE: Unknown write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ break; | |
+ } | |
+} | |
+ | |
+static uint64_t pmgr_base_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ uint64_t ret = 0; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&ret, &s->pmgr_base_regs[addr], size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP PMGR_BASE: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
+ addr); | |
+ break; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+static const MemoryRegionOps pmgr_base_reg_ops = { | |
+ .write = pmgr_base_reg_write, | |
+ .read = pmgr_base_reg_read, | |
+ .endianness = DEVICE_NATIVE_ENDIAN, | |
+ .valid.min_access_size = 4, | |
+ .valid.max_access_size = 4, | |
+ .impl.min_access_size = 4, | |
+ .impl.max_access_size = 4, | |
+ .valid.unaligned = false, | |
+}; | |
+ | |
+ | |
+static void key_base_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&s->key_base_regs[addr], &data, size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP KEY_BASE: Unknown write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ break; | |
+ } | |
+} | |
+ | |
+static uint64_t key_base_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ uint64_t ret = 0; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&ret, &s->key_base_regs[addr], size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP KEY_BASE: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
+ addr); | |
+ break; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+static const MemoryRegionOps key_base_reg_ops = { | |
+ .write = key_base_reg_write, | |
+ .read = key_base_reg_read, | |
+ .endianness = DEVICE_NATIVE_ENDIAN, | |
+ .valid.min_access_size = 4, | |
+ .valid.max_access_size = 4, | |
+ .impl.min_access_size = 4, | |
+ .impl.max_access_size = 4, | |
+ .valid.unaligned = false, | |
+}; | |
+ | |
+ | |
+static void key_fcfg_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ case 0x0: | |
+ //if (data == 0x3) | |
+ { | |
+#if 0 | |
+ if (0) | |
+ { | |
+ qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ } | |
+#endif | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP KEY_FCFG: TEST0 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ //CPUState *cs = CPU(s->cpu); | |
+ //cpu_dump_state(cs, stderr, CPU_DUMP_CODE); | |
+ //usleep(500); | |
+ } | |
+ | |
+ goto jump_default; | |
+ case 0x4: | |
+ //if (data == 0x3) | |
+ { | |
+#if 0 | |
+ qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+#endif | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP KEY_FCFG: TEST1 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ //CPUState *cs = CPU(s->cpu); | |
+ //cpu_dump_state(cs, stderr, CPU_DUMP_CODE); | |
+ } | |
+ | |
+ goto jump_default; | |
+ default: | |
+ jump_default: | |
+ memcpy(&s->key_fcfg_regs[addr], &data, size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP KEY_FCFG: Unknown write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ break; | |
+ } | |
+} | |
+ | |
+static uint64_t key_fcfg_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ uint64_t ret = 0; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&ret, &s->key_fcfg_regs[addr], size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP KEY_FCFG: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
+ addr); | |
+ break; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+static const MemoryRegionOps key_fcfg_reg_ops = { | |
+ .write = key_fcfg_reg_write, | |
+ .read = key_fcfg_reg_read, | |
+ .endianness = DEVICE_NATIVE_ENDIAN, | |
+ .valid.min_access_size = 4, | |
+ .valid.max_access_size = 4, | |
+ .impl.min_access_size = 4, | |
+ .impl.max_access_size = 4, | |
+ .valid.unaligned = false, | |
+}; | |
+ | |
+ | |
+static void moni_base_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&s->moni_base_regs[addr], &data, size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP MONI_BASE: Unknown write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ break; | |
+ } | |
+} | |
+ | |
+static uint64_t moni_base_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ uint64_t ret = 0; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&ret, &s->moni_base_regs[addr], size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP MONI_BASE: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
+ addr); | |
+ break; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+static const MemoryRegionOps moni_base_reg_ops = { | |
+ .write = moni_base_reg_write, | |
+ .read = moni_base_reg_read, | |
+ .endianness = DEVICE_NATIVE_ENDIAN, | |
+ .valid.min_access_size = 4, | |
+ .valid.max_access_size = 4, | |
+ .impl.min_access_size = 4, | |
+ .impl.max_access_size = 4, | |
+ .valid.unaligned = false, | |
+}; | |
+ | |
+ | |
+static void moni_thrm_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&s->moni_thrm_regs[addr], &data, size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP MONI_THRM: Unknown write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ break; | |
+ } | |
+} | |
+ | |
+static uint64_t moni_thrm_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ uint64_t ret = 0; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&ret, &s->moni_thrm_regs[addr], size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP MONI_THRM: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
+ addr); | |
+ break; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+static const MemoryRegionOps moni_thrm_reg_ops = { | |
+ .write = moni_thrm_reg_write, | |
+ .read = moni_thrm_reg_read, | |
+ .endianness = DEVICE_NATIVE_ENDIAN, | |
+ .valid.min_access_size = 4, | |
+ .valid.max_access_size = 4, | |
+ .impl.min_access_size = 4, | |
+ .impl.max_access_size = 4, | |
+ .valid.unaligned = false, | |
+}; | |
+ | |
+ | |
+static void eisp_base_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&s->eisp_base_regs[addr], &data, size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP EISP_BASE: Unknown write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ break; | |
+ } | |
+} | |
+ | |
+static uint64_t eisp_base_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ uint64_t ret = 0; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&ret, &s->eisp_base_regs[addr], size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP EISP_BASE: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
+ addr); | |
+ break; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+static const MemoryRegionOps eisp_base_reg_ops = { | |
+ .write = eisp_base_reg_write, | |
+ .read = eisp_base_reg_read, | |
+ .endianness = DEVICE_NATIVE_ENDIAN, | |
+ .valid.min_access_size = 4, | |
+ .valid.max_access_size = 4, | |
+ .impl.min_access_size = 4, | |
+ .impl.max_access_size = 4, | |
+ .valid.unaligned = false, | |
+}; | |
+ | |
+ | |
+static void eisp_hmac_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&s->eisp_hmac_regs[addr], &data, size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP EISP_HMAC: Unknown write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ break; | |
+ } | |
+} | |
+ | |
+static uint64_t eisp_hmac_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ uint64_t ret = 0; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&ret, &s->eisp_hmac_regs[addr], size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP EISP_HMAC: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
+ addr); | |
+ break; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+static const MemoryRegionOps eisp_hmac_reg_ops = { | |
+ .write = eisp_hmac_reg_write, | |
+ .read = eisp_hmac_reg_read, | |
+ .endianness = DEVICE_NATIVE_ENDIAN, | |
+ .valid.min_access_size = 4, | |
+ .valid.max_access_size = 4, | |
+ .impl.min_access_size = 4, | |
+ .impl.max_access_size = 4, | |
+ .valid.unaligned = false, | |
+}; | |
+ | |
+ | |
+static void aess_base_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&s->aess_base_regs[addr], &data, size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP AESS_BASE: Unknown write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ break; | |
+ } | |
+} | |
+ | |
+static uint64_t aess_base_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ uint64_t ret = 0; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&ret, &s->aess_base_regs[addr], size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP AESS_BASE: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
+ addr); | |
+ break; | |
+ } | |
+ | |
+ return ret; | |
+} | |
- s = (AppleTRNGState *)opaque; | |
+static const MemoryRegionOps aess_base_reg_ops = { | |
+ .write = aess_base_reg_write, | |
+ .read = aess_base_reg_read, | |
+ .endianness = DEVICE_NATIVE_ENDIAN, | |
+ .valid.min_access_size = 4, | |
+ .valid.max_access_size = 4, | |
+ .impl.min_access_size = 4, | |
+ .impl.max_access_size = 4, | |
+ .valid.unaligned = false, | |
+}; | |
+ | |
+static void pka_base_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
switch (addr) { | |
- case REG_TRNG_CONFIG: | |
- s->config = (uint32_t)data; | |
- break; | |
- case REG_TRNG_AES_KEY_BASE ... REG_TRNG_AES_KEY_END: | |
- memcpy(s->key + (addr - REG_TRNG_AES_KEY_BASE), &data, size); | |
- break; | |
- case REG_TRNG_ECID_LOW: | |
- s->ecid &= 0xFFFFFFFF00000000; | |
- s->ecid |= data & 0xFFFFFFFF; | |
+ default: | |
+ memcpy(&s->pka_base_regs[addr], &data, size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP PKA_BASE: Unknown write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
break; | |
- case REG_TRNG_ECID_HI: | |
- s->ecid &= 0x00000000FFFFFFFF; | |
- s->ecid |= (data & 0xFFFFFFFF) << 32; | |
+ } | |
+} | |
+ | |
+static uint64_t pka_base_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ uint64_t ret = 0; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&ret, &s->pka_base_regs[addr], size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP PKA_BASE: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
+ addr); | |
break; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+static const MemoryRegionOps pka_base_reg_ops = { | |
+ .write = pka_base_reg_write, | |
+ .read = pka_base_reg_read, | |
+ .endianness = DEVICE_NATIVE_ENDIAN, | |
+ .valid.min_access_size = 4, | |
+ .valid.max_access_size = 4, | |
+ .impl.min_access_size = 4, | |
+ .impl.max_access_size = 4, | |
+ .valid.unaligned = false, | |
+}; | |
+ | |
+#if 0 | |
+ | |
+static void gpio_base_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
default: | |
+ memcpy(&s->gpio_base_regs[addr], &data, size); | |
qemu_log_mask(LOG_UNIMP, | |
- "TRNG: Unknown write at 0x" HWADDR_FMT_plx | |
- " of value 0x" HWADDR_FMT_plx "\n", | |
+ "SEP GPIO_BASE: Unknown write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
addr, data); | |
break; | |
} | |
} | |
-static uint64_t trng_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+static uint64_t gpio_base_reg_read(void *opaque, hwaddr addr, unsigned size) | |
{ | |
- AppleTRNGState *s; | |
- uint64_t ret; | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ uint64_t ret = 0; | |
- s = (AppleTRNGState *)opaque; | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ case 0xc: | |
+ case 0x800: | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP GPIO_BASE: TEST0 read 0x" HWADDR_FMT_plx "\n", | |
+ addr); | |
+ CPUState *cs = CPU(s->cpu); | |
+ cpu_dump_state(cs, stderr, CPU_DUMP_CODE); | |
+ //usleep(500); | |
+ goto jump_default; | |
+ default: | |
+ jump_default: | |
+ memcpy(&ret, &s->gpio_base_regs[addr], size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP GPIO_BASE: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
+ addr); | |
+ break; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+static const MemoryRegionOps gpio_base_reg_ops = { | |
+ .write = gpio_base_reg_write, | |
+ .read = gpio_base_reg_read, | |
+ .endianness = DEVICE_NATIVE_ENDIAN, | |
+ .valid.min_access_size = 4, | |
+ .valid.max_access_size = 4, | |
+ .impl.min_access_size = 4, | |
+ .impl.max_access_size = 4, | |
+ .valid.unaligned = false, | |
+}; | |
+ | |
+static void i2c_base_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
switch (addr) { | |
- case REG_TRNG_FIFO_OUTPUT_BASE ... REG_TRNG_FIFO_OUTPUT_END: { | |
- uint64_t ret = 0; | |
- qcrypto_random_bytes(&ret, size, NULL); | |
- return ret; | |
+ default: | |
+ memcpy(&s->i2c_base_regs[addr], &data, size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP I2C_BASE: Unknown write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ break; | |
} | |
- case REG_TRNG_STATUS: | |
- return TRNG_STATUS_FILLED; | |
- case REG_TRNG_CONFIG: | |
- return s->config; | |
- case REG_TRNG_AES_KEY_BASE ... REG_TRNG_AES_KEY_END: | |
- memcpy(&ret, s->key + (addr - REG_TRNG_AES_KEY_BASE), size); | |
- return ret; | |
- case REG_TRNG_ECID_LOW: | |
- return s->ecid & 0xFFFFFFFF; | |
- case REG_TRNG_ECID_HI: | |
- return (s->ecid & 0xFFFFFFFF00000000) >> 32; | |
+} | |
+ | |
+static uint64_t i2c_base_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ uint64_t ret = 0; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
default: | |
- qemu_log_mask(LOG_UNIMP, "TRNG: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
+ memcpy(&ret, &s->i2c_base_regs[addr], size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP I2C_BASE: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
addr); | |
- return 0; | |
+ break; | |
} | |
+ | |
+ return ret; | |
} | |
-static const MemoryRegionOps trng_reg_ops = { | |
- .write = trng_reg_write, | |
- .read = trng_reg_read, | |
+static const MemoryRegionOps i2c_base_reg_ops = { | |
+ .write = i2c_base_reg_write, | |
+ .read = i2c_base_reg_read, | |
.endianness = DEVICE_NATIVE_ENDIAN, | |
.valid.min_access_size = 4, | |
.valid.max_access_size = 4, | |
@@ -114,11 +882,15 @@ static const MemoryRegionOps trng_reg_ops = { | |
.valid.unaligned = false, | |
}; | |
+#endif | |
+ | |
+ | |
static void misc0_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
unsigned size) | |
{ | |
AppleSEPState *s = APPLE_SEP(opaque); | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
switch (addr) { | |
default: | |
memcpy(&s->misc0_regs[addr], &data, size); | |
@@ -135,6 +907,7 @@ static uint64_t misc0_reg_read(void *opaque, hwaddr addr, unsigned size) | |
AppleSEPState *s = APPLE_SEP(opaque); | |
uint64_t ret = 0; | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
switch (addr) { | |
case 0xc: // ???? bit1 clear, bit0 set | |
return (0 << 1) | (1 << 0); | |
@@ -166,6 +939,8 @@ static void misc1_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
unsigned size) | |
{ | |
AppleSEPState *s = APPLE_SEP(opaque); | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
switch (addr) { | |
// case 0x20: | |
// break; | |
@@ -184,6 +959,7 @@ static uint64_t misc1_reg_read(void *opaque, hwaddr addr, unsigned size) | |
AppleSEPState *s = APPLE_SEP(opaque); | |
uint64_t ret = 0; | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
switch (addr) { | |
case 0xc: // ???? bit1 clear, bit0 set | |
return (0 << 1) | (1 << 0); | |
@@ -219,6 +995,8 @@ static void misc2_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
unsigned size) | |
{ | |
AppleSEPState *s = APPLE_SEP(opaque); | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
switch (addr) { | |
default: | |
memcpy(&s->misc2_regs[addr], &data, size); | |
@@ -235,6 +1013,7 @@ static uint64_t misc2_reg_read(void *opaque, hwaddr addr, unsigned size) | |
AppleSEPState *s = APPLE_SEP(opaque); | |
uint64_t ret = 0; | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
switch (addr) { | |
case 0x24: // ???? | |
return 0x0; | |
@@ -261,8 +1040,412 @@ static const MemoryRegionOps misc2_reg_ops = { | |
}; | |
+static void misc3_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&s->misc3_regs[addr], &data, size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP MISC3: Unknown write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ break; | |
+ } | |
+} | |
+ | |
+static uint64_t misc3_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ uint64_t ret = 0; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&ret, &s->misc3_regs[addr], size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP MISC3: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
+ addr); | |
+ break; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+static const MemoryRegionOps misc3_reg_ops = { | |
+ .write = misc3_reg_write, | |
+ .read = misc3_reg_read, | |
+ .endianness = DEVICE_NATIVE_ENDIAN, | |
+ .valid.min_access_size = 4, | |
+ .valid.max_access_size = 4, | |
+ .impl.min_access_size = 4, | |
+ .impl.max_access_size = 4, | |
+ .valid.unaligned = false, | |
+}; | |
+ | |
+ | |
+static void misc4_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
+ unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ struct sep_message sep_msg = { 0 }; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ case 0x4: | |
+ if (data == 0xf2e31133) // iBoot would send those requests. iOS warns about the responses, because it doesn't expect them. | |
+ { | |
+ sep_msg.endpoint = 0xff; | |
+ | |
+ sep_msg.opcode = 3; // kOpCode_GenerateNonce | |
+ sep_msg.tag = 0x67; | |
+ //memcpy(msg0->data, sep_msg, 16); | |
+ //apple_mbox_inbox_push(s->mbox, msg0); | |
+ //IOP_LOG_MSG(s->mbox, "SEP MISC4: Sent fake SEPROM_Opcode3/kOpCode_GenerateNonce", msg0); | |
+ apple_mbox_send_inbox_control_message(s->mbox, 0, sep_msg.raw); | |
+ qemu_log_mask(LOG_UNIMP, "SEP MISC4: Sent fake SEPROM_Opcode3/kOpCode_GenerateNonce\n"); | |
+ | |
+ | |
+ sep_msg.opcode = 17; // Opcode 17 | |
+ sep_msg.tag = 0x0; | |
+ sep_msg.data = 0x8000; // SEPFW on iOS 14.0/14.4.2 for T8020, if I found the correct data in Ghidra. | |
+ apple_mbox_send_inbox_control_message(s->mbox, 0, sep_msg.raw); | |
+ qemu_log_mask(LOG_UNIMP, "SEP MISC4: Sent fake SEPROM_Opcode17\n"); | |
+ } | |
+ if (data == 0xfc4a2cac) // Enable Trace Buffer | |
+ { | |
+ AddressSpace *nsas = &address_space_memory; | |
+ typedef struct QEMU_PACKED { | |
+ uint32_t name; | |
+ uint32_t size; | |
+ uint64_t offset; | |
+ } shm_region_t; | |
+#if 0 | |
+ shm_region_t shm_region_PAD0 = { 0 }; | |
+ g_assert(sizeof(shm_region_PAD0) == 0x10); | |
+ shm_region_PAD0.name = 'PAD0'; | |
+ shm_region_PAD0.size = 0x4000; | |
+ shm_region_PAD0.offset = 0x10000; | |
+#endif | |
+ shm_region_t shm_region_TRAC = { 0 }; | |
+ g_assert(sizeof(shm_region_TRAC) == 0x10); | |
+ shm_region_TRAC.name = 'TRAC'; | |
+ shm_region_TRAC.size = DEBUG_TRACE_SIZE; | |
+ shm_region_TRAC.offset = 0x10000; | |
+ shm_region_t shm_region_null = { 0 }; | |
+ g_assert(sizeof(shm_region_null) == 0x10); | |
+ shm_region_null.name = 'null'; | |
+ //address_space_write(nsas, 0x80c020, MEMTXATTRS_UNSPECIFIED, &shm_region_PAD0, sizeof(shm_region_PAD0)); | |
+ address_space_write(nsas, 0x80c020, MEMTXATTRS_UNSPECIFIED, &shm_region_TRAC, sizeof(shm_region_TRAC)); | |
+ address_space_write(nsas, 0x80c030, MEMTXATTRS_UNSPECIFIED, &shm_region_null, sizeof(shm_region_null)); | |
+ uint32_t value; | |
+ value = 0xffffffff; | |
+ address_space_write(nsas, 0x80c000 + 0x10000, MEMTXATTRS_UNSPECIFIED, &value, sizeof(value)); | |
+ value = 0x100; | |
+ address_space_write(nsas, 0x80c000 + 0x10004, MEMTXATTRS_UNSPECIFIED, &value, sizeof(value)); | |
+ typedef struct QEMU_PACKED { | |
+ uint64_t name; | |
+ uint64_t size; | |
+ uint8_t maybe_permissions; // 0x04/0x06/0x16 // (arg5 & 1) != 0 create_object panic? ;; maybe permissions | |
+ uint8_t arg6; // 0x00/0x02/0x06 // >= 0x03 create_object panic? | |
+ uint8_t arg7; // 0x01/0x02/0x03/0x04/0x05/0x0d/0x0e/0x0f/0x10 // if (arg7 != 0) create_object data_346d0 checking block ;; maybe module_index | |
+ uint8_t pad0; | |
+ uint32_t unkn1; // maybe segment name like _dat, _asc, STAK, TEXT, PMGR or _hep. | |
+ uint64_t phys; | |
+ uint32_t phys_module_name; // phys module name like EISP | |
+ uint32_t phys_region_name; // phys region name like BASE | |
+ uint64_t virt_mapping_next; // sepos_virt_mapping_t | |
+ uint64_t virt_mapping_previous; // sepos_virt_mapping_t.next or object_mappings_t.virt_mapping_next | |
+ uint64_t acl_next; // sepos_acl_t | |
+ uint64_t acl_previous; // sepos_acl_t.next or object_mappings_t.acl_next | |
+ } object_mappings_t; | |
+ typedef struct QEMU_PACKED | |
+ { | |
+ uint64_t object_mapping; // object_mappings_t | |
+ uint64_t maybe_virt_base; | |
+ uint8_t sending_pid; | |
+ uint8_t maybe_permissions; // maybe permissions ;; data0 | |
+ uint8_t maybe_subregion; // 0x00/0x01/0x02 ;; data1 | |
+ uint8_t pad0; | |
+ uint32_t pad1; | |
+ uint64_t module_next; // sepos_virt_mapping_t | |
+ uint64_t module_previous; // sepos_virt_mapping_t.next | |
+ uint64_t all_next; // sepos_virt_mapping_t | |
+ uint64_t all_previous; // sepos_virt_mapping_t.all_next | |
+ } sepos_virt_mapping_t; | |
+ typedef struct QEMU_PACKED { | |
+ uint32_t maybe_module_id; // 0x2/0x3/0x4/10001 | |
+ uint32_t acl; // 0x4/0x6/0x14/0x16 | |
+ uint64_t next; // sepos_acl_t | |
+ uint64_t previous; // sepos_acl_t.next | |
+ } sepos_acl_t; | |
+ object_mappings_t object_mapping_TRAC = { 0 }; | |
+ g_assert(sizeof(object_mapping_TRAC) == 0x48); | |
+ sepos_acl_t acl_for_TRAC = { 0 }; | |
+ g_assert(sizeof(acl_for_TRAC) == 0x18); | |
+ sepos_virt_mapping_t virt_mapping_for_TRAC = { 0 }; | |
+ g_assert(sizeof(virt_mapping_for_TRAC) == 0x38); | |
+#define SEPOS_PHYS_BASE 0x340600000ull | |
+#define SEPOS_OBJECT_MAPPING_BASE 0x198d0 | |
+#define SEPOS_OBJECT_MAPPING_INDEX 7 | |
+//#define SEPOS_VIRT_MAPPING_BASE 0x282d0 | |
+//#define SEPOS_VIRT_MAPPING_INDEX 555 | |
+#define SEPOS_ACL_BASE 0x140d0 | |
+#define SEPOS_ACL_INDEX 19 | |
+ object_mapping_TRAC.name = 'TRAC'; | |
+ object_mapping_TRAC.size = DEBUG_TRACE_SIZE; | |
+ //object_mapping_TRAC.size = 0x8000; | |
+ object_mapping_TRAC.maybe_permissions = 0x06; | |
+ object_mapping_TRAC.arg6 = 0x00; | |
+ object_mapping_TRAC.arg7 = 0x01; | |
+ object_mapping_TRAC.unkn1 = '_dat'; | |
+ object_mapping_TRAC.phys = 0x80c000 + 0x10000; | |
+ object_mapping_TRAC.virt_mapping_previous = SEPOS_OBJECT_MAPPING_BASE + (sizeof(object_mappings_t) * SEPOS_OBJECT_MAPPING_INDEX) + offsetof(object_mappings_t, virt_mapping_next); | |
+ //object_mapping_TRAC.virt_mapping_next = SEPOS_VIRT_MAPPING_BASE + (sizeof(sepos_virt_mapping_t) * SEPOS_VIRT_MAPPING_INDEX); | |
+ //object_mapping_TRAC.virt_mapping_previous = SEPOS_VIRT_MAPPING_BASE + (sizeof(sepos_virt_mapping_t) * SEPOS_VIRT_MAPPING_INDEX) + offsetof(sepos_virt_mapping_t, module_next); | |
+ object_mapping_TRAC.acl_next = SEPOS_ACL_BASE + (sizeof(sepos_acl_t) * SEPOS_ACL_INDEX); | |
+ object_mapping_TRAC.acl_previous = SEPOS_ACL_BASE + (sizeof(sepos_acl_t) * SEPOS_ACL_INDEX) + offsetof(sepos_acl_t, next); | |
+ address_space_write(nsas, SEPOS_PHYS_BASE + SEPOS_OBJECT_MAPPING_BASE + (sizeof(object_mappings_t) * SEPOS_OBJECT_MAPPING_INDEX), MEMTXATTRS_UNSPECIFIED, &object_mapping_TRAC, sizeof(object_mapping_TRAC)); | |
+#if 0 | |
+ virt_mapping_for_TRAC.object_mapping = SEPOS_OBJECT_MAPPING_BASE + (sizeof(object_mappings_t) * SEPOS_OBJECT_MAPPING_INDEX); | |
+ virt_mapping_for_TRAC.maybe_virt_base = 0xdeadbeef00000000ull; | |
+ //virt_mapping_for_TRAC.sending_pid = 0x01; | |
+ virt_mapping_for_TRAC.sending_pid = 0x02; | |
+ virt_mapping_for_TRAC.maybe_permissions = 0x06; | |
+ //virt_mapping_for_TRAC.maybe_subregion = 0x00; | |
+ //virt_mapping_for_TRAC.maybe_subregion = 0x01; | |
+ virt_mapping_for_TRAC.maybe_subregion = 0x02; | |
+ virt_mapping_for_TRAC.module_previous = SEPOS_VIRT_MAPPING_BASE + (sizeof(sepos_virt_mapping_t) * SEPOS_VIRT_MAPPING_INDEX) + offsetof(sepos_virt_mapping_t, module_next); | |
+ virt_mapping_for_TRAC.all_previous = SEPOS_VIRT_MAPPING_BASE + (sizeof(sepos_virt_mapping_t) * SEPOS_VIRT_MAPPING_INDEX) + offsetof(sepos_virt_mapping_t, all_next); | |
+ address_space_write(nsas, SEPOS_PHYS_BASE + SEPOS_VIRT_MAPPING_BASE + (sizeof(sepos_virt_mapping_t) * SEPOS_VIRT_MAPPING_INDEX), MEMTXATTRS_UNSPECIFIED, &virt_mapping_for_TRAC, sizeof(virt_mapping_for_TRAC)); | |
+#endif | |
+ acl_for_TRAC.maybe_module_id = 10001; | |
+ ////acl_for_TRAC.maybe_module_id = 55; // non-existant | |
+ acl_for_TRAC.acl = 0x6; | |
+ acl_for_TRAC.previous = SEPOS_OBJECT_MAPPING_BASE + (sizeof(object_mappings_t) * SEPOS_OBJECT_MAPPING_INDEX) + offsetof(object_mappings_t, acl_next); | |
+ address_space_write(nsas, SEPOS_PHYS_BASE + SEPOS_ACL_BASE + (sizeof(sepos_acl_t) * SEPOS_ACL_INDEX), MEMTXATTRS_UNSPECIFIED, &acl_for_TRAC, sizeof(acl_for_TRAC)); | |
+#if 0 | |
+ // bypass if_module_AAES_Debu_or_SEPD(sending_pid) check inside get_acl_check_is_sender_matching_or_AAES_Debu_or_SEPD_and_accessible_by_all_processes(ool_handle, sending_pid) | |
+ uint32_t value32_nop = 0xd503201f; // nop | |
+ address_space_write(nsas, SEPOS_PHYS_BASE + 0xd82c, MEMTXATTRS_UNSPECIFIED, &value32_nop, sizeof(value32_nop)); | |
+#elif 0 | |
+ // alternative bypass as if_module_AAES_Debu_or_SEPD is also used by other functions, very wide-reaching, as it's bypassing e.g. overflow checks on many different functions. | |
+ uint32_t value32_mov_x0_1 = 0xd2800020; // mov x0, #0x1 | |
+ address_space_write(nsas, SEPOS_PHYS_BASE + 0x133d4, MEMTXATTRS_UNSPECIFIED, &value32_mov_x0_1, sizeof(value32_mov_x0_1)); | |
+#else | |
+ // alternative bypass as if_module_AAES_Debu_or_SEPD is also used by other functions, more restrictive. | |
+ uint32_t value32_nop = 0xd503201f; // nop | |
+ address_space_write(nsas, SEPOS_PHYS_BASE + 0x11bb0, MEMTXATTRS_UNSPECIFIED, &value32_nop, sizeof(value32_nop)); | |
+#endif | |
+ } | |
+ break; | |
+ case 0x8: | |
+ if (data == 0x23bfdfe7) | |
+ { | |
+ AddressSpace *nsas = &address_space_memory; | |
+ //uint32_t value32_mov_x8_0 = 0xd2800008; // mov x8, #0x0 | |
+ uint8_t zeroes_16bytes[16] = {0}; | |
+ // The first 16bytes of SEPB.random_0 are being used for SEPOS' ASLR. GDB's awatch refuses to tell me where it ends up, so here you go, I'm just zeroing that shit. | |
+ address_space_write(nsas, 0x340736380ULL, MEMTXATTRS_UNSPECIFIED, &zeroes_16bytes, sizeof(zeroes_16bytes)); | |
+ } | |
+ break; | |
+ case 0x0: | |
+ memcpy(&s->misc4_regs[addr], &data, size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP MISC4: MISC4_0 write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ if (data == 0xdeadbee0) { | |
+ qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ } | |
+ if (data == 0xdeadbee1) { | |
+ qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ)); | |
+ } | |
+ if (data == 0xdeadbee2) { | |
+ qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_VIRQ)); | |
+ } | |
+ if (data == 0xdeadbee3) { | |
+ qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_VFIQ)); | |
+ } | |
+ | |
+ if (data == 0xdeadbee4) { | |
+ qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ } | |
+ if (data == 0xdeadbee5) { | |
+ qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ)); | |
+ } | |
+ if (data == 0xdeadbee6) { | |
+ qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_VIRQ)); | |
+ } | |
+ if (data == 0xdeadbee7) { | |
+ qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_VFIQ)); | |
+ } | |
+ break; | |
+ case 0x3370: | |
+ memcpy(&s->misc4_regs[addr], &data, size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP MISC4: MISC4_1 write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ apple_mbox_set_custom0(s->mbox, data); | |
+ break; | |
+ //case 0x4: | |
+ //case 0x8: | |
+ case 0x114: | |
+ case 0x214: | |
+ case 0x218: | |
+ case 0x21c: | |
+ case 0x220: | |
+ case 0x2d8: | |
+ case 0x2dc: | |
+ case 0x2e0: // ecid low | |
+ case 0x2e4: // ecid high | |
+ case 0x2e8: // board-id | |
+ case 0x2ec: // chip-id | |
+ case 0x314: | |
+ case 0x318: | |
+ case 0x31c: | |
+ memcpy(&s->misc4_regs[addr], &data, size); | |
+ break; | |
+ default: | |
+ //jump_default: | |
+ memcpy(&s->misc4_regs[addr], &data, size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP MISC4: Unknown write at 0x" HWADDR_FMT_plx | |
+ " with value 0x" HWADDR_FMT_plx "\n", | |
+ addr, data); | |
+ break; | |
+ } | |
+} | |
+ | |
+static uint64_t misc4_reg_read(void *opaque, hwaddr addr, unsigned size) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ uint64_t ret = 0; | |
+ | |
+ cpu_dump_state(CPU(s->cpu), stderr, CPU_DUMP_CODE); | |
+ switch (addr) { | |
+ default: | |
+ memcpy(&ret, &s->misc4_regs[addr], size); | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "SEP MISC4: Unknown read at 0x" HWADDR_FMT_plx "\n", | |
+ addr); | |
+ break; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+static const MemoryRegionOps misc4_reg_ops = { | |
+ .write = misc4_reg_write, | |
+ .read = misc4_reg_read, | |
+ .endianness = DEVICE_NATIVE_ENDIAN, | |
+ .valid.min_access_size = 4, | |
+ .valid.max_access_size = 4, | |
+ .impl.min_access_size = 4, | |
+ .impl.max_access_size = 4, | |
+ .valid.unaligned = false, | |
+}; | |
+ | |
+static uint64_t alarm_counter = 0; | |
+ | |
static const struct AppleMboxOps sep_mailbox_ops = {}; | |
+static void sep_alarm(void *opaque) | |
+{ | |
+ AppleSEPState *s = APPLE_SEP(opaque); | |
+ | |
+ //if ((alarm_counter % 1000) == 0) | |
+ //if ((alarm_counter % 250) == 0) | |
+ { | |
+ //fprintf(stderr, "sep_alarm: entered function\n"); | |
+ } | |
+ alarm_counter++; | |
+ int64_t qemu_now; | |
+ qemu_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); | |
+ //timer_mod_ns(s->timer, qemu_now + 10000); | |
+ //timer_mod_ns(s->timer, qemu_now + 1000000); | |
+ //timer_mod_ns(s->timer, qemu_now + 10000000); | |
+ //timer_mod_ns(s->timer, qemu_now + 10000000ull*1000); | |
+ //timer_mod_ns(s->timer, qemu_now + 10000000ull*50); | |
+ //timer_mod_ns(s->timer, qemu_now + 10000000ull*100); | |
+ timer_mod_ns(s->timer, qemu_now + 10000000ull*10); | |
+ MachineState *machine = MACHINE(qdev_get_machine()); | |
+ T8030MachineState *tms = T8030_MACHINE(machine); | |
+ DeviceState *gpio = NULL; | |
+ gpio = DEVICE(object_property_get_link(OBJECT(machine), "sep_gpio", &error_fatal)); | |
+ | |
+#if 0 | |
+ //int gpio_irq = 3; | |
+ //int gpio_irq = 0; | |
+ //qemu_set_irq(qdev_get_gpio_in(gpio, gpio_irq), false); | |
+ //qemu_set_irq(qdev_get_gpio_in(gpio, gpio_irq), true); | |
+ AppleGPIOState *gpio_s; | |
+ gpio_s = APPLE_GPIO(gpio); | |
+ //qemu_set_irq(gpio_s->irqs[0], false); | |
+ for (int i = 0; i < 4; i++) | |
+ { | |
+ //qemu_set_irq(gpio_s->out[i], 0); | |
+ //qemu_set_irq(qdev_get_gpio_in(gpio, i), false); | |
+ qemu_set_irq(gpio_s->out[i], 1); | |
+ qemu_set_irq(qdev_get_gpio_in(gpio, i), true); | |
+ //qemu_set_irq(qdev_get_gpio_in(gpio, i), false); | |
+ } | |
+ qemu_set_irq(gpio_s->irqs[0], true); | |
+#endif | |
+ | |
+ | |
+#if 0 | |
+ | |
+ qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ | |
+ //qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ)); | |
+ //qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ)); | |
+ | |
+ qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_VIRQ)); | |
+ qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_VIRQ)); | |
+ | |
+ qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_VFIQ)); | |
+ qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_VFIQ)); | |
+ | |
+#else | |
+//fprintf(stderr, "sep_alarm: raise_low_irq\n"); | |
+ if (((uint32_t *)s->misc4_regs)[0x00] == 0xdeadbee8ull) { | |
+ //fprintf(stderr, "sep_alarm: if0: raise_irq\n"); | |
+ qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ } else if (((uint32_t *)s->misc4_regs)[0x00] == 0xdeadbee9ull) { | |
+ //fprintf(stderr, "sep_alarm: if1: lower_irq\n"); | |
+ qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ } else if (((uint32_t *)s->misc4_regs)[0x00] == 0xdeadbeeaull) { | |
+ //fprintf(stderr, "sep_alarm: if2: lower_raise_irq\n"); | |
+ qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ } else { | |
+ //fprintf(stderr, "sep_alarm: else: raise_lower_irq\n"); | |
+ qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ } | |
+ | |
+ //qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ)); | |
+ //qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ)); | |
+ | |
+ //qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_VIRQ)); | |
+ //qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_VIRQ)); | |
+ | |
+ //qemu_irq_raise(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_VFIQ)); | |
+ //qemu_irq_lower(qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_VFIQ)); | |
+ | |
+ | |
+ | |
+#endif | |
+ | |
+} | |
+ | |
+ | |
AppleSEPState *apple_sep_create(DTBNode *node, vaddr base, uint32_t cpu_id, | |
uint32_t build_version, bool modern) | |
{ | |
@@ -297,6 +1480,7 @@ AppleSEPState *apple_sep_create(DTBNode *node, vaddr base, uint32_t cpu_id, | |
BUILD_VERSION_MAJOR(build_version) - 3, | |
&sep_mailbox_ops); | |
apple_mbox_set_real(s->mbox, true); | |
+ apple_mbox_set_custom0(s->mbox, 0x0); | |
object_property_add_child(OBJECT(s), "mbox", OBJECT(s->mbox)); | |
@@ -305,30 +1489,143 @@ AppleSEPState *apple_sep_create(DTBNode *node, vaddr base, uint32_t cpu_id, | |
APPLE_MBOX_MMIO_V2)); | |
sysbus_pass_irq(sbd, SYS_BUS_DEVICE(s->mbox)); | |
- memory_region_init_io(&s->trng_mr, OBJECT(dev), &trng_reg_ops, | |
- &s->trng_state, "sep.trng", 0x10000); | |
- sysbus_init_mmio(sbd, &s->trng_mr); | |
+ memory_region_init_io(&s->pmgr_base_mr, OBJECT(dev), &pmgr_base_reg_ops, s, | |
+ "sep.pmgr_base", 0x10000); // PMGR_BASE T8020 | |
+ sysbus_init_mmio(sbd, &s->pmgr_base_mr); | |
+ memory_region_init_io(&s->trng_regs_mr, OBJECT(dev), &trng_regs_reg_ops, &s->trng_state, | |
+ "sep.trng_regs", 0x10000); // TRNG_REGS T8020 | |
+ sysbus_init_mmio(sbd, &s->trng_regs_mr); | |
+ memory_region_init_io(&s->key_base_mr, OBJECT(dev), &key_base_reg_ops, s, | |
+ "sep.key_base", 0x10000); // KEY_BASE T8020 | |
+ sysbus_init_mmio(sbd, &s->key_base_mr); | |
+ memory_region_init_io(&s->key_fcfg_mr, OBJECT(dev), &key_fcfg_reg_ops, s, | |
+ "sep.key_fcfg", 0x18000); // KEY_FCFG T8020 | |
+ sysbus_init_mmio(sbd, &s->key_fcfg_mr); | |
+ memory_region_init_io(&s->moni_base_mr, OBJECT(dev), &moni_base_reg_ops, s, | |
+ "sep.moni_base", 0x40000); // MONI_BASE T8020 | |
+ sysbus_init_mmio(sbd, &s->moni_base_mr); | |
+ memory_region_init_io(&s->moni_thrm_mr, OBJECT(dev), &moni_thrm_reg_ops, s, | |
+ "sep.moni_thrm", 0x10000); // MONI_THRM T8020 | |
+ sysbus_init_mmio(sbd, &s->moni_thrm_mr); | |
+ memory_region_init_io(&s->eisp_base_mr, OBJECT(dev), &eisp_base_reg_ops, s, | |
+ "sep.eisp_base", 0x240000); // EISP_BASE T8020 | |
+ sysbus_init_mmio(sbd, &s->eisp_base_mr); | |
+ memory_region_init_io(&s->eisp_hmac_mr, OBJECT(dev), &eisp_hmac_reg_ops, s, | |
+ "sep.eisp_hmac", 0x4000); // EISP_HMAC T8020 | |
+ sysbus_init_mmio(sbd, &s->eisp_hmac_mr); | |
+ memory_region_init_io(&s->aess_base_mr, OBJECT(dev), &aess_base_reg_ops, s, | |
+ "sep.aess_base", 0x10000); // AESS_BASE T8020 | |
+ sysbus_init_mmio(sbd, &s->aess_base_mr); | |
+ memory_region_init_io(&s->pka_base_mr, OBJECT(dev), &pka_base_reg_ops, s, | |
+ "sep.pka_base", 0x10000); // PKA_BASE T8020 | |
+ sysbus_init_mmio(sbd, &s->pka_base_mr); | |
+#if 0 | |
+ memory_region_init_io(&s->gpio_base_mr, OBJECT(dev), &gpio_base_reg_ops, s, | |
+ "sep.gpio_base", 0x10000); // GPIO_BASE T8020 | |
+ sysbus_init_mmio(sbd, &s->gpio_base_mr); | |
+ memory_region_init_io(&s->i2c_base_mr, OBJECT(dev), &i2c_base_reg_ops, s, | |
+ "sep.i2c_base", 0x10000); // I2C_BASE T8020 | |
+ sysbus_init_mmio(sbd, &s->i2c_base_mr); | |
+#endif | |
memory_region_init_io(&s->misc0_mr, OBJECT(dev), &misc0_reg_ops, s, | |
- "sep.misc0", 0x100); | |
+ "sep.misc0", 0x4000); | |
sysbus_init_mmio(sbd, &s->misc0_mr); | |
memory_region_init_io(&s->misc1_mr, OBJECT(dev), &misc1_reg_ops, s, | |
- "sep.misc1", 0x1000); | |
+ "sep.misc1", 0x4000); | |
sysbus_init_mmio(sbd, &s->misc1_mr); | |
memory_region_init_io(&s->misc2_mr, OBJECT(dev), &misc2_reg_ops, s, | |
- "sep.misc2", 0x100); | |
+ "sep.misc2", 0x4000); | |
sysbus_init_mmio(sbd, &s->misc2_mr); | |
+ memory_region_init_io(&s->misc3_mr, OBJECT(dev), &misc3_reg_ops, s, | |
+ "sep.misc3", 0x4000); | |
+ sysbus_init_mmio(sbd, &s->misc3_mr); | |
+ memory_region_init_io(&s->misc4_mr, OBJECT(dev), &misc4_reg_ops, s, | |
+ "sep.misc4", 0x4000); // MISC4 ; was: MISC48 Sicily(T8101). now: Some encrypted data from SEPROM. | |
+ sysbus_init_mmio(sbd, &s->misc4_mr); | |
+ memory_region_init_io(&s->debug_trace_mr, OBJECT(dev), &debug_trace_reg_ops, s, | |
+ "sep.debug_trace", DEBUG_TRACE_SIZE); // Debug trace printing | |
+ sysbus_init_mmio(sbd, &s->debug_trace_mr); | |
DTBNode *child = find_dtb_node(node, "iop-sep-nub"); | |
assert(child); | |
//! SEPFW needs to be loaded by restore, supposedly | |
// uint32_t data = 1; | |
// set_dtb_prop(child, "sepfw-loaded", sizeof(data), &data); | |
+#if 0 | |
+ uint32_t data = 0; | |
+ set_dtb_prop(node, "HasXART", sizeof(data), &data); | |
+ set_dtb_prop(child, "HasXART", sizeof(data), &data); | |
+ //uint32_t data = 0; | |
+ //set_dtb_prop(node, "has-art", sizeof(data), &data); | |
+ //set_dtb_prop(child, "has-art", sizeof(data), &data); | |
+ prop = find_dtb_prop(node, "has-art"); | |
+ if (prop) { | |
+ remove_dtb_prop(node, prop); | |
+ } | |
+ prop = find_dtb_prop(child, "has-art"); | |
+ if (prop) { | |
+ remove_dtb_prop(child, prop); | |
+ } | |
+ remove_dtb_node_by_name(child, "hilo"); | |
+ remove_dtb_node_by_name(child, "Lynx"); | |
+ remove_dtb_node_by_name(child, "xART"); | |
+#endif | |
+ | |
+ MachineState *machine = MACHINE(qdev_get_machine()); | |
+ T8030MachineState *tms = T8030_MACHINE(machine); | |
+ DeviceState *gpio = NULL; | |
+ //gpio = apple_custom_gpio_create((char *)"sep_gpio", 0x10000, 0xd0, 0x7, 0xdeadbeef); // SEP S8000? AP 0xd0 SEP size 0x10000 | |
+ //gpio = apple_custom_gpio_create((char *)"sep_gpio", 0x10000, 0xd4, 0x7, 0xdeadbeef); // SEP T8030? AP 0xd4 SEP size 0x10000 | |
+ //gpio = apple_custom_gpio_create((char *)"sep_gpio", 0x100000, 0xd0, 0x7, 0xdeadbeef); // S8000 AP 0xd0 AP size 0x100000 | |
+ //gpio = apple_custom_gpio_create((char *)"sep_gpio", 0x100000, 0xd4, 0x7, 0xdeadbeef); // T8030 AP 0xd4 AP size 0x100000 | |
+ uint32_t sep_gpio_pins = 0x4; | |
+ uint32_t sep_gpio_int_groups = 0x1; | |
+ gpio = apple_custom_gpio_create((char *)"sep_gpio_dev", 0x10000, sep_gpio_pins, sep_gpio_int_groups, 0xdeadbeef); | |
+ g_assert(gpio); | |
+ object_property_add_child(OBJECT(machine), "sep_gpio", OBJECT(gpio)); | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(gpio), 0, tms->soc_base_pa + 0x41480000); | |
+ | |
+ //uint32_t ints[4] = { 0, 1, 2, 3 }; | |
+ //uint32_t ints[4] = { 0 }; | |
+ | |
+ uint32_t i = 0; | |
+ //for (i = 0; i < sizeof(ints) / sizeof(uint32_t); i++) | |
+ for (i = 0; i < sep_gpio_int_groups; i++) | |
+ { | |
+ sysbus_connect_irq(SYS_BUS_DEVICE(gpio), i, qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ } | |
+ for (i = 0; i < sep_gpio_pins; i++) | |
+ { | |
+ qdev_connect_gpio_out(gpio, i, qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ } | |
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(gpio), &error_fatal); | |
+ | |
+ SysBusDevice *i2c = NULL; | |
+ i2c = apple_i2c_create("sep_i2c_dev"); | |
+ g_assert(i2c); | |
+ object_property_add_child(OBJECT(machine), "sep_i2c", OBJECT(i2c)); | |
+ sysbus_mmio_map(i2c, 0, tms->soc_base_pa + 0x41440000); | |
+ sysbus_realize_and_unref(i2c, &error_fatal); | |
+ | |
+ s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sep_alarm, s); | |
+ //sep_alarm(s); | |
return s; | |
} | |
+ | |
static void apple_sep_cpu_reset_work(CPUState *cpu, run_on_cpu_data data) | |
{ | |
AppleSEPState *s = data.host_ptr; | |
cpu_reset(cpu); | |
+#ifdef DO_SECUREROM | |
+ AddressSpace *nsas = &address_space_memory; | |
+ MachineState *machine = MACHINE(qdev_get_machine()); | |
+ T8030MachineState *tms = T8030_MACHINE(machine); | |
+ // make it possible to re-run SEPROM after SecureROM panics without powering off | |
+ // replaces e.g.: set *0x241130840=0x0 ; set *0x241130800=0x0 | |
+ //address_space_set(nsas, tms->soc_base_pa + 0x41000000, 0, 0x3000000, MEMTXATTRS_UNSPECIFIED); | |
+ address_space_set(nsas, tms->soc_base_pa + 0x41000000, 0, 0x1000000, MEMTXATTRS_UNSPECIFIED); | |
+#endif | |
+ fprintf(stderr, "apple_sep_cpu_reset_work: before cpu_set_pc: base=0x" HWADDR_FMT_plx "\n", s->base); | |
cpu_set_pc(cpu, s->base); | |
} | |
@@ -346,6 +1643,7 @@ static void apple_sep_realize(DeviceState *dev, Error **errp) | |
qdev_connect_gpio_out_named(DEVICE(s->mbox), APPLE_MBOX_IOP_IRQ, 0, | |
qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); | |
+ sep_alarm(s); | |
} | |
static void apple_sep_unrealize(DeviceState *dev) | |
diff --git a/hw/arm/t8030.c b/hw/arm/t8030.c | |
index 3a95ea9d49..22fe27e4d7 100644 | |
--- a/hw/arm/t8030.c | |
+++ b/hw/arm/t8030.c | |
@@ -46,7 +46,6 @@ | |
#include "hw/spmi/apple_spmi_pmu.h" | |
#include "hw/ssi/apple_spi.h" | |
#include "hw/ssi/ssi.h" | |
-#include "hw/usb/apple_otg.h" | |
#include "hw/usb/apple_typec.h" | |
#include "hw/watchdog/apple_wdt.h" | |
#include "qapi/visitor.h" | |
@@ -66,8 +65,11 @@ | |
#define T8030_DRAM_BASE (0x800000000ull) | |
#define T8030_DRAM_SIZE (4ull * GiB) | |
+#define T8030_SEP_BASE (0x240000000ULL) | |
+#define T8030_SEP_SIZE (0x4000000ULL) | |
+ | |
#define T8030_SEPROM_BASE (0x240000000ULL) | |
-#define T8030_SEPROM_SIZE (0x4000000ULL) | |
+#define T8030_SEPROM_SIZE (0x40000ULL) | |
#define T8030_GPIO_FORCE_DFU (161) | |
@@ -162,6 +164,21 @@ static void t8030_create_s3c_uart(const T8030MachineState *tms, uint32_t port, | |
static void t8030_patch_kernel(MachoHeader64 *hdr) | |
{ | |
+#if 1 | |
+ uint32_t value32_nop = 0xd503201f; // nop | |
+ *(uint32_t *)vtop_static(0xFFFFFFF0077142C8 + g_virt_slide) = 0; | |
+ //*(uint32_t *)vtop_static(0xfffffff009845140 + g_virt_slide) = 0xFFFFFFFF; // AMCC | |
+ // gAppleSMCDebugLevel = 0xFFFFFFFF; | |
+ //*(uint32_t *)vtop_static(0xFFFFFFF0099EAA18 + g_virt_slide) = 0xFFFFFFFF; | |
+ // gAppleSMCDebugPath = 0x2; | |
+ //*(uint32_t *)vtop_static(0xFFFFFFF0099EAA1C + g_virt_slide) = 0x2; | |
+ *(uint32_t *)vtop_static(0xfffffff007eef5c0 + g_virt_slide) = value32_nop; | |
+ *(uint32_t *)vtop_static(0xfffffff007eef600 + g_virt_slide) = value32_nop; | |
+ *(uint32_t *)vtop_static(0xfffffff007eef6a4 + g_virt_slide) = value32_nop; | |
+ uint32_t value32_mov_x21_0 = 0x52800015; // mov x21, #0x0 | |
+ //*(uint32_t *)vtop_static(0xfffffff008b56198 + g_virt_slide) = value32_mov_x21_0; // Disable xART? | |
+ //kpf(); | |
+#endif | |
} | |
static bool t8030_check_panic(MachineState *machine) | |
@@ -286,10 +303,10 @@ static void t8030_load_classic_kc(T8030MachineState *tms, const char *cmdline) | |
if (tms->sepfw_filename) { | |
info->sep_fw_pa = phys_ptr; | |
- macho_load_raw_file(tms->sepfw_filename, nsas, sysmem, "sepfw", | |
- info->sep_fw_pa, &info->sep_fw_size); | |
info->sep_fw_size = align_16k_high(8 * MiB); | |
phys_ptr += info->sep_fw_size; | |
+ size_t garbage = 0; | |
+ macho_load_raw_file(tms->sepfw_filename, nsas, sysmem, "sepfw", 0x4000ULL, &garbage); | |
} | |
//! Kernel boot args | |
@@ -350,11 +367,32 @@ static void t8030_memory_setup(MachineState *machine) | |
(uint8_t *)seprom, fsize, 1); | |
uint64_t value = 0x8000000000000000; | |
- address_space_write(nsas, tms->soc_base_pa + 0x42140108, | |
- MEMTXATTRS_UNSPECIFIED, &value, sizeof(value)); | |
- uint32_t value32 = 0x1; | |
- address_space_write(nsas, tms->soc_base_pa + 0x41448000, | |
- MEMTXATTRS_UNSPECIFIED, &value32, sizeof(value32)); | |
+ uint32_t value32_mov_x0_1 = 0xd2800020; // mov x0, #0x1 | |
+ uint32_t value32_mov_x0_0 = 0xd2800000; // mov x0, #0x0 | |
+ uint32_t value32_nop = 0xd503201f; // nop | |
+ //uint32_t value32_mov_w0_0x10000000 = 0x52a20000; // mov w0, #0x10000000 | |
+ //uint32_t value32_mov_w0_8030 = 0x52900600; // mov w0, #0x8030 | |
+ //uint32_t value32_mov_w0_0 = 0x52800000; // mov w0, #0x0 | |
+ //uint32_t value32_mov_w8_0x1000 = 0x52820008; | |
+#if 1 // for T8020 SEPROM | |
+ address_space_write(nsas, tms->soc_base_pa + 0x42140108, MEMTXATTRS_UNSPECIFIED, &value, sizeof(value)); // _entry: prevent busy-loop (data section) | |
+ //address_space_write(nsas, T8030_SEPROM_BASE + 0x0d2c8, MEMTXATTRS_UNSPECIFIED, &value32_nop, sizeof(value32_nop)); // image4_validate_property_callback: skip AMNM | |
+ address_space_write(nsas, T8030_SEPROM_BASE + 0x12144, MEMTXATTRS_UNSPECIFIED, &value32_nop, sizeof(value32_nop)); // maybe_Img4DecodeEvaluateTrust: Skip RSA verification result. | |
+ address_space_write(nsas, T8030_SEPROM_BASE + 0x121d8, MEMTXATTRS_UNSPECIFIED, &value32_nop, sizeof(value32_nop)); // maybe_Img4DecodeEvaluateTrust: payload_raw hashing stuck, nop'ing | |
+ address_space_write(nsas, T8030_SEPROM_BASE + 0x121dc, MEMTXATTRS_UNSPECIFIED, &value32_nop, sizeof(value32_nop)); // maybe_Img4DecodeEvaluateTrust: nop'ing result of payload_raw hashing | |
+ address_space_write(nsas, T8030_SEPROM_BASE + 0x0abd8, MEMTXATTRS_UNSPECIFIED, &value32_mov_x0_0, sizeof(value32_mov_x0_0)); // memcmp_validstrs30: fake success | |
+ address_space_write(nsas, T8030_SEPROM_BASE + 0x0ca84, MEMTXATTRS_UNSPECIFIED, &value32_mov_x0_0, sizeof(value32_mov_x0_0)); // memcmp_validstrs14: fake success | |
+ //address_space_write(nsas, T8030_SEPROM_BASE + 0x091b4, MEMTXATTRS_UNSPECIFIED, &value32_mov_w0_8030, sizeof(value32_mov_w0_8030)); // get_chipid: patch get_chipid to return 0x8030 instead of 0x8020 | |
+ address_space_write(nsas, T8030_SEPROM_BASE + 0x077ac, MEMTXATTRS_UNSPECIFIED, &value32_mov_x0_1, sizeof(value32_mov_x0_1)); // load_sepos: jump over img4_compare_verified_values_true_on_success | |
+ //*(uint32_t *)vtop_static(0xfffffff008b4e018 + g_virt_slide) = value32_mov_w0_0x10000000; // AppleSEPBooter::getBootTimeout: increase timeout for debugging (GDB tracing). The _initTimeoutMultiplier change is preferred compared to this. | |
+ //*(uint32_t *)vtop_static(0xfffffff008b576b4 + g_virt_slide) = value32_nop; // AppleSEPManager::_tracingEnabled: Don't require _PE_i_can_has_debugger. | |
+ //*(uint32_t *)vtop_static(0xfffffff008b57ad4 + g_virt_slide) = value32_mov_x0_1; // AppleSEPManager::_bootSEP:: Don't require _PE_i_can_has_debugger. | |
+ //*(uint32_t *)vtop_static(0xfffffff008b56b18 + g_virt_slide) = value32_nop; // AppleSEPManager::_initPMControl: Don't require _PE_i_can_has_debugger. // _PE_parse_boot_argn "sep_pm" | |
+ //*(uint32_t *)vtop_static(0xfffffff007a231d8 + g_virt_slide) = value32_mov_x0_1; // _kern_config_is_development | |
+ //*(uint32_t *)vtop_static(0xfffffff008b56aa4 + g_virt_slide) = value32_mov_w8_0x1000; // AppleSEPManager::_initTimeoutMultiplier: Increasing the FastSIM timeout. Conflicts with getBootTimeout. | |
+ //*(uint32_t *)vtop_static(0xfffffff0079f95a8 + g_virt_slide) = value32_mov_w0_0; // SEP::_kern_register_coredump_helper: Needed for the bootSEP patch. | |
+ //*(uint32_t *)vtop_static(0xfffffff008794f24 + g_virt_slide) = value32_mov_x0_0; // ApplePMGR::_cpuIdle: skip time check | |
+#endif // for T8020 SEPROM | |
nvram = APPLE_NVRAM(qdev_find_recursive(sysbus_get_default(), "nvram")); | |
if (!nvram) { | |
@@ -478,10 +516,23 @@ static void t8030_memory_setup(MachineState *machine) | |
} | |
} | |
+static uint64_t pmgr_unk_e4800 = 0; | |
+static uint32_t pmgr_unk_e4000[0x180/4] = {0}; | |
+ | |
static void pmgr_unk_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
unsigned size) | |
{ | |
hwaddr base = (hwaddr)opaque; | |
+ switch (base + addr) { | |
+ case 0x3D2E4800: // ???? 0x240002c00 and 0x2400037a4 | |
+ pmgr_unk_e4800 = data; // 0x240002c00 and 0x2400037a4 | |
+ break; | |
+ case 0x3D2E4000 ... 0x3D2E417f: // ???? 0x24000377c | |
+ pmgr_unk_e4000[((base + addr) - 0x3D2E4000)/4] = data; // 0x24000377c | |
+ break; | |
+ default: | |
+ break; | |
+ } | |
#if 1 | |
qemu_log_mask(LOG_UNIMP, | |
"PMGR reg WRITE unk @ 0x" TARGET_FMT_lx | |
@@ -492,51 +543,98 @@ static void pmgr_unk_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
static uint64_t pmgr_unk_reg_read(void *opaque, hwaddr addr, unsigned size) | |
{ | |
+ MachineState *machine = MACHINE(qdev_get_machine()); | |
+ T8030MachineState *tms = T8030_MACHINE(machine); | |
+ AppleSEPState *sep; | |
hwaddr base = (hwaddr)opaque; | |
+ sep = APPLE_SEP(object_property_get_link(OBJECT(machine), "sep", &error_fatal)); | |
#if 1 | |
+ if (((base + addr) & 0xfffffffb) != 0x10E20020) { | |
qemu_log_mask(LOG_UNIMP, | |
"PMGR reg READ unk @ 0x" TARGET_FMT_lx | |
" base: 0x" TARGET_FMT_lx "\n", | |
base + addr, base); | |
+ } | |
#endif | |
+ uint32_t chip_revision; | |
+ //chip_revision = 0x01; | |
+ chip_revision = 0x11; | |
switch (base + addr) { | |
- case 0x3D2BC000: | |
- // return 0xA050C030; // IBFL | 0x00 | |
- return 0xA55AC33C; // IBFL | 0x10 | |
- case 0x3D2BC008: | |
+ case 0x3D2BC000: // DPRO | |
+ case 0x3D2BC200: | |
+ //// return 0xA050C030; // IBFL | 0x00 | |
+ return 0xA55AC33C; // IBFL | 0x10 // my | |
+ //return 0xA050C030; // Ntrung | |
+ case 0x3D2BC004: // ??? DPRO? is value==0xA050C030 (disabled), take value from 0xbc600 | |
+ case 0x3D2BC204: | |
+ return 0xA55AC33C; // force return enabled | |
+ //return 0xA050C030; // force return disabled ; skip loop inside FUN_240003fcc_wait_for_DAT_23d2bc004_maybe_memory_encryption | |
+ // FUN_240003fcc_wait_for_DAT_23d2bc004 | |
+ if ((sep->misc3_regs[0] & 0x2) != 0) | |
+ return 0xA050C030; // if bit1 is set | |
+ else | |
+ return 0xA55AC33C; // if bit1 is unset | |
+ case 0x3D2BC008: // EDOM_0? Effective SDOM_0? (Security Domain) T8030? | |
+ case 0x3D2BC208: // EDOM_0? Effective SDOM_0? (Security Domain) AppleSEPROM-A12-D331pAP | |
return 0xA55AC33C; // security domain | 0x1 | |
- case 0x3D2BC00C: | |
- // return 0xA55AC33C; // security domain | 0x2 | |
+ //return 0xA050C030; // MAYBE security domain | 0x0 | |
+ case 0x3D2BC00C: // EDOM_1? Effective SDOM_1? (Security Domain) T8030? | |
+ case 0x3D2BC20C: // EDOM_1? Effective SDOM_1? (Security Domain) AppleSEPROM-A12-D331pAP | |
+ //return 0xA55AC33C; // security domain | 0x2 | |
return 0xA050C030; // security domain | 0x0 | |
- case 0x3D2BC010: | |
- return (1 << 5) | (1 << 31); // _rCFG_FUSE0 ; (security epoch & 0x7F) << | |
- // 5 ;; (1 << 31) for SEP | |
- case 0x3D2BC030: | |
- // return 0xFFFFFFFF; // CPRV | |
- // return 0x7 << 6; // LOW NIBBLE | |
- // return 0x70 << 5; // HIGH NIBBLE | |
- return 0x1 << 6; | |
- case 0x3D2BC300: // TODO | |
- return 0xCAFEBABE; // ECID lower | |
- case 0x3D2BC304: // TODO | |
- return 0xDEADBEEF; // ECID upper | |
- case 0x3D2BC400: | |
+ case 0x3D2BC010: // maybe effective CEPO? SEPO/BOARDID (upper three??/five bits stored in the three lower bits) | |
+ case 0x3D2BC210: // CEPO? SEPO? AppleSEPROM-A12-D331pAP | |
+ //uint64_t sep_bit30 = 0; | |
+ uint64_t sep_bit30 = ((sep->misc3_regs[0] & 0x1) != 0); | |
+ //return (1 << 5) | (0 << 30) | (1 << 31); // _rCFG_FUSE0 ; (security epoch & 0x7F) << 5 ;; (0 << 30) | (1 << 31) for SEP | |
+ return (1 << 5) | (sep_bit30 << 30) | (1 << 31); // _rCFG_FUSE0 ; (security epoch & 0x7F) << 5 ;; (sep_bit30 << 30) | (1 << 31) for SEP | |
+ case 0x3D2BC020: // T8030 iBSS: FUN_19c07feac_return_value_causes_crash | |
+ //return 0xA050C030; // causes panic, so does a invalid value | |
+ return 0xA55AC33C; | |
+ //0x3d2bc024 T8030 | |
+ //0x3d2bc028 T8030 | |
+ //0x3d2bc02c T8030 | |
+ //case 0x3D2BC028: // CPRV (Chip Revision) AppleSEPROM-S4-S5-B1 | |
+ //case 0x3D2BC02c: // T8030 iBSS: _DAT_23d2bc02c >> 30 | (_DAT_23d2bc030 & 15) << 2; | |
+ case 0x3D2BC030: // CPRV (Chip Revision) T8030? T8020? | |
+ return ((chip_revision & 0x7) << 6) | (((chip_revision & 0x70) >> 4) << 5); // LOW&HIGH NIBBLE T8030 and AppleSEPROM-S4-S5-B1 | |
+ case 0x3D2BC100: // ECID lower T8020? | |
+ case 0x3D2BC300: // ECID lower T8030? | |
+ //return 0xCAFEBABE; // ECID lower | |
+ return tms->ecid & 0xffffffff; // ECID lower | |
+ case 0x3D2BC104: // ECID upper T8020? | |
+ case 0x3D2BC304: // ECID upper T8030? | |
+ //return 0xDEADBEEF; // ECID upper | |
+ return tms->ecid >> 32; // ECID upper | |
+ case 0x3D2BC400: // EKEY_0 | |
// if 0xBC404 returns 1==0xA55AC33C, this will get ignored | |
- // return 0xA050C030; // CPFM | 0x00 ; IBFL_base == 0x04 | |
- return 0xA55AC33C; // CPFM | 0x03 ; IBFL_base == 0x0C | |
- case 0x3D2BC404: | |
- // return 0xA55AC33C; // CPFM | 0x01 ; IBFL_base == 0x0C | |
- return 0xA050C030; // CPFM | 0x00 ; IBFL_base == 0x04 | |
- case 0x3D2BC604: //? | |
- return 0xA050C030; | |
+ //// return 0xA050C030; // CPFM | 0x00 ; IBFL_base == 0x04 | |
+ return 0xA55AC33C; // CPFM | 0x03 ; IBFL_base == 0x0C // my | |
+ //return 0xA050C030; // Ntrung | |
+ case 0x3D2BC404: // EKEY_1 | |
+ return 0xA55AC33C; // CPFM | 0x01 ; IBFL_base == 0x0C | |
+ //return 0xA050C030; // CPFM | 0x00 ; IBFL_base == 0x04 | |
+ case 0x3D2BC600: //? EPRO (Effective Production Status)? CPRO (Certificate Production Status)? | |
+ //return 0xA55AC33C; // avoided panic(0x74/0xf1) with patches | |
+ //return 0xA050C030; // needed to avoid panic(0x74) ? // maybe AMK off | |
+ //return 0; | |
+ return 0xA55AC33C; // EPRO enabled | |
+ //return 0xA050C030; // EPRO disabled | |
+ case 0x3D2BC604: //? CSEC (Certificate Security Mode)? | |
+ //return 0xA55AC33C; // set at 0x24000b070, causes crash at 0x240008928 // avoided panic(0x74/0xf1) with patches | |
+ //return 0xA050C030; // needed to avoid panic(0x74) ? // maybe AMK off | |
+ //return 0; // panic(0x74) ? | |
+ return 0xA55AC33C; // CSEC enabled | |
+ //return 0xA050C030; // CSEC disabled | |
case 0x3D2E8000: // ???? | |
- return 0x32B3; // memory encryption AMK (Authentication Master Key) | |
- // disabled | |
- // return 0xC2E9; // memory encryption AMK (Authentication Master Key) | |
- // enabled | |
- case 0x3D2D0034: //? | |
- return (1 << 24) | (1 << 25); | |
+ //return 0x32B3; // memory encryption AMK (Authentication Master Key) disabled // avoided panic(0x74/0xf1) with patches | |
+ return 0xC2E9; // memory encryption AMK (Authentication Master Key) enabled // needed to avoid panic(0x74) ? | |
+ case 0x3D2E4800: // ???? 0x240002c00 and 0x2400037a4 | |
+ //////return 0x3; // 0x2400037a4 | |
+ return pmgr_unk_e4800; // 0x240002c00 and 0x2400037a4 | |
+ case 0x3D2E4000 ... 0x3D2E417f: // ???? 0x24000377c | |
+ return pmgr_unk_e4000[((base + addr) - 0x3D2E4000)/4]; // 0x24000377c | |
default: | |
if (((base + addr) & 0x10E70000) == 0x10E70000) { | |
return (108 << 4) | 0x200000; //? | |
@@ -555,6 +653,7 @@ static void pmgr_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
{ | |
MachineState *machine = MACHINE(opaque); | |
T8030MachineState *tms = T8030_MACHINE(opaque); | |
+ AppleSEPState *sep; | |
uint32_t value = data; | |
if (addr >= 0x80000 && addr <= 0x8C000) { | |
@@ -570,6 +669,19 @@ static void pmgr_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
case 0xD4004: | |
t8030_start_cpus(machine, data); | |
return; | |
+ case 0x80C00: | |
+ cpu_dump_state(first_cpu, stderr, CPU_DUMP_CODE); | |
+ sep = APPLE_SEP(object_property_get_link(OBJECT(machine), "sep", &error_fatal)); | |
+ if (((data >> 31) & 1) == 1) { | |
+ apple_a13_cpu_reset(APPLE_A13(sep->cpu)); | |
+ } else if (((data >> 10) & 1) == 0) { | |
+ if (apple_a13_cpu_is_powered_off(APPLE_A13(sep->cpu))) { | |
+ apple_a13_cpu_start(APPLE_A13(sep->cpu)); | |
+ } | |
+ } else if (((data >> 10) & 1) == 1) { | |
+ apple_a13_cpu_off(APPLE_A13(sep->cpu)); | |
+ } | |
+ break; | |
} | |
memcpy(tms->pmgr_reg + addr, &value, size); | |
} | |
@@ -582,17 +694,6 @@ static uint64_t pmgr_reg_read(void *opaque, hwaddr addr, unsigned size) | |
case 0xF0010: //! AppleT8030PMGR::commonSramCheck | |
result = 0x5000; | |
break; | |
- case 0x80C00: //! SEP Power State, Manual & Actual: Run Max | |
- result = 0xFF; | |
- break; | |
-#if 0 | |
- case 0xBC008: | |
- result = 0xFFFFFFFF; | |
- break; | |
- case 0xBC00C: | |
- result = 0xFFFFFFFF; | |
- break; | |
-#endif | |
default: | |
memcpy(&result, tms->pmgr_reg + addr, size); | |
break; | |
@@ -617,44 +718,62 @@ static void amcc_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
T8030MachineState *tms = T8030_MACHINE(opaque); | |
uint32_t value = data; | |
+#if 1 | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "AMCC reg WRITE @ 0x" TARGET_FMT_lx " value: 0x" TARGET_FMT_lx | |
+ "\n", | |
+ addr, data); | |
+#endif | |
memcpy(tms->amcc_reg + addr, &value, size); | |
} | |
static uint64_t amcc_reg_read(void *opaque, hwaddr addr, unsigned size) | |
{ | |
- T8030MachineState *tms = T8030_MACHINE(opaque); | |
+ MachineState *machine = MACHINE(opaque); | |
+ T8030MachineState *tms = T8030_MACHINE(machine); | |
+ hwaddr orig_addr = addr; | |
+ uint64_t result = 0; | |
+ uint64_t base = (T8030_KERNEL_REGION_BASE-T8030_DRAM_BASE)+T8030_KERNEL_REGION_SIZE; | |
switch (addr) { | |
case 0x6A0: | |
case 0x406A0: | |
case 0x806A0: | |
case 0xC06A0: | |
- return 0x0; | |
+ result = base >> 12; | |
+ break; | |
case 0x6A4: | |
- // return 0x1003; | |
case 0x406A4: | |
- // return 0x2003; | |
case 0x806A4: | |
- // return 0x3003; | |
case 0xC06A4: | |
- // return 0x3; | |
- return 0x1003; // 0x1003 == 0x1004000 | |
- // return 0x4003; | |
+ result = ((0xada0000+base)-1)>>12; | |
+ break; | |
case 0x6A8: | |
case 0x406A8: | |
case 0x806A8: | |
case 0xC06A8: | |
- return 0x1; | |
+ result = 0x1; | |
+ break; | |
case 0x6B8: | |
case 0x406B8: | |
case 0x806B8: | |
case 0xC06B8: | |
- return 0x1; | |
+ result = 0x1; | |
+ break; | |
+ case 0x4: | |
+ result = 0xcf; | |
+ break; | |
default: { | |
- uint64_t result = 0; | |
memcpy(&result, tms->amcc_reg + addr, size); | |
- return result; | |
+ break; | |
} | |
} | |
+#if 1 | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "AMCC reg READ @ 0x" TARGET_FMT_lx " value: 0x" TARGET_FMT_lx | |
+ "\n", | |
+ orig_addr, result); | |
+#endif | |
+ return result; | |
} | |
static const MemoryRegionOps amcc_reg_ops = { | |
@@ -1650,14 +1769,55 @@ static void t8030_create_sep(MachineState *machine) | |
g_assert(prop); | |
reg = (uint64_t *)prop->value; | |
sysbus_mmio_map(SYS_BUS_DEVICE(sep), 0, tms->soc_base_pa + reg[0]); | |
+ // SEP Kernel: | |
+ // 0x23d200000: size 0xc0000 | |
+ // 0x242400000: size 0x5c000 AKF | |
+ // 0x2412c0000: size 0x180000 DART | |
+ // 0x240a40000: size 0x4000 | |
+ // 0x240a50000: size 0x4000 | |
+ // SEPD: | |
+ // 0x23d2d0000: XPRT_PMSC == apple.aes.disable_key.mmio ; size 0x4000 | |
+ // 0x23d2bc000: XPRT_FUSE == pmgr_unk_reg ; size 0x10000 | |
+ // 0x23d2e8000: XPRT_MISC == pmgr_unk_reg ; size 0x3c4000 | |
+ // 0x242400000: AKF_MBOX == apple.mbox.SEP.akf-reg ; size 0x8000 | |
sysbus_mmio_map(SYS_BUS_DEVICE(sep), 1, | |
- tms->soc_base_pa + 0x41180000); // TRNG | |
+ tms->soc_base_pa + 0x41000000); // PMGR_BASE T8020 | |
sysbus_mmio_map(SYS_BUS_DEVICE(sep), 2, | |
- tms->soc_base_pa + 0x41080000); // MISC0 | |
+ tms->soc_base_pa + 0x41100000); // TRNG_REGS T8020 | |
sysbus_mmio_map(SYS_BUS_DEVICE(sep), 3, | |
- tms->soc_base_pa + 0x41040000); // MISC1 | |
+ tms->soc_base_pa + 0x41180000); // KEY_BASE T8020 | |
sysbus_mmio_map(SYS_BUS_DEVICE(sep), 4, | |
+ tms->soc_base_pa + 0x41400000); // KEY_FCFG T8020 | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(sep), 5, | |
+ tms->soc_base_pa + 0x41380000); // MONI_BASE T8020 | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(sep), 6, | |
+ tms->soc_base_pa + 0x413c0000); // MONI_THRM T8020 | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(sep), 7, | |
+ tms->soc_base_pa + 0x40800000); // EISP_BASE T8020 | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(sep), 8, | |
+ tms->soc_base_pa + 0x40a60000); // EISP_HMAC T8020 | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(sep), 9, | |
+ tms->soc_base_pa + 0x41040000); // AESS_BASE T8020 | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(sep), 10, | |
+ tms->soc_base_pa + 0x41140000); // PKA_BASE T8020 | |
+#if 0 | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(sep), 11, | |
+ tms->soc_base_pa + 0x41480000); // GPIO_BASE T8020 | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(sep), 12, | |
+ tms->soc_base_pa + 0x41440000); // I2C_BASE T8020 | |
+#endif | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(sep), 11, | |
+ tms->soc_base_pa + 0x41080000); // MISC0 | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(sep), 12, | |
+ tms->soc_base_pa + 0x41040000); // MISC1 | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(sep), 13, | |
tms->soc_base_pa + 0x410C4000); // MISC2 | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(sep), 14, | |
+ tms->soc_base_pa + 0x41008000); // MISC3 | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(sep), 15, | |
+ tms->soc_base_pa + 0x41240000); // MISC4 ; Some encrypted data from SEPROM. | |
+ sysbus_mmio_map(SYS_BUS_DEVICE(sep), 16, | |
+ 0x80c000+0x14000); // Debug trace printing | |
prop = find_dtb_prop(child, "interrupts"); | |
g_assert(prop); | |
@@ -1684,13 +1844,21 @@ static void t8030_create_sep(MachineState *machine) | |
OBJECT(sep->dma_mr))); | |
sep->dma_as = g_new0(AddressSpace, 1); | |
address_space_init(sep->dma_as, sep->dma_mr, "sep.dma"); | |
+ MemoryRegion *mr = g_new0(MemoryRegion, 1); | |
+ memory_region_init_alias(mr, OBJECT(tms), "sep.dma.alias", sep->dma_mr, 0x80c000, 0x10000+0x4000); | |
+ memory_region_add_subregion(tms->sysmem, 0x80c000, mr); | |
sysbus_realize_and_unref(SYS_BUS_DEVICE(sep), &error_fatal); | |
} | |
static void t8030_cpu_reset_work(CPUState *cpu, run_on_cpu_data data) | |
{ | |
- T8030MachineState *tms; | |
+ T8030MachineState *tms = data.host_ptr; | |
+ CPUARMState *env; | |
+ AppleA13State *tcpu = APPLE_A13(cpu); | |
+ if (!tcpu) { | |
+ return; | |
+ } | |
tms = data.host_ptr; | |
cpu_reset(cpu); | |
@@ -1779,9 +1947,9 @@ static void t8030_machine_init(MachineState *machine) | |
// allocate_ram(tms->sysmem, "SROM", T8030_SROM_BASE, T8030_SROM_SIZE, 0); | |
// allocate_ram(tms->sysmem, "SRAM", T8030_SRAM_BASE, T8030_SRAM_SIZE, 0); | |
allocate_ram(tms->sysmem, "DRAM", T8030_DRAM_BASE, T8030_DRAM_SIZE, 0); | |
- allocate_ram(tms->sysmem, "SEPROM", T8030_SEPROM_BASE, T8030_SEPROM_SIZE, | |
- 0); | |
+ allocate_ram(tms->sysmem, "SEP", T8030_SEP_BASE, T8030_SEP_SIZE, 0); | |
allocate_ram(tms->sysmem, "DRAM_3", 0x300000000ULL, 0x100000000ULL, 0); | |
+ allocate_ram(tms->sysmem, "SEPFW", 0x000000000ULL, 0x1000000ULL, 0); | |
hdr = macho_load_file(machine->kernel_filename, NULL); | |
g_assert(hdr); | |
diff --git a/hw/arm/xnu.c b/hw/arm/xnu.c | |
index ce24c90ceb..97bac03584 100644 | |
--- a/hw/arm/xnu.c | |
+++ b/hw/arm/xnu.c | |
@@ -119,6 +119,8 @@ static const char *REM_PROPS[] = { | |
"nvme-coastguard", | |
"pmp", | |
"soc-tuning", | |
+ "function-wait_for_power_gate", | |
+ "self-power-gate", | |
}; | |
static void allocate_and_copy(MemoryRegion *mem, AddressSpace *as, | |
@@ -464,6 +466,18 @@ void macho_populate_dtb(DTBNode *root, AppleBootInfo *info) | |
set_dtb_prop(child, "security-domain", sizeof(data), &data); | |
set_dtb_prop(child, "chip-epoch", sizeof(data), &data); | |
set_dtb_prop(child, "amfi-allows-trust-cache-load", sizeof(data), &data); | |
+#if 0 | |
+ data = 0; | |
+ set_dtb_prop(child, "debug-enabled", sizeof(data), &data); | |
+#if 1 | |
+ data = 0; | |
+ set_dtb_prop(child, "protected-data-access", sizeof(data), &data); | |
+ set_dtb_prop(child, "sepfw-load-at-boot", sizeof(data), &data); | |
+ data = 1; | |
+ set_dtb_prop(child, "no-protected-data-access", sizeof(data), &data); | |
+ set_dtb_prop(child, "no-sepfw-load-at-boot", sizeof(data), &data); | |
+#endif | |
+#endif | |
// data = 1; | |
// set_dtb_prop(child, "debug-enabled", sizeof(data), &data); | |
diff --git a/hw/gpio/apple_gpio.c b/hw/gpio/apple_gpio.c | |
index 476242e57e..d543753c65 100644 | |
--- a/hw/gpio/apple_gpio.c | |
+++ b/hw/gpio/apple_gpio.c | |
@@ -8,6 +8,8 @@ | |
#include "qemu/log.h" | |
#include "qemu/module.h" | |
#include "qemu/timer.h" | |
+#include "trace.h" | |
+ | |
#define GPIO_MAX_PIN_NR (512) | |
#define GPIO_MAX_INT_GRP_NR (0x7) | |
@@ -333,31 +335,39 @@ static void apple_gpio_reg_write(void *opaque, hwaddr addr, uint64_t data, | |
__func__, addr, data); | |
break; | |
} | |
+ | |
+ trace_apple_gpio_reg_write(addr, data); | |
} | |
static uint64_t apple_gpio_reg_read(void *opaque, hwaddr addr, unsigned size) | |
{ | |
AppleGPIOState *s = APPLE_GPIO(opaque); | |
+ uint64_t ret = 0; | |
switch (addr) { | |
case rGPIOCFG(0)... rGPIOCFG(GPIO_MAX_PIN_NR - 1): | |
- return apple_gpio_cfg_read(s, (addr - rGPIOCFG(0)) >> 2, addr); | |
+ ret = apple_gpio_cfg_read(s, (addr - rGPIOCFG(0)) >> 2, addr); | |
+ break; | |
case rGPIOINT(0, 0)... rGPIOINT(GPIO_MAX_INT_GRP_NR, GPIO_MAX_PIN_NR - 1): | |
- return apple_gpio_int_read(s, (addr - rGPIOINT(0, 0)) >> 6, addr); | |
+ ret = apple_gpio_int_read(s, (addr - rGPIOINT(0, 0)) >> 6, addr); | |
+ break; | |
case rGPIO_NPL_IN_EN: | |
- return s->npl; | |
+ ret = s->npl; | |
+ break; | |
case 0xC4C: | |
- return 0xFF; | |
+ ret = 0xFF; | |
+ break; | |
default: | |
qemu_log_mask(LOG_UNIMP, "%s: Bad offset 0x" HWADDR_FMT_plx "\n", | |
__func__, addr); | |
} | |
- return 0; | |
+ trace_apple_gpio_reg_read(addr, ret); | |
+ return ret; | |
} | |
static const MemoryRegionOps gpio_reg_ops = { | |
@@ -368,6 +378,43 @@ static const MemoryRegionOps gpio_reg_ops = { | |
.valid.unaligned = false, | |
}; | |
+ | |
+DeviceState *apple_custom_gpio_create(char *name, uint64_t mmio_size, uint32_t gpio_pins, uint32_t gpio_int_groups, uint32_t phandle) | |
+{ | |
+ int i; | |
+ DeviceState *dev; | |
+ SysBusDevice *sbd; | |
+ AppleGPIOState *s; | |
+ | |
+ dev = qdev_new(TYPE_APPLE_GPIO); | |
+ sbd = SYS_BUS_DEVICE(dev); | |
+ s = APPLE_GPIO(dev); | |
+ | |
+ s->iomem = g_new(MemoryRegion, 1); | |
+ dev->id = g_strdup(name); | |
+ memory_region_init_io(s->iomem, OBJECT(dev), &gpio_reg_ops, s, | |
+ (const char *)name, mmio_size); | |
+ sysbus_init_mmio(sbd, s->iomem); | |
+ | |
+ s->npins = gpio_pins; | |
+ assert(s->npins < GPIO_MAX_PIN_NR); | |
+ qdev_init_gpio_in(dev, apple_gpio_set, s->npins); | |
+ | |
+ s->out = g_new(qemu_irq, s->npins); | |
+ qdev_init_gpio_out(dev, s->out, s->npins); | |
+ | |
+ s->nirqgrps = gpio_int_groups; | |
+ s->irqs = g_new(qemu_irq, s->nirqgrps); | |
+ | |
+ for (i = 0; i < s->nirqgrps; i++) { | |
+ sysbus_init_irq(sbd, &s->irqs[i]); | |
+ } | |
+ | |
+ s->phandle = phandle; | |
+ | |
+ return dev; | |
+} | |
+ | |
DeviceState *apple_gpio_create(DTBNode *node) | |
{ | |
int i; | |
diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events | |
index 9736b362ac..56a18bc420 100644 | |
--- a/hw/gpio/trace-events | |
+++ b/hw/gpio/trace-events | |
@@ -31,3 +31,7 @@ sifive_gpio_update_output_irq(int64_t line, int64_t value) "line %" PRIi64 " val | |
# aspeed_gpio.c | |
aspeed_gpio_read(uint64_t offset, uint64_t value) "offset: 0x%" PRIx64 " value 0x%" PRIx64 | |
aspeed_gpio_write(uint64_t offset, uint64_t value) "offset: 0x%" PRIx64 " value 0x%" PRIx64 | |
+ | |
+# apple_gpio.c | |
+apple_gpio_reg_read(uint64_t addr, uint32_t val) "0x%04" PRIx64 " val 0x%08x" | |
+apple_gpio_reg_write(uint64_t addr, uint32_t val) "0x%04" PRIx64 " val 0x%08x" | |
diff --git a/hw/i2c/apple_i2c.c b/hw/i2c/apple_i2c.c | |
index 4583380d56..49580c5ad8 100644 | |
--- a/hw/i2c/apple_i2c.c | |
+++ b/hw/i2c/apple_i2c.c | |
@@ -10,7 +10,7 @@ | |
#include "qemu/module.h" | |
#include "qemu/timer.h" | |
-// #define DEBUG_APPLE_I2C | |
+#define DEBUG_APPLE_I2C | |
#define MMIO_SIZE (0x10000) | |
diff --git a/hw/misc/apple_aes.c b/hw/misc/apple_aes.c | |
index e8b3717d6a..0aab85ea5d 100644 | |
--- a/hw/misc/apple_aes.c | |
+++ b/hw/misc/apple_aes.c | |
@@ -372,8 +372,9 @@ static uint64_t aes_security_reg_read(void *opaque, hwaddr addr, unsigned size) | |
switch (addr) { | |
case 0x20: //! board-id | |
return 0x4; | |
- case 0x34: //? bit 24 = is fresh boot? | |
- return (1 << 24) | (1 << 25); | |
+ case 0x34: //? bit 24 = is first boot ; bit 25 = something with memory encryption? | |
+ //return (1 << 24) | (1 << 25); | |
+ return (1 << 24) | (0 << 25); | |
default: //! We don't know the rest | |
return 0xFF; | |
} | |
diff --git a/hw/misc/apple_mbox.c b/hw/misc/apple_mbox.c | |
index fbe337fce3..7b0e36289b 100644 | |
--- a/hw/misc/apple_mbox.c | |
+++ b/hw/misc/apple_mbox.c | |
@@ -37,20 +37,24 @@ | |
#define REG_V3_CPU_STATUS (0x0048) | |
#define V3_CPU_STATUS_IDLE (0x1) | |
+#define REG_V3_UNKNOWN0 (0x004c) | |
+#define REG_V3_UNKNOWN1 (0x0818) | |
+#define REG_V3_UNKNOWN2 (0x081c) // "akf: READ IRQ %x" | |
+ | |
#define REG_V3_NMI0 (0xC04) // ?? | |
#define REG_V3_NMI1 (0xC14) // ?? | |
#define REG_AKF_CONFIG (0x2043) // ?? | |
-#define REG_V3_IOP_INT_MASK_SET (0x4100) | |
-#define REG_V3_IOP_INT_MASK_CLR (0x4108) | |
+#define REG_V3_IOP_INT_MASK_SET (0x4100) // T8020 32-bit | |
+#define REG_V3_IOP_INT_MASK_CLR (0x4104) // T8020 32-bit | |
-#define REG_V3_IOP_I2A_CTRL (0x4114) | |
+#define REG_V3_IOP_I2A_CTRL (0x410c) // T8020 32-bit | |
#define REG_V3_IOP_I2A_SEND0 (0x4820) | |
#define REG_V3_IOP_I2A_SEND1 (0x4824) | |
#define REG_V3_IOP_I2A_SEND2 (0x4828) | |
#define REG_V3_IOP_I2A_SEND3 (0x482C) | |
-#define REG_V3_IOP_A2I_CTRL (0x4110) | |
+#define REG_V3_IOP_A2I_CTRL (0x4108) // T8020 32-bit | |
#define REG_V3_IOP_A2I_RECV0 (0x4810) | |
#define REG_V3_IOP_A2I_RECV1 (0x4814) | |
#define REG_V3_IOP_A2I_RECV2 (0x4818) | |
@@ -164,14 +168,15 @@ static inline uint32_t iop_outbox_flags(AppleMboxState *s) | |
static void iop_update_irq(AppleMboxState *s) | |
{ | |
if (s->real) { | |
- qemu_set_irq(s->iop_irq, (apple_mbox_inbox_empty(s) && | |
+ s->iop_irq_raised = (apple_mbox_inbox_empty(s) && | |
!(s->iop_int_mask & V2_A2I_EMPTY)) || | |
(!apple_mbox_inbox_empty(s) && | |
!(s->iop_int_mask & V2_A2I_NONEMPTY)) || | |
(apple_mbox_outbox_empty(s) && | |
!(s->iop_int_mask & V2_I2A_EMPTY)) || | |
(!apple_mbox_outbox_empty(s) && | |
- !(s->iop_int_mask & V2_I2A_NONEMPTY))); | |
+ !(s->iop_int_mask & V2_I2A_NONEMPTY)); | |
+ qemu_set_irq(s->iop_irq, s->iop_irq_raised); | |
} | |
smp_mb(); | |
} | |
@@ -248,6 +253,15 @@ static apple_mbox_msg_t apple_mbox_outbox_pop(AppleMboxState *s) | |
return msg; | |
} | |
+void apple_mbox_send_inbox_control_message(AppleMboxState *s, uint32_t ep, | |
+ uint64_t msg) | |
+{ | |
+ apple_mbox_msg_t m = g_new0(struct apple_mbox_msg, 1); | |
+ m->msg = msg; | |
+ m->endpoint = ep; | |
+ apple_mbox_inbox_push(s, m); | |
+} | |
+ | |
void apple_mbox_send_control_message(AppleMboxState *s, uint32_t ep, | |
uint64_t msg) | |
{ | |
@@ -455,6 +469,7 @@ static void apple_mbox_v3_reg_write(void *opaque, hwaddr addr, | |
{ | |
AppleMboxState *s = APPLE_MBOX(opaque); | |
apple_mbox_msg_t msg = NULL; | |
+ struct sep_message sep_msg = { 0 }; | |
s->int_mask = 0; | |
WITH_QEMU_LOCK_GUARD(&s->mutex) | |
@@ -486,6 +501,11 @@ static void apple_mbox_v3_reg_write(void *opaque, hwaddr addr, | |
if (addr + size == REG_V3_A2I_PUSH3 + 4) { | |
msg = g_new0(struct apple_mbox_msg, 1); | |
memcpy(msg->data, &s->regs[REG_V3_A2I_PUSH0], 16); | |
+ if (!strcmp(s->role, "SEP")) | |
+ { | |
+ memcpy(&sep_msg.raw, msg->data, 8); | |
+ qemu_log_mask(LOG_UNIMP, "%s: REG_V3_A2I_PUSH3: ep=0x%02x, tag=0x%02x, opcode=0x%02x(%u), param=0x%02x, data=0x%08x\n", s->role, sep_msg.endpoint, sep_msg.tag, sep_msg.opcode, sep_msg.opcode, sep_msg.param, sep_msg.data); | |
+ } | |
apple_mbox_inbox_push(s, msg); | |
IOP_LOG_MSG(s, "AP sent", msg); | |
} | |
@@ -518,6 +538,11 @@ static void apple_mbox_v3_reg_write(void *opaque, hwaddr addr, | |
if (addr + size == REG_V3_IOP_I2A_SEND3 + 4) { | |
msg = g_new0(struct apple_mbox_msg, 1); | |
memcpy(msg->data, &s->regs[REG_V3_IOP_I2A_SEND0], 16); | |
+ if (!strcmp(s->role, "SEP")) | |
+ { | |
+ memcpy(&sep_msg.raw, msg->data, 8); | |
+ qemu_log_mask(LOG_UNIMP, "%s: REG_V3_IOP_I2A_SEND3: ep=0x%02x, tag=0x%02x, opcode=0x%02x(%u), param=0x%02x, data=0x%08x\n", s->role, sep_msg.endpoint, sep_msg.tag, sep_msg.opcode, sep_msg.opcode, sep_msg.param, sep_msg.data); | |
+ } | |
apple_mbox_outbox_push(s, msg); | |
IOP_LOG_MSG(s, "IOP sent", msg); | |
} | |
@@ -545,6 +570,7 @@ static uint64_t apple_mbox_v3_reg_read(void *opaque, hwaddr addr, unsigned size) | |
AppleMboxState *s = APPLE_MBOX(opaque); | |
uint64_t ret = 0; | |
apple_mbox_msg_t msg = NULL; | |
+ struct sep_message sep_msg = { 0 }; | |
WITH_QEMU_LOCK_GUARD(&s->mutex) | |
{ | |
@@ -552,9 +578,13 @@ static uint64_t apple_mbox_v3_reg_read(void *opaque, hwaddr addr, unsigned size) | |
switch (addr) { | |
case REG_V3_INT_MASK_SET: | |
- return s->int_mask; | |
+ //return s->int_mask; | |
+ ret = s->int_mask; | |
+ break; | |
case REG_V3_INT_MASK_CLR: | |
- return ~s->int_mask; | |
+ //return ~s->int_mask; | |
+ ret = ~s->int_mask; | |
+ break; | |
case REG_V3_I2A_POP_0_LOW: | |
msg = apple_mbox_outbox_pop(s); | |
if (!msg) { | |
@@ -563,6 +593,11 @@ static uint64_t apple_mbox_v3_reg_read(void *opaque, hwaddr addr, unsigned size) | |
msg->flags = iop_outbox_flags(s); | |
IOP_LOG_MSG(s, "AP received", msg); | |
+ if (!strcmp(s->role, "SEP")) | |
+ { | |
+ memcpy(&sep_msg.raw, msg->data, 8); | |
+ qemu_log_mask(LOG_UNIMP, "%s: REG_V3_I2A_POP_0_LOW: ep=0x%02x, tag=0x%02x, opcode=0x%02x(%u), param=0x%02x, data=0x%08x\n", s->role, sep_msg.endpoint, sep_msg.tag, sep_msg.opcode, sep_msg.opcode, sep_msg.param, sep_msg.data); | |
+ } | |
memcpy(&s->regs[REG_V3_I2A_POP_0_LOW], msg->data, 16); | |
memcpy(&ret, &s->regs[addr], size); | |
@@ -575,9 +610,13 @@ static uint64_t apple_mbox_v3_reg_read(void *opaque, hwaddr addr, unsigned size) | |
case REG_V3_I2A_POP_1_HIGH: | |
break; | |
case REG_V3_IOP_INT_MASK_SET: | |
- return s->iop_int_mask; | |
+ //return s->iop_int_mask; | |
+ ret = s->iop_int_mask; | |
+ break; | |
case REG_V3_IOP_INT_MASK_CLR: | |
- return ~s->iop_int_mask; | |
+ //return ~s->iop_int_mask; | |
+ ret = ~s->iop_int_mask; | |
+ break; | |
case REG_V3_A2I_CTRL: | |
QEMU_FALLTHROUGH; | |
case REG_V3_IOP_A2I_CTRL: | |
@@ -588,6 +627,9 @@ static uint64_t apple_mbox_v3_reg_read(void *opaque, hwaddr addr, unsigned size) | |
ret |= | |
(s->inboxCount << V3_CTRL_COUNT_SHIFT) & V3_CTRL_COUNT_MASK; | |
} | |
+ qemu_log_mask(LOG_UNIMP, | |
+ "%s AKF: REG_V3_IOP_A2I_CTRL read from 0x" HWADDR_FMT_plx " ret: 0x" HWADDR_FMT_plx "\n", | |
+ s->role, addr, ret); | |
break; | |
case REG_V3_I2A_CTRL: | |
QEMU_FALLTHROUGH; | |
@@ -602,6 +644,41 @@ static uint64_t apple_mbox_v3_reg_read(void *opaque, hwaddr addr, unsigned size) | |
break; | |
case REG_V3_CPU_STATUS: | |
break; | |
+ case REG_V3_UNKNOWN0: | |
+ ret = 1; | |
+ // TODO: response not interrupt available, but something with REG_V3_CPU_CTRL? | |
+ break; | |
+ case REG_V3_UNKNOWN1: | |
+ break; | |
+ case REG_V3_UNKNOWN2: | |
+ //ret = 1; | |
+ //ret = 0xffffffff; | |
+ //return 0; | |
+ //return 0x70000; | |
+ //return 0x40000; // IRQ0? ASC1 crash | |
+ //return 0x10000; | |
+ //return 0x1002c; // Interrupt_0x2c? panic(cpu 1 caller 0xfffffff008b69bb0): SEP Panic: [elfour panic] [&&&&&&&&] iommu.c:)*) | |
+ //return 0x10008; // Interrupt_0x08? panic(cpu 1 caller 0xfffffff008b69bb0): SEP Panic: [elfour panic] [/,&&&&&,] exception.c:,. | |
+ //return 0x10084; | |
+ //return 0x10100; | |
+ //return 0x10060; | |
+ //return 0x70060; | |
+ //return 0x40060; | |
+ //return 0x40001; | |
+ //return 0x40002; | |
+ //return 0x40003; | |
+ //return 0x10080; | |
+ //return 0x10065; | |
+ ////if (!s->iop_irq_raised) | |
+ if (s->custom0) { | |
+ return s->custom0; | |
+ } else if (!apple_mbox_inbox_empty(s) && !apple_mbox_outbox_empty(s)) | |
+ { | |
+ return 0x40000; | |
+ } else { | |
+ return 0x0; | |
+ } | |
+ break; | |
case REG_V3_IOP_A2I_RECV0: | |
msg = apple_mbox_inbox_pop(s); | |
if (!msg) { | |
@@ -609,6 +686,11 @@ static uint64_t apple_mbox_v3_reg_read(void *opaque, hwaddr addr, unsigned size) | |
} | |
msg->flags = iop_outbox_flags(s); | |
IOP_LOG_MSG(s, "IOP received", msg); | |
+ if (!strcmp(s->role, "SEP")) | |
+ { | |
+ memcpy(&sep_msg.raw, msg->data, 8); | |
+ qemu_log_mask(LOG_UNIMP, "%s: REG_V3_IOP_A2I_RECV0: ep=0x%02x, tag=0x%02x, opcode=0x%02x(%u), param=0x%02x, data=0x%08x\n", s->role, sep_msg.endpoint, sep_msg.tag, sep_msg.opcode, sep_msg.opcode, sep_msg.param, sep_msg.data); | |
+ } | |
memcpy(&s->regs[addr], msg->data, 16); | |
memcpy(&ret, &s->regs[addr], size); | |
g_free(msg); | |
@@ -646,6 +728,7 @@ static void apple_mbox_v2_reg_write(void *opaque, hwaddr addr, | |
{ | |
AppleMboxState *s = APPLE_MBOX(opaque); | |
apple_mbox_msg_t msg = NULL; | |
+ struct sep_message sep_msg = { 0 }; | |
WITH_QEMU_LOCK_GUARD(&s->mutex) | |
{ | |
@@ -671,6 +754,11 @@ static void apple_mbox_v2_reg_write(void *opaque, hwaddr addr, | |
if (addr + size == REG_V2_A2I_PUSH_HIGH + 4) { | |
msg = g_new0(struct apple_mbox_msg, 1); | |
memcpy(msg->data, &s->regs[REG_V2_A2I_PUSH_LOW], 8); | |
+ if (!strcmp(s->role, "SEP")) | |
+ { | |
+ memcpy(&sep_msg.raw, msg->data, 8); | |
+ qemu_log_mask(LOG_UNIMP, "%s: REG_V2_A2I_PUSH_HIGH: ep=0x%02x, tag=0x%02x, opcode=0x%02x(%u), param=0x%02x, data=0x%08x\n", s->role, sep_msg.endpoint, sep_msg.tag, sep_msg.opcode, sep_msg.opcode, sep_msg.param, sep_msg.data); | |
+ } | |
apple_mbox_inbox_push(s, msg); | |
IOP_LOG_MSG(s, "AP sent", msg); | |
} | |
@@ -699,6 +787,11 @@ static void apple_mbox_v2_reg_write(void *opaque, hwaddr addr, | |
if (addr + size == REG_V2_IOP_I2A_SEND1 + 4) { | |
msg = g_new0(struct apple_mbox_msg, 1); | |
memcpy(msg->data, &s->regs[REG_V2_IOP_I2A_SEND0], 8); | |
+ if (!strcmp(s->role, "SEP")) | |
+ { | |
+ memcpy(&sep_msg.raw, msg->data, 8); | |
+ qemu_log_mask(LOG_UNIMP, "%s: REG_V2_IOP_I2A_SEND1: ep=0x%02x, tag=0x%02x, opcode=0x%02x(%u), param=0x%02x, data=0x%08x\n", s->role, sep_msg.endpoint, sep_msg.tag, sep_msg.opcode, sep_msg.opcode, sep_msg.param, sep_msg.data); | |
+ } | |
apple_mbox_outbox_push(s, msg); | |
IOP_LOG_MSG(s, "IOP sent", msg); | |
} | |
@@ -724,6 +817,7 @@ static void apple_mbox_v2_reg_write(void *opaque, hwaddr addr, | |
static uint64_t apple_mbox_v2_reg_read(void *opaque, hwaddr addr, unsigned size) | |
{ | |
AppleMboxState *s = APPLE_MBOX(opaque); | |
+ struct sep_message sep_msg = { 0 }; | |
uint64_t ret = 0; | |
WITH_QEMU_LOCK_GUARD(&s->mutex) | |
@@ -733,9 +827,13 @@ static uint64_t apple_mbox_v2_reg_read(void *opaque, hwaddr addr, unsigned size) | |
switch (addr) { | |
case REG_V2_INT_MASK_SET: | |
- return s->int_mask; | |
+ //return s->int_mask; | |
+ ret = s->int_mask; | |
+ break; | |
case REG_V2_INT_MASK_CLR: | |
- return ~s->int_mask; | |
+ //return ~s->int_mask; | |
+ ret = ~s->int_mask; | |
+ break; | |
case REG_V2_I2A_POP_LOW: | |
m = apple_mbox_outbox_pop(s); | |
if (!m) { | |
@@ -744,6 +842,11 @@ static uint64_t apple_mbox_v2_reg_read(void *opaque, hwaddr addr, unsigned size) | |
m->flags = iop_outbox_flags(s); | |
IOP_LOG_MSG(s, "AP received", m); | |
+ if (!strcmp(s->role, "SEP")) | |
+ { | |
+ memcpy(&sep_msg.raw, m->data, 8); | |
+ qemu_log_mask(LOG_UNIMP, "%s: REG_V2_I2A_POP_LOW: ep=0x%02x, tag=0x%02x, opcode=0x%02x(%u), param=0x%02x, data=0x%08x\n", s->role, sep_msg.endpoint, sep_msg.tag, sep_msg.opcode, sep_msg.opcode, sep_msg.param, sep_msg.data); | |
+ } | |
memcpy(&s->regs[REG_V2_I2A_POP_LOW], m->data, 8); | |
memcpy(&ret, &s->regs[addr], size); | |
@@ -752,9 +855,13 @@ static uint64_t apple_mbox_v2_reg_read(void *opaque, hwaddr addr, unsigned size) | |
case REG_V2_I2A_POP_HIGH: | |
break; | |
case REG_V2_IOP_INT_MASK_SET: | |
- return s->iop_int_mask; | |
+ //return s->iop_int_mask; | |
+ ret = s->iop_int_mask; | |
+ break; | |
case REG_V2_IOP_INT_MASK_CLR: | |
- return ~s->iop_int_mask; | |
+ //return ~s->iop_int_mask; | |
+ ret = ~s->iop_int_mask; | |
+ break; | |
case REG_V2_A2I_CTRL: | |
QEMU_FALLTHROUGH; | |
case REG_V2_IOP_A2I_CTRL: | |
@@ -780,6 +887,11 @@ static uint64_t apple_mbox_v2_reg_read(void *opaque, hwaddr addr, unsigned size) | |
} | |
m->flags = iop_outbox_flags(s); | |
IOP_LOG_MSG(s, "IOP received", m); | |
+ if (!strcmp(s->role, "SEP")) | |
+ { | |
+ memcpy(&sep_msg.raw, m->data, 8); | |
+ qemu_log_mask(LOG_UNIMP, "%s: REG_V2_IOP_A2I_RECV_LOW: ep=0x%02x, tag=0x%02x, opcode=0x%02x(%u), param=0x%02x, data=0x%08x\n", s->role, sep_msg.endpoint, sep_msg.tag, sep_msg.opcode, sep_msg.opcode, sep_msg.param, sep_msg.data); | |
+ } | |
memcpy(&s->regs[addr], m->data, 8); | |
memcpy(&ret, &s->regs[addr], size); | |
g_free(m); | |
@@ -817,6 +929,14 @@ void apple_mbox_set_real(AppleMboxState *s, bool real) | |
smp_wmb(); | |
} | |
+void apple_mbox_set_custom0(AppleMboxState *s, uint32_t custom0) | |
+{ | |
+ s->custom0 = custom0; | |
+ qemu_log_mask(LOG_GUEST_ERROR, "%s AKF: s->custom0: 0x%x\n", s->role, | |
+ s->custom0); | |
+ smp_wmb(); | |
+} | |
+ | |
void apple_mbox_register_endpoint(AppleMboxState *s, uint32_t ep, | |
AppleMboxEPHandler *handler) | |
{ | |
@@ -882,6 +1002,7 @@ AppleMboxState *apple_mbox_create(const char *role, void *opaque, | |
s->protocol_version = protocol_version; | |
s->role = g_strdup(role); | |
s->ops = ops; | |
+ //s->custom0 = 0; | |
snprintf(name, sizeof(name), TYPE_APPLE_MBOX ".%s.akf-reg", s->role); | |
diff --git a/include/hw/arm/apple_a13.h b/include/hw/arm/apple_a13.h | |
index 0d807aded5..506650ad5d 100644 | |
--- a/include/hw/arm/apple_a13.h | |
+++ b/include/hw/arm/apple_a13.h | |
@@ -86,6 +86,8 @@ typedef struct AppleA13State { | |
A13_CPREG_VAR_DEF(ARM64_REG_HID14); | |
A13_CPREG_VAR_DEF(ARM64_REG_HID16); | |
A13_CPREG_VAR_DEF(ARM64_REG_LSU_ERR_STS); | |
+ A13_CPREG_VAR_DEF(SYS_E_LSU_ERR_STS); | |
+ A13_CPREG_VAR_DEF(SYS_E_FED_ERR_STS); | |
A13_CPREG_VAR_DEF(IMP_BARRIER_LBSY_BST_SYNC_W0_EL0); | |
A13_CPREG_VAR_DEF(IMP_BARRIER_LBSY_BST_SYNC_W1_EL0); | |
A13_CPREG_VAR_DEF(ARM64_REG_3_3_15_7); | |
@@ -95,6 +97,10 @@ typedef struct AppleA13State { | |
A13_CPREG_VAR_DEF(PMCR1); | |
A13_CPREG_VAR_DEF(PMSR); | |
A13_CPREG_VAR_DEF(S3_4_c15_c0_5); | |
+ A13_CPREG_VAR_DEF(SYS_HCR_EL2); // TODO: already exists in target/arm/helper.c | |
+ A13_CPREG_VAR_DEF(SYS_PRE_LLCFLUSH_TMR); | |
+ A13_CPREG_VAR_DEF(SYS_ACC_PWR_DN_SAVE); | |
+ A13_CPREG_VAR_DEF(SYS_AON_CNT_CTL); | |
A13_CPREG_VAR_DEF(AMX_STATUS_EL1); | |
A13_CPREG_VAR_DEF(AMX_CTL_EL1); | |
A13_CPREG_VAR_DEF(ARM64_REG_CYC_OVRD); | |
@@ -132,5 +138,6 @@ AppleA13State *apple_a13_cpu_create(DTBNode *node, char *name, uint32_t cpu_id, | |
bool apple_a13_cpu_is_sleep(AppleA13State *tcpu); | |
bool apple_a13_cpu_is_powered_off(AppleA13State *tcpu); | |
void apple_a13_cpu_start(AppleA13State *tcpu); | |
+void apple_a13_cpu_reset(AppleA13State *tcpu); | |
void apple_a13_cpu_off(AppleA13State *tcpu); | |
#endif /* HW_ARM_APPLE_A13_H */ | |
diff --git a/include/hw/arm/apple_sep.h b/include/hw/arm/apple_sep.h | |
index aacc0aa917..9f4e6a9b69 100644 | |
--- a/include/hw/arm/apple_sep.h | |
+++ b/include/hw/arm/apple_sep.h | |
@@ -31,6 +31,8 @@ | |
#define TYPE_APPLE_SEP "secure-enclave" | |
OBJECT_DECLARE_SIMPLE_TYPE(AppleSEPState, APPLE_SEP) | |
+#define DEBUG_TRACE_SIZE (0x80000) | |
+ | |
typedef struct { | |
uint8_t key[32]; | |
uint64_t ecid; | |
@@ -48,14 +50,47 @@ struct AppleSEPState { | |
AppleMboxState *mbox; | |
MemoryRegion *dma_mr; | |
AddressSpace *dma_as; | |
- MemoryRegion trng_mr; | |
+ MemoryRegion pmgr_base_mr; | |
+ MemoryRegion trng_regs_mr; | |
+ MemoryRegion key_base_mr; | |
+ MemoryRegion key_fcfg_mr; | |
+ MemoryRegion moni_base_mr; | |
+ MemoryRegion moni_thrm_mr; | |
+ MemoryRegion eisp_base_mr; | |
+ MemoryRegion eisp_hmac_mr; | |
+ MemoryRegion aess_base_mr; | |
+ MemoryRegion pka_base_mr; | |
+#if 0 | |
+ MemoryRegion gpio_base_mr; | |
+ MemoryRegion i2c_base_mr; | |
+#endif | |
MemoryRegion misc0_mr; | |
MemoryRegion misc1_mr; | |
MemoryRegion misc2_mr; | |
- AppleTRNGState trng_state; | |
+ MemoryRegion misc3_mr; | |
+ MemoryRegion misc4_mr; | |
+ MemoryRegion debug_trace_mr; | |
+ uint8_t pmgr_base_regs[REG_SIZE]; | |
+ uint8_t key_base_regs[REG_SIZE]; | |
+ uint8_t key_fcfg_regs[REG_SIZE]; | |
+ uint8_t moni_base_regs[REG_SIZE]; | |
+ uint8_t moni_thrm_regs[REG_SIZE]; | |
+ uint8_t eisp_base_regs[REG_SIZE]; | |
+ uint8_t eisp_hmac_regs[REG_SIZE]; | |
+ uint8_t aess_base_regs[REG_SIZE]; | |
+ uint8_t pka_base_regs[REG_SIZE]; | |
+#if 0 | |
+ uint8_t gpio_base_regs[REG_SIZE]; | |
+ uint8_t i2c_base_regs[REG_SIZE]; | |
+#endif | |
uint8_t misc0_regs[REG_SIZE]; | |
uint8_t misc1_regs[REG_SIZE]; | |
uint8_t misc2_regs[REG_SIZE]; | |
+ uint8_t misc3_regs[REG_SIZE]; | |
+ uint8_t misc4_regs[REG_SIZE]; | |
+ uint8_t debug_trace_regs[DEBUG_TRACE_SIZE]; | |
+ QEMUTimer *timer; | |
+ AppleTRNGState trng_state; | |
}; | |
AppleSEPState *apple_sep_create(DTBNode *node, vaddr base, uint32_t cpu_id, | |
diff --git a/include/hw/gpio/apple_gpio.h b/include/hw/gpio/apple_gpio.h | |
index a7a249d430..ee1a1c84f6 100644 | |
--- a/include/hw/gpio/apple_gpio.h | |
+++ b/include/hw/gpio/apple_gpio.h | |
@@ -28,5 +28,6 @@ struct AppleGPIOState { | |
uint32_t phandle; | |
}; | |
+DeviceState *apple_custom_gpio_create(char *name, uint64_t mmio_size, uint32_t gpio_pins, uint32_t gpio_int_groups, uint32_t phandle); | |
DeviceState *apple_gpio_create(DTBNode *node); | |
#endif | |
diff --git a/include/hw/misc/apple_mbox.h b/include/hw/misc/apple_mbox.h | |
index d802cffd40..ea465b3035 100644 | |
--- a/include/hw/misc/apple_mbox.h | |
+++ b/include/hw/misc/apple_mbox.h | |
@@ -114,6 +114,8 @@ struct AppleMboxState { | |
uint32_t int_mask; | |
uint32_t iop_int_mask; | |
bool real; | |
+ bool iop_irq_raised; | |
+ uint32_t custom0; | |
}; | |
struct iop_rollcall_data { | |
@@ -128,6 +130,22 @@ struct AppleMboxOps { | |
void (*wakeup)(void *opaque); | |
}; | |
+void apple_mbox_send_inbox_control_message(AppleMboxState *s, uint32_t ep, uint64_t msg); | |
+ | |
+struct QEMU_PACKED sep_message { | |
+ union { | |
+ struct QEMU_PACKED { | |
+ uint8_t endpoint; | |
+ uint8_t tag; | |
+ uint8_t opcode; | |
+ uint8_t param; | |
+ uint32_t data; | |
+ }; | |
+ uint64_t raw; | |
+ }; | |
+}; | |
+ | |
+ | |
/* | |
* Send message to an endpoint | |
*/ | |
@@ -157,6 +175,7 @@ void apple_mbox_register_control_endpoint(AppleMboxState *s, uint32_t ep, | |
AppleMboxEPHandler *handler); | |
void apple_mbox_set_real(AppleMboxState *s, bool real); | |
+void apple_mbox_set_custom0(AppleMboxState *s, uint32_t custom0); | |
AppleMboxState *apple_mbox_create(const char *role, void *opaque, | |
uint64_t mmio_size, uint32_t protocol_version, | |
diff --git a/meson.build b/meson.build | |
index 7d26691204..ba57333214 100644 | |
--- a/meson.build | |
+++ b/meson.build | |
@@ -1365,8 +1365,10 @@ endif | |
liblzfse = not_found | |
if not get_option('lzfse').auto() or have_block | |
- liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'], | |
- required: get_option('lzfse')) | |
+ liblzfse = dependency('lzfse', required: get_option('lzfse'), | |
+ method: 'pkg-config') | |
+# liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'], | |
+# required: get_option('lzfse')) | |
endif | |
if liblzfse.found() and not cc.links(''' | |
#include <lzfse.h> | |
diff --git a/softmmu/memory.c b/softmmu/memory.c | |
index 7d9494ce70..78a1ed7475 100644 | |
--- a/softmmu/memory.c | |
+++ b/softmmu/memory.c | |
@@ -1397,6 +1397,8 @@ bool memory_region_access_valid(MemoryRegion *mr, | |
{ | |
if (mr->ops->valid.accepts | |
&& !mr->ops->valid.accepts(mr->opaque, addr, size, is_write, attrs)) { | |
+ CPUState *cpu = first_cpu; | |
+ cpu_dump_state(cpu, stderr, CPU_DUMP_CODE); | |
qemu_log_mask(LOG_GUEST_ERROR, "Invalid %s at addr 0x%" HWADDR_PRIX | |
", size %u, region '%s', reason: rejected\n", | |
is_write ? "write" : "read", | |
@@ -1469,6 +1471,8 @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr, | |
pval, op, attrs); | |
} | |
if (!memory_region_access_valid(mr, addr, size, false, attrs)) { | |
+ fprintf(stderr, "Invalid read: addr: 0x%llx ; size : %d\n", addr, size); | |
+ //__asm__("int3"); | |
*pval = unassigned_mem_read(mr, addr, size); | |
return MEMTX_DECODE_ERROR; | |
} | |
@@ -1518,6 +1522,8 @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr, | |
data, op, attrs); | |
} | |
if (!memory_region_access_valid(mr, addr, size, true, attrs)) { | |
+ fprintf(stderr, "Invalid write: addr: 0x%llx ; data: 0x%llx ; size : %d\n", addr, data, size); | |
+ //__asm__("int3"); | |
unassigned_mem_write(mr, addr, data, size); | |
return MEMTX_DECODE_ERROR; | |
} | |
diff --git a/ui/gtk.c b/ui/gtk.c | |
index cddbc46791..ebf5bdb7c6 100644 | |
--- a/ui/gtk.c | |
+++ b/ui/gtk.c | |
@@ -967,10 +967,9 @@ static gboolean gd_button_event(GtkWidget *widget, GdkEventButton *button, | |
if (button->button == 1 && button->type == GDK_BUTTON_PRESS && | |
!qemu_input_is_absolute() && s->ptr_owner != vc) { | |
if (!vc->window) { | |
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), | |
- TRUE); | |
+ //gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), TRUE); | |
} else { | |
- gd_grab_pointer(vc, "relative-mode-click"); | |
+ //gd_grab_pointer(vc, "relative-mode-click"); | |
} | |
return TRUE; | |
} | |
@@ -1369,7 +1368,7 @@ static gboolean gd_win_grab(void *opaque) | |
if (vc->s->ptr_owner) { | |
gd_ungrab_pointer(vc->s); | |
} else { | |
- gd_grab_pointer(vc, "user-request-detached-tab"); | |
+ //gd_grab_pointer(vc, "user-request-detached-tab"); | |
} | |
return TRUE; | |
} | |
@@ -1445,7 +1444,7 @@ static void gd_menu_full_screen(GtkMenuItem *item, void *opaque) | |
{ | |
GtkDisplayState *s = opaque; | |
VirtualConsole *vc = gd_vc_find_current(s); | |
- | |
+#if 0 | |
if (!s->full_screen) { | |
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(s->notebook), FALSE); | |
gtk_widget_hide(s->menu_bar); | |
@@ -1468,7 +1467,7 @@ static void gd_menu_full_screen(GtkMenuItem *item, void *opaque) | |
gd_update_windowsize(vc); | |
} | |
} | |
- | |
+#endif | |
gd_update_cursor(vc); | |
} | |
@@ -1644,8 +1643,8 @@ static void gd_menu_grab_input(GtkMenuItem *item, void *opaque) | |
VirtualConsole *vc = gd_vc_find_current(s); | |
if (gd_is_grab_active(s)) { | |
- gd_grab_keyboard(vc, "user-request-main-window"); | |
- gd_grab_pointer(vc, "user-request-main-window"); | |
+ //gd_grab_keyboard(vc, "user-request-main-window"); | |
+ //gd_grab_pointer(vc, "user-request-main-window"); | |
} else { | |
gd_ungrab_keyboard(s); | |
gd_ungrab_pointer(s); | |
@@ -1669,16 +1668,13 @@ static void gd_change_page(GtkNotebook *nb, gpointer arg1, guint arg2, | |
if (!vc) { | |
return; | |
} | |
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(vc->menu_item), | |
- TRUE); | |
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(vc->menu_item), TRUE); | |
on_vga = (vc->type == GD_VC_GFX && | |
qemu_console_is_graphic(vc->gfx.dcl.con)); | |
if (!on_vga) { | |
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), | |
- FALSE); | |
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), FALSE); | |
} else if (s->full_screen) { | |
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), | |
- TRUE); | |
+ //gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), TRUE); | |
} | |
gtk_widget_set_sensitive(s->grab_item, on_vga); | |
#ifdef CONFIG_VTE | |
@@ -1696,7 +1692,7 @@ static gboolean gd_enter_event(GtkWidget *widget, GdkEventCrossing *crossing, | |
GtkDisplayState *s = vc->s; | |
if (gd_grab_on_hover(s)) { | |
- gd_grab_keyboard(vc, "grab-on-hover"); | |
+ //gd_grab_keyboard(vc, "grab-on-hover"); | |
} | |
return TRUE; | |
} | |
diff --git a/ui/sdl2.c b/ui/sdl2.c | |
index 0d91b555e3..2e8bbe5c8d 100644 | |
--- a/ui/sdl2.c | |
+++ b/ui/sdl2.c | |
@@ -274,24 +274,25 @@ static void absolute_mouse_grab(struct sdl2_console *scon) | |
SDL_GetWindowSize(scon->real_window, &scr_w, &scr_h); | |
if (mouse_x > 0 && mouse_x < scr_w - 1 && | |
mouse_y > 0 && mouse_y < scr_h - 1) { | |
- sdl_grab_start(scon); | |
+ //sdl_grab_start(scon); | |
} | |
} | |
static void sdl_mouse_mode_change(Notifier *notify, void *data) | |
{ | |
- if (qemu_input_is_absolute()) { | |
+ if (qemu_input_is_absolute() && 0) { | |
if (!absolute_enabled) { | |
- absolute_enabled = 1; | |
- SDL_SetRelativeMouseMode(SDL_FALSE); | |
- absolute_mouse_grab(&sdl2_console[0]); | |
+ //absolute_enabled = 1; | |
+ //SDL_SetRelativeMouseMode(SDL_FALSE); | |
+ //absolute_mouse_grab(&sdl2_console[0]); | |
} | |
} else if (absolute_enabled) { | |
if (!gui_fullscreen) { | |
- sdl_grab_end(&sdl2_console[0]); | |
+ //sdl_grab_end(&sdl2_console[0]); | |
} | |
absolute_enabled = 0; | |
} | |
+ absolute_enabled = 0; | |
} | |
static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy, | |
@@ -333,15 +334,14 @@ static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy, | |
static void toggle_full_screen(struct sdl2_console *scon) | |
{ | |
- gui_fullscreen = !gui_fullscreen; | |
+ gui_fullscreen = 0;//!gui_fullscreen; | |
if (gui_fullscreen) { | |
- SDL_SetWindowFullscreen(scon->real_window, | |
- SDL_WINDOW_FULLSCREEN_DESKTOP); | |
- gui_saved_grab = gui_grab; | |
- sdl_grab_start(scon); | |
+ //SDL_SetWindowFullscreen(scon->real_window, SDL_WINDOW_FULLSCREEN_DESKTOP); | |
+ //gui_saved_grab = gui_grab; | |
+ //sdl_grab_start(scon); | |
} else { | |
if (!gui_saved_grab) { | |
- sdl_grab_end(scon); | |
+ //sdl_grab_end(scon); | |
} | |
SDL_SetWindowFullscreen(scon->real_window, 0); | |
} | |
@@ -397,7 +397,7 @@ static void handle_keydown(SDL_Event *ev) | |
case SDL_SCANCODE_8: | |
case SDL_SCANCODE_9: | |
if (gui_grab) { | |
- sdl_grab_end(scon); | |
+ //sdl_grab_end(scon); | |
} | |
win = ev->key.keysym.scancode - SDL_SCANCODE_1; | |
@@ -414,15 +414,15 @@ static void handle_keydown(SDL_Event *ev) | |
} | |
break; | |
case SDL_SCANCODE_F: | |
- toggle_full_screen(scon); | |
+ //toggle_full_screen(scon); | |
gui_keysym = 1; | |
break; | |
case SDL_SCANCODE_G: | |
gui_keysym = 1; | |
if (!gui_grab) { | |
- sdl_grab_start(scon); | |
+ //sdl_grab_start(scon); | |
} else if (!gui_fullscreen) { | |
- sdl_grab_end(scon); | |
+ //sdl_grab_end(scon); | |
} | |
break; | |
case SDL_SCANCODE_U: | |
@@ -506,12 +506,12 @@ static void handle_mousemotion(SDL_Event *ev) | |
if (gui_grab && !gui_fullscreen | |
&& (ev->motion.x == 0 || ev->motion.y == 0 || | |
ev->motion.x == max_x || ev->motion.y == max_y)) { | |
- sdl_grab_end(scon); | |
+ //sdl_grab_end(scon); | |
} | |
if (!gui_grab && | |
(ev->motion.x > 0 && ev->motion.x < max_x && | |
ev->motion.y > 0 && ev->motion.y < max_y)) { | |
- sdl_grab_start(scon); | |
+ //sdl_grab_start(scon); | |
} | |
} | |
if (gui_grab || qemu_input_is_absolute() || absolute_enabled) { | |
@@ -534,7 +534,7 @@ static void handle_mousebutton(SDL_Event *ev) | |
if (!gui_grab && !qemu_input_is_absolute()) { | |
if (ev->type == SDL_MOUSEBUTTONUP && bev->button == SDL_BUTTON_LEFT) { | |
/* start grabbing all events */ | |
- sdl_grab_start(scon); | |
+ //sdl_grab_start(scon); | |
} | |
} else { | |
if (ev->type == SDL_MOUSEBUTTONDOWN) { | |
@@ -605,7 +605,7 @@ static void handle_windowevent(SDL_Event *ev) | |
/* fall through */ | |
case SDL_WINDOWEVENT_ENTER: | |
if (!gui_grab && (qemu_input_is_absolute() || absolute_enabled)) { | |
- absolute_mouse_grab(scon); | |
+ //absolute_mouse_grab(scon); | |
} | |
/* If a new console window opened using a hotkey receives the | |
* focus, SDL sends another KEYDOWN event to the new window, | |
@@ -621,7 +621,7 @@ static void handle_windowevent(SDL_Event *ev) | |
win32_kbd_set_window(NULL); | |
} | |
if (gui_grab && !gui_fullscreen) { | |
- sdl_grab_end(scon); | |
+ //sdl_grab_end(scon); | |
} | |
break; | |
case SDL_WINDOWEVENT_RESTORED: | |
@@ -950,7 +950,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o) | |
sdl_cursor_normal = SDL_GetCursor(); | |
if (gui_fullscreen) { | |
- sdl_grab_start(&sdl2_console[0]); | |
+ //sdl_grab_start(&sdl2_console[0]); | |
} | |
atexit(sdl_cleanup); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment