|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /* HISTORY
26:
27: 1997/05/16 Rene Vega -- cleanup sync/isync usage.
28: */
29:
30: #import <machdep/ppc/exception.h>
31: #import <mach/mach_types.h>
32: #import <kern/mach_param.h>
33: #import <kern/thread.h>
34: #import <kern/kernel_stack.h>
35: #import <machdep/ppc/thread.h>
36: #import <bsd/ppc/psl.h>
37: #import <sys/time.h>
38: #import <bsd/ppc/vmparam.h>
39: #import <kernserv/ppc/spl.h>
40: #import <sys/param.h>
41: #import <sys/proc.h>
42: #import <kern/parallel.h>
43: #include <machdep/ppc/proc_reg.h>
44: #include <ppc/trap.h>
1.1.1.2 ! root 45: #if KDEBUG
1.1 root 46: #include <kern/kdebug.h>
47: #include <mach_counters.h>
48: #include <kern/counters.h>
49: #import <machdep/ppc/frame.h>
50: #endif
51: #import <machdep/ppc/asm.h>
52: #import <assym.h>
53:
54: pcb_t active_pcbs[NCPUS]; /* PCB belonging to the active thread */
55:
56: #if DEBUG
57: int fpu_trap_count = 0;
58: int fpu_switch_count = 0;
59: #endif
60:
61: extern struct per_proc_info per_proc_info[];
62:
63: #define current_pcb() active_pcbs[cpu_number()]
64:
65: zone_t pcb_zone;
66:
67: /*
68: * Initialize pcb allocation zone.
69: */
70: void
71: pcb_module_init(void)
72: {
73: int i;
74: pcb_zone = zinit(
75: sizeof (struct pcb),
76: THREAD_MAX * sizeof (struct pcb),
77: THREAD_CHUNK * sizeof (struct pcb),
78: FALSE, "pcb");
79:
80: for (i=0; i < NCPUS; i++) {
81: active_pcbs[i] = 0;
82: }
83: }
84:
85: /*
86: * Allocated and initialize a pcb for a new thread.
87: */
88: void pcb_init(thread_t thread)
89: {
90: struct pcb *pcb = (void *)zalloc(pcb_zone);
91: pmap_t pmap = thread->task->map->pmap;
92:
93:
94: thread->pcb = pcb;
95:
96: /* all fields default to zero */
97: bzero((caddr_t)pcb, sizeof (struct pcb));
98:
99: /*
100: * User threads will pull their context from the pcb when first
101: * returning to user mode, so fill in all the necessary values.
102: * Kernel threads are initialized from the save state structure
103: * at the base of the kernel stack (see stack_attach()).
104: */
105:
106: pcb->ss.srr1 = MSR_EXPORT_MASK_SET;
107:
108: pcb->sr0 = SEG_REG_PROT | (pmap->space<<4);
109: pcb->ss.sr_copyin = SEG_REG_PROT | SR_COPYIN + (pmap->space<<4);
110: }
111:
112: /*
113: * Release machine dependent resources on
114: * thread termination.
115: */
116: pcb_terminate(
117: thread_t thread
118: )
119: {
120: struct pcb *pcb = thread->pcb;
121:
122:
123: if (per_proc_info[cpu_number()].fpu_pcb == pcb)
124: {
125: per_proc_info[cpu_number()].fpu_pcb = (pcb_t)0;
126: }
127:
128: thread->pcb = 0;
129: zfree(pcb_zone, pcb);
130: }
131:
132: #define KF_SIZE (FM_SIZE+ARG_SIZE+FM_REDZONE)
133:
134: /*
135: * stack_attach: Attach a kernel stack to a thread.
136: */
137: void stack_attach(thread, stack, continuation)
138: register thread_t thread;
139: vm_offset_t stack;
140: void (*continuation)();
141: {
142: struct ppc_kernel_state *kss;
143: struct pcb *pcb = thread->pcb;
144:
1.1.1.2 ! root 145: #if KDEBUG
1.1 root 146: if (continuation) {
147: KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_SCHED,MACH_STACK_ATTACH),
148: thread, thread->priority,
149: thread->sched_pri, continuation,
150: 0);
151: }
152: #endif
153: thread->kernel_stack = stack;
154: kss = STACK_IKS(stack);
155:
156: /*
157: * Build a kernel state area + arg frame on the stack for the initial
158: * switch into the thread. We also store a zero into the kernel
159: * stack pointer so the trap code knows there is already a frame
160: * on the kernel stack.
161: */
162:
163: kss->lr = (unsigned int) continuation;
164: kss->r1 = (vm_offset_t) ((int)kss - KF_SIZE);
165:
166: *((int*)kss->r1) = 0; /* Zero the frame backpointer */
167:
168: pcb->ksp = 0;
169: }
170:
171: vm_offset_t
172: stack_detach(
173: thread_t thread
174: )
175: {
176: vm_offset_t stack;
177:
178: stack = thread->kernel_stack;
179: thread->kernel_stack = 0;
180:
181: return (stack);
182: }
183:
184: /*
185: * stack_handoff: Move the current threads kernel stack to the new thread.
186: */
187: void
188: stack_handoff(
189: thread_t old,
190: thread_t new
191: )
192: {
193: vm_offset_t stack = stack_detach(old);
194:
1.1.1.2 ! root 195: #if KDEBUG
1.1 root 196: KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_SCHED,MACH_STACK_HANDOFF),
197: old, new,
198: old->priority, old->sched_pri,
199: new->sched_pri);
1.1.1.2 ! root 200: #endif
1.1 root 201:
202: stack_attach(new, stack, 0);
203:
204: /*
205: * Change software state.
206: */
207: if (new->task != old->task) {
208: int mycpu = cpu_number();
209:
210: PMAP_DEACTIVATE(vm_map_pmap(old->task->map), old, mycpu);
211: PMAP_ACTIVATE(vm_map_pmap(new->task->map), new, mycpu);
212: pmap_switch(new->task->map->pmap);
213: }
214:
215: // current_thread() = new; // can't use this because it may be inlined!
216: cpu_data[cpu_number()].active_thread = new;
217: current_pcb() = new->pcb;
218: cpu_data[cpu_number()].flags = new->pcb->flags;
219:
220: #if NCPUS > 1
221: /* There is no free lunch!
222: * save the floating point state for the old thread
223: * if the fpu has been used since the last context switch
224: */
225: fp_state_save(old);
226:
227: #endif /* NCPUS > 1 */
228:
229: new->pcb->ksp = 0;
230:
231: }
232:
233: void
234: call_continuation(
235: void (*continuation)(void)
236: )
237: {
238: struct ppc_kernel_state *kss;
239: extern Call_continuation();
240: int tkss;
241:
242:
1.1.1.2 ! root 243: #if KDEBUG
1.1 root 244: KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_SCHED,MACH_CALL_CONT),
245: current_thread(), current_thread()->priority,
246: current_thread()->sched_pri, continuation,
247: 0);
1.1.1.2 ! root 248: #endif
1.1 root 249:
250: kss = STACK_IKS(current_thread()->kernel_stack);
251:
252: *((int*)((int)kss - KF_SIZE)) = 0; /* Zero the frame backpointer */
253: tkss = (int)kss - KF_SIZE;
254:
255: Call_continuation(continuation, tkss);
256: }
257:
258:
259: /*
260: * switch_context: Switch from one thread to another.
261: */
262: thread_t
263: switch_context(
264: thread_t old,
265: void (*continuation)(void),
266: thread_t new
267: )
268: {
269: thread_t ret_thread;
270: extern thread_t Switch_context();
1.1.1.2 ! root 271: #if KDEBUG
1.1 root 272: struct linkage_area *frame_ptr;
273: uint i;
274: uint lr[4];
275: #endif
276:
277: if (new->task != old->task) {
278: int mycpu = cpu_number();
279:
280: PMAP_DEACTIVATE(vm_map_pmap(old->task->map), old, mycpu);
281: PMAP_ACTIVATE(vm_map_pmap(new->task->map), new, mycpu);
282:
283: pmap_switch(new->task->map->pmap);
284: }
285:
286: // current_thread() = new; // can't use this because it may be inlined!
287: cpu_data[cpu_number()].active_thread = new;
288: //current_stack() = new->kernel_stack; // assembly does this
289: current_pcb()= new->pcb;
290: cpu_data[cpu_number()].flags = new->pcb->flags;
291:
292: #if NCPUS > 1
293: /* There is no free lunch!
294: * Save the floating point state for the old thread
295: * if the fpu has been used since the last context switch.
296: * Otherwise we need to broadcast an interrupt to the
297: * old fpu to get the state.
298: */
299: fp_state_save(old);
300:
301: #else
302: //disable_fpu();
303: #endif
304:
1.1.1.2 ! root 305: #if KDEBUG
1.1 root 306: KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_SCHED,MACH_SCHED) | DBG_FUNC_END,
307: old, new,
308: old->priority, old->sched_pri,
309: new->sched_pri);
310:
311: frame_ptr = STACK_IKS(new->kernel_stack)->r1;
312: lr[0] = lr[1] = lr[2] = lr[3] = 0;
313: lr[0] = STACK_IKS(new->kernel_stack)->lr;
314: for (i=1;i<4;i++) {
315: if (frame_ptr == NULL) break;
316: lr[i] = frame_ptr->saved_lr;
317: frame_ptr = frame_ptr->saved_sp;
318: }
319: KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_SCHED,MACH_SCHED) | DBG_FUNC_START,
320: new, lr[0], lr[1], lr[2], lr[3]);
321:
322: lr[0] = lr[1] = lr[2] = lr[3] = 0;
323: for (i=0;i<4;i++) {
324: if (frame_ptr == NULL) break;
325: lr[i] = frame_ptr->saved_lr;
326: frame_ptr = frame_ptr->saved_sp;
327: }
328: if (lr[0]) {
329: KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_SCHED,MACH_SCHED),
330: 0, lr[0], lr[1], lr[2], lr[3]);
331: };
332: #endif
333: ret_thread = Switch_context(old, continuation, new);
334:
335: return(ret_thread);
336: }
337:
338: void
339: start_initial_context(
340: thread_t thread
341: )
342: {
343: struct pcb *pcb = thread->pcb;
344:
345: /*
346: * Change software state.
347: */
348:
349: PMAP_ACTIVATE(vm_map_pmap(thread->task->map), thread, 0);
350:
351: // current_thread() = thread; // can't use this because it may be inlined!
352: cpu_data[cpu_number()].active_thread = thread;
353: current_stack() = thread->kernel_stack;
354: current_pcb() = thread->pcb;
355: cpu_data[cpu_number()].flags = thread->pcb->flags;
356:
357: /*
358: * Change hardware state
359: */
360: load_context(thread);
361: /*NOTREACHED*/
362: }
363:
364: /*
365: * Duplicate parent state in child
366: * for U**X fork.
367: */
368: thread_dup(
369: thread_t parent,
370: thread_t child
371: )
372: {
373: struct ppc_saved_state *parent_state, *child_state;
374: struct ppc_float_state *parent_float_state, *child_float_state;
375: struct ppc_exception_state *parent_exception_state,
376: *child_exception_state;
377:
378: /* Save the FPU state */
379: if (per_proc_info[cpu_number()].fpu_pcb == parent->pcb) {
380: fp_state_save(parent);
381: }
382:
383: parent_state = &parent->pcb->ss;
384: child_state = &child->pcb->ss;
385:
386: /* rely on compiler structure assignment */
387: *child_state = *parent_state;
388:
389: parent_float_state = &parent->pcb->fs;
390: child_float_state = &child->pcb->fs;
391:
392: /* rely on compiler structure assignment */
393: *child_float_state = *parent_float_state;
394: #if 0
395: parent_exception_state = &parent->pcb->es;
396: child_exception_state = &child->pcb->es;
397:
398: /* rely on compiler structure assignment */
399: *child_exception_state = *parent_exception_state;
400: #endif
401: child_state->r3 = child->task->proc->p_pid;
402: child_state->r4 = 1;
403:
404: child_state->sr_copyin = child->pcb->sr0 + SR_COPYIN;
405: }
406:
407: /*
408: * Set thread integer state
409: */
410: kern_return_t
411: set_thread_state(
412: thread_t thread,
413: thread_state_t tstate,
414: unsigned int count
415: )
416: {
417: struct ppc_saved_state *saved_state;
418: struct ppc_thread_state *state;
419:
420: if (count < PPC_THREAD_STATE_COUNT)
421: return (KERN_INVALID_ARGUMENT);
422:
423: if (thread->task->kernel_privilege) {
424: /*
425: * State for kernel threads
426: * can only be set before thread
427: * is first started.
428: *
429: * XXX This hack is due to the
430: * fact that the &^%$#@! kernel loader
431: * uses the thread_set_state() call to
432: * start a thread in kernel mode.
433: */
434: if (thread->swap_func != thread_bootstrap_return)
435: return (KERN_INVALID_ARGUMENT);
436: }
437:
438: state = (struct ppc_thread_state *)tstate;
439: saved_state = &thread->pcb->ss;
440:
441: /*
442: * structure assignment - depends on
443: * ppc_thread_state being a prefix of ppc_saved_state !
444: */
445:
446: *((struct ppc_thread_state *)saved_state) = *state;
447:
448: saved_state->sr_copyin = thread->pcb->sr0 + SR_COPYIN;
449:
450: saved_state->srr1 |= MSR_EXPORT_MASK_SET;
451:
452: if (thread->task->kernel_privilege) {
453: saved_state->srr1 &= ~ MASK(MSR_PR);
454: thread_start(thread, state->srr0);
455: }
456:
457: return (KERN_SUCCESS);
458: }
459:
460: /*
461: * Set thread floating point state
462: */
463: kern_return_t
464: set_thread_fpstate(
465: thread_t thread,
466: thread_state_t tstate,
467: unsigned int count
468: )
469: {
470: struct ppc_float_state *state;
471:
472: if (count < PPC_FLOAT_STATE_COUNT)
473: return (KERN_INVALID_ARGUMENT);
474:
475: fpu_save();
476: fpu_disable();
477:
478: state = (struct ppc_float_state *)tstate;
479:
480: /* structure assignment */
481: thread->pcb->fs = *state;
482:
483: return (KERN_SUCCESS);
484: }
485:
486: /*
487: * Set thread exception point state
488: */
489: kern_return_t
490: set_thread_exstate(
491: thread_t thread,
492: thread_state_t tstate,
493: unsigned int count
494: )
495: {
496: struct ppc_exception_state *state;
497:
498: if (count < PPC_EXCEPTION_STATE_COUNT)
499: return (KERN_INVALID_ARGUMENT);
500:
501: state = (struct ppc_exception_state *)tstate;
502:
503: /* structure assignment */
504: thread->pcb->es = *state;
505:
506: return (KERN_SUCCESS);
507: }
508:
509: /*
510: * Set externally visible thread
511: * state.
512: */
513: kern_return_t
514: thread_setstatus(
515: thread_t thread,
516: int flavor,
517: thread_state_t tstate,
518: unsigned int count
519: )
520: {
521: switch (flavor) {
522:
523: case PPC_THREAD_STATE:
524: return (set_thread_state(thread, tstate, count));
525:
526: case PPC_FLOAT_STATE:
527: return (set_thread_fpstate(thread, tstate, count));
528:
529: case PPC_EXCEPTION_STATE:
530: return (set_thread_exstate(thread, tstate, count));
531:
532: default:
533: return (KERN_INVALID_ARGUMENT);
534: }
535: }
536:
537: /*
538: * Get thread state flavor list
539: */
540: kern_return_t
541: get_thread_state_flavor_list(
542: thread_state_t tstate,
543: unsigned int *count
544: )
545: {
546: struct thread_state_flavor *state;
547:
548: if (*count < PPC_THREAD_STATE_FLAVOR_LIST_COUNT)
549: return (KERN_INVALID_ARGUMENT);
550:
551: state = (struct thread_state_flavor *)tstate;
552:
553: state->flavor = PPC_THREAD_STATE;
554: state->count = PPC_THREAD_STATE_COUNT;
555:
556: (++state)->flavor = PPC_FLOAT_STATE;
557: state->count = PPC_FLOAT_STATE_COUNT;
558:
559: (++state)->flavor = PPC_EXCEPTION_STATE;
560: state->count = PPC_EXCEPTION_STATE_COUNT;
561:
562: *count = PPC_THREAD_STATE_FLAVOR_LIST_COUNT;
563:
564: return (KERN_SUCCESS);
565: }
566:
567: /*
568: * Get thread integer state
569: */
570: kern_return_t
571: get_thread_state(
572: thread_t thread,
573: thread_state_t tstate,
574: unsigned int *count
575: )
576: {
577: struct ppc_thread_state *saved_state;
578: struct ppc_thread_state *state;
579:
580: if (*count < PPC_THREAD_STATE_COUNT)
581: return (KERN_INVALID_ARGUMENT);
582:
583: state = (struct ppc_thread_state *)tstate;
584: saved_state = (struct ppc_thread_state *) &thread->pcb->ss;
585:
586: /*
587: * structure assignment - depends on
588: * ppc_thread_state being a prefix of ppc_saved_state !
589: */
590: *state = *((struct ppc_thread_state *)saved_state);
591:
592: *count = PPC_THREAD_STATE_COUNT;
593:
594: return (KERN_SUCCESS);
595: }
596:
597: /*
598: * Get thread floating point state
599: */
600: kern_return_t
601: get_thread_fpstate(
602: thread_t thread,
603: thread_state_t tstate,
604: unsigned int *count
605: )
606: {
607: struct ppc_float_state *state;
608:
609: if (*count < PPC_FLOAT_STATE_COUNT)
610: return (KERN_INVALID_ARGUMENT);
611:
612: fpu_save();
613: fpu_disable();
614:
615: state = (struct ppc_float_state *)tstate;
616:
617: /* structure assignment */
618: *state = thread->pcb->fs;
619:
620: *count = PPC_FLOAT_STATE_COUNT;
621:
622: return (KERN_SUCCESS);
623: }
624:
625: /*
626: * Get thread exception point state
627: */
628: kern_return_t
629: get_thread_exstate(
630: thread_t thread,
631: thread_state_t tstate,
632: unsigned int *count
633: )
634: {
635: struct ppc_exception_state *state;
636:
637: if (*count < PPC_EXCEPTION_STATE_COUNT)
638: return (KERN_INVALID_ARGUMENT);
639:
640: state = (struct ppc_exception_state *)tstate;
641:
642: /* structure assignment */
643: *state = thread->pcb->es;
644:
645: *count = PPC_EXCEPTION_STATE_COUNT;
646:
647: return (KERN_SUCCESS);
648: }
649:
650: /*
651: * Return externally visible
652: * thread status.
653: */
654: kern_return_t
655: thread_getstatus(
656: thread_t thread,
657: int flavor,
658: thread_state_t tstate,
659: unsigned int *count
660: )
661: {
662: switch (flavor) {
663:
664: case THREAD_STATE_FLAVOR_LIST:
665: return (get_thread_state_flavor_list(tstate, count));
666:
667: case PPC_THREAD_STATE:
668: return (get_thread_state(thread, tstate, count));
669:
670: case PPC_FLOAT_STATE:
671: return (get_thread_fpstate(thread, tstate, count));
672:
673: case PPC_EXCEPTION_STATE:
674: return (get_thread_exstate(thread, tstate, count));
675:
676: default:
677: return (KERN_INVALID_ARGUMENT);
678: }
679: }
680:
681: /*
682: * thread_userstack:
683: *
684: * Return the user stack pointer from the machine
685: * dependent thread state info.
686: */
687: kern_return_t
688: thread_userstack(
689: thread_t thread,
690: int flavor,
691: thread_state_t tstate,
692: unsigned int count,
693: vm_offset_t *user_stack
694: )
695: {
696: struct ppc_thread_state *state;
697:
698: /*
699: * Set a default.
700: */
701: if (*user_stack == 0)
702: *user_stack = USRSTACK;
703:
704: switch (flavor) {
705: case PPC_THREAD_STATE:
706: if (count < PPC_THREAD_STATE_COUNT)
707: return (KERN_INVALID_ARGUMENT);
708:
709: state = (struct ppc_thread_state *) tstate;
710:
711: /*
712: * If a valid user stack is specified, use it.
713: */
714: *user_stack = state->r1 ? state->r1: USRSTACK;
715: break;
716: default :
717: return (KERN_INVALID_ARGUMENT);
718: }
719:
720: return (KERN_SUCCESS);
721: }
722:
723: kern_return_t
724: thread_entrypoint(
725: thread_t thread,
726: int flavor,
727: thread_state_t tstate,
728: unsigned int count,
729: vm_offset_t *entry_point
730: )
731: {
732: struct ppc_thread_state *state;
733:
734: /*
735: * Set a default.
736: */
737: if (*entry_point == 0)
738: *entry_point = VM_MIN_ADDRESS;
739:
740: switch (flavor) {
741:
742: case PPC_THREAD_STATE:
743: if (count < PPC_THREAD_STATE_COUNT)
744: return (KERN_INVALID_ARGUMENT);
745:
746: state = (struct ppc_thread_state *) tstate;
747:
748: /*
749: * If a valid entry point is specified, use it.
750: */
751: *entry_point = state->srr0 ? state->srr0: VM_MIN_ADDRESS;
752: break;
753: default:
754: return (KERN_INVALID_ARGUMENT);
755: }
756:
757: return (KERN_SUCCESS);
758: }
759:
760:
761: void __volatile__
762: thread_syscall_return(
763: kern_return_t retval)
764: {
765: thread_t thread = current_thread();
766: struct ppc_saved_state *ssp = &thread->pcb->ss;
767:
768: ssp->r3 = retval;
769:
770: thread_exception_return();
771: /* NOTREACHED */
772: }
773:
774: void
775: thread_set_syscall_return(
776: thread_t thread,
777: kern_return_t retval)
778: {
779: struct ppc_saved_state *ssp = &thread->pcb->ss;
780:
781: ssp->r3 = retval;
782: }
783:
784: void
785: pmap_switch(pmap_t map)
786: {
787: unsigned int i;
788:
789: if (map->space == PPC_SID_KERNEL)
790: return;
791:
792: /* sr value has Ks=1, Ku=1, and vsid composed of space+seg num */
793: i = SEG_REG_PROT | (map->space << 4);
794:
795: isync(); /* context sync before */
796: /* mtsr(0x0, i + 0x0); SR0 is part of the kernel address space */
797: /* mtsr(0x1, i + 0x1); SR1 is part of the kernel address space */
798: /* mtsr(0x2, i + 0x2); SR2 is part of the kernel address space */
799: /* mtsr(0x3, i + 0x3); SR3 is part of the kernel address space */
800: mtsr(0x4, i + 0x4);
801: mtsr(0x5, i + 0x5);
802: mtsr(0x6, i + 0x6);
803: mtsr(0x7, i + 0x7);
804: mtsr(0x8, i + 0x8);
805: mtsr(0x9, i + 0x9);
806: mtsr(0xa, i + 0xa);
807: mtsr(0xb, i + 0xb);
808: mtsr(0xc, i + 0xc);
809: mtsr(0xd, i + 0xd);
810: mtsr(0xe, i + 0xe);
811: mtsr(0xf, i + 0xf);
812: isync(); /* context sync after */
813: }
814:
815: /*
816: * task_map_io_ports() is required by the driverkit routines.
817: */
818: kern_return_t
819: task_map_io_ports(
820: task_t task,
821: unsigned int port,
822: unsigned int length,
823: boolean_t unmap
824: )
825: {
826: return (KERN_SUCCESS);
827: }
828:
829:
830: #if MACH_ASSERT
831: void
832: dump_pcb(pcb_t pcb)
833: {
834: printf("pcb @ %8.8x:\n", pcb);
835: printf("ksp = 0x%08x\n\n",pcb->ksp);
836: #if DEBUG
837: regDump(&pcb->ss);
838: #endif /* DEBUG */
839: }
840:
841: void
842: dump_thread(thread_t th)
843: {
844: printf(" thread @ 0x%x:\n", th);
845: }
846: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.