]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/arm64/start.s
xnu-6153.41.3.tar.gz
[apple/xnu.git] / osfmk / arm64 / start.s
index 2776c8f4628a48fccab7ca492c0242bedcec415c..4e964ca8bce3b519c6b6c7b36bab23721d55e8cc 100644 (file)
 #include <arm64/asm.h>
 #include <arm64/proc_reg.h>
 #include <pexpert/arm64/board_config.h>
-#include <pexpert/arm64/cyclone.h>
-#include <pexpert/arm64/hurricane.h>
 #include <mach_assert.h>
 #include <machine/asm.h>
 #include "assym.s"
+#include <arm64/exception_asm.h>
+
+#if __ARM_KERNEL_PROTECT__
+#include <arm/pmap.h>
+#endif /* __ARM_KERNEL_PROTECT__ */
+
 
 
 .macro MSR_VBAR_EL1_X0
@@ -50,7 +54,7 @@
 #if defined(KERNEL_INTEGRITY_KTRR)
        mov             x0, x1
        mov             x1, lr
-       bl              _pinst_set_tcr
+       bl              EXT(pinst_set_tcr)
        mov             lr, x1
 #else
        msr             TCR_EL1, x1
@@ -60,7 +64,7 @@
 .macro MSR_TTBR1_EL1_X0
 #if defined(KERNEL_INTEGRITY_KTRR)
        mov             x1, lr
-       bl              _pinst_set_ttbr1
+       bl              EXT(pinst_set_ttbr1)
        mov             lr, x1
 #else
        msr             TTBR1_EL1, x0
@@ -72,9 +76,9 @@
        mov             x1, lr
 
        // This may abort, do so on SP1
-       bl              _pinst_spsel_1
+       bl              EXT(pinst_spsel_1)
 
-       bl              _pinst_set_sctlr
+       bl              EXT(pinst_set_sctlr)
        msr             SPSel, #0                                                                       // Back to SP0
        mov             lr, x1
 #else
        .align 12
        .globl EXT(LowResetVectorBase)
 LEXT(LowResetVectorBase)
-       // Preserve x0 for start_first_cpu, if called
+       /*
+        * On reset, both RVBAR_EL1 and VBAR_EL1 point here.  SPSel.SP is 1,
+        * so on reset the CPU will jump to offset 0x0 and on exceptions
+        * the CPU will jump to offset 0x200, 0x280, 0x300, or 0x380.
+        * In order for both the reset vector and exception vectors to
+        * coexist in the same space, the reset code is moved to the end
+        * of the exception vector area.
+        */
+       b               EXT(reset_vector)
+
+       /* EL1 SP1: These vectors trap errors during early startup on non-boot CPUs. */
+       .align  9
+       b               .
+       .align  7
+       b               .
+       .align  7
+       b               .
+       .align  7
+       b               .
 
+       .align  7
+       .globl EXT(reset_vector)
+LEXT(reset_vector)
+       // Preserve x0 for start_first_cpu, if called
        // Unlock the core for debugging
        msr             OSLAR_EL1, xzr
+       msr             DAIFSet, #(DAIFSC_ALL)                          // Disable all interrupts
 
 #if !(defined(KERNEL_INTEGRITY_KTRR))
        // Set low reset vector before attempting any loads
@@ -119,18 +146,24 @@ LEXT(LowResetVectorBase)
         * If either values are zero, we're debugging kernel so skip programming KTRR.
         */
 
+       /* spin until bootstrap core has completed machine lockdown */
+       adrp    x17, EXT(lockdown_done)@page
+1:
+       ldr     x18, [x17, EXT(lockdown_done)@pageoff]
+       cbz     x18, 1b
+
        // load stashed rorgn_begin
        adrp    x17, EXT(rorgn_begin)@page
        add             x17, x17, EXT(rorgn_begin)@pageoff
        ldr             x17, [x17]
        // if rorgn_begin is zero, we're debugging. skip enabling ktrr
-       cbz             x17, 1f
+       cbz             x17, Lskip_ktrr
 
        // load stashed rorgn_end
        adrp    x19, EXT(rorgn_end)@page
        add             x19, x19, EXT(rorgn_end)@pageoff
        ldr             x19, [x19]
-       cbz             x19, 1f
+       cbz             x19, Lskip_ktrr
 
        // program and lock down KTRR
        // subtract one page from rorgn_end to make pinst insns NX
@@ -139,8 +172,7 @@ LEXT(LowResetVectorBase)
        msr             ARM64_REG_KTRR_UPPER_EL1, x19
        mov             x17, #1
        msr             ARM64_REG_KTRR_LOCK_EL1, x17
-
-1:
+Lskip_ktrr:
 #endif /* defined(KERNEL_INTEGRITY_KTRR) */
 
        // Process reset handlers
@@ -155,14 +187,14 @@ Lcheck_cpu_data_entry:
        cbz             x21, Lnext_cpu_data_entry
        ldr             w2, [x21, CPU_PHYS_ID]                          // Load ccc cpu phys id
        cmp             x0, x2                                          // Compare cpu data phys cpu and MPIDR_EL1 phys cpu
