/ duct-tape / xnu / osfmk / arm64 / lowmem_vectors.c
lowmem_vectors.c
  1  /*
  2   * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
  3   *
  4   * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  5   *
  6   * This file contains Original Code and/or Modifications of Original Code
  7   * as defined in and that are subject to the Apple Public Source License
  8   * Version 2.0 (the 'License'). You may not use this file except in
  9   * compliance with the License. The rights granted to you under the License
 10   * may not be used to create, or enable the creation or redistribution of,
 11   * unlawful or unlicensed copies of an Apple operating system, or to
 12   * circumvent, violate, or enable the circumvention or violation of, any
 13   * terms of an Apple operating system software license agreement.
 14   *
 15   * Please obtain a copy of the License at
 16   * http://www.opensource.apple.com/apsl/ and read it before using this file.
 17   *
 18   * The Original Code and all software distributed under the License are
 19   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 20   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 21   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 22   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 23   * Please see the License for the specific language governing rights and
 24   * limitations under the License.
 25   *
 26   * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
 27   */
 28  
 29  #include <mach_kdp.h>
 30  #include <mach/vm_param.h>
 31  #include <arm64/lowglobals.h>
 32  #include <vm/vm_object.h>
 33  #include <vm/vm_page.h>
 34  
 35  /*
 36   * On arm64, the low globals get mapped low via machine_init() during kernel
 37   * bootstrap.
 38   */
 39  
 40  extern vm_offset_t vm_kernel_stext;
 41  extern void     *version;
 42  extern void     *kmod;
 43  extern void     *kdp_trans_off;
 44  extern void     *osversion;
 45  extern void     *flag_kdp_trigger_reboot;
 46  extern void     *manual_pkt;
 47  extern struct vm_object pmap_object_store;      /* store pt pages */
 48  
 49  lowglo lowGlo __attribute__ ((aligned(PAGE_MAX_SIZE))) = {
 50  	// Increment the major version for changes that break the current Astris
 51  	// usage of lowGlo values
 52  	// Increment the minor version for changes that provide additonal info/function
 53  	// but does not break current usage
 54  	.lgLayoutMajorVersion = 3,
 55  	.lgLayoutMinorVersion = 2,
 56  	.lgLayoutMagic = LOWGLO_LAYOUT_MAGIC,
 57  	.lgVerCode = { 'K', 'r', 'a', 'k', 'e', 'n', ' ', ' ' },
 58  	.lgZero = 0,
 59  	.lgStext = 0, // To be filled in below
 60  	.lgVersion = (uint64_t) &version,
 61  	.lgOSVersion = (uint64_t) &osversion,
 62  	.lgKmodptr = (uint64_t) &kmod,
 63  #if MACH_KDP && CONFIG_KDP_INTERACTIVE_DEBUGGING
 64  	.lgTransOff = (uint64_t) &kdp_trans_off,
 65  	.lgRebootFlag = (uint64_t) &flag_kdp_trigger_reboot,
 66  	.lgManualPktAddr = (uint64_t) &manual_pkt,
 67  #endif
 68  	.lgPmapMemQ = (uint64_t)&(pmap_object_store.memq),
 69  	.lgPmapMemPageOffset = offsetof(struct vm_page_with_ppnum, vmp_phys_page),
 70  	.lgPmapMemChainOffset = offsetof(struct vm_page, vmp_listq),
 71  	.lgPmapMemPagesize = (uint64_t)sizeof(struct vm_page),
 72  	.lgPmapMemFromArrayMask = VM_PAGE_PACKED_FROM_ARRAY,
 73  	.lgPmapMemPackedShift = VM_PAGE_PACKED_PTR_SHIFT,
 74  	.lgPmapMemPackedBaseAddr = VM_PAGE_PACKED_PTR_BASE,
 75  	.lgPmapMemStartAddr = -1,
 76  	.lgPmapMemEndAddr = -1,
 77  	.lgPmapMemFirstppnum = -1,
 78  	.lgPageShift = ARM_PGSHIFT,
 79  	.lgVmFirstPhys = -1,
 80  	.lgVmLastPhys = -1,
 81  	.lgPhysMapBase = -1,
 82  	.lgPhysMapEnd = -1,
 83  	.lgPmapIoRangePtr = -1,
 84  	.lgNumPmapIoRanges = -1
 85  };
 86  
 87  void
 88  patch_low_glo(void)
 89  {
 90  	lowGlo.lgStext = (uint64_t)vm_kernel_stext;
 91  }
 92  
 93  void
 94  patch_low_glo_static_region(uint64_t address, uint64_t size)
 95  {
 96  	lowGlo.lgStaticAddr = address;
 97  	lowGlo.lgStaticSize = size;
 98  
 99  	/**
100  	 * These values are set in pmap_bootstrap() and represent the range of
101  	 * kernel managed memory.
102  	 */
103  	extern const pmap_paddr_t vm_first_phys;
104  	extern const pmap_paddr_t vm_last_phys;
105  	assertf((vm_first_phys != 0) && (vm_last_phys != 0),
106  	    "Tried setting the Low Globals before pmap_bootstrap()");
107  	lowGlo.lgVmFirstPhys = vm_first_phys;
108  	lowGlo.lgVmLastPhys = vm_last_phys;
109  
110  	/**
111  	 * These values are set in pmap_bootstrap() and represent an array of all
112  	 * kernel-managed I/O regions (pmap-io-ranges in the device tree). Some of
113  	 * these regions may include DRAM carved out for usage by other agents on
114  	 * the system.
115  	 *
116  	 * Need to forward-declare pmap_io_range_t since that only exists in the
117  	 * PMAP code.
118  	 */
119  	typedef struct pmap_io_range pmap_io_range_t;
120  	extern const pmap_io_range_t* io_attr_table;
121  	extern const unsigned int num_io_rgns;
122  	lowGlo.lgPmapIoRangePtr = (uint64_t)io_attr_table;
123  	lowGlo.lgNumPmapIoRanges = (uint64_t)num_io_rgns;
124  
125  	/**
126  	 * These values are set in arm_vm_init() and represent the virtual address
127  	 * space used by the physical aperture.
128  	 */
129  	extern const vm_map_address_t physmap_base;
130  	extern const vm_map_address_t physmap_end;
131  	assertf((physmap_base != 0) && (physmap_end != 0),
132  	    "Tried setting the Low Globals before arm_vm_init()");
133  	lowGlo.lgPhysMapBase = physmap_base;
134  	lowGlo.lgPhysMapEnd = physmap_end;
135  }
136  
137  void
138  patch_low_glo_vm_page_info(void * start_addr, void * end_addr, uint32_t first_ppnum)
139  {
140  	lowGlo.lgPmapMemStartAddr = (uint64_t)start_addr;
141  	lowGlo.lgPmapMemEndAddr = (uint64_t)end_addr;
142  	lowGlo.lgPmapMemFirstppnum = first_ppnum;
143  	lowGlo.lgPageShift = PAGE_SHIFT;
144  }