|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * File: ppc/cpu.c
24: *
25: * cpu specific routines
26: */
27:
28: #include <kern/machine.h>
29: #include <kern/misc_protos.h>
30: #include <kern/thread.h>
31: #include <kern/processor.h>
32: #include <mach/machine.h>
33: #include <mach/processor_info.h>
34: #include <mach/mach_types.h>
35: #include <ppc/proc_reg.h>
36: #include <ppc/misc_protos.h>
37: #include <ppc/machine_routines.h>
38: #include <ppc/machine_cpu.h>
39: #include <ppc/exception.h>
40: #include <pexpert/pexpert.h>
41: #include <pexpert/ppc/powermac.h>
42:
43: /* TODO: BOGUS TO BE REMOVED */
44: int real_ncpus = 1;
45:
46: int wncpu = NCPUS;
47: resethandler_t resethandler_target;
48:
49: #define MMCR0_SUPPORT_MASK 0xf83f1fff
50: #define MMCR1_SUPPORT_MASK 0xffc00000
51: #define MMCR2_SUPPORT_MASK 0x80000000
52:
53: extern int debugger_pending[NCPUS];
54: extern int debugger_is_slave[NCPUS];
55: extern int debugger_holdoff[NCPUS];
56: extern int debugger_sync;
57:
58:
59: kern_return_t
60: cpu_control(
61: int slot_num,
62: processor_info_t info,
63: unsigned int count)
64: {
65: cpu_type_t cpu_type;
66: cpu_subtype_t cpu_subtype;
67: processor_pm_regs_t perf_regs;
68: processor_control_cmd_t cmd;
69: boolean_t oldlevel;
70:
71: cpu_type = machine_slot[slot_num].cpu_type;
72: cpu_subtype = machine_slot[slot_num].cpu_subtype;
73: cmd = (processor_control_cmd_t) info;
74:
75: if (count < PROCESSOR_CONTROL_CMD_COUNT)
76: return(KERN_FAILURE);
77:
78: if ( cpu_type != cmd->cmd_cpu_type ||
79: cpu_subtype != cmd->cmd_cpu_subtype)
80: return(KERN_FAILURE);
81:
82: switch (cmd->cmd_op)
83: {
84: case PROCESSOR_PM_CLR_PMC: /* Clear Performance Monitor Counters */
85: switch (cpu_subtype)
86: {
87: case CPU_SUBTYPE_POWERPC_604:
88: {
89: oldlevel = ml_set_interrupts_enabled(FALSE); /* disable interrupts */
90: mtpmc1(0x0);
91: mtpmc2(0x0);
92: ml_set_interrupts_enabled(oldlevel); /* enable interrupts */
93: return(KERN_SUCCESS);
94: }
95: case CPU_SUBTYPE_POWERPC_604e:
96: case CPU_SUBTYPE_POWERPC_750:
97: case CPU_SUBTYPE_POWERPC_Max:
98: {
99: oldlevel = ml_set_interrupts_enabled(FALSE); /* disable interrupts */
100: mtpmc1(0x0);
101: mtpmc2(0x0);
102: mtpmc3(0x0);
103: mtpmc4(0x0);
104: ml_set_interrupts_enabled(oldlevel); /* enable interrupts */
105: return(KERN_SUCCESS);
106: }
107: default:
108: return(KERN_FAILURE);
109: } /* cpu_subtype */
110: case PROCESSOR_PM_SET_REGS: /* Set Performance Monitor Registors */
111: switch (cpu_subtype)
112: {
113: case CPU_SUBTYPE_POWERPC_604:
114: if (count < (PROCESSOR_CONTROL_CMD_COUNT
115: + PROCESSOR_PM_REGS_COUNT_POWERPC_604))
116: return(KERN_FAILURE);
117: else
118: {
119: perf_regs = (processor_pm_regs_t)cmd->cmd_pm_regs;
120: oldlevel = ml_set_interrupts_enabled(FALSE); /* disable interrupts */
121: mtmmcr0(PERFMON_MMCR0(perf_regs) & MMCR0_SUPPORT_MASK);
122: mtpmc1(PERFMON_PMC1(perf_regs));
123: mtpmc2(PERFMON_PMC2(perf_regs));
124: ml_set_interrupts_enabled(oldlevel); /* enable interrupts */
125: return(KERN_SUCCESS);
126: }
127: case CPU_SUBTYPE_POWERPC_604e:
128: case CPU_SUBTYPE_POWERPC_750:
129: if (count < (PROCESSOR_CONTROL_CMD_COUNT +
130: PROCESSOR_PM_REGS_COUNT_POWERPC_750))
131: return(KERN_FAILURE);
132: else
133: {
134: perf_regs = (processor_pm_regs_t)cmd->cmd_pm_regs;
135: oldlevel = ml_set_interrupts_enabled(FALSE); /* disable interrupts */
136: mtmmcr0(PERFMON_MMCR0(perf_regs) & MMCR0_SUPPORT_MASK);
137: mtpmc1(PERFMON_PMC1(perf_regs));
138: mtpmc2(PERFMON_PMC2(perf_regs));
139: mtmmcr1(PERFMON_MMCR1(perf_regs) & MMCR1_SUPPORT_MASK);
140: mtpmc3(PERFMON_PMC3(perf_regs));
141: mtpmc4(PERFMON_PMC4(perf_regs));
142: ml_set_interrupts_enabled(oldlevel); /* enable interrupts */
143: return(KERN_SUCCESS);
144: }
145: case CPU_SUBTYPE_POWERPC_Max:
146: if (count < (PROCESSOR_CONTROL_CMD_COUNT +
147: PROCESSOR_PM_REGS_COUNT_POWERPC_Max))
148: return(KERN_FAILURE);
149: else
150: {
151: perf_regs = (processor_pm_regs_t)cmd->cmd_pm_regs;
152: oldlevel = ml_set_interrupts_enabled(FALSE); /* disable interrupts */
153: mtmmcr0(PERFMON_MMCR0(perf_regs) & MMCR0_SUPPORT_MASK);
154: mtpmc1(PERFMON_PMC1(perf_regs));
155: mtpmc2(PERFMON_PMC2(perf_regs));
156: mtmmcr1(PERFMON_MMCR1(perf_regs) & MMCR1_SUPPORT_MASK);
157: mtpmc3(PERFMON_PMC3(perf_regs));
158: mtpmc4(PERFMON_PMC4(perf_regs));
159: mtmmcr2(PERFMON_MMCR2(perf_regs) & MMCR2_SUPPORT_MASK);
160: ml_set_interrupts_enabled(oldlevel); /* enable interrupts */
161: return(KERN_SUCCESS);
162: }
163: default:
164: return(KERN_FAILURE);
165: } /* switch cpu_subtype */
166: case PROCESSOR_PM_SET_MMCR:
167: switch (cpu_subtype)
168: {
169: case CPU_SUBTYPE_POWERPC_604:
170: if (count < (PROCESSOR_CONTROL_CMD_COUNT +
171: PROCESSOR_PM_REGS_COUNT_POWERPC_604))
172: return(KERN_FAILURE);
173: else
174: {
175: perf_regs = (processor_pm_regs_t)cmd->cmd_pm_regs;
176: mtmmcr0(PERFMON_MMCR0(perf_regs) & MMCR0_SUPPORT_MASK);
177: return(KERN_SUCCESS);
178: }
179: case CPU_SUBTYPE_POWERPC_604e:
180: case CPU_SUBTYPE_POWERPC_750:
181: if (count < (PROCESSOR_CONTROL_CMD_COUNT +
182: PROCESSOR_PM_REGS_COUNT_POWERPC_750))
183: return(KERN_FAILURE);
184: else
185: {
186: perf_regs = (processor_pm_regs_t)cmd->cmd_pm_regs;
187: oldlevel = ml_set_interrupts_enabled(FALSE); /* disable interrupts */
188: mtmmcr0(PERFMON_MMCR0(perf_regs) & MMCR0_SUPPORT_MASK);
189: mtmmcr1(PERFMON_MMCR1(perf_regs) & MMCR1_SUPPORT_MASK);
190: ml_set_interrupts_enabled(oldlevel); /* enable interrupts */
191: return(KERN_SUCCESS);
192: }
193: case CPU_SUBTYPE_POWERPC_Max:
194: if (count < (PROCESSOR_CONTROL_CMD_COUNT +
195: PROCESSOR_PM_REGS_COUNT_POWERPC_Max))
196: return(KERN_FAILURE);
197: else
198: {
199: perf_regs = (processor_pm_regs_t)cmd->cmd_pm_regs;
200: oldlevel = ml_set_interrupts_enabled(FALSE); /* disable interrupts */
201: mtmmcr0(PERFMON_MMCR0(perf_regs) & MMCR0_SUPPORT_MASK);
202: mtmmcr1(PERFMON_MMCR1(perf_regs) & MMCR1_SUPPORT_MASK);
203: mtmmcr2(PERFMON_MMCR2(perf_regs) & MMCR2_SUPPORT_MASK);
204: ml_set_interrupts_enabled(oldlevel); /* enable interrupts */
205: return(KERN_SUCCESS);
206: }
207: default:
208: return(KERN_FAILURE);
209: } /* cpu_subtype */
210: default:
211: return(KERN_FAILURE);
212: } /* switch cmd_op */
213: }
214:
215: kern_return_t
216: cpu_info(
217: processor_flavor_t flavor,
218: int slot_num,
219: processor_info_t info,
220: unsigned int *count)
221: {
222: cpu_subtype_t cpu_subtype;
223: processor_pm_regs_t perf_regs;
224: boolean_t oldlevel;
225:
226: cpu_subtype = machine_slot[slot_num].cpu_subtype;
227:
228: switch (flavor)
229: {
230: case PROCESSOR_PM_REGS_INFO:
231: {
232: perf_regs = (processor_pm_regs_t) info;
233:
234: switch (cpu_subtype)
235: {
236: case CPU_SUBTYPE_POWERPC_604:
237: {
238: if (*count < PROCESSOR_PM_REGS_COUNT_POWERPC_604)
239: return(KERN_FAILURE);
240:
241: oldlevel = ml_set_interrupts_enabled(FALSE); /* disable interrupts */
242: PERFMON_MMCR0(perf_regs) = mfmmcr0();
243: PERFMON_PMC1(perf_regs) = mfpmc1();
244: PERFMON_PMC2(perf_regs) = mfpmc2();
245: ml_set_interrupts_enabled(oldlevel); /* enable interrupts */
246:
247: *count = PROCESSOR_PM_REGS_COUNT_POWERPC_604;
248: return(KERN_SUCCESS);
249: }
250: case CPU_SUBTYPE_POWERPC_604e:
251: case CPU_SUBTYPE_POWERPC_750:
252: {
253: if (*count < PROCESSOR_PM_REGS_COUNT_POWERPC_750)
254: return(KERN_FAILURE);
255:
256: oldlevel = ml_set_interrupts_enabled(FALSE); /* disable interrupts */
257: PERFMON_MMCR0(perf_regs) = mfmmcr0();
258: PERFMON_PMC1(perf_regs) = mfpmc1();
259: PERFMON_PMC2(perf_regs) = mfpmc2();
260: PERFMON_MMCR1(perf_regs) = mfmmcr1();
261: PERFMON_PMC3(perf_regs) = mfpmc3();
262: PERFMON_PMC4(perf_regs) = mfpmc4();
263: ml_set_interrupts_enabled(oldlevel); /* enable interrupts */
264:
265: *count = PROCESSOR_PM_REGS_COUNT_POWERPC_750;
266: return(KERN_SUCCESS);
267: }
268: case CPU_SUBTYPE_POWERPC_Max:
269: {
270: if (*count < PROCESSOR_PM_REGS_COUNT_POWERPC_Max)
271: return(KERN_FAILURE);
272:
273: oldlevel = ml_set_interrupts_enabled(FALSE); /* disable interrupts */
274: PERFMON_MMCR0(perf_regs) = mfmmcr0();
275: PERFMON_PMC1(perf_regs) = mfpmc1();
276: PERFMON_PMC2(perf_regs) = mfpmc2();
277: PERFMON_MMCR1(perf_regs) = mfmmcr1();
278: PERFMON_PMC3(perf_regs) = mfpmc3();
279: PERFMON_PMC4(perf_regs) = mfpmc4();
280: PERFMON_MMCR2(perf_regs) = mfmmcr2();
281: ml_set_interrupts_enabled(oldlevel); /* enable interrupts */
282:
283: *count = PROCESSOR_PM_REGS_COUNT_POWERPC_Max;
284: return(KERN_SUCCESS);
285: }
286: default:
287: return(KERN_FAILURE);
288: } /* switch cpu_subtype */
289: } /* PROCESSOR_PM_REGS_INFO */
290: default:
291: return(KERN_INVALID_ARGUMENT);
292: } /* flavor */
293: }
294:
295: cpu_init()
296: {
297: int cpu;
298: cpu_subtype_t t;
299:
300: cpu = cpu_number();
301:
302: machine_slot[cpu].running = TRUE;
303: machine_slot[cpu].cpu_type = CPU_TYPE_POWERPC;
304:
305: switch (PROCESSOR_VERSION) {
306: case PROCESSOR_VERSION_601: /* 601 */
307: t = CPU_SUBTYPE_POWERPC_601; break;
308: case PROCESSOR_VERSION_603: /* ? */
309: t = CPU_SUBTYPE_POWERPC_603; break;
310: case PROCESSOR_VERSION_604: /* ? */
311: t = CPU_SUBTYPE_POWERPC_604; break;
312: case 5: /* ? */
313: t = CPU_SUBTYPE_POWERPC_602; break;
314: case PROCESSOR_VERSION_603e: /* ? */
315: t = CPU_SUBTYPE_POWERPC_603e; break;
316: case 7: /* ? */
317: t = CPU_SUBTYPE_POWERPC_603ev; break;
318: case PROCESSOR_VERSION_604e: /* ? */
319: case PROCESSOR_VERSION_604ev: /* ? */
320: __asm__ volatile("mtspr 1023,%0" : : "r" (cpu)); /* Set logical CPU into the PIR */
321: t = CPU_SUBTYPE_POWERPC_604e; break;
322: case PROCESSOR_VERSION_750: /* ? */
323: t = CPU_SUBTYPE_POWERPC_750; break;
324: case PROCESSOR_VERSION_Max: /* Max */
325: __asm__ volatile("mtspr 1023,%0" : : "r" (cpu)); /* Set logical CPU into the PIR */
326: t = CPU_SUBTYPE_POWERPC_Max; break;
327: default:
328: t = CPU_SUBTYPE_POWERPC_ALL; break;
329: }
330: machine_slot[cpu].cpu_subtype = t;
331:
332: }
333:
334: void
335: cpu_machine_init(
336: void)
337: {
338: /* TODO: realese mutex lock reset_handler_lock */
339:
340: PE_cpu_machine_init(per_proc_info[cpu_number()].cpu_id);
341: }
342:
343: kern_return_t
344: cpu_register(
345: int *target_cpu
346: )
347: {
348: int cpu;
349:
350: /*
351: * TODO:
352: * - Run cpu_register() in exclusion mode
353: */
354:
355: *target_cpu = -1;
356: for(cpu=0; cpu < wncpu; cpu++) {
357: if(!machine_slot[cpu].is_cpu) {
358: machine_slot[cpu].is_cpu = TRUE;
359: *target_cpu = cpu;
360: break;
361: }
362: }
363: if (*target_cpu != -1) {
364: real_ncpus++;
365: return KERN_SUCCESS;
366: } else
367: return KERN_FAILURE;
368: }
369:
370: kern_return_t
371: cpu_start(
372: int cpu)
373: {
374: struct per_proc_info *proc_info;
375: kern_return_t ret;
376:
377: extern void (*exception_handlers[])(void);
378: extern vm_offset_t intstack;
379: extern vm_offset_t debstack;
380:
381: if (cpu == master_cpu) {
382: PE_cpu_machine_init(per_proc_info[cpu].cpu_id);
383:
384: return KERN_SUCCESS;
385: }
386:
387: proc_info = &per_proc_info[cpu];
388:
389: proc_info->cpu_number = cpu;
390: proc_info->cpu_flags = 0;
391: proc_info->istackptr = (vm_offset_t)&intstack + (INTSTACK_SIZE*(cpu+1)) - sizeof (struct ppc_saved_state);
392: proc_info->intstack_top_ss = proc_info->istackptr;
393: #if MACH_KDP || MACH_KDB
394: proc_info->debstackptr = (vm_offset_t)&debstack + (KERNEL_STACK_SIZE*(cpu+1)) - sizeof (struct ppc_saved_state);
395: proc_info->debstack_top_ss = proc_info->debstackptr;
396: #endif /* MACH_KDP || MACH_KDB */
397: proc_info->phys_exception_handlers =
398: kvtophys((vm_offset_t)&exception_handlers);
399: proc_info->get_interrupts_enabled = fake_get_interrupts_enabled;
400: proc_info->set_interrupts_enabled = fake_set_interrupts_enabled;
401: proc_info->virt_per_proc_info = (unsigned int)proc_info;
402: proc_info->active_kloaded = (unsigned int)&active_kloaded[cpu];
403: proc_info->cpu_data = (unsigned int)&cpu_data[cpu];
404: proc_info->active_stacks = (unsigned int)&active_stacks[cpu];
405: proc_info->need_ast = (unsigned int)&need_ast[cpu];
406: proc_info->FPU_thread = 0;
407:
408: if (cpu != cpu_number()) {
409: extern void _start_cpu(void);
410:
411: if (proc_info->start_paddr == EXCEPTION_VECTOR(T_RESET)) {
412:
413: /* TODO: get mutex lock reset_handler_lock */
414:
415: resethandler_target.type = RESET_HANDLER_START;
416: resethandler_target.call_paddr = kvtophys((vm_offset_t)_start_cpu);
417: resethandler_target.arg__paddr = kvtophys((vm_offset_t)proc_info);
418:
419: ml_phys_write((vm_offset_t)&ResetHandler + 0,
420: resethandler_target.type);
421: ml_phys_write((vm_offset_t)&ResetHandler + 4,
422: resethandler_target.call_paddr);
423: ml_phys_write((vm_offset_t)&ResetHandler + 8,
424: resethandler_target.arg__paddr);
425:
426: __asm__ volatile("sync"); /* Commit to storage */
427: __asm__ volatile("isync"); /* Wait a second */
428: }
429:
430: ret = PE_cpu_start(proc_info->cpu_id,
431: proc_info->start_paddr, (vm_offset_t)proc_info);
432:
433: if (ret != KERN_SUCCESS &&
434: proc_info->start_paddr == EXCEPTION_VECTOR(T_RESET)) {
435:
436: /* TODO: realese mutex lock reset_handler_lock */
437: }
438: }
439: else
440: ret = KERN_SUCCESS;
441:
442: return(ret);
443: }
444:
445: kern_return_t
446: cpu_signal_handler_register()
447: {
448: }
449:
450:
451: /*
452: * Here is where we implement the receiver of the signaling protocol.
453: * We wait for the signal status area to be passed to us. Then we snarf
454: * up the status, the sender, and the 3 potential parms. Next we release
455: * the lock and signal the other guy.
456: */
457:
458: void cpu_signal_handler(void) {
459:
460: unsigned int holdStat, holdParm0, holdParm1, holdParm2, mtype;
461: struct per_proc_info *pproc; /* Area for my per_proc address */
462: int cpu;
463:
464: cpu = cpu_number(); /* Get the CPU number */
465: pproc = &per_proc_info[cpu]; /* Point to our block */
466:
467: /*
468: * Since we've been signaled, wait just under 1ms for the signal lock to pass
469: */
470: if(!hw_lock_mbits(&pproc->MPsigpStat, MPsigpMsgp, (MPsigpBusy | MPsigpPass),
471: (MPsigpBusy | MPsigpPass), (powermac_info.bus_clock_rate_hz >> 7))) {
472: panic("cpu_signal_handler: Lock pass timed out\n");
473: }
474:
475: holdStat = pproc->MPsigpStat; /* Snarf stat word */
476: holdParm0 = pproc->MPsigpParm0; /* Snarf parameter */
477: holdParm1 = pproc->MPsigpParm1; /* Snarf parameter */
478: holdParm2 = pproc->MPsigpParm2; /* Snarf parameter */
479:
480: __asm__ volatile("isync"); /* Make sure we don't unlock until memory is in */
481:
482: pproc->MPsigpStat = holdStat & ~(MPsigpMsgp | MPsigpFunc); /* Release lock */
483:
484: switch ((holdStat & MPsigpFunc) >> 8) { /* Decode function code */
485:
486: case MPsigpIdle: /* Was function cancelled? */
487: return; /* Yup... */
488:
489: case MPsigpSigp: /* Signal Processor message? */
490:
491: switch (holdParm0) { /* Decode SIGP message order */
492:
493: case SIGPast: /* Should we do an AST? */
494: #if 0
495: ast_check(); /* Yes, do it */
496: #else
497: kprintf("cpu_signal_handler: AST request disabled\n");
498: #endif
499: return; /* All done... */
500:
501: case SIGPdebug: /* Enter the debugger? */
502:
503: debugger_is_slave[cpu]++; /* Bump up the count to show we're here */
504: hw_atomic_sub(&debugger_sync, 1); /* Show we've received the 'rupt */
505: __asm__ volatile("tw 4,r3,r3"); /* Enter the debugger */
506: return; /* All done now... */
507:
508: case SIGPwake: /* Wake up CPU */
509: return; /* No need to do anything, the interrupt does it all... */
510:
511: default:
512: #if DEBUG
513: kprintf("cpu_signal_handler: unknown SIGP message order - %08X\n", holdParm0);
514: #endif
515: return;
516:
517: }
518:
519: default:
520: #if DEBUG
521: kprintf("cpu_signal_handler: unknown SIGP function - %08X\n", (holdStat & MPsigpFunc) >> 8);
522: #endif
523: return;
524:
525: }
526: panic("cpu_signal_handler: we should never get here\n");
527: }
528:
529: /*
530: * Here is where we send a message to another processor. So far we only have two:
531: * SIGPast and SIGPdebug. SIGPast is used to preempt and kick off threads (this is
532: * currently disabled). SIGPdebug is used to enter the debugger.
533: *
534: * We set up the SIGP function to indicate that this is a simple message and set the
535: * order code (MPsigpParm0) to SIGPast or SIGPdebug). After finding the per_processor
536: * block for the target, we lock the message block. Then we set the parameter(s).
537: * Next we change the lock (also called "busy") to "passing" and finally signal
538: * the other processor. Note that we only wait about 1ms to get the message lock.
539: * If we time out, we return failure to our caller. It is their responsibility to
540: * recover.
541: */
542:
543: kern_return_t cpu_signal(int target, int signal) { /* Signal the target CPU */
544:
545: unsigned int holdStat, holdParm0, holdParm1, holdParm2, mtype;
546: struct per_proc_info *tpproc, *mpproc; /* Area for per_proc addresses */
547: int cpu;
548:
549: #if DEBUG
550: if(target > NCPUS) panic("cpu_signal: invalid target CPU - %08X\n", target);
551: #endif
552:
553: cpu = cpu_number(); /* Get our CPU number */
554: if(target == cpu) return KERN_FAILURE; /* Don't play with ourselves */
555: if(!machine_slot[target].running) return KERN_FAILURE; /* These guys are too young */
556:
557: mpproc = &per_proc_info[cpu]; /* Point to our block */
558: tpproc = &per_proc_info[target]; /* Point to the target's block */
559:
560: if(!hw_lock_mbits(&tpproc->MPsigpStat, MPsigpMsgp, 0, MPsigpBusy,
561: (powermac_info.bus_clock_rate_hz >> 7))) { /* Try to lock the message block */
562: return KERN_FAILURE; /* Timed out, take your ball and go home... */
563: }
564:
565: holdStat = MPsigpBusy | MPsigpPass | (MPsigpSigp << 8) | cpu; /* Set up the signal status word */
566: tpproc->MPsigpParm0 = signal; /* Set message order */
567: tpproc->MPsigpParm1 = 0; /* Clear additional parms for yuks */
568: tpproc->MPsigpParm2 = 0; /* Clear additional parms for yuks */
569:
570: __asm__ volatile("sync"); /* Make sure it's all there */
571:
572: tpproc->MPsigpStat = holdStat; /* Set status and pass the lock */
573: __asm__ volatile("eieio"); /* I'm a paraniod freak */
574:
575: PE_cpu_signal(mpproc->cpu_id, tpproc->cpu_id); /* Kick the other processor */
576:
577: return KERN_SUCCESS; /* All is goodness and rainbows... */
578: }
579:
580: /*
581: * TODO
582: */
583: void init_ast_check(processor_t processor)
584: {}
585:
586: void cause_ast_check(processor_t processor)
587: {}
588:
589: void
590: switch_to_shutdown_context(
591: thread_t thread,
592: void (*doshutdown)(processor_t),
593: processor_t processor)
594: {
595: printf("switch_to_shutdown_processor: not implemented\n");
596: }
597:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.