-       b.eq            Lfound_cpu_data_entry                           // Branch if match
+       b.eq    Lfound_cpu_data_entry                           // Branch if match
 Lnext_cpu_data_entry:
        add             x1, x1, #16                                     // Increment to the next cpu data entry
        cmp             x1, x3
-       b.eq            Lskip_cpu_reset_handler                         // Not found
+       b.eq    Lskip_cpu_reset_handler                         // Not found
        b               Lcheck_cpu_data_entry   // loop
 Lfound_cpu_data_entry:
-       adrp            x20, EXT(const_boot_args)@page
+       adrp    x20, EXT(const_boot_args)@page
        add             x20, x20, EXT(const_boot_args)@pageoff
        ldr             x0, [x21, CPU_RESET_HANDLER]            // Call CPU reset handler
        cbz             x0, Lskip_cpu_reset_handler
@@ -175,21 +207,25 @@ Lfound_cpu_data_entry:
        adrp    x2, EXT(start_cpu)@page
        add             x2, x2, EXT(start_cpu)@pageoff
        cmp             x0, x2
-       bne     Lskip_cpu_reset_handler
+       bne             Lskip_cpu_reset_handler
 1:
 
 
 
+#if __ARM_KERNEL_PROTECT__ && defined(KERNEL_INTEGRITY_KTRR)
+       /*
+        * Populate TPIDR_EL1 (in case the CPU takes an exception while
+        * turning on the MMU).
+        */
+       ldr             x13, [x21, CPU_ACTIVE_THREAD]
+       msr             TPIDR_EL1, x13
+#endif /* __ARM_KERNEL_PROTECT__ */
+
        blr             x0
 Lskip_cpu_reset_handler:
        b               .                                                                       // Hang if the handler is NULL or returns
 
-       .align  3
-       .globl  EXT(ResetHandlerData)
-LEXT(ResetHandlerData)
-       .space  (rhdSize_NUM),0         // (filled with 0s)
-
-       .align  3
+       .align 3
        .global EXT(LowResetVectorEnd)
 LEXT(LowResetVectorEnd)
        .global EXT(SleepToken)
@@ -198,6 +234,13 @@ LEXT(SleepToken)
        .space  (stSize_NUM),0
 #endif
 
+       .section __DATA_CONST,__const
+       .align  3
+       .globl  EXT(ResetHandlerData)
+LEXT(ResetHandlerData)
+       .space  (rhdSize_NUM),0         // (filled with 0s)
+       .text
+
 
 /*
  * __start trampoline is located at a position relative to LowResetVectorBase
@@ -264,6 +307,7 @@ LEXT(LowExceptionVectorBase)
 .align ARM_PGSHIFT
 .globl EXT(bootstrap_instructions)
 LEXT(bootstrap_instructions)
+
 #endif /* defined(KERNEL_INTEGRITY_KTRR)*/
        .align 2
        .globl EXT(resume_idle_cpu)
@@ -291,13 +335,14 @@ start_cpu:
 
        // x20 set to BootArgs phys address
        // x21 set to cpu data phys address
-       msr             DAIFSet, #(DAIFSC_ALL)                          // Disable all interrupts
 
        // Get the kernel memory parameters from the boot args
        ldr             x22, [x20, BA_VIRT_BASE]                        // Get the kernel virt base
        ldr             x23, [x20, BA_PHYS_BASE]                        // Get the kernel phys base
        ldr             x24, [x20, BA_MEM_SIZE]                         // Get the physical memory size
        ldr             x25, [x20, BA_TOP_OF_KERNEL_DATA]       // Get the top of the kernel data
+       ldr             x26, [x20, BA_BOOT_FLAGS]                       // Get the kernel boot flags
+
 
        // Set TPIDRRO_EL0 with the CPU number
        ldr             x0, [x21, CPU_NUMBER_GS]
@@ -310,7 +355,7 @@ start_cpu:
        // Set SP_EL1 to exception stack
 #if defined(KERNEL_INTEGRITY_KTRR)
        mov             x1, lr
-       bl              _pinst_spsel_1
+       bl              EXT(pinst_spsel_1)
        mov             lr, x1
 #else
        msr             SPSel, #1
@@ -382,6 +427,52 @@ start_cpu:
        b.ne    1b
 .endmacro
 
