machdep.c (178471) | machdep.c (181775) |
---|---|
1/*- 2 * Copyright (c) 1992 Terrence R. Lambert. 3 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * William Jolitz. 8 * --- 24 unchanged lines hidden (view full) --- 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 38 */ 39 40#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1992 Terrence R. Lambert. 3 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * William Jolitz. 8 * --- 24 unchanged lines hidden (view full) --- 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 38 */ 39 40#include <sys/cdefs.h> |
41__FBSDID("$FreeBSD: head/sys/i386/i386/machdep.c 178471 2008-04-25 05:18:50Z jeff $"); | 41__FBSDID("$FreeBSD: head/sys/i386/i386/machdep.c 181775 2008-08-15 20:51:31Z kmacy $"); |
42 43#include "opt_apic.h" 44#include "opt_atalk.h" 45#include "opt_compat.h" 46#include "opt_cpu.h" 47#include "opt_ddb.h" 48#include "opt_inet.h" 49#include "opt_ipx.h" --- 86 unchanged lines hidden (view full) --- 136 137#ifdef XBOX 138#include <machine/xbox.h> 139 140int arch_i386_is_xbox = 0; 141uint32_t arch_i386_xbox_memsize = 0; 142#endif 143 | 42 43#include "opt_apic.h" 44#include "opt_atalk.h" 45#include "opt_compat.h" 46#include "opt_cpu.h" 47#include "opt_ddb.h" 48#include "opt_inet.h" 49#include "opt_ipx.h" --- 86 unchanged lines hidden (view full) --- 136 137#ifdef XBOX 138#include <machine/xbox.h> 139 140int arch_i386_is_xbox = 0; 141uint32_t arch_i386_xbox_memsize = 0; 142#endif 143 |
144#ifdef XEN 145/* XEN includes */ 146#include <machine/xen/xen-os.h> 147#include <machine/xen/hypervisor.h> 148#include <machine/xen/xen-os.h> 149#include <machine/xen/xenvar.h> 150#include <machine/xen/xenfunc.h> 151#include <machine/xen/xen_intr.h> 152 153void Xhypervisor_callback(void); 154void failsafe_callback(void); 155 156extern trap_info_t trap_table[]; 157struct proc_ldt default_proc_ldt; 158extern int init_first; 159int running_xen = 1; 160extern unsigned long physfree; 161#endif /* XEN */ 162 |
|
144/* Sanity check for __curthread() */ 145CTASSERT(offsetof(struct pcpu, pc_curthread) == 0); 146 147extern void init386(int first); 148extern void dblfault_handler(void); 149 150extern void printcpuinfo(void); /* XXX header file */ 151extern void finishidentcpu(void); --- 130 unchanged lines hidden (view full) --- 282 ptoa((uintmax_t)cnt.v_free_count), 283 ptoa((uintmax_t)cnt.v_free_count) / 1048576); 284 285 /* 286 * Set up buffers, so they can be used to read disk labels. 287 */ 288 bufinit(); 289 vm_pager_bufferinit(); | 163/* Sanity check for __curthread() */ 164CTASSERT(offsetof(struct pcpu, pc_curthread) == 0); 165 166extern void init386(int first); 167extern void dblfault_handler(void); 168 169extern void printcpuinfo(void); /* XXX header file */ 170extern void finishidentcpu(void); --- 130 unchanged lines hidden (view full) --- 301 ptoa((uintmax_t)cnt.v_free_count), 302 ptoa((uintmax_t)cnt.v_free_count) / 1048576); 303 304 /* 305 * Set up buffers, so they can be used to read disk labels. 306 */ 307 bufinit(); 308 vm_pager_bufferinit(); |
290 | 309#ifndef XEN |
291 cpu_setregs(); | 310 cpu_setregs(); |
311#endif |
|
292} 293 294/* 295 * Send an interrupt to process. 296 * 297 * Stack is set up to allow sigcode stored 298 * at top to call routine, followed by kcall 299 * to sigreturn routine below. After sigreturn --- 813 unchanged lines hidden (view full) --- 1113 * subtract 0.5% of the total. Empirical testing has shown that 1114 * overhead in DELAY() works out to approximately this value. 1115 */ 1116 tsc2 -= tsc1; 1117 *rate = tsc2 * 1000 - tsc2 * 5; 1118 return (0); 1119} 1120 | 312} 313 314/* 315 * Send an interrupt to process. 316 * 317 * Stack is set up to allow sigcode stored 318 * at top to call routine, followed by kcall 319 * to sigreturn routine below. After sigreturn --- 813 unchanged lines hidden (view full) --- 1133 * subtract 0.5% of the total. Empirical testing has shown that 1134 * overhead in DELAY() works out to approximately this value. 1135 */ 1136 tsc2 -= tsc1; 1137 *rate = tsc2 * 1000 - tsc2 * 5; 1138 return (0); 1139} 1140 |
1141 1142void (*cpu_idle_hook)(void) = NULL; /* ACPI idle hook. */ 1143 1144#ifdef XEN 1145 1146void 1147cpu_halt(void) 1148{ 1149 HYPERVISOR_shutdown(SHUTDOWN_poweroff); 1150} 1151 1152static void 1153cpu_idle_hlt(int busy) 1154{ 1155 idle_block(); 1156} 1157 1158#else |
|
1121/* 1122 * Shutdown the CPU as much as possible 1123 */ 1124void 1125cpu_halt(void) 1126{ 1127 for (;;) 1128 __asm__ ("hlt"); 1129} 1130 | 1159/* 1160 * Shutdown the CPU as much as possible 1161 */ 1162void 1163cpu_halt(void) 1164{ 1165 for (;;) 1166 __asm__ ("hlt"); 1167} 1168 |
1131void (*cpu_idle_hook)(void) = NULL; /* ACPI idle hook. */ 1132 | |
1133static void 1134cpu_idle_hlt(int busy) 1135{ 1136 /* 1137 * we must absolutely guarentee that hlt is the next instruction 1138 * after sti or we introduce a timing window. 1139 */ 1140 disable_intr(); 1141 if (sched_runnable()) 1142 enable_intr(); 1143 else 1144 __asm __volatile("sti; hlt"); 1145} | 1169static void 1170cpu_idle_hlt(int busy) 1171{ 1172 /* 1173 * we must absolutely guarentee that hlt is the next instruction 1174 * after sti or we introduce a timing window. 1175 */ 1176 disable_intr(); 1177 if (sched_runnable()) 1178 enable_intr(); 1179 else 1180 __asm __volatile("sti; hlt"); 1181} |
1182#endif |
|
1146 1147static void 1148cpu_idle_acpi(int busy) 1149{ 1150 disable_intr(); 1151 if (sched_runnable()) 1152 enable_intr(); 1153 else if (cpu_idle_hook) --- 278 unchanged lines hidden (view full) --- 1432 * Initialize 386 and configure to run kernel 1433 */ 1434 1435/* 1436 * Initialize segments & interrupt table 1437 */ 1438 1439int _default_ldt; | 1183 1184static void 1185cpu_idle_acpi(int busy) 1186{ 1187 disable_intr(); 1188 if (sched_runnable()) 1189 enable_intr(); 1190 else if (cpu_idle_hook) --- 278 unchanged lines hidden (view full) --- 1469 * Initialize 386 and configure to run kernel 1470 */ 1471 1472/* 1473 * Initialize segments & interrupt table 1474 */ 1475 1476int _default_ldt; |
1477 1478#ifdef XEN 1479union descriptor *gdt; 1480union descriptor *ldt; 1481#else |
|
1440union descriptor gdt[NGDT * MAXCPU]; /* global descriptor table */ | 1482union descriptor gdt[NGDT * MAXCPU]; /* global descriptor table */ |
1483union descriptor ldt[NLDT]; /* local descriptor table */ 1484#endif |
|
1441static struct gate_descriptor idt0[NIDT]; 1442struct gate_descriptor *idt = &idt0[0]; /* interrupt descriptor table */ | 1485static struct gate_descriptor idt0[NIDT]; 1486struct gate_descriptor *idt = &idt0[0]; /* interrupt descriptor table */ |
1443union descriptor ldt[NLDT]; /* local descriptor table */ | |
1444struct region_descriptor r_gdt, r_idt; /* table descriptors */ 1445struct mtx dt_lock; /* lock for GDT and LDT */ 1446 1447#if defined(I586_CPU) && !defined(NO_F00F_HACK) 1448extern int has_f00f_bug; 1449#endif 1450 1451static struct i386tss dblfault_tss; --- 85 unchanged lines hidden (view full) --- 1537{ 0x400, /* segment base address */ 1538 0xfffff, /* length */ 1539 SDT_MEMRWA, /* segment type */ 1540 0, /* segment descriptor priority level */ 1541 1, /* segment descriptor present */ 1542 0, 0, 1543 1, /* default 32 vs 16 bit size */ 1544 1 /* limit granularity (byte/page units)*/ }, | 1487struct region_descriptor r_gdt, r_idt; /* table descriptors */ 1488struct mtx dt_lock; /* lock for GDT and LDT */ 1489 1490#if defined(I586_CPU) && !defined(NO_F00F_HACK) 1491extern int has_f00f_bug; 1492#endif 1493 1494static struct i386tss dblfault_tss; --- 85 unchanged lines hidden (view full) --- 1580{ 0x400, /* segment base address */ 1581 0xfffff, /* length */ 1582 SDT_MEMRWA, /* segment type */ 1583 0, /* segment descriptor priority level */ 1584 1, /* segment descriptor present */ 1585 0, 0, 1586 1, /* default 32 vs 16 bit size */ 1587 1 /* limit granularity (byte/page units)*/ }, |
1588#ifndef XEN |
|
1545/* GPROC0_SEL 9 Proc 0 Tss Descriptor */ 1546{ 1547 0x0, /* segment base address */ 1548 sizeof(struct i386tss)-1,/* length */ 1549 SDT_SYS386TSS, /* segment type */ 1550 0, /* segment descriptor priority level */ 1551 1, /* segment descriptor present */ 1552 0, 0, --- 75 unchanged lines hidden (view full) --- 1628{ 0x0, /* segment base address */ 1629 0x0, /* length */ 1630 0, /* segment type */ 1631 0, /* segment descriptor priority level */ 1632 0, /* segment descriptor present */ 1633 0, 0, 1634 0, /* default 32 vs 16 bit size */ 1635 0 /* limit granularity (byte/page units)*/ }, | 1589/* GPROC0_SEL 9 Proc 0 Tss Descriptor */ 1590{ 1591 0x0, /* segment base address */ 1592 sizeof(struct i386tss)-1,/* length */ 1593 SDT_SYS386TSS, /* segment type */ 1594 0, /* segment descriptor priority level */ 1595 1, /* segment descriptor present */ 1596 0, 0, --- 75 unchanged lines hidden (view full) --- 1672{ 0x0, /* segment base address */ 1673 0x0, /* length */ 1674 0, /* segment type */ 1675 0, /* segment descriptor priority level */ 1676 0, /* segment descriptor present */ 1677 0, 0, 1678 0, /* default 32 vs 16 bit size */ 1679 0 /* limit granularity (byte/page units)*/ }, |
1680#endif /* !XEN */ |
|
1636}; 1637 1638static struct soft_segment_descriptor ldt_segs[] = { 1639 /* Null Descriptor - overwritten by call gate */ 1640{ 0x0, /* segment base address */ 1641 0x0, /* length - all address space */ 1642 0, /* segment type */ 1643 0, /* segment descriptor priority level */ --- 221 unchanged lines hidden (view full) --- 1865 * the framebuffer and inform the OS of this. 1866 */ 1867 physmap[0] = 0; 1868 physmap[1] = (arch_i386_xbox_memsize * 1024 * 1024) - XBOX_FB_SIZE; 1869 physmap_idx = 0; 1870 goto physmap_done; 1871 } 1872#endif | 1681}; 1682 1683static struct soft_segment_descriptor ldt_segs[] = { 1684 /* Null Descriptor - overwritten by call gate */ 1685{ 0x0, /* segment base address */ 1686 0x0, /* length - all address space */ 1687 0, /* segment type */ 1688 0, /* segment descriptor priority level */ --- 221 unchanged lines hidden (view full) --- 1910 * the framebuffer and inform the OS of this. 1911 */ 1912 physmap[0] = 0; 1913 physmap[1] = (arch_i386_xbox_memsize * 1024 * 1024) - XBOX_FB_SIZE; 1914 physmap_idx = 0; 1915 goto physmap_done; 1916 } 1917#endif |
1873 | 1918#if defined(XEN) 1919 has_smap = 0; 1920 Maxmem = xen_start_info->nr_pages - init_first; 1921 physmem = Maxmem; 1922 basemem = 0; 1923 physmap[0] = init_first << PAGE_SHIFT; 1924 physmap[1] = ptoa(Maxmem) - round_page(MSGBUF_SIZE); 1925 physmap_idx = 0; 1926 goto physmap_done; 1927#endif |
1874 hasbrokenint12 = 0; 1875 TUNABLE_INT_FETCH("hw.hasbrokenint12", &hasbrokenint12); 1876 bzero(&vmf, sizeof(vmf)); 1877 bzero(physmap, sizeof(physmap)); 1878 basemem = 0; 1879 1880 /* 1881 * Some newer BIOSes has broken INT 12H implementation which cause --- 145 unchanged lines hidden (view full) --- 2027 vmf.vmf_ax = 0xE801; 2028 if (vm86_intcall(0x15, &vmf) == 0) { 2029 extmem = vmf.vmf_cx + vmf.vmf_dx * 64; 2030 } else { 2031#if 0 2032 vmf.vmf_ah = 0x88; 2033 vm86_intcall(0x15, &vmf); 2034 extmem = vmf.vmf_ax; | 1928 hasbrokenint12 = 0; 1929 TUNABLE_INT_FETCH("hw.hasbrokenint12", &hasbrokenint12); 1930 bzero(&vmf, sizeof(vmf)); 1931 bzero(physmap, sizeof(physmap)); 1932 basemem = 0; 1933 1934 /* 1935 * Some newer BIOSes has broken INT 12H implementation which cause --- 145 unchanged lines hidden (view full) --- 2081 vmf.vmf_ax = 0xE801; 2082 if (vm86_intcall(0x15, &vmf) == 0) { 2083 extmem = vmf.vmf_cx + vmf.vmf_dx * 64; 2084 } else { 2085#if 0 2086 vmf.vmf_ah = 0x88; 2087 vm86_intcall(0x15, &vmf); 2088 extmem = vmf.vmf_ax; |
2035#else | 2089#elif !defined(XEN) |
2036 /* 2037 * Prefer the RTC value for extended memory. 2038 */ 2039 extmem = rtcin(RTC_EXTLO) + (rtcin(RTC_EXTHI) << 8); 2040#endif 2041 } 2042 2043 /* --- 74 unchanged lines hidden (view full) --- 2118 2119 /* 2120 * Get dcons buffer address 2121 */ 2122 if (getenv_quad("dcons.addr", &dcons_addr) == 0 || 2123 getenv_quad("dcons.size", &dcons_size) == 0) 2124 dcons_addr = 0; 2125 | 2090 /* 2091 * Prefer the RTC value for extended memory. 2092 */ 2093 extmem = rtcin(RTC_EXTLO) + (rtcin(RTC_EXTHI) << 8); 2094#endif 2095 } 2096 2097 /* --- 74 unchanged lines hidden (view full) --- 2172 2173 /* 2174 * Get dcons buffer address 2175 */ 2176 if (getenv_quad("dcons.addr", &dcons_addr) == 0 || 2177 getenv_quad("dcons.size", &dcons_size) == 0) 2178 dcons_addr = 0; 2179 |
2180#ifndef XEN |
|
2126 /* 2127 * physmap is in bytes, so when converting to page boundaries, 2128 * round up the start address and round down the end address. 2129 */ 2130 for (i = 0; i <= physmap_idx; i += 2) { 2131 vm_paddr_t end; 2132 2133 end = ptoa((vm_paddr_t)Maxmem); --- 101 unchanged lines hidden (view full) --- 2235 } 2236do_next: 2237 if (full) 2238 break; 2239 } 2240 } 2241 *pte = 0; 2242 invltlb(); | 2181 /* 2182 * physmap is in bytes, so when converting to page boundaries, 2183 * round up the start address and round down the end address. 2184 */ 2185 for (i = 0; i <= physmap_idx; i += 2) { 2186 vm_paddr_t end; 2187 2188 end = ptoa((vm_paddr_t)Maxmem); --- 101 unchanged lines hidden (view full) --- 2290 } 2291do_next: 2292 if (full) 2293 break; 2294 } 2295 } 2296 *pte = 0; 2297 invltlb(); |
2243 | 2298#else 2299 phys_avail[0] = physfree; 2300 phys_avail[1] = xen_start_info->nr_pages*PAGE_SIZE; 2301#endif 2302 |
2244 /* 2245 * XXX 2246 * The last chunk must contain at least one page plus the message 2247 * buffer to avoid complicating other code (message buffer address 2248 * calculation, etc.). 2249 */ 2250 while (phys_avail[pa_indx - 1] + PAGE_SIZE + 2251 round_page(MSGBUF_SIZE) >= phys_avail[pa_indx]) { --- 8 unchanged lines hidden (view full) --- 2260 phys_avail[pa_indx] -= round_page(MSGBUF_SIZE); 2261 2262 /* Map the message buffer. */ 2263 for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE) 2264 pmap_kenter((vm_offset_t)msgbufp + off, phys_avail[pa_indx] + 2265 off); 2266} 2267 | 2303 /* 2304 * XXX 2305 * The last chunk must contain at least one page plus the message 2306 * buffer to avoid complicating other code (message buffer address 2307 * calculation, etc.). 2308 */ 2309 while (phys_avail[pa_indx - 1] + PAGE_SIZE + 2310 round_page(MSGBUF_SIZE) >= phys_avail[pa_indx]) { --- 8 unchanged lines hidden (view full) --- 2319 phys_avail[pa_indx] -= round_page(MSGBUF_SIZE); 2320 2321 /* Map the message buffer. */ 2322 for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE) 2323 pmap_kenter((vm_offset_t)msgbufp + off, phys_avail[pa_indx] + 2324 off); 2325} 2326 |
2327#ifdef XEN 2328#define MTOPSIZE (1<<(14 + PAGE_SHIFT)) 2329 |
|
2268void 2269init386(first) 2270 int first; 2271{ 2272 struct gate_descriptor *gdp; | 2330void 2331init386(first) 2332 int first; 2333{ 2334 struct gate_descriptor *gdp; |
2335 unsigned long gdtmachpfn; 2336 int error, gsel_tss, metadata_missing, x; 2337 struct pcpu *pc; 2338 struct callback_register event = { 2339 .type = CALLBACKTYPE_event, 2340 .address = {GSEL(GCODE_SEL, SEL_KPL), (unsigned long)Xhypervisor_callback }, 2341 }; 2342 struct callback_register failsafe = { 2343 .type = CALLBACKTYPE_failsafe, 2344 .address = {GSEL(GCODE_SEL, SEL_KPL), (unsigned long)failsafe_callback }, 2345 }; 2346 2347 thread0.td_kstack = proc0kstack; 2348 thread0.td_pcb = (struct pcb *) 2349 (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 2350 2351 /* 2352 * This may be done better later if it gets more high level 2353 * components in it. If so just link td->td_proc here. 2354 */ 2355 proc_linkup0(&proc0, &thread0); 2356 2357 metadata_missing = 0; 2358 if (xen_start_info->mod_start) { 2359 preload_metadata = (caddr_t)xen_start_info->mod_start; 2360 preload_bootstrap_relocate(KERNBASE); 2361 } else { 2362 metadata_missing = 1; 2363 } 2364 if (envmode == 1) 2365 kern_envp = static_env; 2366 else if (bootinfo.bi_envp) 2367 kern_envp = (caddr_t)bootinfo.bi_envp + KERNBASE; 2368 2369 /* Init basic tunables, hz etc */ 2370 init_param1(); 2371 2372 /* 2373 * XEN occupies a portion of the upper virtual address space 2374 * At its base it manages an array mapping machine page frames 2375 * to physical page frames - hence we need to be able to 2376 * access 4GB - (64MB - 4MB + 64k) 2377 */ 2378 gdt_segs[GPRIV_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); 2379 gdt_segs[GUFS_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); 2380 gdt_segs[GUGS_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); 2381 gdt_segs[GCODE_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); 2382 gdt_segs[GDATA_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); 2383 gdt_segs[GUCODE_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); 2384 gdt_segs[GUDATA_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); 2385 gdt_segs[GBIOSLOWMEM_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE); 2386 gdt_segs[GCODE_SEL].ssd_limit = atop(0 - 1); 2387 gdt_segs[GDATA_SEL].ssd_limit = atop(0 - 1); 2388 gdt_segs[GUCODE_SEL].ssd_limit = atop(0 - 1); 2389 gdt_segs[GUDATA_SEL].ssd_limit = atop(0 - 1); 2390 gdt_segs[GUFS_SEL].ssd_limit = atop(0 - 1); 2391 gdt_segs[GUGS_SEL].ssd_limit = atop(0 - 1); 2392 2393 pc = &__pcpu[0]; 2394 gdt_segs[GPRIV_SEL].ssd_base = (int) pc; 2395 gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss; 2396 2397 PT_SET_MA(gdt, xpmap_ptom(VTOP(gdt)) | PG_V | PG_RW); 2398 bzero(gdt, PAGE_SIZE); 2399 for (x = 0; x < NGDT; x++) 2400 ssdtosd(&gdt_segs[x], &gdt[x].sd); 2401 2402 mtx_init(&dt_lock, "descriptor tables", NULL, MTX_SPIN); 2403 2404 gdtmachpfn = vtomach(gdt) >> PAGE_SHIFT; 2405 PT_SET_MA(gdt, *vtopte((unsigned long)gdt) & ~(PG_RW|PG_M|PG_A)); 2406 PANIC_IF(HYPERVISOR_set_gdt(&gdtmachpfn, 512) != 0); 2407 lgdt(&r_gdt); 2408 gdtset = 1; 2409 2410 if ((error = HYPERVISOR_set_trap_table(trap_table)) != 0) { 2411 panic("set_trap_table failed - error %d\n", error); 2412 } 2413 2414 error = HYPERVISOR_callback_op(CALLBACKOP_register, &event); 2415 if (error == 0) 2416 error = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe); 2417#if CONFIG_XEN_COMPAT <= 0x030002 2418 if (error == -ENOXENSYS) 2419 HYPERVISOR_set_callbacks(GSEL(GCODE_SEL, SEL_KPL), 2420 (unsigned long)Xhypervisor_callback, 2421 GSEL(GCODE_SEL, SEL_KPL), (unsigned long)failsafe_callback); 2422#endif 2423 pcpu_init(pc, 0, sizeof(struct pcpu)); 2424 PCPU_SET(prvspace, pc); 2425 PCPU_SET(curthread, &thread0); 2426 PCPU_SET(curpcb, thread0.td_pcb); 2427 2428 /* 2429 * Initialize mutexes. 2430 * 2431 * icu_lock: in order to allow an interrupt to occur in a critical 2432 * section, to set pcpu->ipending (etc...) properly, we 2433 * must be able to get the icu lock, so it can't be 2434 * under witness. 2435 */ 2436 mutex_init(); 2437 mtx_init(&icu_lock, "icu", NULL, MTX_SPIN | MTX_NOWITNESS | MTX_NOPROFILE); 2438 2439 /* make ldt memory segments */ 2440 ldt_segs[LUCODE_SEL].ssd_limit = atop(0 - 1); 2441 ldt_segs[LUDATA_SEL].ssd_limit = atop(0 - 1); 2442 for (x = 0; x < sizeof ldt_segs / sizeof ldt_segs[0]; x++) 2443 ssdtosd(&ldt_segs[x], &ldt[x].sd); 2444 2445 default_proc_ldt.ldt_base = (caddr_t)ldt; 2446 default_proc_ldt.ldt_len = 6; 2447 _default_ldt = (int)&default_proc_ldt; 2448 PCPU_SET(currentldt, _default_ldt) 2449 PT_SET_MA(ldt, *vtopte((unsigned long)ldt) & ~PG_RW); 2450 xen_set_ldt((unsigned long) ldt, (sizeof ldt_segs / sizeof ldt_segs[0])); 2451 2452#if defined(XEN_PRIVILEGED) 2453 /* 2454 * Initialize the i8254 before the console so that console 2455 * initialization can use DELAY(). 2456 */ 2457 i8254_init(); 2458#endif 2459 2460 /* 2461 * Initialize the console before we print anything out. 2462 */ 2463 cninit(); 2464 2465 if (metadata_missing) 2466 printf("WARNING: loader(8) metadata is missing!\n"); 2467 2468#ifdef DEV_ISA 2469 elcr_probe(); 2470 atpic_startup(); 2471#endif 2472 2473#ifdef DDB 2474 ksym_start = bootinfo.bi_symtab; 2475 ksym_end = bootinfo.bi_esymtab; 2476#endif 2477 2478 kdb_init(); 2479 2480#ifdef KDB 2481 if (boothowto & RB_KDB) 2482 kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); 2483#endif 2484 2485 finishidentcpu(); /* Final stage of CPU initialization */ 2486 setidt(IDT_UD, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, 2487 GSEL(GCODE_SEL, SEL_KPL)); 2488 setidt(IDT_GP, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, 2489 GSEL(GCODE_SEL, SEL_KPL)); 2490 initializecpu(); /* Initialize CPU registers */ 2491 2492 /* make an initial tss so cpu can get interrupt stack on syscall! */ 2493 /* Note: -16 is so we can grow the trapframe if we came from vm86 */ 2494 PCPU_SET(common_tss.tss_esp0, thread0.td_kstack + 2495 KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb) - 16); 2496 PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL)); 2497 gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); 2498 PCPU_SET(tss_gdt, &gdt[GPROC0_SEL].sd); 2499 PCPU_SET(common_tssd, *PCPU_GET(tss_gdt)); 2500 PCPU_SET(common_tss.tss_ioopt, (sizeof (struct i386tss)) << 16); 2501 ltr(gsel_tss); 2502 2503 /* pointer to selector slot for %fs/%gs */ 2504 PCPU_SET(fsgs_gdt, &gdt[GUFS_SEL].sd); 2505 2506 dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = 2507 dblfault_tss.tss_esp2 = (int)&dblfault_stack[sizeof(dblfault_stack)]; 2508 dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 = 2509 dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL); 2510#ifdef PAE 2511 dblfault_tss.tss_cr3 = (int)IdlePDPT; 2512#else 2513 dblfault_tss.tss_cr3 = (int)IdlePTD; 2514#endif 2515 dblfault_tss.tss_eip = (int)dblfault_handler; 2516 dblfault_tss.tss_eflags = PSL_KERNEL; 2517 dblfault_tss.tss_ds = dblfault_tss.tss_es = 2518 dblfault_tss.tss_gs = GSEL(GDATA_SEL, SEL_KPL); 2519 dblfault_tss.tss_fs = GSEL(GPRIV_SEL, SEL_KPL); 2520 dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL); 2521 dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL); 2522 2523 vm86_initialize(); 2524 getmemsize(first); 2525 init_param2(physmem); 2526 2527 /* now running on new page tables, configured,and u/iom is accessible */ 2528 2529 msgbufinit(msgbufp, MSGBUF_SIZE); 2530 2531 /* make a call gate to reenter kernel with */ 2532 gdp = &ldt[LSYS5CALLS_SEL].gd; 2533 2534 x = (int) &IDTVEC(lcall_syscall); 2535 gdp->gd_looffset = x; 2536 gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL); 2537 gdp->gd_stkcpy = 1; 2538 gdp->gd_type = SDT_SYS386CGT; 2539 gdp->gd_dpl = SEL_UPL; 2540 gdp->gd_p = 1; 2541 gdp->gd_hioffset = x >> 16; 2542 2543 /* XXX does this work? */ 2544 /* XXX yes! */ 2545 ldt[LBSDICALLS_SEL] = ldt[LSYS5CALLS_SEL]; 2546 ldt[LSOL26CALLS_SEL] = ldt[LSYS5CALLS_SEL]; 2547 2548 /* transfer to user mode */ 2549 2550 _ucodesel = GSEL(GUCODE_SEL, SEL_UPL); 2551 _udatasel = GSEL(GUDATA_SEL, SEL_UPL); 2552 2553 /* setup proc 0's pcb */ 2554 thread0.td_pcb->pcb_flags = 0; 2555#ifdef PAE 2556 thread0.td_pcb->pcb_cr3 = (int)IdlePDPT; 2557#else 2558 thread0.td_pcb->pcb_cr3 = (int)IdlePTD; 2559#endif 2560 thread0.td_pcb->pcb_ext = 0; 2561 thread0.td_frame = &proc0_tf; 2562 thread0.td_pcb->pcb_fsd = PCPU_GET(fsgs_gdt)[0]; 2563 thread0.td_pcb->pcb_gsd = PCPU_GET(fsgs_gdt)[1]; 2564} 2565 2566#else 2567void 2568init386(first) 2569 int first; 2570{ 2571 struct gate_descriptor *gdp; |
|
2273 int gsel_tss, metadata_missing, x; 2274 struct pcpu *pc; 2275 2276 thread0.td_kstack = proc0kstack; 2277 thread0.td_pcb = (struct pcb *) 2278 (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 2279 2280 /* --- 241 unchanged lines hidden (view full) --- 2522#ifdef PAE 2523 thread0.td_pcb->pcb_cr3 = (int)IdlePDPT; 2524#else 2525 thread0.td_pcb->pcb_cr3 = (int)IdlePTD; 2526#endif 2527 thread0.td_pcb->pcb_ext = 0; 2528 thread0.td_frame = &proc0_tf; 2529} | 2572 int gsel_tss, metadata_missing, x; 2573 struct pcpu *pc; 2574 2575 thread0.td_kstack = proc0kstack; 2576 thread0.td_pcb = (struct pcb *) 2577 (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 2578 2579 /* --- 241 unchanged lines hidden (view full) --- 2821#ifdef PAE 2822 thread0.td_pcb->pcb_cr3 = (int)IdlePDPT; 2823#else 2824 thread0.td_pcb->pcb_cr3 = (int)IdlePTD; 2825#endif 2826 thread0.td_pcb->pcb_ext = 0; 2827 thread0.td_frame = &proc0_tf; 2828} |
2829#endif |
|
2530 2531void 2532cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) 2533{ 2534 2535 pcpu->pc_acpi_id = 0xffffffff; 2536} 2537 --- 746 unchanged lines hidden --- | 2830 2831void 2832cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) 2833{ 2834 2835 pcpu->pc_acpi_id = 0xffffffff; 2836} 2837 --- 746 unchanged lines hidden --- |