]>
Commit | Line | Data |
---|---|---|
43866e37 | 1 | /* |
39236c6e | 2 | * Copyright (c) 2003-2012 Apple Inc. All rights reserved. |
43866e37 | 3 | * |
2d21ac55 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
43866e37 | 5 | * |
2d21ac55 A |
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. | |
8f6c56a5 | 14 | * |
2d21ac55 A |
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 | |
8f6c56a5 A |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2d21ac55 A |
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. | |
8f6c56a5 | 25 | * |
2d21ac55 | 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
43866e37 A |
27 | */ |
28 | ||
29 | #ifndef _I386_COMMPAGE_H | |
30 | #define _I386_COMMPAGE_H | |
31 | ||
55e303ae A |
32 | #ifndef __ASSEMBLER__ |
33 | #include <stdint.h> | |
b0d623f7 A |
34 | #include <mach/boolean.h> |
35 | #include <mach/vm_types.h> | |
36 | #include <machine/cpu_capabilities.h> | |
55e303ae A |
37 | #endif /* __ASSEMBLER__ */ |
38 | ||
b0d623f7 A |
39 | /* When trying to acquire a spinlock or mutex, we will spin in |
40 | * user mode for awhile, before entering the kernel to relinquish. | |
41 | * MP_SPIN_TRIES is the initial value of _COMM_PAGE_SPIN_COUNT. | |
42 | * The idea is that _COMM_PAGE_SPIN_COUNT will be adjusted up or | |
43 | * down as the machine is plugged in/out, etc. | |
44 | * At present spinlocks do not use _COMM_PAGE_SPIN_COUNT. | |
45 | * They use MP_SPIN_TRIES directly. | |
46 | */ | |
47 | #define MP_SPIN_TRIES 1000 | |
48 | ||
49 | ||
0c530ab8 A |
50 | /* The following macro is used to generate the 64-bit commpage address for a given |
51 | * routine, based on its 32-bit address. This is used in the kernel to compile | |
b0d623f7 | 52 | * the 64-bit commpage. Since the kernel can be a 32-bit object, cpu_capabilities.h |
0c530ab8 A |
53 | * only defines the 32-bit address. |
54 | */ | |
55 | #define _COMM_PAGE_32_TO_64( ADDRESS ) ( ADDRESS + _COMM_PAGE64_START_ADDRESS - _COMM_PAGE32_START_ADDRESS ) | |
56 | ||
57 | ||
55e303ae | 58 | #ifdef __ASSEMBLER__ |
55e303ae | 59 | |
b0d623f7 A |
60 | #define COMMPAGE_DESCRIPTOR_NAME(label) _commpage_ ## label |
61 | ||
b0d623f7 A |
62 | #define COMMPAGE_DESCRIPTOR_FIELD_POINTER .quad |
63 | #define COMMPAGE_DESCRIPTOR_REFERENCE(label) \ | |
64 | .quad COMMPAGE_DESCRIPTOR_NAME(label) | |
65 | ||
b0d623f7 A |
66 | #define COMMPAGE_FUNCTION_START(label,codetype,alignment) \ |
67 | .text ;\ | |
68 | .code ## codetype ;\ | |
69 | .align alignment, 0x90 ;\ | |
70 | L ## label ## : | |
71 | ||
bd504ef0 | 72 | #define COMMPAGE_DESCRIPTOR(label,address) \ |
b0d623f7 A |
73 | L ## label ## _end: ;\ |
74 | .set L ## label ## _size, L ## label ## _end - L ## label ;\ | |
75 | .const_data ;\ | |
76 | .private_extern COMMPAGE_DESCRIPTOR_NAME(label) ;\ | |
77 | COMMPAGE_DESCRIPTOR_NAME(label) ## : ;\ | |
78 | COMMPAGE_DESCRIPTOR_FIELD_POINTER L ## label ;\ | |
79 | .long L ## label ## _size ;\ | |
80 | .long address ;\ | |
55e303ae A |
81 | .text |
82 | ||
b0d623f7 A |
83 | |
84 | /* COMMPAGE_CALL(target,from,start) | |
85 | * | |
86 | * This macro compiles a relative near call to one | |
87 | * commpage routine from another. | |
88 | * The assembler cannot handle this directly because the code | |
89 | * is not being assembled at the address at which it will execute. | |
90 | * The alternative to this macro would be to use an | |
91 | * indirect call, which is slower because the target of an | |
92 | * indirect branch is poorly predicted. | |
93 | * The macro arguments are: | |
94 | * target = the commpage routine we are calling | |
95 | * from = the commpage routine we are in now | |
96 | * start = the label at the start of the code for this func | |
97 | * This is admitedly ugly and fragile. Is there a better way? | |
98 | */ | |
99 | #define COMMPAGE_CALL(target,from,start) \ | |
100 | COMMPAGE_CALL_INTERNAL(target,from,start,__LINE__) | |
101 | ||
102 | #define COMMPAGE_CALL_INTERNAL(target,from,start,unique) \ | |
103 | .byte 0xe8 ;\ | |
104 | .set UNIQUEID(unique), L ## start - . + target - from - 4 ;\ | |
105 | .long UNIQUEID(unique) | |
106 | ||
107 | #define UNIQUEID(name) L ## name | |
108 | ||
55e303ae A |
109 | #else /* __ASSEMBLER__ */ |
110 | ||
111 | /* Each potential commpage routine is described by one of these. | |
112 | * Note that the COMMPAGE_DESCRIPTOR macro (above), used in | |
113 | * assembly language, must agree with this. | |
114 | */ | |
115 | ||
116 | typedef struct commpage_descriptor { | |
b0d623f7 A |
117 | void *code_address; // address of code |
118 | uint32_t code_length; // length in bytes | |
119 | uint32_t commpage_address; // put at this address (_COMM_PAGE_BCOPY etc) | |
55e303ae A |
120 | } commpage_descriptor; |
121 | ||
122 | ||
2d21ac55 A |
123 | /* Warning: following structure must match the layout of the commpage. */ |
124 | /* This is the data starting at _COMM_PAGE_TIME_DATA_START, ie for nanotime() and gettimeofday() */ | |
125 | ||
126 | typedef volatile struct commpage_time_data { | |
127 | uint64_t nt_tsc_base; // _COMM_PAGE_NT_TSC_BASE | |
128 | uint32_t nt_scale; // _COMM_PAGE_NT_SCALE | |
129 | uint32_t nt_shift; // _COMM_PAGE_NT_SHIFT | |
130 | uint64_t nt_ns_base; // _COMM_PAGE_NT_NS_BASE | |
131 | uint32_t nt_generation; // _COMM_PAGE_NT_GENERATION | |
132 | uint32_t gtod_generation; // _COMM_PAGE_GTOD_GENERATION | |
133 | uint64_t gtod_ns_base; // _COMM_PAGE_GTOD_NS_BASE | |
134 | uint64_t gtod_sec_base; // _COMM_PAGE_GTOD_SEC_BASE | |
135 | } commpage_time_data; | |
136 | ||
137 | ||
0c530ab8 A |
138 | extern char *commPagePtr32; // virt address of 32-bit commpage in kernel map |
139 | extern char *commPagePtr64; // ...and of 64-bit commpage | |
140 | ||
2d21ac55 | 141 | extern void commpage_set_timestamp(uint64_t abstime, uint64_t secs); |
2d21ac55 | 142 | extern void commpage_disable_timestamp( void ); |
0c530ab8 | 143 | extern void commpage_set_nanotime(uint64_t tsc_base, uint64_t ns_base, uint32_t scale, uint32_t shift); |
b0d623f7 A |
144 | extern void commpage_set_memory_pressure(unsigned int pressure); |
145 | extern void commpage_set_spin_count(unsigned int count); | |
2d21ac55 | 146 | extern void commpage_sched_gen_inc(void); |
6d2010ae | 147 | extern void commpage_update_active_cpus(void); |
fe8ab488 | 148 | extern void commpage_update_mach_approximate_time(uint64_t abstime); |
a1c7dba1 | 149 | extern void commpage_update_kdebug_enable(void); |
91447636 | 150 | |
b0d623f7 A |
151 | extern uint32_t commpage_is_in_pfz32(uint32_t); |
152 | extern uint32_t commpage_is_in_pfz64(addr64_t); | |
153 | ||
55e303ae | 154 | #endif /* __ASSEMBLER__ */ |
43866e37 A |
155 | |
156 | #endif /* _I386_COMMPAGE_H */ |