+/*
+ *  arg0 - virtual start address
+ *  arg1 - physical start address
+ *  arg2 - number of entries to map
+ *  arg3 - L1 table address
+ *  arg4 - free space pointer
+ *  arg5 - scratch (entries mapped per loop)
+ *  arg6 - scratch
+ *  arg7 - scratch
+ *  arg8 - scratch
+ *  arg9 - scratch
+ */
+.macro create_bootstrap_mapping
+       /* calculate entries left in this page */
+       and     $5, $0, #(ARM_TT_L2_INDEX_MASK)
+       lsr     $5, $5, #(ARM_TT_L2_SHIFT)
+       mov     $6, #(TTE_PGENTRIES)
+       sub     $5, $6, $5
+
+       /* allocate an L2 table */
+3:     add     $4, $4, PGBYTES
+
+       /* create_l1_table_entry(virt_base, L1 table, L2 table, scratch1, scratch2, scratch3) */
+       create_l1_table_entry   $0, $3, $4, $6, $7, $8
+
+       /* determine how many entries to map this loop - the smaller of entries
+        * remaining in page and total entries left */
+       cmp     $2, $5
+       csel    $5, $2, $5, lt
+
+       /* create_l2_block_entries(virt_base, phys_base, L2 table, num_ents, scratch1, scratch2, scratch3) */
+       create_l2_block_entries $0, $1, $4, $5, $6, $7, $8, $9
+
+       /* subtract entries just mapped and bail out if we're done */
+       subs    $2, $2, $5
+       beq     2f
+
+       /* entries left to map - advance base pointers */
+       add     $0, $0, $5, lsl #(ARM_TT_L2_SHIFT)
+       add     $1, $1, $5, lsl #(ARM_TT_L2_SHIFT)
+
+       mov     $5, #(TTE_PGENTRIES)  /* subsequent loops map (up to) a whole L2 page */
+       b       3b
+2:
+.endmacro
+
 /*
  * _start_first_cpu
  * Cold boot init routine.  Called from __start
@@ -393,8 +484,10 @@ LEXT(start_first_cpu)
 
        // Unlock the core for debugging
        msr             OSLAR_EL1, xzr
+       msr             DAIFSet, #(DAIFSC_ALL)                          // Disable all interrupts
+
        mov             x20, x0
-       mov             x21, xzr
+       mov             x21, #0
 
        // Set low reset vector before attempting any loads
        adrp    x0, EXT(LowExceptionVectorBase)@page
@@ -402,14 +495,16 @@ LEXT(start_first_cpu)
        MSR_VBAR_EL1_X0
 
 
-
        // Get the kernel memory parameters from the boot args
        ldr             x22, [x20, BA_VIRT_BASE]                        // Get the kernel virt base
        ldr             x23, [x20, BA_PHYS_BASE]                        // Get the kernel phys base
        ldr             x24, [x20, BA_MEM_SIZE]                         // Get the physical memory size
        ldr             x25, [x20, BA_TOP_OF_KERNEL_DATA]       // Get the top of the kernel data
+       ldr             x26, [x20, BA_BOOT_FLAGS]                       // Get the kernel boot flags
 
-       // Set CPU number to 0
+       // Clear the register that will be used to store the userspace thread pointer and CPU number.
+       // We may not actually be booting from ordinal CPU 0, so this register will be updated
+       // in ml_parse_cpu_topology(), which happens later in bootstrap.
        msr             TPIDRRO_EL0, x21
 
        // Set up exception stack pointer
@@ -420,7 +515,7 @@ LEXT(start_first_cpu)
 
        // Set SP_EL1 to exception stack
 #if defined(KERNEL_INTEGRITY_KTRR)
-       bl              _pinst_spsel_1
+       bl              EXT(pinst_spsel_1)
 #else
        msr             SPSel, #1
 #endif
@@ -450,38 +545,18 @@ LEXT(start_first_cpu)
         *      Page 3 - KVA L1 table
         *      Page 4 - KVA L2 table
         */
-#if __ARM64_TWO_LEVEL_PMAP__
-       /*
-        * If we are using a two level scheme, we don't need the L1 entries, so:
-        *      Page 1 - V=P L2 table
-        *      Page 2 - KVA L2 table
-        */
-#endif
 
        // Invalidate all entries in the bootstrap page tables
        mov             x0, #(ARM_TTE_EMPTY)                            // Load invalid entry template
        mov             x1, x25                                                         // Start at top of kernel
        mov             x2, #(TTE_PGENTRIES)                            // Load number of entries per page
-#if __ARM64_TWO_LEVEL_PMAP__
-       lsl             x2, x2, #1                                                      // Shift by 1 for num entries on 2 pages
-#else
        lsl             x2, x2, #2                                                      // Shift by 2 for num entries on 4 pages
-#endif
-       sub             x2, x2, #1                                                      // Subtract one to terminate on last entry
+
 Linvalidate_bootstrap:                                                 // do {
        str             x0, [x1], #(1 << TTE_SHIFT)                     //   Invalidate and advance
        subs    x2, x2, #1                                                      //   entries--
        b.ne    Linvalidate_bootstrap                           // } while (entries != 0)
 
-       /* Load addresses for page table construction macros
-        *  x0 - Physical base (used to identify V=P section to set up)
-        *      x1 - V=P L1 table base
-        *      x2 - V=P L2 table base
-        *      x3 - KVA L1 table base
-        *      x4 - KVA L2 table base
-        *      x5 - Mem size in entries (up to 1GB)
-        */
-
        /*
         * In order to reclaim memory on targets where TZ0 (or some other entity)
         * must be located at the base of memory, iBoot may set the virtual and
@@ -499,57 +574,60 @@ Linvalidate_bootstrap:                                                    // do {
         * mapping TZ0.
         */
        adrp    x0, EXT(_mh_execute_header)@page        // Use xnu's mach header as the start address
-       add             x0, x0, EXT(_mh_execute_header)@pageoff
-#if __ARM64_TWO_LEVEL_PMAP__
+       add     x0, x0, EXT(_mh_execute_header)@pageoff
+
        /*
-        * We don't need the L1 entries in this case, so skip them.
+        * Adjust physical and virtual base addresses to account for physical
+        * memory preceeding xnu Mach-O header
+        * x22 - Kernel virtual base
+        * x23 - Kernel physical base
+        * x24 - Physical memory size
         */
