X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/3a60a9f5b85abb8c2cf24e1926c5c7b3f608a5e2..0b4c1975fb5e4eccf1012a35081f7e7799b81046:/osfmk/i386/cpu_data.h diff --git a/osfmk/i386/cpu_data.h b/osfmk/i386/cpu_data.h index 172738bc9..9578cc80b 100644 --- a/osfmk/i386/cpu_data.h +++ b/osfmk/i386/cpu_data.h @@ -1,23 +1,29 @@ /* - * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2008 Apple Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * - * 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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * 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 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * 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. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * @OSF_COPYRIGHT@ @@ -29,50 +35,99 @@ #include -#if defined(__GNUC__) - #include #include +#include #include +#include #include +#include +#include +#include +#include +#include +#if CONFIG_VMX +#include +#endif /* * Data structures referenced (anonymously) from per-cpu data: */ -struct cpu_core; struct cpu_cons_buffer; -struct mp_desc_table; +struct cpu_desc_table; +struct mca_state; /* * Data structures embedded in per-cpu data: */ typedef struct rtclock_timer { - uint64_t deadline; - boolean_t is_set; - boolean_t has_expired; + queue_head_t queue; + uint64_t deadline; + boolean_t is_set; + boolean_t has_expired; } rtclock_timer_t; -typedef struct { - uint64_t rnt_tsc; /* timestamp */ - uint64_t rnt_nanos; /* nanoseconds */ - uint32_t rnt_scale; /* tsc -> nanosec multiplier */ - uint32_t rnt_shift; /* tsc -> nanosec shift/div */ - uint64_t rnt_step_tsc; /* tsc when scale applied */ - uint64_t rnt_step_nanos; /* ns when scale applied */ -} rtc_nanotime_t; + +#if defined(__i386__) typedef struct { struct i386_tss *cdi_ktss; #if MACH_KDB struct i386_tss *cdi_dbtss; #endif /* MACH_KDB */ - struct fake_descriptor *cdi_gdt; - struct fake_descriptor *cdi_idt; - struct fake_descriptor *cdi_ldt; + struct __attribute__((packed)) { + uint16_t size; + struct fake_descriptor *ptr; + } cdi_gdt, cdi_idt; + struct fake_descriptor *cdi_ldt; + vm_offset_t cdi_sstk; } cpu_desc_index_t; +typedef enum { + TASK_MAP_32BIT, /* 32-bit, compatibility mode */ + TASK_MAP_64BIT, /* 64-bit, separate address space */ + TASK_MAP_64BIT_SHARED /* 64-bit, kernel-shared addr space */ +} task_map_t; + +#elif defined(__x86_64__) + + +typedef struct { + struct x86_64_tss *cdi_ktss; +#if MACH_KDB + struct x86_64_tss *cdi_dbtss; +#endif /* MACH_KDB */ + struct __attribute__((packed)) { + uint16_t size; + void *ptr; + } cdi_gdt, cdi_idt; + struct fake_descriptor *cdi_ldt; + vm_offset_t cdi_sstk; +} cpu_desc_index_t; + +typedef enum { + TASK_MAP_32BIT, /* 32-bit user, compatibility mode */ + TASK_MAP_64BIT, /* 64-bit user thread, shared space */ +} task_map_t; + +#else +#error Unsupported architecture +#endif + +/* + * This structure is used on entry into the (uber-)kernel on syscall from + * a 64-bit user. It contains the address of the machine state save area + * for the current thread and a temporary place to save the user's rsp + * before loading this address into rsp. + */ +typedef struct { + addr64_t cu_isf; /* thread->pcb->iss.isf */ + uint64_t cu_tmp; /* temporary scratch */ + addr64_t cu_user_gs_base; +} cpu_uber_t; + /* * Per-cpu data. @@ -91,9 +146,9 @@ typedef struct cpu_data { struct cpu_data *cpu_this; /* pointer to myself */ thread_t cpu_active_thread; - thread_t cpu_active_kloaded; - vm_offset_t cpu_active_stack; - vm_offset_t cpu_kernel_stack; + void *cpu_int_state; /* interrupt state */ + vm_offset_t cpu_active_stack; /* kernel stack base */ + vm_offset_t cpu_kernel_stack; /* kernel stack top */ vm_offset_t cpu_int_stack_top; int cpu_preemption_level; int cpu_simple_lock_count; @@ -108,37 +163,82 @@ typedef struct cpu_data int cpu_subtype; int cpu_threadtype; int cpu_running; - struct cpu_core *cpu_core; /* cpu's parent core */ - uint64_t cpu_rtc_tick_deadline; - uint64_t cpu_rtc_intr_deadline; - rtclock_timer_t cpu_rtc_timer; - rtc_nanotime_t cpu_rtc_nanotime; + rtclock_timer_t rtclock_timer; + boolean_t cpu_is64bit; + task_map_t cpu_task_map; + volatile addr64_t cpu_task_cr3; + volatile addr64_t cpu_active_cr3; + addr64_t cpu_kernel_cr3; + cpu_uber_t cpu_uber; + void *cpu_chud; void *cpu_console_buf; + struct x86_lcpu lcpu; struct processor *cpu_processor; +#if NCOPY_WINDOWS > 0 struct cpu_pmap *cpu_pmap; - struct mp_desc_table *cpu_desc_tablep; +#endif + struct cpu_desc_table *cpu_desc_tablep; + struct fake_descriptor *cpu_ldtp; cpu_desc_index_t cpu_desc_index; - boolean_t cpu_iflag; + int cpu_ldt; #ifdef MACH_KDB /* XXX Untested: */ int cpu_db_pass_thru; vm_offset_t cpu_db_stacks; - struct i386_saved_state *cpu_kdb_saved_state; + void *cpu_kdb_saved_state; spl_t cpu_kdb_saved_ipl; int cpu_kdb_is_slave; int cpu_kdb_active; #endif /* MACH_KDB */ - int cpu_hibernate; + boolean_t cpu_iflag; + boolean_t cpu_boot_complete; + int cpu_hibernate; + +#if NCOPY_WINDOWS > 0 + vm_offset_t cpu_copywindow_base; + uint64_t *cpu_copywindow_pdp; + + vm_offset_t cpu_physwindow_base; + uint64_t *cpu_physwindow_ptep; + void *cpu_hi_iss; +#endif + + + + volatile boolean_t cpu_tlb_invalid; + uint32_t cpu_hwIntCnt[256]; /* Interrupt counts */ + uint64_t cpu_dr7; /* debug control register */ + uint64_t cpu_int_event_time; /* intr entry/exit time */ +#if CONFIG_VMX + vmx_cpu_t cpu_vmx; /* wonderful world of virtualization */ +#endif +#if CONFIG_MCA + struct mca_state *cpu_mca_state; /* State at MC fault */ +#endif + uint64_t cpu_uber_arg_store; /* Double mapped address + * of current thread's + * uu_arg array. + */ + uint64_t cpu_uber_arg_store_valid; /* Double mapped + * address of pcb + * arg store + * validity flag. + */ + rtc_nanotime_t *cpu_nanotime; /* Nanotime info */ + thread_t csw_old_thread; + thread_t csw_new_thread; } cpu_data_t; extern cpu_data_t *cpu_data_ptr[]; extern cpu_data_t cpu_data_master; /* Macro to generate inline bodies to retrieve per-cpu data fields. */ +#ifndef offsetof #define offsetof(TYPE,MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif /* offsetof */ #define CPU_DATA_GET(member,type) \ type ret; \ - __asm__ volatile ("movl %%gs:%P1,%0" \ + __asm__ volatile ("mov %%gs:%P1,%0" \ : "=r" (ret) \ : "i" (offsetof(cpu_data_t,member))); \ return ret; @@ -156,6 +256,17 @@ get_active_thread(void) #define current_thread_fast() get_active_thread() #define current_thread() current_thread_fast() +#if defined(__i386__) +static inline boolean_t +get_is64bit(void) +{ + CPU_DATA_GET(cpu_is64bit, boolean_t) +} +#define cpu_mode_is64bit() get_is64bit() +#elif defined(__x86_64__) +#define cpu_mode_is64bit() TRUE +#endif + static inline int get_preemption_level(void) { @@ -181,11 +292,7 @@ get_cpu_phys_number(void) { CPU_DATA_GET(cpu_phys_number,int) } -static inline struct -cpu_core * get_cpu_core(void) -{ - CPU_DATA_GET(cpu_core,struct cpu_core *) -} + static inline void disable_preemption(void) @@ -247,14 +354,9 @@ current_cpu_datap(void) static inline cpu_data_t * cpu_datap(int cpu) { - assert(cpu_data_ptr[cpu]); return cpu_data_ptr[cpu]; } extern cpu_data_t *cpu_data_alloc(boolean_t is_boot_cpu); -#else /* !defined(__GNUC__) */ - -#endif /* defined(__GNUC__) */ - #endif /* I386_CPU_DATA */