1/*
2 * Copyright (c) 2007 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 * FILE_ID: vm_param.h
30 */
31
32/*
33 * ARM machine dependent virtual memory parameters.
34 */
35
36#ifndef _MACH_ARM_VM_PARAM_H_
37#define _MACH_ARM_VM_PARAM_H_
38
39#if defined (__arm__) || defined (__arm64__)
40
41#if defined(XNU_KERNEL_PRIVATE) && defined(__arm64__)
42#include <arm64/proc_reg.h>
43#endif
44
45#if defined(KERNEL_PRIVATE) && __ARM_16K_PG__
46#include <arm64/proc_reg.h>
47#endif
48
49#if !defined (KERNEL) && !defined (__ASSEMBLER__)
50#include <mach/vm_page_size.h>
51#endif
52
53#define BYTE_SIZE 8 /* byte size in bits */
54
55#if defined (KERNEL)
56
57#ifndef __ASSEMBLER__
58
59#ifdef __arm__
60#define PAGE_SHIFT_CONST 12
61#elif defined(__arm64__)
62extern int PAGE_SHIFT_CONST;
63#else
64#error Unsupported arch
65#endif
66
67#if defined(KERNEL_PRIVATE) && __ARM_16K_PG__
68#define PAGE_SHIFT ARM_PGSHIFT
69#else
70#define PAGE_SHIFT PAGE_SHIFT_CONST
71#endif
72#define PAGE_SIZE (1 << PAGE_SHIFT)
73#define PAGE_MASK (PAGE_SIZE-1)
74
75#define VM_PAGE_SIZE PAGE_SIZE
76
77#define machine_ptob(x) ((x) << PAGE_SHIFT)
78
79/*
80 * Defined for the purpose of testing the pmap advertised page
81 * size; this does not necessarily match the hardware page size.
82 */
83#define TEST_PAGE_SIZE_16K ((PAGE_SHIFT_CONST == 14))
84#define TEST_PAGE_SIZE_4K ((PAGE_SHIFT_CONST == 12))
85
86#endif /* !__ASSEMBLER__ */
87
88#else
89
90#define PAGE_SHIFT vm_page_shift
91#define PAGE_SIZE vm_page_size
92#define PAGE_MASK vm_page_mask
93
94#define VM_PAGE_SIZE vm_page_size
95
96#define machine_ptob(x) ((x) << PAGE_SHIFT)
97
98#endif
99
100#define PAGE_MAX_SHIFT 14
101#define PAGE_MAX_SIZE (1 << PAGE_MAX_SHIFT)
102#define PAGE_MAX_MASK (PAGE_MAX_SIZE-1)
103
104#define PAGE_MIN_SHIFT 12
105#define PAGE_MIN_SIZE (1 << PAGE_MIN_SHIFT)
106#define PAGE_MIN_MASK (PAGE_MIN_SIZE-1)
107
108#define VM_MAX_PAGE_ADDRESS MACH_VM_MAX_ADDRESS
109
110#ifndef __ASSEMBLER__
111
112#ifdef MACH_KERNEL_PRIVATE
113
114#define VM32_SUPPORT 1
115#define VM32_MIN_ADDRESS ((vm32_offset_t) 0)
116#define VM32_MAX_ADDRESS ((vm32_offset_t) (VM_MAX_ADDRESS & 0xFFFFFFFF))
117
118#endif /* MACH_KERNEL_PRIVATE */
119
120#if defined (__arm__)
121
122#define VM_MIN_ADDRESS ((vm_address_t) 0x00000000)
123#define VM_MAX_ADDRESS ((vm_address_t) 0x80000000)
124
125/* system-wide values */
126#define MACH_VM_MIN_ADDRESS ((mach_vm_offset_t) 0)
127#define MACH_VM_MAX_ADDRESS ((mach_vm_offset_t) VM_MAX_ADDRESS)
128
129#elif defined (__arm64__)
130
131#define VM_MIN_ADDRESS ((vm_address_t) 0x0000000000000000ULL)
132#define VM_MAX_ADDRESS ((vm_address_t) 0x00000000F0000000ULL)
133
134/* system-wide values */
135#define MACH_VM_MIN_ADDRESS_RAW 0x0ULL
136#if defined(XNU_PLATFORM_MacOSX) || defined(XNU_PLATFORM_DriverKit)
137#define MACH_VM_MAX_ADDRESS_RAW 0x00007FFFFE000000ULL
138#else
139#define MACH_VM_MAX_ADDRESS_RAW 0x0000000FC0000000ULL
140#endif
141
142#define MACH_VM_MIN_ADDRESS ((mach_vm_offset_t) MACH_VM_MIN_ADDRESS_RAW)
143#define MACH_VM_MAX_ADDRESS ((mach_vm_offset_t) MACH_VM_MAX_ADDRESS_RAW)
144
145#define MACH_VM_MIN_GPU_CARVEOUT_ADDRESS_RAW 0x0000001000000000ULL
146#define MACH_VM_MAX_GPU_CARVEOUT_ADDRESS_RAW 0x0000007000000000ULL
147#define MACH_VM_MIN_GPU_CARVEOUT_ADDRESS ((mach_vm_offset_t) MACH_VM_MIN_GPU_CARVEOUT_ADDRESS_RAW)
148#define MACH_VM_MAX_GPU_CARVEOUT_ADDRESS ((mach_vm_offset_t) MACH_VM_MAX_GPU_CARVEOUT_ADDRESS_RAW)
149
150#else /* defined(__arm64__) */
151#error architecture not supported
152#endif
153
154#define VM_MAP_MIN_ADDRESS VM_MIN_ADDRESS
155#define VM_MAP_MAX_ADDRESS VM_MAX_ADDRESS
156
157#ifdef KERNEL
158
159#if defined (__arm__)
160#define VM_KERNEL_POINTER_SIGNIFICANT_BITS 31
161#define VM_MIN_KERNEL_ADDRESS ((vm_address_t) 0x80000000)
162#define VM_MAX_KERNEL_ADDRESS ((vm_address_t) 0xFFFEFFFF)
163#define VM_HIGH_KERNEL_WINDOW ((vm_address_t) 0xFFFE0000)
164
165#elif defined (__arm64__)
166/*
167 * kalloc() parameters:
168 *
169 * Historically kalloc's underlying zones were power-of-2 sizes, with a
170 * KALLOC_MINSIZE of 16 bytes. Thus the allocator ensured that
171 * (sizeof == alignof) >= 16 for all kalloc allocations.
172 *
173 * Today kalloc may use zones with intermediate (small) sizes, constrained by
174 * KALLOC_MINSIZE and a minimum alignment, expressed by KALLOC_LOG2_MINALIGN.
175 *
176 * Note that most dynamically allocated data structures contain more than
177 * one int/long/pointer member, so KALLOC_MINSIZE should probably start at 8.
178 */
179#define TiB(x) ((0ULL + (x)) << 40)
180#define GiB(x) ((0ULL + (x)) << 30)
181#define KALLOC_MINSIZE 16 /* minimum allocation size */
182#define KALLOC_LOG2_MINALIGN 4 /* log2 minimum alignment */
183
184/*
185 * The minimum and maximum kernel address; some configurations may
186 * constrain the address space further.
187 */
188
189#if XNU_KERNEL_PRIVATE
190#if defined(ARM_LARGE_MEMORY)
191/*
192 * +-----------------------+--------+--------+------------------------+
193 * | 0xffff_fe90_0000_0000 |-1472GB | 576GB | KASAN_SHADOW_MIN |
194 * | | | | VM_MAX_KERNEL_ADDRESS |
195 * +-----------------------+--------+--------+------------------------+
196 * | 0xffff_fe10_0000_0000 |-1984GB | 64GB | PMAP_HEAP_RANGE_START |
197 * +-----------------------+--------+--------+------------------------+
198 * | 0xffff_fe00_0700_4000 | | | VM_KERNEL_LINK_ADDRESS |
199 * +-----------------------+--------+--------+------------------------+
200 * | 0xffff_fe00_0000_0000 | -2TB | 0GB | VM_MIN_KERNEL_ADDRESS |
201 * | | | | LOW_GLOBALS |
202 * +-----------------------+--------+--------+------------------------+
203 */
204#define VM_KERNEL_POINTER_SIGNIFICANT_BITS 41
205
206// Kernel VA space starts at -2TB
207#define VM_MIN_KERNEL_ADDRESS ((vm_address_t) (0ULL - TiB(2)))
208
209// 1.25TB for static_memory_region, 512GB for kernel heap, 256GB for KASAN
210#define VM_MAX_KERNEL_ADDRESS ((vm_address_t) (VM_MIN_KERNEL_ADDRESS + GiB(64) + GiB(512) - 1))
211
212#else // ARM_LARGE_MEMORY
213/*
214 * +-----------------------+--------+--------+------------------------+
215 * | 0xffff_fffc_0000_0000 | -16GB | 112GB | KASAN_SHADOW_MIN |
216 * | | | | VM_MAX_KERNEL_ADDRESS |
217 * +-----------------------+--------+--------+------------------------+
218 * | 0xffff_fff0_0700_4000 | | | VM_KERNEL_LINK_ADDRESS |
219 * +-----------------------+--------+--------+------------------------+
220 * | 0xffff_fff0_0000_0000 | -64GB | 64GB | LOW_GLOBALS |
221 * | | | | PMAP_HEAP_RANGE_START | <= H8
222 * +-----------------------+--------+--------+------------------------+
223 * | 0xffff_ffe0_0000_0000 | -128GB | 0GB | VM_MIN_KERNEL_ADDRESS | <= H8
224 * +-----------------------+--------+--------+------------------------+
225 * | 0xffff_ffdc_0000_0000 | -144GB | 0GB | VM_MIN_KERNEL_ADDRESS | >= H9
226 * | | | | PMAP_HEAP_RANGE_START | >= H9
227 * +-----------------------+--------+--------+------------------------+
228 */
229#if defined(KERNEL_INTEGRITY_KTRR) || defined(KERNEL_INTEGRITY_CTRR)
230#define VM_KERNEL_POINTER_SIGNIFICANT_BITS 38
231#define VM_MIN_KERNEL_ADDRESS ((vm_address_t) (0ULL - GiB(144)))
232#else /* defined(KERNEL_INTEGRITY_KTRR) || defined(KERNEL_INTEGRITY_CTRR) */
233#define VM_KERNEL_POINTER_SIGNIFICANT_BITS 37
234#define VM_MIN_KERNEL_ADDRESS ((vm_address_t) 0xffffffe000000000ULL)
235#endif /* defined(KERNEL_INTEGRITY_KTRR) || defined(KERNEL_INTEGRITY_CTRR) */
236#define VM_MAX_KERNEL_ADDRESS ((vm_address_t) 0xfffffffbffffffffULL)
237
238#endif // ARM_LARGE_MEMORY
239
240#else // !XNU_KERNEL_PRIVATE
241// Inform kexts about largest possible kernel address space
242#define VM_KERNEL_POINTER_SIGNIFICANT_BITS 41
243#define VM_MIN_KERNEL_ADDRESS ((vm_address_t) (0ULL - TiB(2)))
244#define VM_MAX_KERNEL_ADDRESS ((vm_address_t) 0xfffffffbffffffffULL)
245#endif // XNU_KERNEL_PRIVATE
246#else
247#error architecture not supported
248#endif
249
250#define VM_MIN_KERNEL_AND_KEXT_ADDRESS VM_MIN_KERNEL_ADDRESS
251
252#if defined (__arm64__)
253/* Top-Byte-Ignore */
254#define ARM_TBI_USER_MASK (0xFF00000000000000ULL)
255#define VM_USER_STRIP_TBI(_v) ((typeof (_v))(((uintptr_t)(_v)) &~ (ARM_TBI_USER_MASK)))
256#else /* __arm64__ */
257#define VM_USER_STRIP_TBI(_v) (_v)
258#endif /* __arm64__ */
259
260#if CONFIG_KERNEL_TAGGING
261#include <vm/vm_memtag.h>
262/*
263 * 'strip' in PAC sense, therefore replacing the stripped bits sign extending
264 * the sign bit. In kernel space the sign bit is 1, so 0xFF is a valid mask
265 * here.
266 */
267#define VM_KERNEL_STRIP_TAG(_v) (vm_memtag_canonicalize_address((vm_offset_t)_v))
268#else /* CONFIG_KERNEL_TAGGING */
269#define VM_KERNEL_STRIP_TAG(_v) (_v)
270#endif /* CONFIG_KERNEL_TAGGING */
271
272#if __has_feature(ptrauth_calls)
273#include <ptrauth.h>
274#define VM_KERNEL_STRIP_PAC(_v) (ptrauth_strip((void *)(uintptr_t)(_v), ptrauth_key_asia))
275#else /* !ptrauth_calls */
276#define VM_KERNEL_STRIP_PAC(_v) (_v)
277#endif /* ptrauth_calls */
278
279#define VM_KERNEL_STRIP_PTR(_va) ((VM_KERNEL_STRIP_TAG(VM_KERNEL_STRIP_PAC((_va)))))
280#define VM_KERNEL_STRIP_UPTR(_va) ((vm_address_t)VM_KERNEL_STRIP_PTR((uintptr_t)(_va)))
281#define VM_KERNEL_ADDRESS(_va) \
282 ((VM_KERNEL_STRIP_UPTR(_va) >= VM_MIN_KERNEL_ADDRESS) && \
283 (VM_KERNEL_STRIP_UPTR(_va) <= VM_MAX_KERNEL_ADDRESS))
284
285#define VM_USER_STRIP_PTR(_v) (VM_USER_STRIP_TBI(_v))
286
287#ifdef MACH_KERNEL_PRIVATE
288/*
289 * Physical memory is mapped linearly at an offset virtual memory.
290 */
291extern unsigned long gVirtBase, gPhysBase, gPhysSize;
292
293#define isphysmem(a) (((vm_address_t)(a) - gPhysBase) < gPhysSize)
294#define physmap_enclosed(a) isphysmem(a)
295
296/*
297 * gPhysBase/Size only represent kernel-managed memory. These globals represent
298 * the actual DRAM base address and size as reported by iBoot through the device
299 * tree.
300 */
301#include <stdint.h>
302extern uint64_t gDramBase, gDramSize;
303#define is_dram_addr(addr) (((uint64_t)(addr) - gDramBase) < gDramSize)
304
305#endif /* MACH_KERNEL_PRIVATE */
306
307#ifdef XNU_KERNEL_PRIVATE
308
309#if KASAN
310/* Increase the stack sizes to account for the redzones that get added to every
311 * stack object. */
312# define KERNEL_STACK_SIZE (4*4*4096)
313#elif DEBUG
314/**
315 * Increase the stack size to account for less efficient use of stack space when
316 * compiling with -O0.
317 */
318# define KERNEL_STACK_SIZE (2*4*4096)
319#else
320/*
321 * KERNEL_STACK_MULTIPLIER can be defined externally to get a larger
322 * kernel stack size. For example, adding "-DKERNEL_STACK_MULTIPLIER=2"
323 * helps avoid kernel stack overflows when compiling with "-O0".
324 */
325#ifndef KERNEL_STACK_MULTIPLIER
326#define KERNEL_STACK_MULTIPLIER (1)
327#endif /* KERNEL_STACK_MULTIPLIER */
328# define KERNEL_STACK_SIZE (4*4096*KERNEL_STACK_MULTIPLIER)
329#endif /* XNU_KERNEL_PRIVATE */
330
331#define INTSTACK_SIZE (4*4096)
332
333#ifdef __arm64__
334#define EXCEPSTACK_SIZE (4*4096)
335#else
336#define FIQSTACK_SIZE (4096)
337#endif
338
339#if defined (__arm__)
340#define HIGH_EXC_VECTORS ((vm_address_t) 0xFFFF0000)
341#endif
342
343/*
344 * TODO: We're hardcoding the expected virtual TEXT base here;
345 * that gives us an ugly dependency on a linker argument in
346 * the make files. Clean this up, so we don't hardcode it
347 * twice; this is nothing but trouble.
348 */
349#if defined (__arm__)
350#define VM_KERNEL_LINK_ADDRESS ((vm_address_t) 0x80000000)
351#elif defined (__arm64__)
352/* VM_KERNEL_LINK_ADDRESS defined in makedefs/MakeInc.def for arm64 platforms */
353#else
354#error architecture not supported
355#endif
356
357#endif /* MACH_KERNEL_PRIVATE */
358#endif /* KERNEL */
359
360#endif /* !__ASSEMBLER__ */
361
362#define SWI_SYSCALL 0x80
363
364#endif /* defined (__arm__) || defined (__arm64__) */
365
366#endif /* _MACH_ARM_VM_PARAM_H_ */
367