-       mov             x2, x25                                                         // Load V=P L2 table address
-       add             x4, x2, PGBYTES                                         // Load KVA L2 table address
-#else
-       mov             x1, x25                                                         // Load V=P L1 table address
-       add             x2, x1, PGBYTES                                         // Load V=P L2 table address
-       add             x3, x2, PGBYTES                                         // Load KVA L1 table address
-       add             x4, x3, PGBYTES                                         // Load KVA L2 table address
-#endif
+       sub             x18, x0, x23
+       sub             x24, x24, x18
+       add             x22, x22, x18
+       add             x23, x23, x18
+
        /*
-        * We must adjust the amount we wish to map in order to account for the
-        * memory preceeding xnu's mach header.
-        */
-       sub             x5, x0, x23                                                     // Map from the mach header up to the end of our memory
-       sub             x5, x24, x5
-       lsr             x5, x5, #(ARM_TT_L2_SHIFT)
-       mov             x6, #(TTE_PGENTRIES)                            // Load number of L2 entries per page
-       cmp             x5, x6                                                          // If memsize requires more than 1 page of entries
-       csel    x5, x5, x6, lt                                          // ... round down to a single page (first 1GB)
-
-#if !__ARM64_TWO_LEVEL_PMAP__
-       /* Create entry for L2 table in V=P L1 table
-        * create_l1_table_entry(V=P, L1 table, L2 table, scratch1, scratch2, scratch3)
+        * x0  - V=P virtual cursor
+        * x4  - V=P physical cursor
+        * x14 - KVA virtual cursor
+        * x15 - KVA physical cursor
         */
-       create_l1_table_entry   x0, x1, x2, x10, x11, x12
-#endif
+       mov             x4, x0
+       mov             x14, x22
+       mov             x15, x23
 
-       /* Create block entry in V=P L2 table
-        * create_l2_block_entries(V=P virt, V=P phys, L2 table, num_ents, scratch1, scratch2, scratch3)
+       /*
+        * Allocate L1 tables
+        * x1 - V=P L1 page
+        * x3 - KVA L1 page
+        * x2 - free mem pointer from which we allocate a variable number of L2
+        * pages. The maximum number of bootstrap page table pages is limited to
+        * BOOTSTRAP_TABLE_SIZE. For a 2G 4k page device, assuming the worst-case
+        * slide, we need 1xL1 and up to 3xL2 pages (1GB mapped per L1 entry), so
+        * 8 total pages for V=P and KVA.
         */
-       create_l2_block_entries x0, x0, x2, x5, x10, x11, x12, x13
+       mov             x1, x25
+       add             x3, x1, PGBYTES
+       mov             x2, x3
 
-#if !__ARM64_TWO_LEVEL_PMAP__
-       /* Create entry for L2 table in KVA L1 table
-        * create_l1_table_entry(virt_base, L1 table, L2 table, scratch1, scratch2, scratch3)
+       /*
+        * Setup the V=P bootstrap mapping
+        * x5 - total number of L2 entries to allocate
         */
-       create_l1_table_entry   x22, x3, x4, x10, x11, x12
-#endif
+       lsr             x5,  x24, #(ARM_TT_L2_SHIFT)
+       /* create_bootstrap_mapping(vbase, pbase, num_ents, L1 table, freeptr) */
+       create_bootstrap_mapping x0,  x4,  x5, x1, x2, x6, x10, x11, x12, x13
 
-       /* Create block entries in KVA L2 table
-        * create_l2_block_entries(virt_base, phys_base, L2 table, num_ents, scratch1, scratch2, scratch3)
-        */
-       create_l2_block_entries x22, x23, x4, x5, x10, x11, x12, x13
+       /* Setup the KVA bootstrap mapping */
+       lsr             x5,  x24, #(ARM_TT_L2_SHIFT)
+       create_bootstrap_mapping x14, x15, x5, x3, x2, x9, x10, x11, x12, x13
 
        /* Ensure TTEs are visible */
        dsb             ish
 
+
        b               common_start
 
 /*
@@ -560,8 +638,7 @@ Linvalidate_bootstrap:                                                      // do {
  *     x21 - zero on cold boot, PA of cpu data on warm reset
  *     x22 - Kernel virtual base
  *     x23 - Kernel physical base
- *     x24     - Physical memory size
- *     x25 - PA of the end of the kernl
+ *     x25 - PA of the end of the kernel
  *      lr - KVA of C init routine
  *      sp - SP_EL0 selected
  *
@@ -578,7 +655,7 @@ common_start:
 
        /* Set up translation table base registers.
         *      TTBR0 - V=P table @ top of kernel
-        *      TTBR1 - KVA table @ top of kernel + 2 pages
+        *      TTBR1 - KVA table @ top of kernel + 1 page
         */
 #if defined(KERNEL_INTEGRITY_KTRR)
        /* Note that for KTRR configurations, the V=P map will be modified by
@@ -586,21 +663,10 @@ common_start:
         */
 #endif
        and             x0, x25, #(TTBR_BADDR_MASK)
