1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * Copyright (c) 1992 Terrence R. Lambert. 10 * Copyright (c) 1990 The Regents of the University of California. 11 * All rights reserved. 12 * 13 * This code is derived from software contributed to Berkeley by 14 * William Jolitz. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution. 24 * 3. All advertising materials mentioning features or use of this software 25 * must display the following acknowledgement: 26 * This product includes software developed by the University of 27 * California, Berkeley and its contributors. 28 * 4. Neither the name of the University nor the names of its contributors 29 * may be used to endorse or promote products derived from this software 30 * without specific prior written permission. 31 * 32 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 42 * SUCH DAMAGE. 43 * 44 * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 45 */ 46 47 #include <sys/types.h> 48 #include <sys/tss.h> 49 #include <sys/segments.h> 50 #include <sys/trap.h> 51 #include <sys/cpuvar.h> 52 #include <sys/x86_archext.h> 53 #include <sys/archsystm.h> 54 #include <sys/machsystm.h> 55 #include <sys/kobj.h> 56 #include <sys/cmn_err.h> 57 #include <sys/reboot.h> 58 #include <sys/kdi.h> 59 60 extern void syscall_int(void); 61 62 /* 63 * cpu0 and default tables and structures. 64 */ 65 #pragma align 16(gdt0) 66 user_desc_t gdt0[NGDT]; /* global descriptor table */ 67 desctbr_t gdt0_default_r; 68 69 #pragma align 16(ldt0_default) 70 user_desc_t ldt0_default[MINNLDT]; /* default local descriptor table */ 71 system_desc_t ldt0_default_desc; /* seg descriptor for ldt0_default */ 72 73 #if defined(__amd64) 74 #pragma align 16(ltd0_default64) 75 user_desc_t ldt0_default64[MINNLDT]; /* default LDT for 64-bit apps */ 76 system_desc_t ldt0_default64_desc; /* seg descriptor for ldt0_default64 */ 77 #endif /* __amd64 */ 78 79 #pragma align 16(idt0) 80 gate_desc_t idt0[NIDT]; /* interrupt descriptor table */ 81 desctbr_t idt0_default_r; /* describes idt0 in IDTR format */ 82 83 #pragma align 16(ktss0) 84 struct tss ktss0; /* kernel task state structure */ 85 86 #if defined(__i386) 87 #pragma align 16(dftss0) 88 struct tss dftss0; /* #DF double-fault exception */ 89 #endif /* __i386 */ 90 91 user_desc_t zero_udesc; /* base zero user desc native procs */ 92 93 #if defined(__amd64) 94 user_desc_t zero_u32desc; /* 32-bit compatibility procs */ 95 #endif /* __amd64 */ 96 97 #pragma align 16(dblfault_stack0) 98 char dblfault_stack0[DEFAULTSTKSZ]; 99 100 extern void fast_null(void); 101 extern hrtime_t get_hrtime(void); 102 extern hrtime_t gethrvtime(void); 103 extern hrtime_t get_hrestime(void); 104 extern uint64_t getlgrp(void); 105 106 void (*(fasttable[]))(void) = { 107 fast_null, /* T_FNULL routine */ 108 fast_null, /* T_FGETFP routine (initially null) */ 109 fast_null, /* T_FSETFP routine (initially null) */ 110 (void (*)())get_hrtime, /* T_GETHRTIME */ 111 (void (*)())gethrvtime, /* T_GETHRVTIME */ 112 (void (*)())get_hrestime, /* T_GETHRESTIME */ 113 (void (*)())getlgrp /* T_GETLGRP */ 114 }; 115 116 /* 117 * software prototypes for default local descriptor table 118 */ 119 120 /* 121 * Routines for loading segment descriptors in format the hardware 122 * can understand. 123 */ 124 125 #if defined(__amd64) 126 127 /* 128 * In long mode we have the new L or long mode attribute bit 129 * for code segments. Only the conforming bit in type is used along 130 * with descriptor priority and present bits. Default operand size must 131 * be zero when in long mode. In 32-bit compatibility mode all fields 132 * are treated as in legacy mode. For data segments while in long mode 133 * only the present bit is loaded. 134 */ 135 void 136 set_usegd(user_desc_t *dp, uint_t lmode, void *base, size_t size, 137 uint_t type, uint_t dpl, uint_t gran, uint_t defopsz) 138 { 139 ASSERT(lmode == SDP_SHORT || lmode == SDP_LONG); 140 141 /* 142 * 64-bit long mode. 143 */ 144 if (lmode == SDP_LONG) 145 dp->usd_def32 = 0; /* 32-bit operands only */ 146 else 147 /* 148 * 32-bit compatibility mode. 149 */ 150 dp->usd_def32 = defopsz; /* 0 = 16, 1 = 32-bit ops */ 151 152 dp->usd_long = lmode; /* 64-bit mode */ 153 dp->usd_type = type; 154 dp->usd_dpl = dpl; 155 dp->usd_p = 1; 156 dp->usd_gran = gran; /* 0 = bytes, 1 = pages */ 157 158 dp->usd_lobase = (uintptr_t)base; 159 dp->usd_midbase = (uintptr_t)base >> 16; 160 dp->usd_hibase = (uintptr_t)base >> (16 + 8); 161 dp->usd_lolimit = size; 162 dp->usd_hilimit = (uintptr_t)size >> 16; 163 } 164 165 #elif defined(__i386) 166 167 /* 168 * Install user segment descriptor for code and data. 169 */ 170 void 171 set_usegd(user_desc_t *dp, void *base, size_t size, uint_t type, 172 uint_t dpl, uint_t gran, uint_t defopsz) 173 { 174 dp->usd_lolimit = size; 175 dp->usd_hilimit = (uintptr_t)size >> 16; 176 177 dp->usd_lobase = (uintptr_t)base; 178 dp->usd_midbase = (uintptr_t)base >> 16; 179 dp->usd_hibase = (uintptr_t)base >> (16 + 8); 180 181 dp->usd_type = type; 182 dp->usd_dpl = dpl; 183 dp->usd_p = 1; 184 dp->usd_def32 = defopsz; /* 0 = 16, 1 = 32 bit operands */ 185 dp->usd_gran = gran; /* 0 = bytes, 1 = pages */ 186 } 187 188 #endif /* __i386 */ 189 190 /* 191 * Install system segment descriptor for LDT and TSS segments. 192 */ 193 194 #if defined(__amd64) 195 196 void 197 set_syssegd(system_desc_t *dp, void *base, size_t size, uint_t type, 198 uint_t dpl) 199 { 200 dp->ssd_lolimit = size; 201 dp->ssd_hilimit = (uintptr_t)size >> 16; 202 203 dp->ssd_lobase = (uintptr_t)base; 204 dp->ssd_midbase = (uintptr_t)base >> 16; 205 dp->ssd_hibase = (uintptr_t)base >> (16 + 8); 206 dp->ssd_hi64base = (uintptr_t)base >> (16 + 8 + 8); 207 208 dp->ssd_type = type; 209 dp->ssd_zero1 = 0; /* must be zero */ 210 dp->ssd_zero2 = 0; 211 dp->ssd_dpl = dpl; 212 dp->ssd_p = 1; 213 dp->ssd_gran = 0; /* force byte units */ 214 } 215 216 #elif defined(__i386) 217 218 void 219 set_syssegd(system_desc_t *dp, void *base, size_t size, uint_t type, 220 uint_t dpl) 221 { 222 dp->ssd_lolimit = size; 223 dp->ssd_hilimit = (uintptr_t)size >> 16; 224 225 dp->ssd_lobase = (uintptr_t)base; 226 dp->ssd_midbase = (uintptr_t)base >> 16; 227 dp->ssd_hibase = (uintptr_t)base >> (16 + 8); 228 229 dp->ssd_type = type; 230 dp->ssd_zero = 0; /* must be zero */ 231 dp->ssd_dpl = dpl; 232 dp->ssd_p = 1; 233 dp->ssd_gran = 0; /* force byte units */ 234 } 235 236 #endif /* __i386 */ 237 238 /* 239 * Install gate segment descriptor for interrupt, trap, call and task gates. 240 */ 241 242 #if defined(__amd64) 243 244 /* 245 * Note stkcpy is replaced with ist. Read the PRM for details on this. 246 */ 247 void 248 set_gatesegd(gate_desc_t *dp, void (*func)(void), selector_t sel, uint_t ist, 249 uint_t type, uint_t dpl) 250 { 251 dp->sgd_looffset = (uintptr_t)func; 252 dp->sgd_hioffset = (uintptr_t)func >> 16; 253 dp->sgd_hi64offset = (uintptr_t)func >> (16 + 16); 254 255 dp->sgd_selector = (uint16_t)sel; 256 dp->sgd_ist = ist; 257 dp->sgd_type = type; 258 dp->sgd_dpl = dpl; 259 dp->sgd_p = 1; 260 } 261 262 #elif defined(__i386) 263 264 void 265 set_gatesegd(gate_desc_t *dp, void (*func)(void), selector_t sel, 266 uint_t wcount, uint_t type, uint_t dpl) 267 { 268 dp->sgd_looffset = (uintptr_t)func; 269 dp->sgd_hioffset = (uintptr_t)func >> 16; 270 271 dp->sgd_selector = (uint16_t)sel; 272 dp->sgd_stkcpy = wcount; 273 dp->sgd_type = type; 274 dp->sgd_dpl = dpl; 275 dp->sgd_p = 1; 276 } 277 278 #endif /* __i386 */ 279 280 /* 281 * Build kernel GDT. 282 */ 283 284 #if defined(__amd64) 285 286 static void 287 init_gdt(void) 288 { 289 desctbr_t r_bgdt, r_gdt; 290 user_desc_t *bgdt; 291 size_t alen = 0xfffff; /* entire 32-bit address space */ 292 293 /* 294 * Copy in from boot's gdt to our gdt entries 1 - 4. 295 * Entry 0 is the null descriptor by definition. 296 */ 297 rd_gdtr(&r_bgdt); 298 bgdt = (user_desc_t *)r_bgdt.dtr_base; 299 if (bgdt == NULL) 300 panic("null boot gdt"); 301 302 gdt0[GDT_B32DATA] = bgdt[GDT_B32DATA]; 303 gdt0[GDT_B32CODE] = bgdt[GDT_B32CODE]; 304 gdt0[GDT_B64DATA] = bgdt[GDT_B64DATA]; 305 gdt0[GDT_B64CODE] = bgdt[GDT_B64CODE]; 306 307 /* 308 * 64-bit kernel code segment. 309 */ 310 set_usegd(&gdt0[GDT_KCODE], SDP_LONG, NULL, 0, SDT_MEMERA, SEL_KPL, 311 SDP_PAGES, SDP_OP32); 312 313 /* 314 * 64-bit kernel data segment. The limit attribute is ignored in 64-bit 315 * mode, but we set it here to 0xFFFF so that we can use the SYSRET 316 * instruction to return from system calls back to 32-bit applications. 317 * SYSRET doesn't update the base, limit, or attributes of %ss or %ds 318 * descriptors. We therefore must ensure that the kernel uses something, 319 * though it will be ignored by hardware, that is compatible with 32-bit 320 * apps. For the same reason we must set the default op size of this 321 * descriptor to 32-bit operands. 322 */ 323 set_usegd(&gdt0[GDT_KDATA], SDP_LONG, NULL, alen, SDT_MEMRWA, 324 SEL_KPL, SDP_PAGES, SDP_OP32); 325 gdt0[GDT_KDATA].usd_def32 = 1; 326 327 /* 328 * 64-bit user code segment. 329 */ 330 set_usegd(&gdt0[GDT_UCODE], SDP_LONG, NULL, 0, SDT_MEMERA, SEL_UPL, 331 SDP_PAGES, SDP_OP32); 332 333 /* 334 * 32-bit user code segment. 335 */ 336 set_usegd(&gdt0[GDT_U32CODE], SDP_SHORT, NULL, alen, SDT_MEMERA, 337 SEL_UPL, SDP_PAGES, SDP_OP32); 338 339 /* 340 * 32 and 64 bit data segments can actually share the same descriptor. 341 * In long mode only the present bit is checked but all other fields 342 * are loaded. But in compatibility mode all fields are interpreted 343 * as in legacy mode so they must be set correctly for a 32-bit data 344 * segment. 345 */ 346 set_usegd(&gdt0[GDT_UDATA], SDP_SHORT, NULL, alen, SDT_MEMRWA, SEL_UPL, 347 SDP_PAGES, SDP_OP32); 348 349 /* 350 * LDT descriptor for 64-bit processes 351 */ 352 set_syssegd((system_desc_t *)&gdt0[GDT_LDT], ldt0_default64, 353 sizeof (ldt0_default64) - 1, SDT_SYSLDT, SEL_KPL); 354 ldt0_default64_desc = *((system_desc_t *)&gdt0[GDT_LDT]); 355 356 /* 357 * LDT descriptor for 32-bit processes 358 */ 359 set_syssegd((system_desc_t *)&gdt0[GDT_LDT], ldt0_default, 360 sizeof (ldt0_default) - 1, SDT_SYSLDT, SEL_KPL); 361 ldt0_default_desc = *((system_desc_t *)&gdt0[GDT_LDT]); 362 363 /* 364 * Kernel TSS 365 */ 366 set_syssegd((system_desc_t *)&gdt0[GDT_KTSS], &ktss0, 367 sizeof (ktss0) - 1, SDT_SYSTSS, SEL_KPL); 368 369 /* 370 * Initialize fs and gs descriptors for 32 bit processes. 371 * Only attributes and limits are initialized, the effective 372 * base address is programmed via fsbase/gsbase. 373 */ 374 set_usegd(&gdt0[GDT_LWPFS], SDP_SHORT, NULL, alen, SDT_MEMRWA, 375 SEL_UPL, SDP_PAGES, SDP_OP32); 376 set_usegd(&gdt0[GDT_LWPGS], SDP_SHORT, NULL, alen, SDT_MEMRWA, 377 SEL_UPL, SDP_PAGES, SDP_OP32); 378 379 /* 380 * Install our new GDT 381 */ 382 r_gdt.dtr_limit = sizeof (gdt0) - 1; 383 r_gdt.dtr_base = (uintptr_t)gdt0; 384 wr_gdtr(&r_gdt); 385 386 /* 387 * Initialize convenient zero base user descriptors for clearing 388 * lwp private %fs and %gs descriptors in GDT. See setregs() for 389 * an example. 390 */ 391 set_usegd(&zero_udesc, SDP_LONG, 0, 0, SDT_MEMRWA, SEL_UPL, 392 SDP_BYTES, SDP_OP32); 393 set_usegd(&zero_u32desc, SDP_SHORT, 0, -1, SDT_MEMRWA, SEL_UPL, 394 SDP_PAGES, SDP_OP32); 395 } 396 397 #elif defined(__i386) 398 399 static void 400 init_gdt(void) 401 { 402 desctbr_t r_bgdt, r_gdt; 403 user_desc_t *bgdt; 404 405 /* 406 * Copy in from boot's gdt to our gdt entries 1 - 4. 407 * Entry 0 is null descriptor by definition. 408 */ 409 rd_gdtr(&r_bgdt); 410 bgdt = (user_desc_t *)r_bgdt.dtr_base; 411 if (bgdt == NULL) 412 panic("null boot gdt"); 413 414 gdt0[GDT_BOOTFLAT] = bgdt[GDT_BOOTFLAT]; 415 gdt0[GDT_BOOTCODE] = bgdt[GDT_BOOTCODE]; 416 gdt0[GDT_BOOTCODE16] = bgdt[GDT_BOOTCODE16]; 417 gdt0[GDT_BOOTDATA] = bgdt[GDT_BOOTDATA]; 418 419 /* 420 * Text and data for both kernel and user span entire 32 bit 421 * address space. 422 */ 423 424 /* 425 * kernel code segment. 426 */ 427 set_usegd(&gdt0[GDT_KCODE], NULL, -1, SDT_MEMERA, SEL_KPL, SDP_PAGES, 428 SDP_OP32); 429 430 /* 431 * kernel data segment. 432 */ 433 set_usegd(&gdt0[GDT_KDATA], NULL, -1, SDT_MEMRWA, SEL_KPL, SDP_PAGES, 434 SDP_OP32); 435 436 /* 437 * user code segment. 438 */ 439 set_usegd(&gdt0[GDT_UCODE], NULL, -1, SDT_MEMERA, SEL_UPL, SDP_PAGES, 440 SDP_OP32); 441 442 /* 443 * user data segment. 444 */ 445 set_usegd(&gdt0[GDT_UDATA], NULL, -1, SDT_MEMRWA, SEL_UPL, SDP_PAGES, 446 SDP_OP32); 447 448 /* 449 * LDT for current process 450 */ 451 set_syssegd((system_desc_t *)&gdt0[GDT_LDT], ldt0_default, 452 sizeof (ldt0_default) - 1, SDT_SYSLDT, SEL_KPL); 453 454 ldt0_default_desc = *((system_desc_t *)&gdt0[GDT_LDT]); 455 456 /* 457 * TSS for T_DBLFLT (double fault) handler 458 */ 459 set_syssegd((system_desc_t *)&gdt0[GDT_DBFLT], &dftss0, 460 sizeof (dftss0) - 1, SDT_SYSTSS, SEL_KPL); 461 462 /* 463 * TSS for kernel 464 */ 465 set_syssegd((system_desc_t *)&gdt0[GDT_KTSS], &ktss0, 466 sizeof (ktss0) - 1, SDT_SYSTSS, SEL_KPL); 467 468 /* 469 * %gs selector for kernel 470 */ 471 set_usegd(&gdt0[GDT_GS], &cpus[0], sizeof (struct cpu) -1, SDT_MEMRWA, 472 SEL_KPL, SDP_BYTES, SDP_OP32); 473 474 /* 475 * Initialize lwp private descriptors. 476 * Only attributes and limits are initialized, the effective 477 * base address is programmed via fsbase/gsbase. 478 */ 479 set_usegd(&gdt0[GDT_LWPFS], NULL, (size_t)-1, SDT_MEMRWA, SEL_UPL, 480 SDP_PAGES, SDP_OP32); 481 set_usegd(&gdt0[GDT_LWPGS], NULL, (size_t)-1, SDT_MEMRWA, SEL_UPL, 482 SDP_PAGES, SDP_OP32); 483 484 /* 485 * Install our new GDT 486 */ 487 r_gdt.dtr_limit = sizeof (gdt0) - 1; 488 r_gdt.dtr_base = (uintptr_t)gdt0; 489 wr_gdtr(&r_gdt); 490 491 /* 492 * Initialize convenient zero base user descriptors for clearing 493 * lwp private %fs and %gs descriptors in GDT. See setregs() for 494 * an example. 495 */ 496 set_usegd(&zero_udesc, 0, -1, SDT_MEMRWA, SEL_UPL, SDP_PAGES, SDP_OP32); 497 } 498 499 #endif /* __i386 */ 500 501 #if defined(__amd64) 502 503 /* 504 * Build kernel IDT. 505 * 506 * Note that we pretty much require every gate to be an interrupt gate; 507 * that's because of our dependency on using 'swapgs' every time we come 508 * into the kernel to find the cpu structure - if we get interrupted just 509 * before doing that, so that %cs is in kernel mode (so that the trap prolog 510 * doesn't do a swapgs), but %gsbase is really still pointing at something 511 * in userland, bad things ensue. 512 * 513 * Perhaps they should have invented a trap gate that does an atomic swapgs? 514 * 515 * XX64 We do need to think further about the follow-on impact of this. 516 * Most of the kernel handlers re-enable interrupts as soon as they've 517 * saved register state and done the swapgs, but there may be something 518 * more subtle going on. 519 */ 520 static void 521 init_idt(void) 522 { 523 char ivctname[80]; 524 void (*ivctptr)(void); 525 int i; 526 527 /* 528 * Initialize entire table with 'reserved' trap and then overwrite 529 * specific entries. T_EXTOVRFLT (9) is unsupported and reserved 530 * since it can only be generated on a 386 processor. 15 is also 531 * unsupported and reserved. 532 */ 533 for (i = 0; i < NIDT; i++) 534 set_gatesegd(&idt0[i], &resvtrap, KCS_SEL, 0, SDT_SYSIGT, 535 SEL_KPL); 536 537 set_gatesegd(&idt0[T_ZERODIV], &div0trap, KCS_SEL, 0, SDT_SYSIGT, 538 SEL_KPL); 539 set_gatesegd(&idt0[T_SGLSTP], &dbgtrap, KCS_SEL, 0, SDT_SYSIGT, 540 SEL_KPL); 541 set_gatesegd(&idt0[T_NMIFLT], &nmiint, KCS_SEL, 0, SDT_SYSIGT, 542 SEL_KPL); 543 set_gatesegd(&idt0[T_BPTFLT], &brktrap, KCS_SEL, 0, SDT_SYSIGT, 544 SEL_UPL); 545 set_gatesegd(&idt0[T_OVFLW], &ovflotrap, KCS_SEL, 0, SDT_SYSIGT, 546 SEL_UPL); 547 set_gatesegd(&idt0[T_BOUNDFLT], &boundstrap, KCS_SEL, 0, SDT_SYSIGT, 548 SEL_KPL); 549 set_gatesegd(&idt0[T_ILLINST], &invoptrap, KCS_SEL, 0, SDT_SYSIGT, 550 SEL_KPL); 551 set_gatesegd(&idt0[T_NOEXTFLT], &ndptrap, KCS_SEL, 0, SDT_SYSIGT, 552 SEL_KPL); 553 554 /* 555 * double fault handler. 556 */ 557 set_gatesegd(&idt0[T_DBLFLT], &syserrtrap, KCS_SEL, 1, SDT_SYSIGT, 558 SEL_KPL); 559 560 /* 561 * T_EXTOVRFLT coprocessor-segment-overrun not supported. 562 */ 563 564 set_gatesegd(&idt0[T_TSSFLT], &invtsstrap, KCS_SEL, 0, SDT_SYSIGT, 565 SEL_KPL); 566 set_gatesegd(&idt0[T_SEGFLT], &segnptrap, KCS_SEL, 0, SDT_SYSIGT, 567 SEL_KPL); 568 set_gatesegd(&idt0[T_STKFLT], &stktrap, KCS_SEL, 0, SDT_SYSIGT, 569 SEL_KPL); 570 set_gatesegd(&idt0[T_GPFLT], &gptrap, KCS_SEL, 0, SDT_SYSIGT, 571 SEL_KPL); 572 set_gatesegd(&idt0[T_PGFLT], &pftrap, KCS_SEL, 0, SDT_SYSIGT, 573 SEL_KPL); 574 575 /* 576 * 15 reserved. 577 */ 578 set_gatesegd(&idt0[15], &resvtrap, KCS_SEL, 0, SDT_SYSIGT, SEL_KPL); 579 580 set_gatesegd(&idt0[T_EXTERRFLT], &ndperr, KCS_SEL, 0, SDT_SYSIGT, 581 SEL_KPL); 582 set_gatesegd(&idt0[T_ALIGNMENT], &achktrap, KCS_SEL, 0, SDT_SYSIGT, 583 SEL_KPL); 584 set_gatesegd(&idt0[T_MCE], &mcetrap, KCS_SEL, 0, SDT_SYSIGT, 585 SEL_KPL); 586 set_gatesegd(&idt0[T_SIMDFPE], &xmtrap, KCS_SEL, 0, SDT_SYSIGT, 587 SEL_KPL); 588 589 /* 590 * 20-31 reserved 591 */ 592 for (i = 20; i < 32; i++) 593 set_gatesegd(&idt0[i], &invaltrap, KCS_SEL, 0, SDT_SYSIGT, 594 SEL_KPL); 595 596 /* 597 * interrupts 32 - 255 598 */ 599 for (i = 32; i < 256; i++) { 600 (void) snprintf(ivctname, sizeof (ivctname), "ivct%d", i); 601 ivctptr = (void (*)(void))kobj_getsymvalue(ivctname, 0); 602 if (ivctptr == NULL) 603 panic("kobj_getsymvalue(%s) failed", ivctname); 604 605 set_gatesegd(&idt0[i], ivctptr, KCS_SEL, 0, SDT_SYSIGT, 606 SEL_KPL); 607 } 608 609 /* 610 * install fast trap handler at 210. 611 */ 612 set_gatesegd(&idt0[T_FASTTRAP], &fasttrap, KCS_SEL, 0, 613 SDT_SYSIGT, SEL_UPL); 614 615 /* 616 * System call handler. 617 */ 618 set_gatesegd(&idt0[T_SYSCALLINT], &sys_syscall_int, KCS_SEL, 0, 619 SDT_SYSIGT, SEL_UPL); 620 621 /* 622 * Install the DTrace interrupt handlers for the fasttrap provider. 623 */ 624 set_gatesegd(&idt0[T_DTRACE_PROBE], &dtrace_fasttrap, KCS_SEL, 0, 625 SDT_SYSIGT, SEL_UPL); 626 set_gatesegd(&idt0[T_DTRACE_RET], &dtrace_ret, KCS_SEL, 0, 627 SDT_SYSIGT, SEL_UPL); 628 629 if (boothowto & RB_DEBUG) 630 kdi_dvec_idt_sync(idt0); 631 632 /* 633 * We must maintain a description of idt0 in convenient IDTR format 634 * for use by T_NMIFLT and T_PGFLT (nmiint() and pentium_pftrap()) 635 * handlers. 636 */ 637 idt0_default_r.dtr_limit = sizeof (idt0) - 1; 638 idt0_default_r.dtr_base = (uintptr_t)idt0; 639 wr_idtr(&idt0_default_r); 640 } 641 642 #elif defined(__i386) 643 644 /* 645 * Build kernel IDT. 646 */ 647 static void 648 init_idt(void) 649 { 650 char ivctname[80]; 651 void (*ivctptr)(void); 652 int i; 653 654 /* 655 * Initialize entire table with 'reserved' trap and then overwrite 656 * specific entries. T_EXTOVRFLT (9) is unsupported and reserved 657 * since it can only be generated on a 386 processor. 15 is also 658 * unsupported and reserved. 659 */ 660 for (i = 0; i < NIDT; i++) 661 set_gatesegd(&idt0[i], &resvtrap, KCS_SEL, 0, SDT_SYSTGT, 662 SEL_KPL); 663 664 set_gatesegd(&idt0[T_ZERODIV], &div0trap, KCS_SEL, 0, SDT_SYSTGT, 665 SEL_KPL); 666 set_gatesegd(&idt0[T_SGLSTP], &dbgtrap, KCS_SEL, 0, SDT_SYSIGT, 667 SEL_KPL); 668 set_gatesegd(&idt0[T_NMIFLT], &nmiint, KCS_SEL, 0, SDT_SYSIGT, 669 SEL_KPL); 670 set_gatesegd(&idt0[T_BPTFLT], &brktrap, KCS_SEL, 0, SDT_SYSTGT, 671 SEL_UPL); 672 set_gatesegd(&idt0[T_OVFLW], &ovflotrap, KCS_SEL, 0, SDT_SYSTGT, 673 SEL_UPL); 674 set_gatesegd(&idt0[T_BOUNDFLT], &boundstrap, KCS_SEL, 0, SDT_SYSTGT, 675 SEL_KPL); 676 set_gatesegd(&idt0[T_ILLINST], &invoptrap, KCS_SEL, 0, SDT_SYSIGT, 677 SEL_KPL); 678 set_gatesegd(&idt0[T_NOEXTFLT], &ndptrap, KCS_SEL, 0, SDT_SYSIGT, 679 SEL_KPL); 680 681 /* 682 * Install TSS for T_DBLFLT handler. 683 */ 684 set_gatesegd(&idt0[T_DBLFLT], NULL, DFTSS_SEL, 0, SDT_SYSTASKGT, 685 SEL_KPL); 686 687 /* 688 * T_EXTOVRFLT coprocessor-segment-overrun not supported. 689 */ 690 691 set_gatesegd(&idt0[T_TSSFLT], &invtsstrap, KCS_SEL, 0, SDT_SYSTGT, 692 SEL_KPL); 693 set_gatesegd(&idt0[T_SEGFLT], &segnptrap, KCS_SEL, 0, SDT_SYSTGT, 694 SEL_KPL); 695 set_gatesegd(&idt0[T_STKFLT], &stktrap, KCS_SEL, 0, SDT_SYSTGT, 696 SEL_KPL); 697 set_gatesegd(&idt0[T_GPFLT], &gptrap, KCS_SEL, 0, SDT_SYSTGT, 698 SEL_KPL); 699 set_gatesegd(&idt0[T_PGFLT], &pftrap, KCS_SEL, 0, SDT_SYSIGT, 700 SEL_KPL); 701 702 /* 703 * 15 reserved. 704 */ 705 set_gatesegd(&idt0[15], &resvtrap, KCS_SEL, 0, SDT_SYSTGT, SEL_KPL); 706 707 set_gatesegd(&idt0[T_EXTERRFLT], &ndperr, KCS_SEL, 0, SDT_SYSIGT, 708 SEL_KPL); 709 set_gatesegd(&idt0[T_ALIGNMENT], &achktrap, KCS_SEL, 0, SDT_SYSTGT, 710 SEL_KPL); 711 set_gatesegd(&idt0[T_MCE], &mcetrap, KCS_SEL, 0, SDT_SYSIGT, 712 SEL_KPL); 713 set_gatesegd(&idt0[T_SIMDFPE], &xmtrap, KCS_SEL, 0, SDT_SYSTGT, 714 SEL_KPL); 715 716 /* 717 * 20-31 reserved 718 */ 719 for (i = 20; i < 32; i++) 720 set_gatesegd(&idt0[i], &invaltrap, KCS_SEL, 0, SDT_SYSTGT, 721 SEL_KPL); 722 723 /* 724 * interrupts 32 - 255 725 */ 726 for (i = 32; i < 256; i++) { 727 (void) snprintf(ivctname, sizeof (ivctname), "ivct%d", i); 728 ivctptr = (void (*)(void))kobj_getsymvalue(ivctname, 0); 729 if (ivctptr == NULL) 730 panic("kobj_getsymvalue(%s) failed", ivctname); 731 732 set_gatesegd(&idt0[i], ivctptr, KCS_SEL, 0, SDT_SYSIGT, 733 SEL_KPL); 734 } 735 736 /* 737 * install fast trap handler at 210. 738 */ 739 set_gatesegd(&idt0[T_FASTTRAP], &fasttrap, KCS_SEL, 0, 740 SDT_SYSIGT, SEL_UPL); 741 742 /* 743 * System call handler. Note that we don't use the hardware's parameter 744 * copying mechanism here; see the comment above sys_call() for details. 745 */ 746 set_gatesegd(&idt0[T_SYSCALLINT], &sys_call, KCS_SEL, 0, 747 SDT_SYSIGT, SEL_UPL); 748 749 /* 750 * Install the DTrace interrupt handlers for the fasttrap provider. 751 */ 752 set_gatesegd(&idt0[T_DTRACE_PROBE], &dtrace_fasttrap, KCS_SEL, 0, 753 SDT_SYSIGT, SEL_UPL); 754 set_gatesegd(&idt0[T_DTRACE_RET], &dtrace_ret, KCS_SEL, 0, 755 SDT_SYSIGT, SEL_UPL); 756 757 if (boothowto & RB_DEBUG) 758 kdi_dvec_idt_sync(idt0); 759 760 /* 761 * We must maintain a description of idt0 in convenient IDTR format 762 * for use by T_NMIFLT and T_PGFLT (nmiint() and pentium_pftrap()) 763 * handlers. 764 */ 765 idt0_default_r.dtr_limit = sizeof (idt0) - 1; 766 idt0_default_r.dtr_base = (uintptr_t)idt0; 767 wr_idtr(&idt0_default_r); 768 } 769 770 #endif /* __i386 */ 771 772 #if defined(__amd64) 773 774 static void 775 init_ldt(void) 776 { 777 /* 778 * System calls using call gates from libc.a and libc.so.1 779 * must cause a #NP fault and be processed in trap(). 780 * Therefore clear the "present" bit in the gate descriptor. 781 */ 782 783 /* 784 * call gate for libc.a (obsolete) 785 */ 786 set_gatesegd((gate_desc_t *)&ldt0_default[LDT_SYSCALL], 787 (void (*)(void))&sys_lcall32, KCS_SEL, 1, SDT_SYSCGT, SEL_UPL); 788 ((gate_desc_t *)&ldt0_default[LDT_SYSCALL])->sgd_p = 0; 789 790 /* 791 * i386 call gate for system calls from libc. 792 */ 793 set_gatesegd((gate_desc_t *)&ldt0_default[LDT_ALTSYSCALL], 794 (void (*)(void))&sys_lcall32, KCS_SEL, 1, SDT_SYSCGT, SEL_UPL); 795 ((gate_desc_t *)&ldt0_default[LDT_ALTSYSCALL])->sgd_p = 0; 796 797 wr_ldtr(ULDT_SEL); 798 } 799 800 #elif defined(__i386) 801 802 /* 803 * Note that the call gates for system calls ask the hardware to copy exactly 804 * one parameter onto the kernel stack for us; the parameter itself is not used. 805 * The real reason this is done is to make room for a snapshot of EFLAGS. See 806 * comment above sys_call() for details. 807 */ 808 static void 809 init_ldt(void) 810 { 811 /* 812 * call gate for libc.a (obsolete) 813 */ 814 set_gatesegd((gate_desc_t *)&ldt0_default[LDT_SYSCALL], 815 (void (*)(void))&sys_call, KCS_SEL, 1, SDT_SYSCGT, SEL_UPL); 816 817 /* 818 * i386 call gate for system calls from libc. 819 */ 820 set_gatesegd((gate_desc_t *)&ldt0_default[LDT_ALTSYSCALL], 821 (void (*)(void))&sys_call, KCS_SEL, 1, SDT_SYSCGT, SEL_UPL); 822 823 wr_ldtr(ULDT_SEL); 824 } 825 826 #endif /* __i386 */ 827 828 #if defined(__amd64) 829 830 static void 831 init_tss(void) 832 { 833 /* 834 * tss_rsp0 is dynamically filled in by resume() on each context switch. 835 * All exceptions but #DF will run on the thread stack. 836 * Set up the double fault stack here. 837 */ 838 ktss0.tss_ist1 = 839 (uint64_t)&dblfault_stack0[sizeof (dblfault_stack0)]; 840 841 /* 842 * Set I/O bit map offset equal to size of TSS segment limit 843 * for no I/O permission map. This will force all user I/O 844 * instructions to generate #gp fault. 845 */ 846 ktss0.tss_bitmapbase = sizeof (ktss0); 847 848 /* 849 * Point %tr to descriptor for ktss0 in gdt. 850 */ 851 wr_tsr(KTSS_SEL); 852 } 853 854 #elif defined(__i386) 855 856 static void 857 init_tss(void) 858 { 859 /* 860 * ktss0.tss_esp dynamically filled in by resume() on each 861 * context switch. 862 */ 863 ktss0.tss_ss0 = KDS_SEL; 864 ktss0.tss_eip = (uint32_t)_start; 865 ktss0.tss_ds = ktss0.tss_es = ktss0.tss_ss = KDS_SEL; 866 ktss0.tss_cs = KCS_SEL; 867 ktss0.tss_fs = KFS_SEL; 868 ktss0.tss_gs = KGS_SEL; 869 ktss0.tss_ldt = ULDT_SEL; 870 871 /* 872 * Initialize double fault tss. 873 */ 874 dftss0.tss_esp0 = (uint32_t)&dblfault_stack0[sizeof (dblfault_stack0)]; 875 dftss0.tss_ss0 = KDS_SEL; 876 877 /* 878 * tss_cr3 will get initialized in hat_kern_setup() once our page 879 * tables have been setup. 880 */ 881 dftss0.tss_eip = (uint32_t)syserrtrap; 882 dftss0.tss_esp = (uint32_t)&dblfault_stack0[sizeof (dblfault_stack0)]; 883 dftss0.tss_cs = KCS_SEL; 884 dftss0.tss_ds = KDS_SEL; 885 dftss0.tss_es = KDS_SEL; 886 dftss0.tss_ss = KDS_SEL; 887 dftss0.tss_fs = KFS_SEL; 888 dftss0.tss_gs = KGS_SEL; 889 890 /* 891 * Set I/O bit map offset equal to size of TSS segment limit 892 * for no I/O permission map. This will force all user I/O 893 * instructions to generate #gp fault. 894 */ 895 ktss0.tss_bitmapbase = sizeof (ktss0); 896 897 /* 898 * Point %tr to descriptor for ktss0 in gdt. 899 */ 900 wr_tsr(KTSS_SEL); 901 } 902 903 #endif /* __i386 */ 904 905 void 906 init_tables(void) 907 { 908 init_gdt(); 909 init_tss(); 910 init_idt(); 911 init_ldt(); 912 } 913