X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d7e50217d7adf6e52786a38bcaa4cd698cb9a79e..e5568f75972dfc723778653c11cb6b4dc825716a:/osfmk/i386/locore.s diff --git a/osfmk/i386/locore.s b/osfmk/i386/locore.s index f0a0a08d8..596c8e8bd 100644 --- a/osfmk/i386/locore.s +++ b/osfmk/i386/locore.s @@ -3,22 +3,19 @@ * * @APPLE_LICENSE_HEADER_START@ * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -71,7 +68,7 @@ #include #include -#include +#include #define PREEMPT_DEBUG_LOG 0 @@ -651,12 +648,17 @@ Entry(t_debug) testl $3,4(%esp) /* is trap from kernel mode? */ jnz 0f /* if so: */ cmpl $syscall_entry,(%esp) /* system call entry? */ - jne 0f /* if so: */ + jne 1f /* if so: */ /* flags are sitting where syscall */ /* wants them */ addl $8,%esp /* remove eip/cs */ jmp syscall_entry_2 /* continue system call entry */ +1: cmpl $trap_unix_addr,(%esp) + jne 0f + addl $8,%esp + jmp trap_unix_2 + 0: pushl $0 /* otherwise: */ pushl $(T_DEBUG) /* handle as normal */ jmp EXT(alltraps) /* debug fault */ @@ -774,9 +776,6 @@ LEXT(return_to_user) jnz EXT(return_xfer_stack) movl $ CPD_ACTIVE_THREAD,%ebx movl %gs:(%ebx),%ebx /* get active thread */ - movl TH_TOP_ACT(%ebx),%ebx /* get thread->top_act */ - cmpl $0,ACT_KLOADING(%ebx) /* check if kernel-loading */ - jnz EXT(return_kernel_loading) #if MACH_RT #if MACH_ASSERT @@ -842,13 +841,10 @@ LEXT(return_kernel_loading) movl CX(EXT(kernel_stack),%eax),%esp movl $ CPD_ACTIVE_THREAD,%ebx movl %gs:(%ebx),%ebx /* get active thread */ - movl TH_TOP_ACT(%ebx),%ebx /* get thread->top_act */ movl %ebx,%edx /* save for later */ - movl $0,ACT_KLOADING(%edx) /* clear kernel-loading bit */ FRAME_PCB_TO_STACK(%ebx) movl %ebx,%esp /* start running on new stack */ - movl $1,ACT_KLOADED(%edx) /* set kernel-loaded bit */ - movl %edx,CX(EXT(active_kloaded),%eax) /* set cached indicator */ + movl $0,CX(EXT(active_kloaded),%eax) /* set cached indicator */ jmp EXT(return_from_kernel) /* @@ -1055,11 +1051,13 @@ Entry(call_continuation) #define CHECK_INTERRUPT_TIME(n) #endif +.data imsg_start: String "interrupt start" imsg_end: String "interrupt end" +.text /* * All interrupts enter here. * old %eax on stack; interrupt number in %eax. @@ -1074,6 +1072,8 @@ Entry(all_intrs) pushl %ds /* save segment registers */ pushl %es + pushl %fs + pushl %gs mov %ss,%dx /* switch to kernel segments */ mov %dx,%ds mov %dx,%es @@ -1083,7 +1083,7 @@ Entry(all_intrs) CPU_NUMBER(%edx) movl CX(EXT(int_stack_top),%edx),%ecx - movl 20(%esp),%edx /* get eip */ + movl %esp,%edx /* & i386_interrupt_state */ xchgl %ecx,%esp /* switch to interrupt stack */ #if STAT_TIME @@ -1095,7 +1095,7 @@ Entry(all_intrs) TIME_INT_ENTRY /* do timing */ #endif - pushl %edx /* pass eip to pe_incoming_interrupt */ + pushl %edx /* pass &i386_interrupt_state to pe_incoming_interrupt */ #if MACH_RT movl $ CPD_PREEMPTION_LEVEL,%edx @@ -1182,6 +1182,8 @@ LEXT(return_to_iret) /* (label for kdb_kintr and hardclock) */ #endif /* MACH_RT */ 1: + pop %gs + pop %fs pop %es /* restore segment regs */ pop %ds pop %edx @@ -1198,13 +1200,14 @@ int_from_intstack: movl $ CPD_INTERRUPT_LEVEL,%edx incl %gs:(%edx) - movl 12(%esp),%edx - pushl %edx /* push eip */ + subl $16, %esp /* dummy ds, es, fs, gs */ + movl %esp, %edx /* &i386_interrupt_state */ + pushl %edx /* pass &i386_interrupt_state to PE_incoming_interrupt /* pushl %eax /* Push trap number */ call EXT(PE_incoming_interrupt) - addl $4,%esp /* pop eip */ + addl $20,%esp /* pop i386_interrupt_state, dummy gs,fs,es,ds */ LEXT(return_to_iret_i) /* ( label for kdb_kintr) */ @@ -1238,6 +1241,8 @@ LEXT(return_to_iret_i) /* ( label for kdb_kintr) */ * ss */ ast_from_interrupt: + pop %gs + pop %fs pop %es /* restore all registers ... */ pop %ds popl %edx @@ -1561,9 +1566,22 @@ Entry(mach_rpc) * ebx contains user regs pointer */ 2: + + pushl %ebx /* arg ptr */ + pushl %eax /* call # - preserved across */ + call EXT(mach_call_start) + addl $ 8, %esp + movl %eax, %ebx /* need later */ + CAH(call_call) call *EXT(mach_trap_table)+4(%eax) /* call procedure */ + + pushl %eax /* retval */ + pushl %ebx /* call # */ + call EXT(mach_call_end) + addl $ 8, %esp + movl %esp,%ecx /* get kernel stack */ or $(KERNEL_STACK_SIZE-1),%ecx movl -3-IKS_SIZE(%ecx),%esp /* switch back to PCB stack */ @@ -1687,8 +1705,6 @@ syscall_entry_3: 1: movl $ CPD_ACTIVE_THREAD,%edx movl %gs:(%edx),%edx /* get active thread */ - /* point to current thread */ - movl TH_TOP_ACT(%edx),%edx /* get thread->top_act */ movl ACT_TASK(%edx),%edx /* point to task */ movl TASK_EMUL(%edx),%edx /* get emulation vector */ orl %edx,%edx /* if none, */ @@ -1725,8 +1741,6 @@ syscall_native: movl $ CPD_ACTIVE_THREAD,%edx movl %gs:(%edx),%edx /* get active thread */ - /* point to current thread */ - movl TH_TOP_ACT(%edx),%edx /* get thread->top_act */ movl ACT_TASK(%edx),%edx /* point to task */ movl TASK_EMUL(%edx),%edx /* get emulation vector */ orl %edx,%edx /* if it exists, */ @@ -1794,7 +1808,20 @@ mach_call_call: #endif /* ETAP_EVENT_MONITOR */ make_syscall: + + pushl %ebx /* arg ptr */ + pushl %eax /* call # - preserved across */ + call EXT(mach_call_start) + addl $ 8, %esp + movl %eax, %ebx /* need later */ + call *EXT(mach_trap_table)+4(%eax) /* call procedure */ + + pushl %eax /* retval */ + pushl %ebx /* call # */ + call EXT(mach_call_end) + addl $ 8, %esp + skip_syscall: movl %esp,%ecx /* get kernel stack */ @@ -1829,8 +1856,6 @@ mach_call_addr: mach_call_range: movl $ CPD_ACTIVE_THREAD,%edx movl %gs:(%edx),%edx /* get active thread */ - - movl TH_TOP_ACT(%edx),%edx /* get thread->top_act */ movl ACT_TASK(%edx),%edx /* point to task */ movl TASK_EMUL(%edx),%edx /* get emulation vector */ orl %edx,%edx /* if emulator, */ @@ -1946,7 +1971,6 @@ ENTRY(copyin) movl $ CPD_ACTIVE_THREAD,%ecx movl %gs:(%ecx),%ecx /* get active thread */ - movl TH_TOP_ACT(%ecx),%ecx /* get thread->top_act */ movl ACT_MAP(%ecx),%ecx /* get act->map */ movl MAP_PMAP(%ecx),%ecx /* get map->pmap */ cmpl EXT(kernel_pmap), %ecx @@ -2001,7 +2025,6 @@ Entry(copyinstr) movl $ CPD_ACTIVE_THREAD,%ecx movl %gs:(%ecx),%ecx /* get active thread */ - movl TH_TOP_ACT(%ecx),%ecx /* get thread->top_act */ movl ACT_MAP(%ecx),%ecx /* get act->map */ movl MAP_PMAP(%ecx),%ecx /* get map->pmap */ cmpl EXT(kernel_pmap), %ecx @@ -2029,11 +2052,10 @@ Entry(copyinstr) je 5f /* Zero count.. error out */ cmpl $0,%eax jne 2b /* .. a NUL found? */ - jmp 4f + jmp 4f /* return zero (%eax) */ 5: movl $ ENAMETOOLONG,%eax /* String is too long.. */ 4: - xorl %eax,%eax /* return zero for success */ movl 8+S_ARG3,%edi /* get OUT len ptr */ cmpl $0,%edi jz copystr_ret /* if null, just return */ @@ -2068,7 +2090,6 @@ ENTRY(copyout) movl $ CPD_ACTIVE_THREAD,%ecx movl %gs:(%ecx),%ecx /* get active thread */ - movl TH_TOP_ACT(%ecx),%ecx /* get thread->top_act */ movl ACT_MAP(%ecx),%ecx /* get act->map */ movl MAP_PMAP(%ecx),%ecx /* get map->pmap */ cmpl EXT(kernel_pmap), %ecx @@ -2102,41 +2123,6 @@ copyout_retry: subl %edi,%edx / movl %edi,%ebx /* ebx = edi; */ - mov %es,%cx - cmpl $ USER_DS,%cx /* If kernel data segment */ - jnz 0f /* skip check */ - - cmpb $(CPUID_FAMILY_386), EXT(cpuid_family) - ja 0f - - movl %cr3,%ecx /* point to page directory */ -#if NCPUS > 1 - andl $(~0x7), %ecx /* remove cpu number */ -#endif /* NCPUS > 1 && AT386 */ - movl %edi,%eax /* get page directory bits */ - shrl $(PDESHIFT),%eax /* from user address */ - movl KERNELBASE(%ecx,%eax,4),%ecx - /* get page directory pointer */ - testl $(PTE_V),%ecx /* present? */ - jz 0f /* if not, fault is OK */ - andl $(PTE_PFN),%ecx /* isolate page frame address */ - movl %edi,%eax /* get page table bits */ - shrl $(PTESHIFT),%eax - andl $(PTEMASK),%eax /* from user address */ - leal KERNELBASE(%ecx,%eax,4),%ecx - /* point to page table entry */ - movl (%ecx),%eax /* get it */ - testl $(PTE_V),%eax /* present? */ - jz 0f /* if not, fault is OK */ - testl $(PTE_W),%eax /* writable? */ - jnz 0f /* OK if so */ -/* - * Not writable - must fake a fault. Turn off access to the page. - */ - andl $(PTE_INVALID),(%ecx) /* turn off valid bit */ - movl %cr3,%eax /* invalidate TLB */ - movl %eax,%cr3 -0: /* * Copy only what fits on the current destination page. * Check for write-fault again on the next page. @@ -2909,25 +2895,6 @@ ENTRY(jail) #endif /* NCPUS > 1 */ -/* - * delay(microseconds) - */ - -ENTRY(delay) - movl 4(%esp),%eax - testl %eax, %eax - jle 3f - movl EXT(delaycount), %ecx -1: - movl %ecx, %edx -2: - decl %edx - jne 2b - decl %eax - jne 1b -3: - ret - /* * unsigned int * div_scale(unsigned int dividend, @@ -3001,19 +2968,15 @@ ENTRY(mul_scale) POP_FRAME ret -#if NCPUS > 1 -ENTRY(_cpu_number) - CPU_NUMBER(%eax) - ret -#endif /* NCPUS > 1 */ - #ifdef MACH_BSD /* * BSD System call entry point.. */ Entry(trap_unix_syscall) +trap_unix_addr: pushf /* save flags as soon as possible */ +trap_unix_2: pushl %eax /* save system call number */ pushl $0 /* clear trap number slot */