-       msr             TTBR0_EL1, x0
-#if __ARM64_TWO_LEVEL_PMAP__
-       /*
-        * If we're using a two level pmap, we'll only need a
-        * single page per bootstrap pmap.
-        */
-       mov             x12, #1
-#else
-       /*
-        * If we're using a three level pmap, we'll need two
-        * pages per bootstrap pmap.
-        */
-       mov             x12, #2
-#endif
-       add             x0, x25, x12, lsl PGSHIFT
+       mov             x19, lr
+       bl              EXT(set_mmu_ttb)
+       mov             lr, x19
+       add             x0, x25, PGBYTES
        and             x0, x0, #(TTBR_BADDR_MASK)
        MSR_TTBR1_EL1_X0
 
@@ -618,11 +684,12 @@ common_start:
        orr             x0, x0, x1
        mov             x1, #(MAIR_POSTED << MAIR_ATTR_SHIFT(CACHE_ATTRINDX_POSTED))
        orr             x0, x0, x1
+       mov             x1, #(MAIR_POSTED_REORDERED << MAIR_ATTR_SHIFT(CACHE_ATTRINDX_POSTED_REORDERED))
+       orr             x0, x0, x1
+       mov             x1, #(MAIR_POSTED_COMBINED_REORDERED << MAIR_ATTR_SHIFT(CACHE_ATTRINDX_POSTED_COMBINED_REORDERED))
+       orr             x0, x0, x1
        msr             MAIR_EL1, x0
 
-       // Disable interrupts
-       msr     DAIFSet, #(DAIFSC_IRQF | DAIFSC_FIQF)
-
 #if defined(APPLEHURRICANE)
 
        // <rdar://problem/26726624> Increase Snoop reservation in EDB to reduce starvation risk
@@ -634,6 +701,20 @@ common_start:
 
 #endif
 
+#if defined(BCM2837)
+       // Setup timer interrupt routing; must be done before MMU is enabled
+       mrs             x15, MPIDR_EL1                                          // Load MPIDR to get CPU number
+       and             x15, x15, #0xFF                                         // CPU number is in MPIDR Affinity Level 0
+       mov             x0, #0x4000
+       lsl             x0, x0, #16
+       add             x0, x0, #0x0040                                         // x0: 0x4000004X Core Timers interrupt control
+       add             x0, x0, x15, lsl #2
+       mov             w1, #0xF0                                               // x1: 0xF0       Route to Core FIQs
+       str             w1, [x0]
+       isb             sy
+#endif
+
+
 
 #ifndef __ARM_IC_NOALIAS_ICACHE__
        /* Invalidate the TLB and icache on systems that do not guarantee that the
@@ -656,20 +737,124 @@ common_start:
 1:
 
        // Set up the exception vectors
+#if __ARM_KERNEL_PROTECT__
+       /* If this is not the first reset of the boot CPU, the alternate mapping
+        * for the exception vectors will be set up, so use it.  Otherwise, we
+        * should use the mapping located in the kernelcache mapping.
+        */
+       MOV64   x0, ARM_KERNEL_PROTECT_EXCEPTION_START
+
+       cbnz            x21, 1f
+#endif /* __ARM_KERNEL_PROTECT__ */
        adrp    x0, EXT(ExceptionVectorsBase)@page                      // Load exception vectors base address
        add             x0, x0, EXT(ExceptionVectorsBase)@pageoff
        add             x0, x0, x22                                                                     // Convert exception vector address to KVA
        sub             x0, x0, x23
+1:
        MSR_VBAR_EL1_X0
 
