]> git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/cpu.c
23b38e3db33940a4b0fe8190dc239dbbf76728e2
[apple/xnu.git] / osfmk / i386 / cpu.c
1 /*
2 * Copyright (c) 2000-2009 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: i386/cpu.c
30 *
31 * cpu specific routines
32 */
33
34 #include <kern/kalloc.h>
35 #include <kern/misc_protos.h>
36 #include <kern/machine.h>
37 #include <mach/processor_info.h>
38 #include <i386/pmap.h>
39 #include <i386/machine_cpu.h>
40 #include <i386/machine_routines.h>
41 #include <i386/misc_protos.h>
42 #include <i386/cpu_threads.h>
43 #include <i386/rtclock_protos.h>
44 #include <i386/cpuid.h>
45 #if CONFIG_VMX
46 #include <i386/vmx/vmx_cpu.h>
47 #endif
48 #include <vm/vm_kern.h>
49 #include <kern/etimer.h>
50 #include <kern/timer_call.h>
51
52 struct processor processor_master;
53
54 /*ARGSUSED*/
55 kern_return_t
56 cpu_control(
57 int slot_num,
58 processor_info_t info,
59 unsigned int count)
60 {
61 printf("cpu_control(%d,%p,%d) not implemented\n",
62 slot_num, info, count);
63 return (KERN_FAILURE);
64 }
65
66 /*ARGSUSED*/
67 kern_return_t
68 cpu_info_count(
69 __unused processor_flavor_t flavor,
70 unsigned int *count)
71 {
72 *count = 0;
73 return (KERN_FAILURE);
74 }
75
76 /*ARGSUSED*/
77 kern_return_t
78 cpu_info(
79 processor_flavor_t flavor,
80 int slot_num,
81 processor_info_t info,
82 unsigned int *count)
83 {
84 printf("cpu_info(%d,%d,%p,%p) not implemented\n",
85 flavor, slot_num, info, count);
86 return (KERN_FAILURE);
87 }
88
89 void
90 cpu_sleep(void)
91 {
92 cpu_data_t *cdp = current_cpu_datap();
93
94 PE_cpu_machine_quiesce(cdp->cpu_id);
95
96 cpu_thread_halt();
97 }
98
99 void
100 cpu_init(void)
101 {
102 cpu_data_t *cdp = current_cpu_datap();
103
104 timer_call_initialize_queue(&cdp->rtclock_timer.queue);
105 cdp->rtclock_timer.deadline = EndOfAllTime;
106
107 cdp->cpu_type = cpuid_cputype();
108 cdp->cpu_subtype = cpuid_cpusubtype();
109
110 i386_activate_cpu();
111 }
112
113 kern_return_t
114 cpu_start(
115 int cpu)
116 {
117 kern_return_t ret;
118
119 if (cpu == cpu_number()) {
120 cpu_machine_init();
121 return KERN_SUCCESS;
122 }
123
124 /*
125 * Try to bring the CPU back online without a reset.
126 * If the fast restart doesn't succeed, fall back to
127 * the slow way.
128 */
129 ret = intel_startCPU_fast(cpu);
130 if (ret != KERN_SUCCESS) {
131 /*
132 * Should call out through PE.
133 * But take the shortcut here.
134 */
135 ret = intel_startCPU(cpu);
136 }
137
138 if (ret != KERN_SUCCESS)
139 kprintf("cpu: cpu_start(%d) returning failure!\n", cpu);
140
141 return(ret);
142 }
143
144 void
145 cpu_exit_wait(
146 int cpu)
147 {
148 cpu_data_t *cdp = cpu_datap(cpu);
149
150 /*
151 * Wait until the CPU indicates that it has stopped.
152 */
153 simple_lock(&x86_topo_lock);
154 while ((cdp->lcpu.state != LCPU_HALT)
155 && (cdp->lcpu.state != LCPU_OFF)
156 && !cdp->lcpu.stopped) {
157 simple_unlock(&x86_topo_lock);
158 cpu_pause();
159 simple_lock(&x86_topo_lock);
160 }
161 simple_unlock(&x86_topo_lock);
162 }
163
164 void
165 cpu_machine_init(
166 void)
167 {
168 cpu_data_t *cdp = current_cpu_datap();
169
170 PE_cpu_machine_init(cdp->cpu_id, !cdp->cpu_boot_complete);
171 cdp->cpu_boot_complete = TRUE;
172 cdp->cpu_running = TRUE;
173 ml_init_interrupt();
174
175 #if CONFIG_VMX
176 /* for every CPU, get the VT specs */
177 vmx_get_specs();
178 #endif
179 }
180
181 processor_t
182 cpu_processor_alloc(boolean_t is_boot_cpu)
183 {
184 int ret;
185 processor_t proc;
186
187 if (is_boot_cpu)
188 return &processor_master;
189
190 ret = kmem_alloc(kernel_map, (vm_offset_t *) &proc, sizeof(*proc));
191 if (ret != KERN_SUCCESS)
192 return NULL;
193
194 bzero((void *) proc, sizeof(*proc));
195 return proc;
196 }
197
198 void
199 cpu_processor_free(processor_t proc)
200 {
201 if (proc != NULL && proc != &processor_master)
202 kfree((void *) proc, sizeof(*proc));
203 }
204
205 processor_t
206 current_processor(void)
207 {
208 return current_cpu_datap()->cpu_processor;
209 }
210
211 processor_t
212 cpu_to_processor(
213 int cpu)
214 {
215 return cpu_datap(cpu)->cpu_processor;
216 }
217
218 ast_t *
219 ast_pending(void)
220 {
221 return (&current_cpu_datap()->cpu_pending_ast);
222 }
223
224 cpu_type_t
225 slot_type(
226 int slot_num)
227 {
228 return (cpu_datap(slot_num)->cpu_type);
229 }
230
231 cpu_subtype_t
232 slot_subtype(
233 int slot_num)
234 {
235 return (cpu_datap(slot_num)->cpu_subtype);
236 }
237
238 cpu_threadtype_t
239 slot_threadtype(
240 int slot_num)
241 {
242 return (cpu_datap(slot_num)->cpu_threadtype);
243 }
244
245 cpu_type_t
246 cpu_type(void)
247 {
248 return (current_cpu_datap()->cpu_type);
249 }
250
251 cpu_subtype_t
252 cpu_subtype(void)
253 {
254 return (current_cpu_datap()->cpu_subtype);
255 }
256
257 cpu_threadtype_t
258 cpu_threadtype(void)
259 {
260 return (current_cpu_datap()->cpu_threadtype);
261 }