]> git.saurik.com Git - apple/xnu.git/blobdiff - pexpert/arm/pe_identify_machine.c
xnu-7195.81.3.tar.gz
[apple/xnu.git] / pexpert / arm / pe_identify_machine.c
index 4e734fbe62ad618918580bb51e50b8a810db425e..1ddd6fc651a755cfbf502dbf496c78caa81a79ec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2019 Apple Inc. All rights reserved.
  * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
  */
 #include <pexpert/pexpert.h>
 #include <pexpert/arm64/board_config.h>
 #endif
 
+#include <kern/clock.h>
 #include <machine/machine_routines.h>
 #if DEVELOPMENT || DEBUG
 #include <kern/simple_lock.h>
 #include <kern/cpu_number.h>
 #endif
 /* Local declarations */
-void           pe_identify_machine(boot_args * bootArgs);
+void            pe_identify_machine(boot_args * bootArgs);
 
 /* External declarations */
 extern void clean_mmu_dcache(void);
 
 static char    *gPESoCDeviceType;
-static char    gPESoCDeviceTypeBuffer[SOC_DEVICE_TYPE_BUFFER_SIZE];
+static char     gPESoCDeviceTypeBuffer[SOC_DEVICE_TYPE_BUFFER_SIZE];
 static vm_offset_t gPESoCBasePhys;
 
-static uint32_t        gTCFG0Value;
+static uint32_t gTCFG0Value;
 
 static uint32_t pe_arm_init_timer(void *args);
 
 #if DEVELOPMENT || DEBUG