+1:
+#ifdef HAS_APPLE_PAC
+#ifdef __APSTS_SUPPORTED__
+       mrs             x0, ARM64_REG_APSTS_EL1
+       and             x1, x0, #(APSTS_EL1_MKEYVld)
+       cbz             x1, 1b                                                                          // Poll APSTS_EL1.MKEYVld
+       mrs             x0, ARM64_REG_APCTL_EL1
+       orr             x0, x0, #(APCTL_EL1_AppleMode)
+       orr             x0, x0, #(APCTL_EL1_KernKeyEn)
+       and             x0, x0, #~(APCTL_EL1_EnAPKey0)
+       msr             ARM64_REG_APCTL_EL1, x0
+#else
+       mrs             x0, ARM64_REG_APCTL_EL1
+       and             x1, x0, #(APCTL_EL1_MKEYVld)
+       cbz             x1, 1b                                                                          // Poll APCTL_EL1.MKEYVld
+       orr             x0, x0, #(APCTL_EL1_AppleMode)
+       orr             x0, x0, #(APCTL_EL1_KernKeyEn)
+       msr             ARM64_REG_APCTL_EL1, x0
+#endif /* APSTS_SUPPORTED */
+
+       /* ISB necessary to ensure APCTL_EL1_AppleMode logic enabled before proceeding */
+       isb             sy
+       /* Load static kernel key diversification values */
+       ldr             x0, =KERNEL_ROP_ID
+       /* set ROP key. must write at least once to pickup mkey per boot diversification */
+       msr             APIBKeyLo_EL1, x0
+       add             x0, x0, #1
+       msr             APIBKeyHi_EL1, x0
+       add             x0, x0, #1
+       msr             APDBKeyLo_EL1, x0
+       add             x0, x0, #1
+       msr             APDBKeyHi_EL1, x0
+       add             x0, x0, #1
+       msr             ARM64_REG_KERNELKEYLO_EL1, x0
+       add             x0, x0, #1
+       msr             ARM64_REG_KERNELKEYHI_EL1, x0
+       /* set JOP key. must write at least once to pickup mkey per boot diversification */
+       add             x0, x0, #1
+       msr             APIAKeyLo_EL1, x0
+       add             x0, x0, #1
+       msr             APIAKeyHi_EL1, x0
+       add             x0, x0, #1
+       msr             APDAKeyLo_EL1, x0
+       add             x0, x0, #1
+       msr             APDAKeyHi_EL1, x0
+       /* set G key */
+       add             x0, x0, #1
+       msr             APGAKeyLo_EL1, x0
+       add             x0, x0, #1
+       msr             APGAKeyHi_EL1, x0
+
+       // Enable caches, MMU, ROP and JOP
+       mov             x0, #(SCTLR_EL1_DEFAULT & 0xFFFF)
+       mov             x1, #(SCTLR_EL1_DEFAULT & 0xFFFF0000)
+       orr             x0, x0, x1
+       orr             x0, x0, #(SCTLR_PACIB_ENABLED) /* IB is ROP */
+
+#if DEBUG || DEVELOPMENT
+       and             x2, x26, BA_BOOT_FLAGS_DISABLE_JOP
+#if __APCFG_SUPPORTED__
+       // for APCFG systems, JOP keys are always on for EL1 unless ELXENKEY is cleared.
+       // JOP keys for EL0 will be toggled on the first time we pmap_switch to a pmap that has JOP enabled
+       cbz             x2, Lenable_mmu
+       mrs             x3, APCFG_EL1
+       and             x3, x3, #~(APCFG_EL1_ELXENKEY)
+       msr             APCFG_EL1, x3
+#else /* __APCFG_SUPPORTED__ */
+       cbnz    x2, Lenable_mmu
+#endif /* __APCFG_SUPPORTED__ */
+#endif /* DEBUG || DEVELOPMENT */
+
+#if !__APCFG_SUPPORTED__
+       MOV64   x1, SCTLR_JOP_KEYS_ENABLED
+       orr     x0, x0, x1
+#endif /* !__APCFG_SUPPORTED__ */
+Lenable_mmu:
+#else  /* HAS_APPLE_PAC */
 
        // Enable caches and MMU
        mov             x0, #(SCTLR_EL1_DEFAULT & 0xFFFF)
        mov             x1, #(SCTLR_EL1_DEFAULT & 0xFFFF0000)
        orr             x0, x0, x1
+#endif /* HAS_APPLE_PAC */
        MSR_SCTLR_EL1_X0
        isb             sy
 
+       MOV32   x1, SCTLR_EL1_DEFAULT
+#if HAS_APPLE_PAC
+       orr             x1, x1, #(SCTLR_PACIB_ENABLED)
+#if !__APCFG_SUPPORTED__
+       MOV64   x2, SCTLR_JOP_KEYS_ENABLED
+#if (DEBUG || DEVELOPMENT)
+       // Ignore the JOP bits, since we can't predict at compile time whether BA_BOOT_FLAGS_DISABLE_JOP is set
+       bic             x0, x0, x2
+#else
+       orr             x1, x1, x2
+#endif /* (DEBUG || DEVELOPMENT) */
+#endif /* !__APCFG_SUPPORTED__ */
+#endif /* HAS_APPLE_PAC */
+       cmp             x0, x1
+       bne             .
+
 #if (!CONFIG_KERNEL_INTEGRITY || (CONFIG_KERNEL_INTEGRITY && !defined(KERNEL_INTEGRITY_WT)))
        /* Watchtower
         *
@@ -686,42 +871,39 @@ common_start:
        mov             x0, #0
        msr             TPIDR_EL1, x0                                           // Set thread register
 
-#if defined(APPLECYCLONE) || defined(APPLETYPHOON)
+#if defined(APPLE_ARM64_ARCH_FAMILY)
+       // Initialization common to all Apple targets
+       ARM64_IS_PCORE x15
+       ARM64_READ_EP_SPR x15, x12, ARM64_REG_EHID4, ARM64_REG_HID4
+       orr             x12, x12, ARM64_REG_HID4_DisDcMVAOps
+       orr             x12, x12, ARM64_REG_HID4_DisDcSWL2Ops
+       ARM64_WRITE_EP_SPR x15, x12, ARM64_REG_EHID4, ARM64_REG_HID4
+#endif  // APPLE_ARM64_ARCH_FAMILY
+
+#if defined(APPLETYPHOON)
        //
-       // Cyclone/Typhoon-Specific initialization
-       // For tunable summary, see <rdar://problem/13503621> Alcatraz/H6: Confirm Cyclone CPU tunables have been set
+       // Typhoon-Specific initialization
+       // For tunable summary, see <rdar://problem/13503621>
        //
 
        //
        // Disable LSP flush with context switch to work around bug in LSP
-       // that can cause Cyclone to wedge when CONTEXTIDR is written.
-       // <rdar://problem/12387704> Innsbruck11A175: panic(cpu 0 caller 0xffffff800024e30c): "wait queue deadlock - wq=0xffffff805a7a63c0, cpu=0\n"
+       // that can cause Typhoon to wedge when CONTEXTIDR is written.
+       // <rdar://problem/12387704>
        //
 
        mrs             x12, ARM64_REG_HID0
        orr             x12, x12, ARM64_REG_HID0_LoopBuffDisb
        msr             ARM64_REG_HID0, x12
-       
+
        mrs             x12, ARM64_REG_HID1
        orr             x12, x12, ARM64_REG_HID1_rccDisStallInactiveIexCtl
-#if defined(APPLECYCLONE)
-       orr             x12, x12, ARM64_REG_HID1_disLspFlushWithContextSwitch
-#endif
        msr             ARM64_REG_HID1, x12
 
        mrs             x12, ARM64_REG_HID3
        orr             x12, x12, ARM64_REG_HID3_DisXmonSnpEvictTriggerL2StarvationMode
        msr             ARM64_REG_HID3, x12
 
-       // Do not disable cache ops -- XNU's cache operations already are no-op'ed for Cyclone, but explicit _Force variants are provided
-       // for when we really do need the L2 cache to be cleaned: <rdar://problem/14350417> Innsbruck11A416: Panic logs not preserved on h6
-/*
-       mrs             x12, ARM64_REG_HID4
-       orr             x12, x12, ARM64_REG_HID4_DisDcMVAOps
-       orr             x12, x12, ARM64_REG_HID4_DisDcSWL2Ops
-       msr             ARM64_REG_HID4, x12
-*/
-
        mrs             x12, ARM64_REG_HID5
        and             x12, x12, (~ARM64_REG_HID5_DisHwpLd)
        and             x12, x12, (~ARM64_REG_HID5_DisHwpSt)
