|
|
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: * @OSF_COPYRIGHT@ ! 24: */ ! 25: /* ! 26: * Mach Operating System ! 27: * Copyright (c) 1991,1990 Carnegie Mellon University ! 28: * All Rights Reserved. ! 29: * ! 30: * Permission to use, copy, modify and distribute this software and its ! 31: * documentation is hereby granted, provided that both the copyright ! 32: * notice and this permission notice appear in all copies of the ! 33: * software, derivative works or modified versions, and any portions ! 34: * thereof, and that both notices appear in supporting documentation. ! 35: * ! 36: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 37: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 38: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 39: * ! 40: * Carnegie Mellon requests users of this software to return to ! 41: * ! 42: * Software Distribution Coordinator or [email protected] ! 43: * School of Computer Science ! 44: * Carnegie Mellon University ! 45: * Pittsburgh PA 15213-3890 ! 46: * ! 47: * any improvements or extensions that they make and grant Carnegie Mellon ! 48: * the rights to redistribute these changes. ! 49: */ ! 50: /* ! 51: */ ! 52: ! 53: #include <cpus.h> ! 54: #include <platforms.h> ! 55: ! 56: #include <i386/asm.h> ! 57: #include <i386/proc_reg.h> ! 58: #include <assym.s> ! 59: ! 60: #if NCPUS > 1 ! 61: ! 62: #ifdef SYMMETRY ! 63: #include <sqt/asm_macros.h> ! 64: #endif ! 65: ! 66: #if AT386 ! 67: #include <i386/AT386/mp/mp.h> ! 68: #endif /* AT386 */ ! 69: ! 70: #define CX(addr, reg) addr(,reg,4) ! 71: ! 72: #else /* NCPUS == 1 */ ! 73: ! 74: #define CPU_NUMBER(reg) ! 75: #define CX(addr,reg) addr ! 76: ! 77: #endif /* NCPUS == 1 */ ! 78: ! 79: /* ! 80: * Context switch routines for i386. ! 81: */ ! 82: ! 83: Entry(Load_context) ! 84: movl S_ARG0,%ecx /* get thread */ ! 85: movl TH_KERNEL_STACK(%ecx),%ecx /* get kernel stack */ ! 86: lea KERNEL_STACK_SIZE-IKS_SIZE-IEL_SIZE(%ecx),%edx ! 87: /* point to stack top */ ! 88: CPU_NUMBER(%eax) ! 89: movl %ecx,CX(EXT(active_stacks),%eax) /* store stack address */ ! 90: movl %edx,CX(EXT(kernel_stack),%eax) /* store stack top */ ! 91: ! 92: movl KSS_ESP(%ecx),%esp /* switch stacks */ ! 93: movl KSS_ESI(%ecx),%esi /* restore registers */ ! 94: movl KSS_EDI(%ecx),%edi ! 95: movl KSS_EBP(%ecx),%ebp ! 96: movl KSS_EBX(%ecx),%ebx ! 97: xorl %eax,%eax /* return zero (no old thread) */ ! 98: jmp *KSS_EIP(%ecx) /* resume thread */ ! 99: ! 100: /* ! 101: * This really only has to save registers ! 102: * when there is no explicit continuation. ! 103: */ ! 104: ! 105: Entry(Switch_context) ! 106: CPU_NUMBER(%edx) ! 107: movl CX(EXT(active_stacks),%edx),%ecx /* get old kernel stack */ ! 108: ! 109: movl %ebx,KSS_EBX(%ecx) /* save registers */ ! 110: movl %ebp,KSS_EBP(%ecx) ! 111: movl %edi,KSS_EDI(%ecx) ! 112: movl %esi,KSS_ESI(%ecx) ! 113: popl KSS_EIP(%ecx) /* save return PC */ ! 114: movl %esp,KSS_ESP(%ecx) /* save SP */ ! 115: ! 116: movl 0(%esp),%eax /* get old thread */ ! 117: movl 4(%esp),%ebx /* get continuation */ ! 118: movl %ebx,TH_CONTINUATION(%eax) /* save continuation */ ! 119: movl %ecx,TH_KERNEL_STACK(%eax) /* save kernel stack */ ! 120: ! 121: movl 8(%esp),%esi /* get new thread */ ! 122: movl $CPD_ACTIVE_THREAD,%ecx ! 123: movl %esi,%gs:(%ecx) /* new thread is active */ ! 124: movl TH_KERNEL_STACK(%esi),%ecx /* get its kernel stack */ ! 125: lea KERNEL_STACK_SIZE-IKS_SIZE-IEL_SIZE(%ecx),%ebx ! 126: /* point to stack top */ ! 127: ! 128: movl %ecx,CX(EXT(active_stacks),%edx) /* set current stack */ ! 129: movl %ebx,CX(EXT(kernel_stack),%edx) /* set stack top */ ! 130: ! 131: movl TH_TOP_ACT(%esi),%esi /* get new_thread->top_act */ ! 132: cmpl $0,ACT_KLOADED(%esi) /* check kernel-loaded flag */ ! 133: je 0f ! 134: movl %esi,CX(EXT(active_kloaded),%edx) ! 135: jmp 1f ! 136: 0: ! 137: movl $0,CX(EXT(active_kloaded),%edx) ! 138: 1: ! 139: movl KSS_ESP(%ecx),%esp /* switch stacks */ ! 140: movl KSS_ESI(%ecx),%esi /* restore registers */ ! 141: movl KSS_EDI(%ecx),%edi ! 142: movl KSS_EBP(%ecx),%ebp ! 143: movl KSS_EBX(%ecx),%ebx ! 144: jmp *KSS_EIP(%ecx) /* return old thread */ ! 145: ! 146: Entry(Thread_continue) ! 147: pushl %eax /* push the thread argument */ ! 148: xorl %ebp,%ebp /* zero frame pointer */ ! 149: call *%ebx /* call real continuation */ ! 150: ! 151: #if NCPUS > 1 ! 152: /* ! 153: * void switch_to_shutdown_context(thread_t thread, ! 154: * void (*routine)(processor_t), ! 155: * processor_t processor) ! 156: * ! 157: * saves the kernel context of the thread, ! 158: * switches to the interrupt stack, ! 159: * continues the thread (with thread_continue), ! 160: * then runs routine on the interrupt stack. ! 161: * ! 162: * Assumes that the thread is a kernel thread (thus ! 163: * has no FPU state) ! 164: */ ! 165: Entry(switch_to_shutdown_context) ! 166: CPU_NUMBER(%edx) ! 167: movl EXT(active_stacks)(,%edx,4),%ecx /* get old kernel stack */ ! 168: movl %ebx,KSS_EBX(%ecx) /* save registers */ ! 169: movl %ebp,KSS_EBP(%ecx) ! 170: movl %edi,KSS_EDI(%ecx) ! 171: movl %esi,KSS_ESI(%ecx) ! 172: popl KSS_EIP(%ecx) /* save return PC */ ! 173: movl %esp,KSS_ESP(%ecx) /* save SP */ ! 174: ! 175: movl 0(%esp),%eax /* get old thread */ ! 176: movl $0,TH_CONTINUATION(%eax) /* clear continuation */ ! 177: movl %ecx,TH_KERNEL_STACK(%eax) /* save old stack */ ! 178: movl 4(%esp),%ebx /* get routine to run next */ ! 179: movl 8(%esp),%esi /* get its argument */ ! 180: ! 181: movl CX(EXT(interrupt_stack),%edx),%ecx /* point to its intr stack */ ! 182: lea INTSTACK_SIZE(%ecx),%esp /* switch to it (top) */ ! 183: ! 184: pushl %eax /* push thread */ ! 185: call EXT(thread_dispatch) /* reschedule thread */ ! 186: addl $4,%esp /* clean stack */ ! 187: ! 188: pushl %esi /* push argument */ ! 189: call *%ebx /* call routine to run */ ! 190: hlt /* (should never return) */ ! 191: ! 192: #endif /* NCPUS > 1 */ ! 193: ! 194: .text ! 195: ! 196: .globl EXT(locore_end) ! 197: LEXT(locore_end) ! 198:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.