-decl_simple_lock_data(, panic_trace_lock;)
+decl_simple_lock_data(, panic_hook_lock);
 #endif
 /*
  * pe_identify_machine:
- * 
+ *
  * Sets up platform parameters. Returns:    nothing
  */
 void
 pe_identify_machine(boot_args * bootArgs)
 {
        OpaqueDTEntryIterator iter;
-       DTEntry         cpus, cpu;
-       uint32_t        mclk = 0, hclk = 0, pclk = 0, tclk = 0, use_dt = 0;
-       unsigned long  *value;
-       unsigned int    size;
-       int             err;
+       DTEntry         cpus, cpu;
+       uint32_t        mclk = 0, hclk = 0, pclk = 0, tclk = 0, use_dt = 0;
+       unsigned long const *value;
+       unsigned int    size;
+       int             err;
 
        (void)bootArgs;
 
-       if (pe_arm_get_soc_base_phys() == 0)
+       if (pe_arm_get_soc_base_phys() == 0) {
                return;
+       }
 
        /* Clear the gPEClockFrequencyInfo struct */
        bzero((void *)&gPEClockFrequencyInfo, sizeof(clock_frequency_info_t));
@@ -67,15 +69,14 @@ pe_identify_machine(boot_args * bootArgs)
 
                gTCFG0Value = tclk - 1;
 
-               tclk = pclk / (4 * tclk);       /* Calculate the "actual"
-                                                * Timer0 frequency in fixed
-                                                * point. */
+               tclk = pclk / (4 * tclk);       /* Calculate the "actual"
+                                                * Timer0 frequency in fixed
+                                                * point. */
 
                mclk = (mclk >> 17) * (125 * 125);
                hclk = (hclk >> 17) * (125 * 125);
                pclk = (pclk >> 17) * (125 * 125);
                tclk = (((((tclk * 125) + 2) >> 2) * 125) + (1 << 14)) >> 15;
-
        } else if (!strcmp(gPESoCDeviceType, "integratorcp-io")) {
                mclk = 200000000;
                hclk = mclk / 2;
@@ -87,23 +88,18 @@ pe_identify_machine(boot_args * bootArgs)
                pclk = hclk / 2;
                tclk = pclk;
        } else if (!strcmp(gPESoCDeviceType, "omap3430sdp-io")) {
-                mclk = 332000000;
-                hclk =  19200000;
-                pclk = hclk;
-                tclk = pclk;
+               mclk = 332000000;
+               hclk =  19200000;
+               pclk = hclk;
+               tclk = pclk;
        } else if (!strcmp(gPESoCDeviceType, "s5i3000-io")) {
                mclk = 400000000;
                hclk = mclk / 4;
                pclk = hclk / 2;
-               tclk = 100000;  /* timer is at 100khz */
-
-       } else if (!strcmp(gPESoCDeviceType, "bcm2837-io")) {
-               mclk = 1200000000;
-               hclk = mclk / 4;
-               pclk = hclk / 2;
-               tclk = 1000000;
-       } else
+               tclk = 100000;  /* timer is at 100khz */
+       } else {
                use_dt = 1;
+       }
 
        if (use_dt) {
                /* Start with default values. */
@@ -111,87 +107,96 @@ pe_identify_machine(boot_args * bootArgs)
                gPEClockFrequencyInfo.bus_clock_rate_hz = 100000000;
                gPEClockFrequencyInfo.cpu_clock_rate_hz = 400000000;
 
-               err = DTLookupEntry(NULL, "/cpus", &cpus);
+               err = SecureDTLookupEntry(NULL, "/cpus", &cpus);
                assert(err == kSuccess);
 
-               err = DTInitEntryIterator(cpus, &iter);
+               err = SecureDTInitEntryIterator(cpus, &iter);
                assert(err == kSuccess);
 
-               while (kSuccess == DTIterateEntries(&iter, &cpu)) {
-                       if ((kSuccess != DTGetProperty(cpu, "state", (void **)&value, &size)) ||
-                           (strncmp((char*)value, "running", size) != 0))
+               while (kSuccess == SecureDTIterateEntries(&iter, &cpu)) {
+                       if ((kSuccess != SecureDTGetProperty(cpu, "state", (void const **)&value, &size)) ||
+                           (strncmp((char const *)value, "running", size) != 0)) {
                                continue;
+                       }
 
                        /* Find the time base frequency first. */
-                       if (DTGetProperty(cpu, "timebase-frequency", (void **)&value, &size) == kSuccess) {
+                       if (SecureDTGetProperty(cpu, "timebase-frequency", (void const **)&value, &size) == kSuccess) {
                                /*
                                 * timebase_frequency_hz is only 32 bits, and
                                 * the device tree should never provide 64
                                 * bits so this if should never be taken.
                                 */
-                               if (size == 8)
-                                       gPEClockFrequencyInfo.timebase_frequency_hz = *(unsigned long long *)value;
-                               else
+                               if (size == 8) {
+                                       gPEClockFrequencyInfo.timebase_frequency_hz = *(unsigned long long const *)value;
+                               } else {
                                        gPEClockFrequencyInfo.timebase_frequency_hz = *value;
+                               }
                        }
                        gPEClockFrequencyInfo.dec_clock_rate_hz = gPEClockFrequencyInfo.timebase_frequency_hz;
 
                        /* Find the bus frequency next. */
-                       if (DTGetProperty(cpu, "bus-frequency", (void **)&value, &size) == kSuccess) {
-                               if (size == 8)
-                                       gPEClockFrequencyInfo.bus_frequency_hz = *(unsigned long long *)value;
-                               else
+                       if (SecureDTGetProperty(cpu, "bus-frequency", (void const **)&value, &size) == kSuccess) {
+                               if (size == 8) {
+                                       gPEClockFrequencyInfo.bus_frequency_hz = *(unsigned long long const *)value;
+                               } else {
                                        gPEClockFrequencyInfo.bus_frequency_hz = *value;
+                               }
                        }
                        gPEClockFrequencyInfo.bus_frequency_min_hz = gPEClockFrequencyInfo.bus_frequency_hz;
                        gPEClockFrequencyInfo.bus_frequency_max_hz = gPEClockFrequencyInfo.bus_frequency_hz;
 
-                       if (gPEClockFrequencyInfo.bus_frequency_hz < 0x100000000ULL)
+                       if (gPEClockFrequencyInfo.bus_frequency_hz < 0x100000000ULL) {
                                gPEClockFrequencyInfo.bus_clock_rate_hz = gPEClockFrequencyInfo.bus_frequency_hz;
-                       else
+                       } else {
                                gPEClockFrequencyInfo.bus_clock_rate_hz = 0xFFFFFFFF;
+                       }
 
                        /* Find the memory frequency next. */
-                       if (DTGetProperty(cpu, "memory-frequency", (void **)&value, &size) == kSuccess) {
-                               if (size == 8)
-                                       gPEClockFrequencyInfo.mem_frequency_hz = *(unsigned long long *)value;
-                               else
+                       if (SecureDTGetProperty(cpu, "memory-frequency", (void const **)&value, &size) == kSuccess) {
+                               if (size == 8) {
+                                       gPEClockFrequencyInfo.mem_frequency_hz = *(unsigned long long const *)value;
+                               } else {
                                        gPEClockFrequencyInfo.mem_frequency_hz = *value;
+                               }
                        }
                        gPEClockFrequencyInfo.mem_frequency_min_hz = gPEClockFrequencyInfo.mem_frequency_hz;
                        gPEClockFrequencyInfo.mem_frequency_max_hz = gPEClockFrequencyInfo.mem_frequency_hz;
 
                        /* Find the peripheral frequency next. */
-                       if (DTGetProperty(cpu, "peripheral-frequency", (void **)&value, &size) == kSuccess) {
-                               if (size == 8)
-                                       gPEClockFrequencyInfo.prf_frequency_hz = *(unsigned long long *)value;
-                               else
+                       if (SecureDTGetProperty(cpu, "peripheral-frequency", (void const **)&value, &size) == kSuccess) {
+                               if (size == 8) {
+                                       gPEClockFrequencyInfo.prf_frequency_hz = *(unsigned long long const *)value;
+                               } else {
                                        gPEClockFrequencyInfo.prf_frequency_hz = *value;
+                               }
                        }
                        gPEClockFrequencyInfo.prf_frequency_min_hz = gPEClockFrequencyInfo.prf_frequency_hz;
                        gPEClockFrequencyInfo.prf_frequency_max_hz = gPEClockFrequencyInfo.prf_frequency_hz;
 
                        /* Find the fixed frequency next. */
-                       if (DTGetProperty(cpu, "fixed-frequency", (void **)&value, &size) == kSuccess) {
-                               if (size == 8)
-                                       gPEClockFrequencyInfo.fix_frequency_hz = *(unsigned long long *)value;
-                               else
+                       if (SecureDTGetProperty(cpu, "fixed-frequency", (void const **)&value, &size) == kSuccess) {
+                               if (size == 8) {
+                                       gPEClockFrequencyInfo.fix_frequency_hz = *(unsigned long long const *)value;
+                               } else {
                                        gPEClockFrequencyInfo.fix_frequency_hz = *value;
+                               }
                        }
                        /* Find the cpu frequency last. */
-                       if (DTGetProperty(cpu, "clock-frequency", (void **)&value, &size) == kSuccess) {
-                               if (size == 8)
-                                       gPEClockFrequencyInfo.cpu_frequency_hz = *(unsigned long long *)value;
-                               else
+                       if (SecureDTGetProperty(cpu, "clock-frequency", (void const **)&value, &size) == kSuccess) {
+                               if (size == 8) {
+                                       gPEClockFrequencyInfo.cpu_frequency_hz = *(unsigned long long const *)value;
+                               } else {
                                        gPEClockFrequencyInfo.cpu_frequency_hz = *value;
+                               }
                        }
                        gPEClockFrequencyInfo.cpu_frequency_min_hz = gPEClockFrequencyInfo.cpu_frequency_hz;
                        gPEClockFrequencyInfo.cpu_frequency_max_hz = gPEClockFrequencyInfo.cpu_frequency_hz;
 
-                       if (gPEClockFrequencyInfo.cpu_frequency_hz < 0x100000000ULL)
+                       if (gPEClockFrequencyInfo.cpu_frequency_hz < 0x100000000ULL) {
                                gPEClockFrequencyInfo.cpu_clock_rate_hz = gPEClockFrequencyInfo.cpu_frequency_hz;
-                       else
+                       } else {
                                gPEClockFrequencyInfo.cpu_clock_rate_hz = 0xFFFFFFFF;
+                       }
                }
        } else {
                /* Use the canned values. */
@@ -218,29 +223,29 @@ pe_identify_machine(boot_args * bootArgs)
        gPEClockFrequencyInfo.bus_clock_rate_den = 1;
 
        gPEClockFrequencyInfo.bus_to_cpu_rate_num =
-               (2 * gPEClockFrequencyInfo.cpu_clock_rate_hz) / gPEClockFrequencyInfo.bus_clock_rate_hz;
+           (2 * gPEClockFrequencyInfo.cpu_clock_rate_hz) / gPEClockFrequencyInfo.bus_clock_rate_hz;
        gPEClockFrequencyInfo.bus_to_cpu_rate_den = 2;
 
        gPEClockFrequencyInfo.bus_to_dec_rate_num = 1;
        gPEClockFrequencyInfo.bus_to_dec_rate_den =
-               gPEClockFrequencyInfo.bus_clock_rate_hz / gPEClockFrequencyInfo.dec_clock_rate_hz;
+           gPEClockFrequencyInfo.bus_clock_rate_hz / gPEClockFrequencyInfo.dec_clock_rate_hz;
 }
 
 vm_offset_t
 pe_arm_get_soc_base_phys(void)
 {
-       DTEntry         entryP;
-       uintptr_t       *ranges_prop;
-       uint32_t        prop_size;
-       char           *tmpStr;
+       DTEntry         entryP;
+       uintptr_t const *ranges_prop;
+       uint32_t        prop_size;
+       char const      *tmpStr;
 
-       if (DTFindEntry("name", "arm-io", &entryP) == kSuccess) {
+       if (SecureDTFindEntry("name", "arm-io", &entryP) == kSuccess) {
                if (gPESoCDeviceType == 0) {
-                       DTGetProperty(entryP, "device_type", (void **)&tmpStr, &prop_size);
+                       SecureDTGetProperty(entryP, "device_type", (void const **)&tmpStr, &prop_size);
                        strlcpy(gPESoCDeviceTypeBuffer, tmpStr, SOC_DEVICE_TYPE_BUFFER_SIZE);
                        gPESoCDeviceType = gPESoCDeviceTypeBuffer;
 
-                       DTGetProperty(entryP, "ranges", (void **)&ranges_prop, &prop_size);
+                       SecureDTGetProperty(entryP, "ranges", (void const **)&ranges_prop, &prop_size);
                        gPESoCBasePhys = *(ranges_prop + 1);
                }
                return gPESoCBasePhys;
@@ -248,125 +253,76 @@ pe_arm_get_soc_base_phys(void)
        return 0;
 }
 
-uint32_t
-pe_arm_get_soc_revision(void)
-{
-       DTEntry         entryP;
-       uint32_t        *value;
-       uint32_t        size;
-
-       if ((DTFindEntry("name", "arm-io", &entryP) == kSuccess) 
-           && (DTGetProperty(entryP, "chip-revision", (void **)&value, &size) == kSuccess)) {
-               if (size == 8)
-                       return((uint32_t)*(unsigned long long *)value);
-               else
-                       return(*value);
-       }
-       return 0;
-}
-
-
-extern void    fleh_fiq_generic(void);
-
-#if defined(ARM_BOARD_CLASS_S5L8960X)
-static struct tbd_ops    s5l8960x_funcs = {NULL, NULL, NULL};
-#endif /* defined(ARM_BOARD_CLASS_S5L8960X) */
-
-#if defined(ARM_BOARD_CLASS_T7000)
-static struct tbd_ops    t7000_funcs = {NULL, NULL, NULL};
-#endif /* defined(ARM_BOARD_CLASS_T7000) */
-
-#if defined(ARM_BOARD_CLASS_S7002)
-extern void     fleh_fiq_s7002(void);
-extern uint32_t        s7002_get_decrementer(void);
-extern void    s7002_set_decrementer(uint32_t);
-static struct tbd_ops    s7002_funcs = {&fleh_fiq_s7002, &s7002_get_decrementer, &s7002_set_decrementer};
-#endif /* defined(ARM_BOARD_CLASS_S7002) */
-
-#if defined(ARM_BOARD_CLASS_S8000)
-static struct tbd_ops    s8000_funcs = {NULL, NULL, NULL};
-#endif /* defined(ARM_BOARD_CLASS_T7000) */
+extern void     fleh_fiq_generic(void);
 
 #if defined(ARM_BOARD_CLASS_T8002)
 extern void     fleh_fiq_t8002(void);
-extern uint32_t        t8002_get_decrementer(void);
-extern void    t8002_set_decrementer(uint32_t);
+extern uint32_t t8002_get_decrementer(void);
+extern void     t8002_set_decrementer(uint32_t);
 static struct tbd_ops    t8002_funcs = {&fleh_fiq_t8002, &t8002_get_decrementer, &t8002_set_decrementer};
 #endif /* defined(ARM_BOARD_CLASS_T8002) */
 
-#if defined(ARM_BOARD_CLASS_T8010)
-static struct tbd_ops    t8010_funcs = {NULL, NULL, NULL};
-#endif /* defined(ARM_BOARD_CLASS_T8010) */
-
-#if defined(ARM_BOARD_CLASS_T8011)
-static struct tbd_ops    t8011_funcs = {NULL, NULL, NULL};
-#endif /* defined(ARM_BOARD_CLASS_T8011) */
-
-#if defined(ARM_BOARD_CLASS_T8015)
-static struct tbd_ops    t8015_funcs = {NULL, NULL, NULL};
-#endif /* defined(ARM_BOARD_CLASS_T8015) */
-
-
-
-
-
-
-#if defined(ARM_BOARD_CLASS_BCM2837)
-static struct tbd_ops    bcm2837_funcs = {NULL, NULL, NULL};
-#endif /* defined(ARM_BOARD_CLASS_BCM2837) */
-
-vm_offset_t    gPicBase;
-vm_offset_t    gTimerBase;
-vm_offset_t    gSocPhys;
+vm_offset_t     gPicBase;
+vm_offset_t     gTimerBase;
+vm_offset_t     gSocPhys;
 
 #if DEVELOPMENT || DEBUG
 // This block contains the panic trace implementation
 
 // These variables are local to this file, and contain the panic trace configuration information
-typedef enum
-{
-    panic_trace_disabled = 0,
-    panic_trace_unused,
-    panic_trace_enabled,
-    panic_trace_alt_enabled,
+typedef enum{
+       panic_trace_disabled = 0,
+       panic_trace_unused,
+       panic_trace_enabled,
+       panic_trace_alt_enabled,
 } panic_trace_t;
 static panic_trace_t bootarg_panic_trace;
 
+static int bootarg_stop_clocks;
+
 // The command buffer contains the converted commands from the device tree for commanding cpu_halt, enable_trace, etc.
 #define DEBUG_COMMAND_BUFFER_SIZE 256
-typedef struct command_buffer_element{
+typedef struct command_buffer_element {
        uintptr_t address;
-       uint16_t destination_cpu_selector;
        uintptr_t value;
+       uint16_t destination_cpu_selector;
+       uint16_t delay_us;
+       bool is_32bit;
 } command_buffer_element_t;
-static command_buffer_element_t debug_command_buffer[DEBUG_COMMAND_BUFFER_SIZE];               // statically allocate to prevent needing alloc at runtime
-static uint32_t  next_command_bufffer_entry = 0;                                                                               // index of next unused slot in debug_command_buffer
-
-#define CPU_SELECTOR_SHIFT                             ((sizeof(int)-2)*8)
-#define CPU_SELECTOR_MASK                              (0xFFFF << CPU_SELECTOR_SHIFT)
-#define REGISTER_OFFSET_MASK                   (~CPU_SELECTOR_MASK)
-#define REGISTER_OFFSET(register_prop) (register_prop & REGISTER_OFFSET_MASK)
-#define CPU_SELECTOR(register_offset)  (register_offset >> CPU_SELECTOR_SHIFT) // Upper 16bits holds the cpu selector
-#define MAX_WINDOW_SIZE                                        0xFFFF
-#define PE_ISSPACE(c)                                  (c == ' ' || c == '\t' || c == '\n' || c == '\12')
+static command_buffer_element_t debug_command_buffer[DEBUG_COMMAND_BUFFER_SIZE];                // statically allocate to prevent needing alloc at runtime
+static uint32_t  next_command_buffer_entry = 0;                                                                                // index of next unused slot in debug_command_buffer
+
+#define CPU_SELECTOR_SHIFT              (16)
+#define CPU_SELECTOR_MASK               (0xFFFF << CPU_SELECTOR_SHIFT)
+#define REGISTER_OFFSET_MASK            ((1 << CPU_SELECTOR_SHIFT) - 1)
+#define REGISTER_OFFSET(register_prop)  (register_prop & REGISTER_OFFSET_MASK)
+#define CPU_SELECTOR(register_offset)   ((register_offset & CPU_SELECTOR_MASK) >> CPU_SELECTOR_SHIFT) // Upper 16bits holds the cpu selector
+#define MAX_WINDOW_SIZE                 0xFFFF
+#define PE_ISSPACE(c)                   (c == ' ' || c == '\t' || c == '\n' || c == '\12')
+#define DELAY_SHIFT                     (32)
+#define DELAY_MASK                      (0xFFFFULL << DELAY_SHIFT)
+#define DELAY_US(register_offset)       ((register_offset & DELAY_MASK) >> DELAY_SHIFT)
+#define REGISTER_32BIT_MASK             (1ULL << 63)
 /*
-0x0000 - all cpus
-0x0001 - cpu 0
-0x0002 - cpu 1
-0x0004 - cpu 2
-0x0003 - cpu 0 and 1
-since it's 16bits, we can have up to 16 cpus
-*/
+ *  0x0000 - all cpus
+ *  0x0001 - cpu 0
+ *  0x0002 - cpu 1
+ *  0x0004 - cpu 2
+ *  0x0003 - cpu 0 and 1
+ *  since it's 16bits, we can have up to 16 cpus
+ */
 #define ALL_CPUS 0x0000
 #define IS_CPU_SELECTED(cpu_number, cpu_selector) (cpu_selector == ALL_CPUS ||  (cpu_selector & (1<<cpu_number) ) != 0 )
 
-#define RESET_VIRTUAL_ADDRESS_WINDOW   0xFFFFFFFF
+#define RESET_VIRTUAL_ADDRESS_WINDOW    0xFFFFFFFF
 
 // Pointers into debug_command_buffer for each operation. Assumes runtime will init them to zero.
 static command_buffer_element_t *cpu_halt;
 static command_buffer_element_t *enable_trace;
 static command_buffer_element_t *enable_alt_trace;
 static command_buffer_element_t *trace_halt;
+static command_buffer_element_t *enable_stop_clocks;
+static command_buffer_element_t *stop_clocks;
 
 // Record which CPU is currently running one of our debug commands, so we can trap panic reentrancy to PE_arm_debug_panic_hook.
 static int running_debug_command_on_cpu_number = -1;
@@ -374,33 +330,32 @@ static int running_debug_command_on_cpu_number = -1;
 static void
 pe_init_debug_command(DTEntry entryP, command_buffer_element_t **command_buffer, const char* entry_name)
 {
-       uintptr_t       *reg_prop;
-       uint32_t        prop_size, reg_window_size = 0, command_starting_index;
-       uintptr_t       debug_reg_window = 0;
+       uintptr_t const *reg_prop;
+       uint32_t        prop_size, reg_window_size = 0, command_starting_index;
+       uintptr_t       debug_reg_window = 0;
 
        if (command_buffer == 0) {
                return;
        }
 
-       if (DTGetProperty(entryP, entry_name, (void **)&reg_prop, &prop_size) != kSuccess) {
+       if (SecureDTGetProperty(entryP, entry_name, (void const **)&reg_prop, &prop_size) != kSuccess) {
                panic("pe_init_debug_command: failed to read property %s\n", entry_name);
        }
 
        // make sure command will fit
-       if (next_command_bufffer_entry + prop_size/sizeof(uintptr_t) > DEBUG_COMMAND_BUFFER_SIZE-1) {
+       if (next_command_buffer_entry + prop_size / sizeof(uintptr_t) > DEBUG_COMMAND_BUFFER_SIZE - 1) {
                panic("pe_init_debug_command: property %s is %u bytes, command buffer only has %lu bytes remaining\n",
-                       entry_name, prop_size, ((DEBUG_COMMAND_BUFFER_SIZE-1) - next_command_bufffer_entry) * sizeof(uintptr_t) );
+                   entry_name, prop_size, ((DEBUG_COMMAND_BUFFER_SIZE - 1) - next_command_buffer_entry) * sizeof(uintptr_t));
        }
 
        // Hold the pointer in a temp variable and later assign it to command buffer, in case we panic while half-initialized
-       command_starting_index = next_command_bufffer_entry;
+       command_starting_index = next_command_buffer_entry;
 
        // convert to real virt addresses and stuff commands into debug_command_buffer
-       for( ; prop_size ;  reg_prop += 2, prop_size -= 2*sizeof(uintptr_t) ) {
+       for (; prop_size; reg_prop += 2, prop_size -= 2 * sizeof(uintptr_t)) {
                if (*reg_prop == RESET_VIRTUAL_ADDRESS_WINDOW) {
                        debug_reg_window = 0; // Create a new window
-               }
-               else if (debug_reg_window==0) {
+               } else if (debug_reg_window == 0) {
                        // create a window from virtual address to the specified physical address
                        reg_window_size = ((uint32_t)*(reg_prop + 1));
                        if (reg_window_size > MAX_WINDOW_SIZE) {
@@ -409,19 +364,26 @@ pe_init_debug_command(DTEntry entryP, command_buffer_element_t **command_buffer,
                        debug_reg_window =  ml_io_map(gSocPhys + *reg_prop, reg_window_size);
                        // for debug -- kprintf("pe_init_debug_command: %s registers @ 0x%08lX for 0x%08lX\n", entry_name, debug_reg_window, *(reg_prop + 1) );
                } else {
-                       if ((REGISTER_OFFSET(*reg_prop)+ sizeof(uintptr_t)) >= reg_window_size) {
-                               panic("pe_init_debug_command: Command Offset is %lx, exceeds allocated size of %x\n", REGISTER_OFFSET(*reg_prop),reg_window_size );
+                       if ((REGISTER_OFFSET(*reg_prop) + sizeof(uintptr_t)) >= reg_window_size) {
+                               panic("pe_init_debug_command: Command Offset is %lx, exceeds allocated size of %x\n", REGISTER_OFFSET(*reg_prop), reg_window_size );
                        }
-                       debug_command_buffer[next_command_bufffer_entry].address = debug_reg_window + REGISTER_OFFSET(*reg_prop);
-                       debug_command_buffer[next_command_bufffer_entry].destination_cpu_selector = CPU_SELECTOR(*reg_prop);
-                       debug_command_buffer[next_command_bufffer_entry++].value = *(reg_prop+1);
+                       debug_command_buffer[next_command_buffer_entry].address = debug_reg_window + REGISTER_OFFSET(*reg_prop);
+                       debug_command_buffer[next_command_buffer_entry].destination_cpu_selector = (uint16_t)CPU_SELECTOR(*reg_prop);
+#if defined(__arm64__)
+                       debug_command_buffer[next_command_buffer_entry].delay_us = DELAY_US(*reg_prop);
+                       debug_command_buffer[next_command_buffer_entry].is_32bit = ((*reg_prop & REGISTER_32BIT_MASK) != 0);
+#else
+                       debug_command_buffer[next_command_buffer_entry].delay_us = 0;
+                       debug_command_buffer[next_command_buffer_entry].is_32bit = false;
+#endif
+                       debug_command_buffer[next_command_buffer_entry++].value = *(reg_prop + 1);
                }
        }
 
        // null terminate the address field of the command to end it
-       debug_command_buffer[next_command_bufffer_entry++].address = 0;
+       debug_command_buffer[next_command_buffer_entry++].address = 0;
 
-       // save pointer into table for this command     
+       // save pointer into table for this command
        *command_buffer = &debug_command_buffer[command_starting_index];
 }
 
@@ -429,43 +391,58 @@ static void
 pe_run_debug_command(command_buffer_element_t *command_buffer)
 {
        // When both the CPUs panic, one will get stuck on the lock and the other CPU will be halted when the first executes the debug command
-       simple_lock(&panic_trace_lock);
+       simple_lock(&panic_hook_lock, LCK_GRP_NULL);
+
        running_debug_command_on_cpu_number = cpu_number();
 
-       while( command_buffer && command_buffer->address ) {
+       while (command_buffer && command_buffer->address) {
                if (IS_CPU_SELECTED(running_debug_command_on_cpu_number, command_buffer->destination_cpu_selector)) {
-                       *((volatile uintptr_t*)(command_buffer->address)) = command_buffer->value;      // register = value;
+                       if (command_buffer->is_32bit) {
+                               *((volatile uint32_t*)(command_buffer->address)) = (uint32_t)(command_buffer->value);
+                       } else {
+                               *((volatile uintptr_t*)(command_buffer->address)) = command_buffer->value;      // register = value;
+                       }
+                       if (command_buffer->delay_us != 0) {
+                               uint64_t deadline;
+                               nanoseconds_to_absolutetime(command_buffer->delay_us * NSEC_PER_USEC, &deadline);
+                               deadline += ml_get_timebase();
+                               while (ml_get_timebase() < deadline) {
+                                       ;
+                               }
+                       }
                }
                command_buffer++;
        }
 
        running_debug_command_on_cpu_number = -1;
-       simple_unlock(&panic_trace_lock);
+       simple_unlock(&panic_hook_lock);
 }
 
 
 void
 PE_arm_debug_enable_trace(void)
 {
-    switch (bootarg_panic_trace) {
-        case panic_trace_enabled:
-            pe_run_debug_command(enable_trace);
-            break;
-            
-        case panic_trace_alt_enabled:
-            pe_run_debug_command(enable_alt_trace);
-            break;
-            
-        default:
-            break;
-    }
+       switch (bootarg_panic_trace) {
+       case panic_trace_enabled:
+               pe_run_debug_command(enable_trace);
+               break;
+
+       case panic_trace_alt_enabled:
+               pe_run_debug_command(enable_alt_trace);
+               break;
+
+       default:
+               break;
+       }
 }
 
 static void
-PEARMDebugPanicHook(const char *str)
+PE_arm_panic_hook(const char *str __unused)
 {
-    (void)str;  // not used
-
+       (void)str; // not used
+       if (bootarg_stop_clocks != 0) {
+               pe_run_debug_command(stop_clocks);
+       }
        // if panic trace is enabled
        if (bootarg_panic_trace != 0) {
                if (running_debug_command_on_cpu_number == cpu_number()) {
@@ -474,61 +451,87 @@ PEARMDebugPanicHook(const char *str)
                        return;  // allow the normal panic operation to occur.
                }
 
-        // Stop tracing to freze the buffer and return to normal panic processing.
+               // Stop tracing to freeze the buffer and return to normal panic processing.
                pe_run_debug_command(trace_halt);
        }
 }
 
-void (*PE_arm_debug_panic_hook)(const char *str) = PEARMDebugPanicHook;
+void (*PE_arm_debug_panic_hook)(const char *str) = PE_arm_panic_hook;
+
+void
+PE_init_cpu(void)
+{
+       if (bootarg_stop_clocks != 0) {
+               pe_run_debug_command(enable_stop_clocks);
+       }
+}
 
 #else
 
-void (*PE_arm_debug_panic_hook)(const char *str) = NULL;
+void(*const PE_arm_debug_panic_hook)(const char *str) = NULL;
+
+void
+PE_init_cpu(void)
+{
+}
 
 #endif  // DEVELOPMENT || DEBUG
 
+void
+PE_panic_hook(const char *str __unused)
+{
+       if (PE_arm_debug_panic_hook != NULL) {
+               PE_arm_debug_panic_hook(str);
+       }
+}
+
 void
 pe_arm_init_debug(void *args)
 {
-       DTEntry         entryP;
-       uintptr_t       *reg_prop;
-       uint32_t        prop_size;
+       DTEntry         entryP;
+       uintptr_t const *reg_prop;
+       uint32_t        prop_size;
 
-       if (gSocPhys == 0 ) {
+       if (gSocPhys == 0) {
                kprintf("pe_arm_init_debug: failed to initialize gSocPhys == 0\n");
-           return;
+               return;
        }
-       
-       if ( DTFindEntry("device_type", "cpu-debug-interface", &entryP) == kSuccess ) {
+
+       if (SecureDTFindEntry("device_type", "cpu-debug-interface", &entryP) == kSuccess) {
                if (args != NULL) {
-                       if (DTGetProperty(entryP, "reg", (void **)&reg_prop, &prop_size) == kSuccess) {
+                       if (SecureDTGetProperty(entryP, "reg", (void const **)&reg_prop, &prop_size) == kSuccess) {
                                ml_init_arm_debug_interface(args, ml_io_map(gSocPhys + *reg_prop, *(reg_prop + 1)));
                        }
 #if DEVELOPMENT || DEBUG
                        // When args != NULL, this means we're being called from arm_init on the boot CPU.
                        // This controls one-time initialization of the Panic Trace infrastructure
 
-                       simple_lock_init(&panic_trace_lock, 0); //assuming single threaded mode
-               
+                       simple_lock_init(&panic_hook_lock, 0); //assuming single threaded mode
+
                        // Panic_halt is deprecated. Please use panic_trace istead.
                        unsigned int temp_bootarg_panic_trace;
                        if (PE_parse_boot_argn("panic_trace", &temp_bootarg_panic_trace, sizeof(temp_bootarg_panic_trace)) ||
                            PE_parse_boot_argn("panic_halt", &temp_bootarg_panic_trace, sizeof(temp_bootarg_panic_trace))) {
-               
                                kprintf("pe_arm_init_debug: panic_trace=%d\n", temp_bootarg_panic_trace);
 
-                // Prepare debug command buffers.
+                               // Prepare debug command buffers.
                                pe_init_debug_command(entryP, &cpu_halt, "cpu_halt");
                                pe_init_debug_command(entryP, &enable_trace, "enable_trace");
                                pe_init_debug_command(entryP, &enable_alt_trace, "enable_alt_trace");
                                pe_init_debug_command(entryP, &trace_halt, "trace_halt");
-                               
+
                                // now that init's are done, enable the panic halt capture (allows pe_init_debug_command to panic normally if necessary)
                                bootarg_panic_trace = temp_bootarg_panic_trace;
 
                                // start tracing now if enabled
                                PE_arm_debug_enable_trace();
                        }
+                       unsigned int temp_bootarg_stop_clocks;
+                       if (PE_parse_boot_argn("stop_clocks", &temp_bootarg_stop_clocks, sizeof(temp_bootarg_stop_clocks))) {
+                               pe_init_debug_command(entryP, &enable_stop_clocks, "enable_stop_clocks");
+                               pe_init_debug_command(entryP, &stop_clocks, "stop_clocks");
+                               bootarg_stop_clocks = temp_bootarg_stop_clocks;
+                       }
 #endif
                }
        } else {
@@ -539,21 +542,22 @@ pe_arm_init_debug(void *args)
 static uint32_t
 pe_arm_map_interrupt_controller(void)
 {
-       DTEntry         entryP;
-       uintptr_t       *reg_prop;
-       uint32_t        prop_size;
-       vm_offset_t     soc_phys = 0;
+       DTEntry         entryP;
+       uintptr_t const *reg_prop;
+       uint32_t        prop_size;
+       vm_offset_t     soc_phys = 0;
 
        gSocPhys = pe_arm_get_soc_base_phys();
 
        soc_phys = gSocPhys;
        kprintf("pe_arm_map_interrupt_controller: soc_phys:  0x%lx\n", (unsigned long)soc_phys);
-       if (soc_phys == 0)
+       if (soc_phys == 0) {
                return 0;
+       }
 
-       if (DTFindEntry("interrupt-controller", "master", &entryP) == kSuccess) {
+       if (SecureDTFindEntry("interrupt-controller", "master", &entryP) == kSuccess) {
                kprintf("pe_arm_map_interrupt_controller: found interrupt-controller\n");
-               DTGetProperty(entryP, "reg", (void **)&reg_prop, &prop_size);
+               SecureDTGetProperty(entryP, "reg", (void const **)&reg_prop, &prop_size);
                gPicBase = ml_io_map(soc_phys + *reg_prop, *(reg_prop + 1));
                kprintf("pe_arm_map_interrupt_controller: gPicBase: 0x%lx\n", (unsigned long)gPicBase);
        }
@@ -562,9 +566,9 @@ pe_arm_map_interrupt_controller(void)
                return 0;
        }
 
-       if (DTFindEntry("device_type", "timer", &entryP) == kSuccess) {
+       if (SecureDTFindEntry("device_type", "timer", &entryP) == kSuccess) {
                kprintf("pe_arm_map_interrupt_controller: found timer\n");
-               DTGetProperty(entryP, "reg", (void **)&reg_prop, &prop_size);
+               SecureDTGetProperty(entryP, "reg", (void const **)&reg_prop, &prop_size);
                gTimerBase = ml_io_map(soc_phys + *reg_prop, *(reg_prop + 1));
                kprintf("pe_arm_map_interrupt_controller: gTimerBase: 0x%lx\n", (unsigned long)gTimerBase);
        }
@@ -591,69 +595,33 @@ pe_arm_init_interrupts(void *args)
        return pe_arm_init_timer(args);
 }
 
-static uint32_t 
+static uint32_t
 pe_arm_init_timer(void *args)
 {
-       vm_offset_t     pic_base = 0;
-       vm_offset_t     timer_base = 0;
-       vm_offset_t     soc_phys;
-       vm_offset_t     eoi_addr = 0;
-       uint32_t        eoi_value = 0;
+       vm_offset_t     pic_base = 0;
+       vm_offset_t     timer_base = 0;
+       vm_offset_t     soc_phys;
+       vm_offset_t     eoi_addr = 0;
+       uint32_t        eoi_value = 0;
        struct tbd_ops  generic_funcs = {&fleh_fiq_generic, NULL, NULL};
-       tbd_ops_t       tbd_funcs = &generic_funcs;
+       struct tbd_ops  empty_funcs __unused = {NULL, NULL, NULL};
+       tbd_ops_t       tbd_funcs = &generic_funcs;
 
        /* The SoC headers expect to use pic_base, timer_base, etc... */
        pic_base = gPicBase;
        timer_base = gTimerBase;
        soc_phys = gSocPhys;
 
-#if defined(ARM_BOARD_CLASS_S5L8960X)
-       if (!strcmp(gPESoCDeviceType, "s5l8960x-io")) {
-
-               tbd_funcs = &s5l8960x_funcs;
-       } else
-#endif 
-#if defined(ARM_BOARD_CLASS_T7000)
-       if (!strcmp(gPESoCDeviceType, "t7000-io") ||
-            !strcmp(gPESoCDeviceType, "t7001-io")) {
-               tbd_funcs = &t7000_funcs;
-       } else
-#endif
-#if defined(ARM_BOARD_CLASS_S7002)
-       if (!strcmp(gPESoCDeviceType, "s7002-io")) {
-
-#ifdef ARM_BOARD_WFE_TIMEOUT_NS
-               // Enable the WFE Timer
-               rPMGR_EVENT_TMR_PERIOD = ((uint64_t)(ARM_BOARD_WFE_TIMEOUT_NS) * gPEClockFrequencyInfo.timebase_frequency_hz) / NSEC_PER_SEC;
-               rPMGR_EVENT_TMR = rPMGR_EVENT_TMR_PERIOD;
-               rPMGR_EVENT_TMR_CTL = PMGR_EVENT_TMR_CTL_EN;
-#endif /* ARM_BOARD_WFE_TIMEOUT_NS */
-
-               rPMGR_INTERVAL_TMR = 0x7FFFFFFF;
-               rPMGR_INTERVAL_TMR_CTL = PMGR_INTERVAL_TMR_CTL_EN | PMGR_INTERVAL_TMR_CTL_CLR_INT;
-
-               eoi_addr = timer_base;
-               eoi_value = PMGR_INTERVAL_TMR_CTL_EN | PMGR_INTERVAL_TMR_CTL_CLR_INT;
-               tbd_funcs = &s7002_funcs;
-       } else
-#endif
-#if defined(ARM_BOARD_CLASS_S8000)
-       if (!strcmp(gPESoCDeviceType, "s8000-io") ||
-           !strcmp(gPESoCDeviceType, "s8001-io")) {
-               tbd_funcs = &s8000_funcs;
-       } else
-#endif
 #if defined(ARM_BOARD_CLASS_T8002)
        if (!strcmp(gPESoCDeviceType, "t8002-io") ||
            !strcmp(gPESoCDeviceType, "t8004-io")) {
-
                /* Enable the Decrementer */
                aic_write32(kAICTmrCnt, 0x7FFFFFFF);
                aic_write32(kAICTmrCfg, kAICTmrCfgEn);
                aic_write32(kAICTmrIntStat, kAICTmrIntStatPct);
 #ifdef ARM_BOARD_WFE_TIMEOUT_NS
                // Enable the WFE Timer
-               rPMGR_EVENT_TMR_PERIOD = ((uint64_t)(ARM_BOARD_WFE_TIMEOUT_NS) * gPEClockFrequencyInfo.timebase_frequency_hz) / NSEC_PER_SEC;
+               rPMGR_EVENT_TMR_PERIOD = ((uint64_t)(ARM_BOARD_WFE_TIMEOUT_NS) *gPEClockFrequencyInfo.timebase_frequency_hz) / NSEC_PER_SEC;
                rPMGR_EVENT_TMR = rPMGR_EVENT_TMR_PERIOD;
                rPMGR_EVENT_TMR_CTL = PMGR_EVENT_TMR_CTL_EN;
 #endif /* ARM_BOARD_WFE_TIMEOUT_NS */
@@ -663,31 +631,15 @@ pe_arm_init_timer(void *args)
                tbd_funcs = &t8002_funcs;
        } else
 #endif
-#if defined(ARM_BOARD_CLASS_T8010)
-       if (!strcmp(gPESoCDeviceType, "t8010-io")) {
-               tbd_funcs = &t8010_funcs;
-       } else
-#endif
-#if defined(ARM_BOARD_CLASS_T8011)
-       if (!strcmp(gPESoCDeviceType, "t8011-io")) {
-               tbd_funcs = &t8011_funcs;
-       } else
-#endif
-#if defined(ARM_BOARD_CLASS_T8015)
-       if (!strcmp(gPESoCDeviceType, "t8015-io")) {
-               tbd_funcs = &t8015_funcs;
-       } else
-#endif
-#if defined(ARM_BOARD_CLASS_BCM2837)
-       if (!strcmp(gPESoCDeviceType, "bcm2837-io")) {
-               tbd_funcs = &bcm2837_funcs;
-       } else
+#if defined(__arm64__)
+       tbd_funcs = &empty_funcs;
+#else
+       return 0;
 #endif
-               return 0;
 
-       if (args != NULL)
+       if (args != NULL) {
                ml_init_timebase(args, tbd_funcs, eoi_addr, eoi_value);
+       }
 
        return 1;
 }
-