@@ -735,23 +917,40 @@ common_start:
 #endif // ARM64_BOARD_CONFIG_T7001
        msr             ARM64_REG_HID8, x12
        isb             sy
-#endif // APPLECYCLONE || APPLETYPHOON
+#endif // APPLETYPHOON
 
 #if defined(APPLETWISTER)
-       mrs     x12, ARM64_REG_HID11
-       and     x12, x12, (~ARM64_REG_HID11_DisFillC1BubOpt)
-       msr     ARM64_REG_HID11, x12
+
+       // rdar://problem/36112905: Set CYC_CFG:skipInit to pull in isAlive by one DCLK
+       // to work around potential hang.  Must only be applied to Maui C0.
+       mrs             x12, MIDR_EL1
+       ubfx            x13, x12, #MIDR_EL1_PNUM_SHIFT, #12
+       cmp             x13, #4         // Part number 4 => Maui, 5 => Malta/Elba
+       bne             Lskip_isalive
+       ubfx            x13, x12, #MIDR_EL1_VAR_SHIFT, #4
+       cmp             x13, #2         // variant 2 => Maui C0
+       b.lt            Lskip_isalive
+
+       mrs             x12, ARM64_REG_CYC_CFG
+       orr             x12, x12, ARM64_REG_CYC_CFG_skipInit
+       msr             ARM64_REG_CYC_CFG, x12
+
+Lskip_isalive:
+
+       mrs             x12, ARM64_REG_HID11
+       and             x12, x12, (~ARM64_REG_HID11_DisFillC1BubOpt)
+       msr             ARM64_REG_HID11, x12
 
        // Change the default memcache data set ID from 0 to 15 for all agents
        mrs             x12, ARM64_REG_HID8
        orr             x12, x12, (ARM64_REG_HID8_DataSetID0_VALUE | ARM64_REG_HID8_DataSetID1_VALUE)
-       orr     x12, x12, (ARM64_REG_HID8_DataSetID2_VALUE | ARM64_REG_HID8_DataSetID3_VALUE)
+       orr             x12, x12, (ARM64_REG_HID8_DataSetID2_VALUE | ARM64_REG_HID8_DataSetID3_VALUE)
        msr             ARM64_REG_HID8, x12
 
        // Use 4-cycle MUL latency to avoid denormal stalls
-       mrs     x12, ARM64_REG_HID7
-       orr     x12, x12, #ARM64_REG_HID7_disNexFastFmul
-       msr     ARM64_REG_HID7, x12
+       mrs             x12, ARM64_REG_HID7
+       orr             x12, x12, #ARM64_REG_HID7_disNexFastFmul
+       msr             ARM64_REG_HID7, x12
 
        // disable reporting of TLB-multi-hit-error
        // <rdar://problem/22163216> 
@@ -787,7 +986,6 @@ common_start:
 #if defined(ARM64_BOARD_CONFIG_T8011)
        // Clear DisDcZvaCmdOnly 
        // Per Myst A0/B0 tunables document
-       // https://seg-docs.csg.apple.com/projects/myst//release/UserManual/tunables_a0/ACC.html
        // <rdar://problem/27627428> Myst: Confirm ACC Per-CPU Tunables
        mrs             x12, ARM64_REG_HID3
        and             x12, x12, ~ARM64_REG_HID3_DisDcZvaCmdOnly
@@ -800,6 +998,88 @@ common_start:
 
 #endif // APPLEHURRICANE
 
+#if defined(APPLEMONSOON)
+
+       /***** Tunables that apply to all skye cores, all chip revs *****/
+
+       // <rdar://problem/28512310> SW WAR/eval: WKdm write ack lost when bif_wke_colorWrAck_XXaH asserts concurrently for both colors
+       mrs             x12, ARM64_REG_HID8
+       orr             x12, x12, #ARM64_REG_HID8_WkeForceStrictOrder
+       msr             ARM64_REG_HID8, x12
+
+       // Skip if not E-core
+       ARM64_IS_PCORE x15
+       cbnz            x15, Lskip_skye_ecore_only
+
+       /***** Tunables that only apply to skye e-cores, all chip revs *****/
+
+       // <rdar://problem/30423928>: Atomic launch eligibility is erroneously taken away when a store at SMB gets invalidated
+       mrs             x12, ARM64_REG_EHID11
+       and             x12, x12, ~(ARM64_REG_EHID11_SmbDrainThresh_mask)
+       msr             ARM64_REG_EHID11, x12
+
+Lskip_skye_ecore_only:
+
+       SKIP_IF_CPU_VERSION_GREATER_OR_EQUAL x12, MONSOON_CPU_VERSION_B0, Lskip_skye_a0_workarounds
+
+       // Skip if not E-core
+       cbnz            x15, Lskip_skye_a0_ecore_only
+
+       /***** Tunables that only apply to skye e-cores, chip revs < B0 *****/
+
+       // Disable downstream fill bypass logic
+       // <rdar://problem/28545159> [Tunable] Skye - L2E fill bypass collision from both pipes to ecore
+       mrs             x12, ARM64_REG_EHID5
+       orr             x12, x12, ARM64_REG_EHID5_DisFillByp
+       msr             ARM64_REG_EHID5, x12
+
+       // Disable forwarding of return addresses to the NFP 
+       // <rdar://problem/30387067> Skye: FED incorrectly taking illegal va exception
+       mrs             x12, ARM64_REG_EHID0
+       orr             x12, x12, ARM64_REG_EHID0_nfpRetFwdDisb
+       msr             ARM64_REG_EHID0, x12
+
+Lskip_skye_a0_ecore_only:
+
+       /***** Tunables that apply to all skye cores, chip revs < B0 *****/
+
+       // Disable clock divider gating
+       // <rdar://problem/30854420> [Tunable/Errata][cpu_1p_1e] [CPGV2] ACC power down issue when link FSM switches from GO_DN to CANCEL and at the same time upStreamDrain request is set.
+       mrs             x12, ARM64_REG_HID6
+       orr             x12, x12, ARM64_REG_HID6_DisClkDivGating
+       msr             ARM64_REG_HID6, x12
+
+       // Disable clock dithering
+       // <rdar://problem/29022199> [Tunable] Skye A0: Linux: LLC PIO Errors
+       mrs             x12, ARM64_REG_ACC_OVRD
+       orr             x12, x12, ARM64_REG_ACC_OVRD_dsblClkDtr
+       msr             ARM64_REG_ACC_OVRD, x12
+
+       mrs             x12, ARM64_REG_ACC_EBLK_OVRD
+       orr             x12, x12, ARM64_REG_ACC_OVRD_dsblClkDtr
+       msr             ARM64_REG_ACC_EBLK_OVRD, x12
+
+Lskip_skye_a0_workarounds:
+
+       SKIP_IF_CPU_VERSION_LESS_THAN x12, MONSOON_CPU_VERSION_B0, Lskip_skye_post_a1_workarounds
+
+       /***** Tunables that apply to all skye cores, chip revs >= B0 *****/
+
+       // <rdar://problem/32512836>: Disable refcount syncing between E and P
+       mrs             x12, ARM64_REG_CYC_OVRD
+       and             x12, x12, ~ARM64_REG_CYC_OVRD_dsblSnoopTime_mask
+       orr             x12, x12, ARM64_REG_CYC_OVRD_dsblSnoopPTime
+       msr             ARM64_REG_CYC_OVRD, x12
+
+Lskip_skye_post_a1_workarounds:
+
+#endif /* defined(APPLEMONSOON) */
+
+
+
+
+
+
 
        // If x21 != 0, we're doing a warm reset, so we need to trampoline to the kernel pmap.
        cbnz    x21, Ltrampoline
@@ -815,7 +1095,7 @@ common_start:
        // x0: boot args
        // x1: KVA page table phys base
        mrs     x1, TTBR1_EL1
-       bl      _kasan_bootstrap
+       bl      EXT(kasan_bootstrap)
 
        mov     x0, x20
        mov     lr, x21
@@ -871,24 +1151,12 @@ arm_init_tramp:
         */
 
 
-       adrp    x0, EXT(invalid_ttep)@page
-       add             x0, x0, EXT(invalid_ttep)@pageoff
-       ldr             x0, [x0]
-
-       msr             TTBR0_EL1, x0
-
+       mov             x19, lr
        // Convert CPU data PA to VA and set as first argument
-       add             x0, x21, x22
-       sub             x0, x0, x23
-       mov             x1, #0
+       mov             x0, x21
+       bl              EXT(phystokv)
 
-       // Make sure that the TLB flush happens after the registers are set!
-       isb             sy
-
-       // Synchronize system for TTBR updates
-       tlbi    vmalle1
-       dsb             sy
-       isb             sy
+       mov             lr, x19
 
        /* Return to arm_init() */
        ret