1 /* 2 * Copyright 2010, Clemens Zeidler, haiku@clemens-zeidler.de. 3 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 4 * Copyright 2002-2010, Axel Dörfler, axeld@pinc-software.de. 5 * Distributed under the terms of the MIT License. 6 * 7 * Copyright 2001, Travis Geiselbrecht. All rights reserved. 8 * Distributed under the terms of the NewOS License. 9 */ 10 11 12 #include <cpu.h> 13 #include <int.h> 14 #include <kscheduler.h> 15 #include <ksyscalls.h> 16 #include <smp.h> 17 #include <team.h> 18 #include <thread.h> 19 #include <vm/vm.h> 20 #include <vm/vm_priv.h> 21 22 #include <arch/cpu.h> 23 #include <arch/int.h> 24 #include <arch/smp.h> 25 #include <arch/user_debugger.h> 26 #include <arch/vm.h> 27 28 #include <arch/x86/apic.h> 29 #include <arch/x86/descriptors.h> 30 #include <arch/x86/vm86.h> 31 32 #include "interrupts.h" 33 #include "irq_routing_table.h" 34 35 #include <ACPI.h> 36 #include <AutoDeleter.h> 37 #include <safemode.h> 38 #include <string.h> 39 #include <stdio.h> 40 41 42 //#define TRACE_ARCH_INT 43 #ifdef TRACE_ARCH_INT 44 # define TRACE(x) dprintf x 45 #else 46 # define TRACE(x) ; 47 #endif 48 49 50 // Definitions for the PIC 8259 controller 51 // (this is not a complete list, only what we're actually using) 52 53 #define PIC_MASTER_CONTROL 0x20 54 #define PIC_MASTER_MASK 0x21 55 #define PIC_SLAVE_CONTROL 0xa0 56 #define PIC_SLAVE_MASK 0xa1 57 #define PIC_MASTER_INIT1 PIC_MASTER_CONTROL 58 #define PIC_MASTER_INIT2 PIC_MASTER_MASK 59 #define PIC_MASTER_INIT3 PIC_MASTER_MASK 60 #define PIC_MASTER_INIT4 PIC_MASTER_MASK 61 #define PIC_SLAVE_INIT1 PIC_SLAVE_CONTROL 62 #define PIC_SLAVE_INIT2 PIC_SLAVE_MASK 63 #define PIC_SLAVE_INIT3 PIC_SLAVE_MASK 64 #define PIC_SLAVE_INIT4 PIC_SLAVE_MASK 65 66 // the edge/level trigger control registers 67 #define PIC_MASTER_TRIGGER_MODE 0x4d0 68 #define PIC_SLAVE_TRIGGER_MODE 0x4d1 69 70 #define PIC_INIT1 0x10 71 #define PIC_INIT1_SEND_INIT4 0x01 72 #define PIC_INIT3_IR2_IS_SLAVE 0x04 73 #define PIC_INIT3_SLAVE_ID2 0x02 74 #define PIC_INIT4_x86_MODE 0x01 75 76 #define PIC_CONTROL3 0x08 77 #define PIC_CONTROL3_READ_ISR 0x03 78 #define PIC_CONTROL3_READ_IRR 0x02 79 80 #define PIC_NON_SPECIFIC_EOI 0x20 81 82 #define PIC_SLAVE_INT_BASE 8 83 #define PIC_NUM_INTS 0x0f 84 85 86 // Definitions for a 82093AA IO APIC controller 87 #define IO_APIC_IDENTIFICATION 0x00 88 #define IO_APIC_VERSION 0x01 89 #define IO_APIC_ARBITRATION 0x02 90 #define IO_APIC_REDIRECTION_TABLE 0x10 // entry = base + 2 * index 91 92 // Fields for the version register 93 #define IO_APIC_VERSION_SHIFT 0 94 #define IO_APIC_VERSION_MASK 0xff 95 #define IO_APIC_MAX_REDIRECTION_ENTRY_SHIFT 16 96 #define IO_APIC_MAX_REDIRECTION_ENTRY_MASK 0xff 97 98 // Fields of each redirection table entry 99 #define IO_APIC_DESTINATION_FIELD_SHIFT 56 100 #define IO_APIC_DESTINATION_FIELD_MASK 0x0f 101 #define IO_APIC_INTERRUPT_MASK_SHIFT 16 102 #define IO_APIC_INTERRUPT_MASKED 1 103 #define IO_APIC_INTERRUPT_UNMASKED 0 104 #define IO_APIC_TRIGGER_MODE_SHIFT 15 105 #define IO_APIC_TRIGGER_MODE_EDGE 0 106 #define IO_APIC_TRIGGER_MODE_LEVEL 1 107 #define IO_APIC_REMOTE_IRR_SHIFT 14 108 #define IO_APIC_PIN_POLARITY_SHIFT 13 109 #define IO_APIC_PIN_POLARITY_HIGH_ACTIVE 0 110 #define IO_APIC_PIN_POLARITY_LOW_ACTIVE 1 111 #define IO_APIC_DELIVERY_STATUS_SHIFT 12 112 #define IO_APIC_DELIVERY_STATUS_IDLE 0 113 #define IO_APIC_DELIVERY_STATUS_PENDING 1 114 #define IO_APIC_DESTINATION_MODE_SHIFT 11 115 #define IO_APIC_DESTINATION_MODE_PHYSICAL 0 116 #define IO_APIC_DESTINATION_MODE_LOGICAL 1 117 #define IO_APIC_DELIVERY_MODE_SHIFT 8 118 #define IO_APIC_DELIVERY_MODE_MASK 0x07 119 #define IO_APIC_DELIVERY_MODE_FIXED 0 120 #define IO_APIC_DELIVERY_MODE_LOWEST_PRIO 1 121 #define IO_APIC_DELIVERY_MODE_SMI 2 122 #define IO_APIC_DELIVERY_MODE_NMI 4 123 #define IO_APIC_DELIVERY_MODE_INIT 5 124 #define IO_APIC_DELIVERY_MODE_EXT_INT 7 125 #define IO_APIC_INTERRUPT_VECTOR_SHIFT 0 126 #define IO_APIC_INTERRUPT_VECTOR_MASK 0xff 127 128 typedef struct ioapic_s { 129 volatile uint32 io_register_select; 130 uint32 reserved[3]; 131 volatile uint32 io_window_register; 132 } ioapic; 133 134 static ioapic *sIOAPIC = NULL; 135 static uint32 sIOAPICMaxRedirectionEntry = 23; 136 137 static uint32 sIRQToIOAPICPin[256]; 138 139 typedef struct interrupt_controller_s { 140 const char *name; 141 void (*enable_io_interrupt)(int32 num); 142 void (*disable_io_interrupt)(int32 num); 143 void (*configure_io_interrupt)(int32 num, uint32 config); 144 bool (*is_spurious_interrupt)(int32 num); 145 bool (*end_of_interrupt)(int32 num); 146 } interrupt_controller; 147 148 static const interrupt_controller *sCurrentPIC = NULL; 149 150 static const char *kInterruptNames[] = { 151 /* 0 */ "Divide Error Exception", 152 /* 1 */ "Debug Exception", 153 /* 2 */ "NMI Interrupt", 154 /* 3 */ "Breakpoint Exception", 155 /* 4 */ "Overflow Exception", 156 /* 5 */ "BOUND Range Exceeded Exception", 157 /* 6 */ "Invalid Opcode Exception", 158 /* 7 */ "Device Not Available Exception", 159 /* 8 */ "Double Fault Exception", 160 /* 9 */ "Coprocessor Segment Overrun", 161 /* 10 */ "Invalid TSS Exception", 162 /* 11 */ "Segment Not Present", 163 /* 12 */ "Stack Fault Exception", 164 /* 13 */ "General Protection Exception", 165 /* 14 */ "Page-Fault Exception", 166 /* 15 */ "-", 167 /* 16 */ "x87 FPU Floating-Point Error", 168 /* 17 */ "Alignment Check Exception", 169 /* 18 */ "Machine-Check Exception", 170 /* 19 */ "SIMD Floating-Point Exception", 171 }; 172 static const int kInterruptNameCount = 20; 173 174 #define MAX_ARGS 16 175 176 typedef struct { 177 uint32 a, b; 178 } desc_table; 179 static desc_table* sIDTs[B_MAX_CPU_COUNT]; 180 181 static uint32 sLevelTriggeredInterrupts = 0; 182 // binary mask: 1 level, 0 edge 183 184 // table with functions handling respective interrupts 185 typedef void interrupt_handler_function(struct iframe* frame); 186 #define INTERRUPT_HANDLER_TABLE_SIZE 256 187 interrupt_handler_function* gInterruptHandlerTable[ 188 INTERRUPT_HANDLER_TABLE_SIZE]; 189 190 191 /*! Initializes a descriptor in an IDT. 192 */ 193 static void 194 set_gate(desc_table *gate_addr, addr_t addr, int type, int dpl) 195 { 196 unsigned int gate1; // first byte of gate desc 197 unsigned int gate2; // second byte of gate desc 198 199 gate1 = (KERNEL_CODE_SEG << 16) | (0x0000ffff & addr); 200 gate2 = (0xffff0000 & addr) | 0x8000 | (dpl << 13) | (type << 8); 201 202 gate_addr->a = gate1; 203 gate_addr->b = gate2; 204 } 205 206 207 /*! Initializes the descriptor for interrupt vector \a n in the IDT of the 208 specified CPU to an interrupt-gate descriptor with the given procedure 209 address. 210 For CPUs other than the boot CPU it must not be called before 211 arch_int_init_post_vm(). 212 */ 213 static void 214 set_interrupt_gate(int32 cpu, int n, void (*addr)()) 215 { 216 set_gate(&sIDTs[cpu][n], (addr_t)addr, 14, DPL_KERNEL); 217 } 218 219 220 /*! Initializes the descriptor for interrupt vector \a n in the IDT of the 221 specified CPU to an trap-gate descriptor with the given procedure address. 222 For CPUs other than the boot CPU it must not be called before 223 arch_int_init_post_vm(). 224 */ 225 static void 226 set_trap_gate(int32 cpu, int n, void (*addr)()) 227 { 228 set_gate(&sIDTs[cpu][n], (unsigned int)addr, 15, DPL_USER); 229 } 230 231 232 /*! Initializes the descriptor for interrupt vector \a n in the IDT of CPU 233 \a cpu to a task-gate descripter referring to the TSS segment identified 234 by TSS segment selector \a segment. 235 For CPUs other than the boot CPU it must not be called before 236 arch_int_init_post_vm() (arch_cpu_init_post_vm() is fine). 237 */ 238 void 239 x86_set_task_gate(int32 cpu, int32 n, int32 segment) 240 { 241 sIDTs[cpu][n].a = (segment << 16); 242 sIDTs[cpu][n].b = 0x8000 | (0 << 13) | (0x5 << 8); // present, dpl 0, type 5 243 } 244 245 246 /*! Returns the virtual IDT address for CPU \a cpu. */ 247 void* 248 x86_get_idt(int32 cpu) 249 { 250 return sIDTs[cpu]; 251 } 252 253 254 // #pragma mark - PIC 255 256 257 /*! Tests if the interrupt in-service register of the responsible 258 PIC is set for interrupts 7 and 15, and if that's not the case, 259 it must assume it's a spurious interrupt. 260 */ 261 static bool 262 pic_is_spurious_interrupt(int32 num) 263 { 264 if (num != 7) 265 return false; 266 267 // Note, detecting spurious interrupts on line 15 obviously doesn't 268 // work correctly - and since those are extremely rare, anyway, we 269 // just ignore them 270 271 out8(PIC_CONTROL3 | PIC_CONTROL3_READ_ISR, PIC_MASTER_CONTROL); 272 int32 isr = in8(PIC_MASTER_CONTROL); 273 out8(PIC_CONTROL3 | PIC_CONTROL3_READ_IRR, PIC_MASTER_CONTROL); 274 275 return (isr & 0x80) == 0; 276 } 277 278 279 /*! Sends a non-specified EOI (end of interrupt) notice to the PIC in 280 question (or both of them). 281 This clears the PIC interrupt in-service bit. 282 */ 283 static bool 284 pic_end_of_interrupt(int32 num) 285 { 286 if (num < 0 || num > PIC_NUM_INTS) 287 return false; 288 289 // PIC 8259 controlled interrupt 290 if (num >= PIC_SLAVE_INT_BASE) 291 out8(PIC_NON_SPECIFIC_EOI, PIC_SLAVE_CONTROL); 292 293 // we always need to acknowledge the master PIC 294 out8(PIC_NON_SPECIFIC_EOI, PIC_MASTER_CONTROL); 295 return true; 296 } 297 298 299 static void 300 pic_enable_io_interrupt(int32 num) 301 { 302 // interrupt is specified "normalized" 303 if (num < 0 || num > PIC_NUM_INTS) 304 return; 305 306 // enable PIC 8259 controlled interrupt 307 308 TRACE(("pic_enable_io_interrupt: irq %ld\n", num)); 309 310 if (num < PIC_SLAVE_INT_BASE) 311 out8(in8(PIC_MASTER_MASK) & ~(1 << num), PIC_MASTER_MASK); 312 else 313 out8(in8(PIC_SLAVE_MASK) & ~(1 << (num - PIC_SLAVE_INT_BASE)), PIC_SLAVE_MASK); 314 } 315 316 317 static void 318 pic_disable_io_interrupt(int32 num) 319 { 320 // interrupt is specified "normalized" 321 // never disable slave pic line IRQ 2 322 if (num < 0 || num > PIC_NUM_INTS || num == 2) 323 return; 324 325 // disable PIC 8259 controlled interrupt 326 327 TRACE(("pic_disable_io_interrupt: irq %ld\n", num)); 328 329 if (num < PIC_SLAVE_INT_BASE) 330 out8(in8(PIC_MASTER_MASK) | (1 << num), PIC_MASTER_MASK); 331 else 332 out8(in8(PIC_SLAVE_MASK) | (1 << (num - PIC_SLAVE_INT_BASE)), PIC_SLAVE_MASK); 333 } 334 335 336 static void 337 pic_configure_io_interrupt(int32 num, uint32 config) 338 { 339 uint8 value; 340 int32 localBit; 341 if (num < 0 || num > PIC_NUM_INTS || num == 2) 342 return; 343 344 TRACE(("pic_configure_io_interrupt: irq %ld; config 0x%08lx\n", num, config)); 345 346 if (num < PIC_SLAVE_INT_BASE) { 347 value = in8(PIC_MASTER_TRIGGER_MODE); 348 localBit = num; 349 } else { 350 value = in8(PIC_SLAVE_TRIGGER_MODE); 351 localBit = num - PIC_SLAVE_INT_BASE; 352 } 353 354 if (config & B_LEVEL_TRIGGERED) 355 value |= 1 << localBit; 356 else 357 value &= ~(1 << localBit); 358 359 if (num < PIC_SLAVE_INT_BASE) 360 out8(value, PIC_MASTER_TRIGGER_MODE); 361 else 362 out8(value, PIC_SLAVE_TRIGGER_MODE); 363 364 sLevelTriggeredInterrupts = in8(PIC_MASTER_TRIGGER_MODE) 365 | (in8(PIC_SLAVE_TRIGGER_MODE) << 8); 366 } 367 368 369 static void 370 pic_init(void) 371 { 372 static interrupt_controller picController = { 373 "8259 PIC", 374 &pic_enable_io_interrupt, 375 &pic_disable_io_interrupt, 376 &pic_configure_io_interrupt, 377 &pic_is_spurious_interrupt, 378 &pic_end_of_interrupt 379 }; 380 381 // Start initialization sequence for the master and slave PICs 382 out8(PIC_INIT1 | PIC_INIT1_SEND_INIT4, PIC_MASTER_INIT1); 383 out8(PIC_INIT1 | PIC_INIT1_SEND_INIT4, PIC_SLAVE_INIT1); 384 385 // Set start of interrupts to 0x20 for master, 0x28 for slave 386 out8(ARCH_INTERRUPT_BASE, PIC_MASTER_INIT2); 387 out8(ARCH_INTERRUPT_BASE + PIC_SLAVE_INT_BASE, PIC_SLAVE_INIT2); 388 389 // Specify cascading through interrupt 2 390 out8(PIC_INIT3_IR2_IS_SLAVE, PIC_MASTER_INIT3); 391 out8(PIC_INIT3_SLAVE_ID2, PIC_SLAVE_INIT3); 392 393 // Set both to operate in 8086 mode 394 out8(PIC_INIT4_x86_MODE, PIC_MASTER_INIT4); 395 out8(PIC_INIT4_x86_MODE, PIC_SLAVE_INIT4); 396 397 out8(0xfb, PIC_MASTER_MASK); // Mask off all interrupts (except slave pic line IRQ 2). 398 out8(0xff, PIC_SLAVE_MASK); // Mask off interrupts on the slave. 399 400 // determine which interrupts are level or edge triggered 401 402 #if 0 403 // should set everything possible to level triggered 404 out8(0xf8, PIC_MASTER_TRIGGER_MODE); 405 out8(0xde, PIC_SLAVE_TRIGGER_MODE); 406 #endif 407 408 sLevelTriggeredInterrupts = in8(PIC_MASTER_TRIGGER_MODE) 409 | (in8(PIC_SLAVE_TRIGGER_MODE) << 8); 410 411 TRACE(("PIC level trigger mode: 0x%08lx\n", sLevelTriggeredInterrupts)); 412 413 // make the pic controller the current one 414 sCurrentPIC = &picController; 415 } 416 417 418 // #pragma mark - I/O APIC 419 420 421 static inline uint32 422 ioapic_read_32(uint8 registerSelect) 423 { 424 sIOAPIC->io_register_select = registerSelect; 425 return sIOAPIC->io_window_register; 426 } 427 428 429 static inline void 430 ioapic_write_32(uint8 registerSelect, uint32 value) 431 { 432 sIOAPIC->io_register_select = registerSelect; 433 sIOAPIC->io_window_register = value; 434 } 435 436 437 static inline uint64 438 ioapic_read_64(uint8 registerSelect) 439 { 440 sIOAPIC->io_register_select = registerSelect + 1; 441 uint64 result = sIOAPIC->io_window_register; 442 result <<= 32; 443 sIOAPIC->io_register_select = registerSelect; 444 result |= sIOAPIC->io_window_register; 445 return result; 446 } 447 448 449 static inline void 450 ioapic_write_64(uint8 registerSelect, uint64 value) 451 { 452 sIOAPIC->io_register_select = registerSelect; 453 sIOAPIC->io_window_register = (uint32)value; 454 sIOAPIC->io_register_select = registerSelect + 1; 455 sIOAPIC->io_window_register = (uint32)(value >> 32); 456 } 457 458 459 static bool 460 ioapic_is_spurious_interrupt(int32 num) 461 { 462 // the spurious interrupt vector is initialized to the max value in smp 463 return num == 0xff - ARCH_INTERRUPT_BASE; 464 } 465 466 467 static bool 468 ioapic_end_of_interrupt(int32 num) 469 { 470 apic_end_of_interrupt(); 471 return true; 472 } 473 474 475 static void 476 ioapic_enable_io_interrupt(int32 num) 477 { 478 int32 pin = sIRQToIOAPICPin[num]; 479 if (pin < 0 || pin > (int32)sIOAPICMaxRedirectionEntry) 480 return; 481 482 TRACE(("ioapic_enable_io_interrupt: IRQ %ld -> pin %ld\n", num, pin)); 483 484 uint64 entry = ioapic_read_64(IO_APIC_REDIRECTION_TABLE + pin * 2); 485 entry &= ~(1 << IO_APIC_INTERRUPT_MASK_SHIFT); 486 entry |= IO_APIC_INTERRUPT_UNMASKED << IO_APIC_INTERRUPT_MASK_SHIFT; 487 ioapic_write_64(IO_APIC_REDIRECTION_TABLE + pin * 2, entry); 488 } 489 490 491 static void 492 ioapic_disable_io_interrupt(int32 num) 493 { 494 int32 pin = sIRQToIOAPICPin[num]; 495 if (pin < 0 || pin > (int32)sIOAPICMaxRedirectionEntry) 496 return; 497 498 TRACE(("ioapic_disable_io_interrupt: IRQ %ld -> pin %ld\n", num, pin)); 499 500 uint64 entry = ioapic_read_64(IO_APIC_REDIRECTION_TABLE + pin * 2); 501 entry &= ~(1 << IO_APIC_INTERRUPT_MASK_SHIFT); 502 entry |= IO_APIC_INTERRUPT_MASKED << IO_APIC_INTERRUPT_MASK_SHIFT; 503 ioapic_write_64(IO_APIC_REDIRECTION_TABLE + pin * 2, entry); 504 } 505 506 507 static void 508 ioapic_configure_io_interrupt(int32 num, uint32 config) 509 { 510 int32 pin = sIRQToIOAPICPin[num]; 511 if (pin < 0 || pin > (int32)sIOAPICMaxRedirectionEntry) 512 return; 513 514 TRACE(("ioapic_configure_io_interrupt: IRQ %ld -> pin %ld; config 0x%08lx\n", 515 num, pin, config)); 516 517 uint64 entry = ioapic_read_64(IO_APIC_REDIRECTION_TABLE + pin * 2); 518 entry &= ~((1 << IO_APIC_TRIGGER_MODE_SHIFT) 519 | (1 << IO_APIC_PIN_POLARITY_SHIFT) 520 | (IO_APIC_INTERRUPT_VECTOR_MASK << IO_APIC_INTERRUPT_VECTOR_SHIFT)); 521 522 if (config & B_LEVEL_TRIGGERED) { 523 entry |= (IO_APIC_TRIGGER_MODE_LEVEL << IO_APIC_TRIGGER_MODE_SHIFT); 524 sLevelTriggeredInterrupts |= (1 << num); 525 } else { 526 entry |= (IO_APIC_TRIGGER_MODE_EDGE << IO_APIC_TRIGGER_MODE_SHIFT); 527 sLevelTriggeredInterrupts &= ~(1 << num); 528 } 529 530 if (config & B_LOW_ACTIVE_POLARITY) 531 entry |= (IO_APIC_PIN_POLARITY_LOW_ACTIVE << IO_APIC_PIN_POLARITY_SHIFT); 532 else 533 entry |= (IO_APIC_PIN_POLARITY_HIGH_ACTIVE << IO_APIC_PIN_POLARITY_SHIFT); 534 535 entry |= (num + ARCH_INTERRUPT_BASE) << IO_APIC_INTERRUPT_VECTOR_SHIFT; 536 ioapic_write_64(IO_APIC_REDIRECTION_TABLE + pin * 2, entry); 537 } 538 539 540 static void 541 ioapic_map(kernel_args* args) 542 { 543 if (args->arch_args.apic == NULL) { 544 dprintf("no local apic available\n"); 545 return; 546 } 547 548 if (args->arch_args.ioapic == NULL) { 549 dprintf("no ioapic available, not using ioapics for interrupt routing\n"); 550 return; 551 } 552 553 // map in the ioapic 554 sIOAPIC = (ioapic *)args->arch_args.ioapic; 555 if (vm_map_physical_memory(B_SYSTEM_TEAM, "ioapic", (void**)&sIOAPIC, 556 B_EXACT_ADDRESS, B_PAGE_SIZE, 557 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 558 args->arch_args.ioapic_phys, true) < 0) { 559 panic("mapping the ioapic failed"); 560 return; 561 } 562 } 563 564 565 static void 566 ioapic_init(kernel_args* args) 567 { 568 static const interrupt_controller ioapicController = { 569 "82093AA IOAPIC", 570 &ioapic_enable_io_interrupt, 571 &ioapic_disable_io_interrupt, 572 &ioapic_configure_io_interrupt, 573 &ioapic_is_spurious_interrupt, 574 &ioapic_end_of_interrupt 575 }; 576 577 if (sIOAPIC == NULL) 578 return; 579 580 if (get_safemode_boolean(B_SAFEMODE_DISABLE_IOAPIC, true)) { 581 dprintf("ioapic explicitly disabled, not using ioapics for interrupt " 582 "routing\n"); 583 return; 584 } 585 586 uint32 version = ioapic_read_32(IO_APIC_VERSION); 587 if (version == 0xffffffff) { 588 dprintf("ioapic seems inaccessible, not using it\n"); 589 return; 590 } 591 592 // load acpi module 593 status_t status; 594 acpi_module_info* acpiModule; 595 status = get_module(B_ACPI_MODULE_NAME, (module_info**)&acpiModule); 596 if (status != B_OK) { 597 dprintf("acpi module not available, not configuring ioapic\n"); 598 return; 599 } 600 BPrivate::CObjectDeleter<const char, status_t> 601 acpiModulePutter(B_ACPI_MODULE_NAME, put_module); 602 603 // load pci module 604 pci_module_info* pciModule; 605 status = get_module(B_PCI_MODULE_NAME, (module_info**)&pciModule); 606 if (status != B_OK) { 607 dprintf("could not load pci module, not configuring ioapic\n"); 608 return; 609 } 610 CObjectDeleter<const char, status_t> pciModulePutter(B_PCI_MODULE_NAME, 611 put_module); 612 613 // TODO: here ACPI needs to be used to properly set up the PCI IRQ 614 // routing. 615 616 IRQRoutingTable table; 617 status = read_irq_routing_table(pciModule, acpiModule, &table); 618 if (status != B_OK) { 619 dprintf("reading IRQ routing table failed, no ioapic.\n"); 620 return; 621 } 622 623 sLevelTriggeredInterrupts = 0; 624 sIOAPICMaxRedirectionEntry 625 = ((version >> IO_APIC_MAX_REDIRECTION_ENTRY_SHIFT) 626 & IO_APIC_MAX_REDIRECTION_ENTRY_MASK); 627 628 // use the boot CPU as the target for all interrupts 629 uint64 targetAPIC = args->arch_args.cpu_apic_id[0]; 630 631 // program the interrupt vectors of the ioapic 632 for (uint32 i = 0; i <= sIOAPICMaxRedirectionEntry; i++) { 633 // initialize everything to deliver to the boot CPU in physical mode 634 // and masked until explicitly enabled through enable_io_interrupt() 635 uint64 entry = (targetAPIC << IO_APIC_DESTINATION_FIELD_SHIFT) 636 | (IO_APIC_INTERRUPT_MASKED << IO_APIC_INTERRUPT_MASK_SHIFT) 637 | (IO_APIC_DESTINATION_MODE_PHYSICAL << IO_APIC_DESTINATION_MODE_SHIFT) 638 | ((i + ARCH_INTERRUPT_BASE) << IO_APIC_INTERRUPT_VECTOR_SHIFT); 639 640 if (i == 0) { 641 // make redirection entry 0 into an external interrupt 642 entry |= (IO_APIC_TRIGGER_MODE_EDGE << IO_APIC_TRIGGER_MODE_SHIFT) 643 | (IO_APIC_PIN_POLARITY_HIGH_ACTIVE << IO_APIC_PIN_POLARITY_SHIFT) 644 | (IO_APIC_DELIVERY_MODE_EXT_INT << IO_APIC_DELIVERY_MODE_SHIFT); 645 } else if (i < 16) { 646 // make 1-15 ISA interrupts 647 entry |= (IO_APIC_TRIGGER_MODE_EDGE << IO_APIC_TRIGGER_MODE_SHIFT) 648 | (IO_APIC_PIN_POLARITY_HIGH_ACTIVE << IO_APIC_PIN_POLARITY_SHIFT) 649 | (IO_APIC_DELIVERY_MODE_FIXED << IO_APIC_DELIVERY_MODE_SHIFT); 650 } else { 651 // and the rest are PCI interrupts 652 entry |= (IO_APIC_TRIGGER_MODE_LEVEL << IO_APIC_TRIGGER_MODE_SHIFT) 653 | (IO_APIC_PIN_POLARITY_LOW_ACTIVE << IO_APIC_PIN_POLARITY_SHIFT) 654 | (IO_APIC_DELIVERY_MODE_FIXED << IO_APIC_DELIVERY_MODE_SHIFT); 655 sLevelTriggeredInterrupts |= (1 << i); 656 } 657 658 ioapic_write_64(IO_APIC_REDIRECTION_TABLE + 2 * i, entry); 659 } 660 661 // setup default 1:1 mapping 662 for (uint32 i = 0; i < 256; i++) 663 sIRQToIOAPICPin[i] = i; 664 665 // configure apic interrupts assume 1:1 mapping 666 for (int i = 0; i < table.Count(); i++) { 667 irq_routing_entry& entry = table.ElementAt(i); 668 irq_descriptor irqDescriptor; 669 read_current_irq(acpiModule, entry.source, &irqDescriptor); 670 uint32 config = 0; 671 config |= irqDescriptor.polarity; 672 config |= irqDescriptor.interrupt_mode; 673 674 int32 num = entry.source_index; 675 for (int a = 0; a < 16 && num == 0; a++) { 676 if (irqDescriptor.irq >> i & 0x01) { 677 num = a; 678 break; 679 } 680 } 681 ioapic_configure_io_interrupt(num, config); 682 } 683 684 // prefer the ioapic over the normal pic 685 dprintf("using ioapic for interrupt routing\n"); 686 sCurrentPIC = &ioapicController; 687 } 688 689 690 // #pragma mark - 691 692 693 void 694 arch_int_enable_io_interrupt(int irq) 695 { 696 sCurrentPIC->enable_io_interrupt(irq); 697 } 698 699 700 void 701 arch_int_disable_io_interrupt(int irq) 702 { 703 sCurrentPIC->disable_io_interrupt(irq); 704 } 705 706 707 void 708 arch_int_configure_io_interrupt(int irq, uint32 config) 709 { 710 sCurrentPIC->configure_io_interrupt(irq, config); 711 } 712 713 714 #undef arch_int_enable_interrupts 715 #undef arch_int_disable_interrupts 716 #undef arch_int_restore_interrupts 717 #undef arch_int_are_interrupts_enabled 718 719 720 void 721 arch_int_enable_interrupts(void) 722 { 723 arch_int_enable_interrupts_inline(); 724 } 725 726 727 int 728 arch_int_disable_interrupts(void) 729 { 730 return arch_int_disable_interrupts_inline(); 731 } 732 733 734 void 735 arch_int_restore_interrupts(int oldState) 736 { 737 arch_int_restore_interrupts_inline(oldState); 738 } 739 740 741 bool 742 arch_int_are_interrupts_enabled(void) 743 { 744 return arch_int_are_interrupts_enabled_inline(); 745 } 746 747 748 static const char * 749 exception_name(int number, char *buffer, int32 bufferSize) 750 { 751 if (number >= 0 && number < kInterruptNameCount) 752 return kInterruptNames[number]; 753 754 snprintf(buffer, bufferSize, "exception %d", number); 755 return buffer; 756 } 757 758 759 static void 760 invalid_exception(struct iframe* frame) 761 { 762 struct thread* thread = thread_get_current_thread(); 763 char name[32]; 764 panic("unhandled trap 0x%lx (%s) at ip 0x%lx, thread %ld!\n", 765 frame->vector, exception_name(frame->vector, name, sizeof(name)), 766 frame->eip, thread ? thread->id : -1); 767 } 768 769 770 static void 771 fatal_exception(struct iframe *frame) 772 { 773 char name[32]; 774 panic("Fatal exception \"%s\" occurred! Error code: 0x%lx\n", 775 exception_name(frame->vector, name, sizeof(name)), frame->error_code); 776 } 777 778 779 static void 780 unexpected_exception(struct iframe* frame) 781 { 782 debug_exception_type type; 783 int signal; 784 785 if (IFRAME_IS_VM86(frame)) { 786 x86_vm86_return((struct vm86_iframe *)frame, (frame->vector == 13) ? 787 B_OK : B_ERROR); 788 // won't get here 789 } 790 791 switch (frame->vector) { 792 case 0: // Divide Error Exception (#DE) 793 type = B_DIVIDE_ERROR; 794 signal = SIGFPE; 795 break; 796 797 case 4: // Overflow Exception (#OF) 798 type = B_OVERFLOW_EXCEPTION; 799 signal = SIGTRAP; 800 break; 801 802 case 5: // BOUND Range Exceeded Exception (#BR) 803 type = B_BOUNDS_CHECK_EXCEPTION; 804 signal = SIGTRAP; 805 break; 806 807 case 6: // Invalid Opcode Exception (#UD) 808 type = B_INVALID_OPCODE_EXCEPTION; 809 signal = SIGILL; 810 break; 811 812 case 13: // General Protection Exception (#GP) 813 type = B_GENERAL_PROTECTION_FAULT; 814 signal = SIGILL; 815 break; 816 817 case 16: // x87 FPU Floating-Point Error (#MF) 818 type = B_FLOATING_POINT_EXCEPTION; 819 signal = SIGFPE; 820 break; 821 822 case 17: // Alignment Check Exception (#AC) 823 type = B_ALIGNMENT_EXCEPTION; 824 signal = SIGTRAP; 825 break; 826 827 case 19: // SIMD Floating-Point Exception (#XF) 828 type = B_FLOATING_POINT_EXCEPTION; 829 signal = SIGFPE; 830 break; 831 832 default: 833 invalid_exception(frame); 834 return; 835 } 836 837 if (IFRAME_IS_USER(frame)) { 838 struct sigaction action; 839 struct thread* thread = thread_get_current_thread(); 840 841 enable_interrupts(); 842 843 // If the thread has a signal handler for the signal, we simply send it 844 // the signal. Otherwise we notify the user debugger first. 845 if (sigaction(signal, NULL, &action) == 0 846 && action.sa_handler != SIG_DFL 847 && action.sa_handler != SIG_IGN) { 848 send_signal(thread->id, signal); 849 } else if (user_debug_exception_occurred(type, signal)) 850 send_signal(team_get_current_team_id(), signal); 851 } else { 852 char name[32]; 853 panic("Unexpected exception \"%s\" occurred in kernel mode! " 854 "Error code: 0x%lx\n", 855 exception_name(frame->vector, name, sizeof(name)), 856 frame->error_code); 857 } 858 } 859 860 861 void 862 x86_double_fault_exception(struct iframe* frame) 863 { 864 int cpu = x86_double_fault_get_cpu(); 865 866 // The double fault iframe contains no useful information (as 867 // per Intel's architecture spec). Thus we simply save the 868 // information from the (unhandlable) exception which caused the 869 // double in our iframe. This will result even in useful stack 870 // traces. Only problem is that we trust that at least the 871 // TSS is still accessible. 872 struct tss *tss = &gCPU[cpu].arch.tss; 873 874 frame->cs = tss->cs; 875 frame->es = tss->es; 876 frame->ds = tss->ds; 877 frame->fs = tss->fs; 878 frame->gs = tss->gs; 879 frame->eip = tss->eip; 880 frame->ebp = tss->ebp; 881 frame->esp = tss->esp; 882 frame->eax = tss->eax; 883 frame->ebx = tss->ebx; 884 frame->ecx = tss->ecx; 885 frame->edx = tss->edx; 886 frame->esi = tss->esi; 887 frame->edi = tss->edi; 888 frame->flags = tss->eflags; 889 890 // Use a special handler for page faults which avoids the triple fault 891 // pitfalls. 892 set_interrupt_gate(cpu, 14, &trap14_double_fault); 893 894 debug_double_fault(cpu); 895 } 896 897 898 void 899 x86_page_fault_exception_double_fault(struct iframe* frame) 900 { 901 uint32 cr2; 902 asm("movl %%cr2, %0" : "=r" (cr2)); 903 904 // Only if this CPU has a fault handler, we're allowed to be here. 905 cpu_ent& cpu = gCPU[x86_double_fault_get_cpu()]; 906 addr_t faultHandler = cpu.fault_handler; 907 if (faultHandler != 0) { 908 debug_set_page_fault_info(cr2, frame->eip, 909 (frame->error_code & 0x2) != 0 ? DEBUG_PAGE_FAULT_WRITE : 0); 910 frame->eip = faultHandler; 911 frame->ebp = cpu.fault_handler_stack_pointer; 912 return; 913 } 914 915 // No fault handler. This is bad. Since we originally came from a double 916 // fault, we don't try to reenter the kernel debugger. Instead we just 917 // print the info we've got and enter an infinite loop. 918 kprintf("Page fault in double fault debugger without fault handler! " 919 "Touching address %p from eip %p. Entering infinite loop...\n", 920 (void*)cr2, (void*)frame->eip); 921 922 while (true); 923 } 924 925 926 static void 927 page_fault_exception(struct iframe* frame) 928 { 929 struct thread *thread = thread_get_current_thread(); 930 uint32 cr2; 931 addr_t newip; 932 933 asm("movl %%cr2, %0" : "=r" (cr2)); 934 935 if (debug_debugger_running()) { 936 // If this CPU or this thread has a fault handler, we're allowed to be 937 // here. 938 if (thread != NULL) { 939 cpu_ent* cpu = &gCPU[smp_get_current_cpu()]; 940 if (cpu->fault_handler != 0) { 941 debug_set_page_fault_info(cr2, frame->eip, 942 (frame->error_code & 0x2) != 0 943 ? DEBUG_PAGE_FAULT_WRITE : 0); 944 frame->eip = cpu->fault_handler; 945 frame->ebp = cpu->fault_handler_stack_pointer; 946 return; 947 } 948 949 if (thread->fault_handler != 0) { 950 kprintf("ERROR: thread::fault_handler used in kernel " 951 "debugger!\n"); 952 debug_set_page_fault_info(cr2, frame->eip, 953 (frame->error_code & 0x2) != 0 954 ? DEBUG_PAGE_FAULT_WRITE : 0); 955 frame->eip = thread->fault_handler; 956 return; 957 } 958 } 959 960 // otherwise, not really 961 panic("page fault in debugger without fault handler! Touching " 962 "address %p from eip %p\n", (void *)cr2, (void *)frame->eip); 963 return; 964 } else if ((frame->flags & 0x200) == 0) { 965 // interrupts disabled 966 967 // If a page fault handler is installed, we're allowed to be here. 968 // TODO: Now we are generally allowing user_memcpy() with interrupts 969 // disabled, which in most cases is a bug. We should add some thread 970 // flag allowing to explicitly indicate that this handling is desired. 971 if (thread && thread->fault_handler != 0) { 972 if (frame->eip != thread->fault_handler) { 973 frame->eip = thread->fault_handler; 974 return; 975 } 976 977 // The fault happened at the fault handler address. This is a 978 // certain infinite loop. 979 panic("page fault, interrupts disabled, fault handler loop. " 980 "Touching address %p from eip %p\n", (void*)cr2, 981 (void*)frame->eip); 982 } 983 984 // If we are not running the kernel startup the page fault was not 985 // allowed to happen and we must panic. 986 panic("page fault, but interrupts were disabled. Touching address " 987 "%p from eip %p\n", (void *)cr2, (void *)frame->eip); 988 return; 989 } else if (thread != NULL && thread->page_faults_allowed < 1) { 990 panic("page fault not allowed at this place. Touching address " 991 "%p from eip %p\n", (void *)cr2, (void *)frame->eip); 992 return; 993 } 994 995 enable_interrupts(); 996 997 vm_page_fault(cr2, frame->eip, 998 (frame->error_code & 0x2) != 0, // write access 999 (frame->error_code & 0x4) != 0, // userland 1000 &newip); 1001 if (newip != 0) { 1002 // the page fault handler wants us to modify the iframe to set the 1003 // IP the cpu will return to to be this ip 1004 frame->eip = newip; 1005 } 1006 } 1007 1008 1009 static void 1010 hardware_interrupt(struct iframe* frame) 1011 { 1012 int32 vector = frame->vector - ARCH_INTERRUPT_BASE; 1013 bool levelTriggered = false; 1014 struct thread* thread = thread_get_current_thread(); 1015 1016 if (sCurrentPIC->is_spurious_interrupt(vector)) { 1017 TRACE(("got spurious interrupt at vector %ld\n", vector)); 1018 return; 1019 } 1020 1021 if (vector < 32) 1022 levelTriggered = (sLevelTriggeredInterrupts & (1 << vector)) != 0; 1023 1024 if (!levelTriggered) { 1025 // if it's not handled by the current pic then it's an apic generated 1026 // interrupt like local interrupts, msi or ipi. 1027 if (!sCurrentPIC->end_of_interrupt(vector)) 1028 apic_end_of_interrupt(); 1029 } 1030 1031 int_io_interrupt_handler(vector, levelTriggered); 1032 1033 if (levelTriggered) { 1034 if (!sCurrentPIC->end_of_interrupt(vector)) 1035 apic_end_of_interrupt(); 1036 } 1037 1038 cpu_status state = disable_interrupts(); 1039 if (thread->cpu->invoke_scheduler) { 1040 GRAB_THREAD_LOCK(); 1041 scheduler_reschedule(); 1042 RELEASE_THREAD_LOCK(); 1043 restore_interrupts(state); 1044 } else if (thread->post_interrupt_callback != NULL) { 1045 restore_interrupts(state); 1046 void (*callback)(void*) = thread->post_interrupt_callback; 1047 void* data = thread->post_interrupt_data; 1048 1049 thread->post_interrupt_callback = NULL; 1050 thread->post_interrupt_data = NULL; 1051 1052 callback(data); 1053 } 1054 } 1055 1056 1057 status_t 1058 arch_int_init(struct kernel_args *args) 1059 { 1060 int i; 1061 interrupt_handler_function** table; 1062 1063 // set the global sIDT variable 1064 sIDTs[0] = (desc_table *)args->arch_args.vir_idt; 1065 1066 // setup the standard programmable interrupt controller 1067 pic_init(); 1068 1069 set_interrupt_gate(0, 0, &trap0); 1070 set_interrupt_gate(0, 1, &trap1); 1071 set_interrupt_gate(0, 2, &trap2); 1072 set_trap_gate(0, 3, &trap3); 1073 set_interrupt_gate(0, 4, &trap4); 1074 set_interrupt_gate(0, 5, &trap5); 1075 set_interrupt_gate(0, 6, &trap6); 1076 set_interrupt_gate(0, 7, &trap7); 1077 // trap8 (double fault) is set in arch_cpu.c 1078 set_interrupt_gate(0, 9, &trap9); 1079 set_interrupt_gate(0, 10, &trap10); 1080 set_interrupt_gate(0, 11, &trap11); 1081 set_interrupt_gate(0, 12, &trap12); 1082 set_interrupt_gate(0, 13, &trap13); 1083 set_interrupt_gate(0, 14, &trap14); 1084 // set_interrupt_gate(0, 15, &trap15); 1085 set_interrupt_gate(0, 16, &trap16); 1086 set_interrupt_gate(0, 17, &trap17); 1087 set_interrupt_gate(0, 18, &trap18); 1088 set_interrupt_gate(0, 19, &trap19); 1089 1090 // legacy or ioapic interrupts 1091 set_interrupt_gate(0, 32, &trap32); 1092 set_interrupt_gate(0, 33, &trap33); 1093 set_interrupt_gate(0, 34, &trap34); 1094 set_interrupt_gate(0, 35, &trap35); 1095 set_interrupt_gate(0, 36, &trap36); 1096 set_interrupt_gate(0, 37, &trap37); 1097 set_interrupt_gate(0, 38, &trap38); 1098 set_interrupt_gate(0, 39, &trap39); 1099 set_interrupt_gate(0, 40, &trap40); 1100 set_interrupt_gate(0, 41, &trap41); 1101 set_interrupt_gate(0, 42, &trap42); 1102 set_interrupt_gate(0, 43, &trap43); 1103 set_interrupt_gate(0, 44, &trap44); 1104 set_interrupt_gate(0, 45, &trap45); 1105 set_interrupt_gate(0, 46, &trap46); 1106 set_interrupt_gate(0, 47, &trap47); 1107 1108 // additional ioapic interrupts 1109 set_interrupt_gate(0, 48, &trap48); 1110 set_interrupt_gate(0, 49, &trap49); 1111 set_interrupt_gate(0, 50, &trap50); 1112 set_interrupt_gate(0, 51, &trap51); 1113 set_interrupt_gate(0, 52, &trap52); 1114 set_interrupt_gate(0, 53, &trap53); 1115 set_interrupt_gate(0, 54, &trap54); 1116 set_interrupt_gate(0, 55, &trap55); 1117 1118 // configurable msi or msi-x interrupts 1119 set_interrupt_gate(0, 56, &trap56); 1120 set_interrupt_gate(0, 57, &trap57); 1121 set_interrupt_gate(0, 58, &trap58); 1122 set_interrupt_gate(0, 59, &trap59); 1123 set_interrupt_gate(0, 60, &trap60); 1124 set_interrupt_gate(0, 61, &trap61); 1125 set_interrupt_gate(0, 62, &trap62); 1126 set_interrupt_gate(0, 63, &trap63); 1127 set_interrupt_gate(0, 64, &trap64); 1128 set_interrupt_gate(0, 65, &trap65); 1129 set_interrupt_gate(0, 66, &trap66); 1130 set_interrupt_gate(0, 67, &trap67); 1131 set_interrupt_gate(0, 68, &trap68); 1132 set_interrupt_gate(0, 69, &trap69); 1133 set_interrupt_gate(0, 70, &trap70); 1134 set_interrupt_gate(0, 71, &trap71); 1135 set_interrupt_gate(0, 72, &trap72); 1136 set_interrupt_gate(0, 73, &trap73); 1137 set_interrupt_gate(0, 74, &trap74); 1138 set_interrupt_gate(0, 75, &trap75); 1139 set_interrupt_gate(0, 76, &trap76); 1140 set_interrupt_gate(0, 77, &trap77); 1141 set_interrupt_gate(0, 78, &trap78); 1142 set_interrupt_gate(0, 79, &trap79); 1143 set_interrupt_gate(0, 80, &trap80); 1144 set_interrupt_gate(0, 81, &trap81); 1145 set_interrupt_gate(0, 82, &trap82); 1146 set_interrupt_gate(0, 83, &trap83); 1147 set_interrupt_gate(0, 84, &trap84); 1148 set_interrupt_gate(0, 85, &trap85); 1149 set_interrupt_gate(0, 86, &trap86); 1150 set_interrupt_gate(0, 87, &trap87); 1151 set_interrupt_gate(0, 88, &trap88); 1152 set_interrupt_gate(0, 89, &trap89); 1153 set_interrupt_gate(0, 90, &trap90); 1154 set_interrupt_gate(0, 91, &trap91); 1155 set_interrupt_gate(0, 92, &trap92); 1156 set_interrupt_gate(0, 93, &trap93); 1157 set_interrupt_gate(0, 94, &trap94); 1158 set_interrupt_gate(0, 95, &trap95); 1159 set_interrupt_gate(0, 96, &trap96); 1160 set_interrupt_gate(0, 97, &trap97); 1161 1162 set_trap_gate(0, 98, &trap98); // for performance testing only 1163 set_trap_gate(0, 99, &trap99); // syscall interrupt 1164 1165 // configurable msi or msi-x interrupts 1166 set_interrupt_gate(0, 100, &trap100); 1167 set_interrupt_gate(0, 101, &trap101); 1168 set_interrupt_gate(0, 102, &trap102); 1169 set_interrupt_gate(0, 103, &trap103); 1170 set_interrupt_gate(0, 104, &trap104); 1171 set_interrupt_gate(0, 105, &trap105); 1172 set_interrupt_gate(0, 106, &trap106); 1173 set_interrupt_gate(0, 107, &trap107); 1174 set_interrupt_gate(0, 108, &trap108); 1175 set_interrupt_gate(0, 109, &trap109); 1176 set_interrupt_gate(0, 110, &trap110); 1177 set_interrupt_gate(0, 111, &trap111); 1178 set_interrupt_gate(0, 112, &trap112); 1179 set_interrupt_gate(0, 113, &trap113); 1180 set_interrupt_gate(0, 114, &trap114); 1181 set_interrupt_gate(0, 115, &trap115); 1182 set_interrupt_gate(0, 116, &trap116); 1183 set_interrupt_gate(0, 117, &trap117); 1184 set_interrupt_gate(0, 118, &trap118); 1185 set_interrupt_gate(0, 119, &trap119); 1186 set_interrupt_gate(0, 120, &trap120); 1187 set_interrupt_gate(0, 121, &trap121); 1188 set_interrupt_gate(0, 122, &trap122); 1189 set_interrupt_gate(0, 123, &trap123); 1190 set_interrupt_gate(0, 124, &trap124); 1191 set_interrupt_gate(0, 125, &trap125); 1192 set_interrupt_gate(0, 126, &trap126); 1193 set_interrupt_gate(0, 127, &trap127); 1194 set_interrupt_gate(0, 128, &trap128); 1195 set_interrupt_gate(0, 129, &trap129); 1196 set_interrupt_gate(0, 130, &trap130); 1197 set_interrupt_gate(0, 131, &trap131); 1198 set_interrupt_gate(0, 132, &trap132); 1199 set_interrupt_gate(0, 133, &trap133); 1200 set_interrupt_gate(0, 134, &trap134); 1201 set_interrupt_gate(0, 135, &trap135); 1202 set_interrupt_gate(0, 136, &trap136); 1203 set_interrupt_gate(0, 137, &trap137); 1204 set_interrupt_gate(0, 138, &trap138); 1205 set_interrupt_gate(0, 139, &trap139); 1206 set_interrupt_gate(0, 140, &trap140); 1207 set_interrupt_gate(0, 141, &trap141); 1208 set_interrupt_gate(0, 142, &trap142); 1209 set_interrupt_gate(0, 143, &trap143); 1210 set_interrupt_gate(0, 144, &trap144); 1211 set_interrupt_gate(0, 145, &trap145); 1212 set_interrupt_gate(0, 146, &trap146); 1213 set_interrupt_gate(0, 147, &trap147); 1214 set_interrupt_gate(0, 148, &trap148); 1215 set_interrupt_gate(0, 149, &trap149); 1216 set_interrupt_gate(0, 150, &trap150); 1217 set_interrupt_gate(0, 151, &trap151); 1218 set_interrupt_gate(0, 152, &trap152); 1219 set_interrupt_gate(0, 153, &trap153); 1220 set_interrupt_gate(0, 154, &trap154); 1221 set_interrupt_gate(0, 155, &trap155); 1222 set_interrupt_gate(0, 156, &trap156); 1223 set_interrupt_gate(0, 157, &trap157); 1224 set_interrupt_gate(0, 158, &trap158); 1225 set_interrupt_gate(0, 159, &trap159); 1226 set_interrupt_gate(0, 160, &trap160); 1227 set_interrupt_gate(0, 161, &trap161); 1228 set_interrupt_gate(0, 162, &trap162); 1229 set_interrupt_gate(0, 163, &trap163); 1230 set_interrupt_gate(0, 164, &trap164); 1231 set_interrupt_gate(0, 165, &trap165); 1232 set_interrupt_gate(0, 166, &trap166); 1233 set_interrupt_gate(0, 167, &trap167); 1234 set_interrupt_gate(0, 168, &trap168); 1235 set_interrupt_gate(0, 169, &trap169); 1236 set_interrupt_gate(0, 170, &trap170); 1237 set_interrupt_gate(0, 171, &trap171); 1238 set_interrupt_gate(0, 172, &trap172); 1239 set_interrupt_gate(0, 173, &trap173); 1240 set_interrupt_gate(0, 174, &trap174); 1241 set_interrupt_gate(0, 175, &trap175); 1242 set_interrupt_gate(0, 176, &trap176); 1243 set_interrupt_gate(0, 177, &trap177); 1244 set_interrupt_gate(0, 178, &trap178); 1245 set_interrupt_gate(0, 179, &trap179); 1246 set_interrupt_gate(0, 180, &trap180); 1247 set_interrupt_gate(0, 181, &trap181); 1248 set_interrupt_gate(0, 182, &trap182); 1249 set_interrupt_gate(0, 183, &trap183); 1250 set_interrupt_gate(0, 184, &trap184); 1251 set_interrupt_gate(0, 185, &trap185); 1252 set_interrupt_gate(0, 186, &trap186); 1253 set_interrupt_gate(0, 187, &trap187); 1254 set_interrupt_gate(0, 188, &trap188); 1255 set_interrupt_gate(0, 189, &trap189); 1256 set_interrupt_gate(0, 190, &trap190); 1257 set_interrupt_gate(0, 191, &trap191); 1258 set_interrupt_gate(0, 192, &trap192); 1259 set_interrupt_gate(0, 193, &trap193); 1260 set_interrupt_gate(0, 194, &trap194); 1261 set_interrupt_gate(0, 195, &trap195); 1262 set_interrupt_gate(0, 196, &trap196); 1263 set_interrupt_gate(0, 197, &trap197); 1264 set_interrupt_gate(0, 198, &trap198); 1265 set_interrupt_gate(0, 199, &trap199); 1266 set_interrupt_gate(0, 200, &trap200); 1267 set_interrupt_gate(0, 201, &trap201); 1268 set_interrupt_gate(0, 202, &trap202); 1269 set_interrupt_gate(0, 203, &trap203); 1270 set_interrupt_gate(0, 204, &trap204); 1271 set_interrupt_gate(0, 205, &trap205); 1272 set_interrupt_gate(0, 206, &trap206); 1273 set_interrupt_gate(0, 207, &trap207); 1274 set_interrupt_gate(0, 208, &trap208); 1275 set_interrupt_gate(0, 209, &trap209); 1276 set_interrupt_gate(0, 210, &trap210); 1277 set_interrupt_gate(0, 211, &trap211); 1278 set_interrupt_gate(0, 212, &trap212); 1279 set_interrupt_gate(0, 213, &trap213); 1280 set_interrupt_gate(0, 214, &trap214); 1281 set_interrupt_gate(0, 215, &trap215); 1282 set_interrupt_gate(0, 216, &trap216); 1283 set_interrupt_gate(0, 217, &trap217); 1284 set_interrupt_gate(0, 218, &trap218); 1285 set_interrupt_gate(0, 219, &trap219); 1286 set_interrupt_gate(0, 220, &trap220); 1287 set_interrupt_gate(0, 221, &trap221); 1288 set_interrupt_gate(0, 222, &trap222); 1289 set_interrupt_gate(0, 223, &trap223); 1290 set_interrupt_gate(0, 224, &trap224); 1291 set_interrupt_gate(0, 225, &trap225); 1292 set_interrupt_gate(0, 226, &trap226); 1293 set_interrupt_gate(0, 227, &trap227); 1294 set_interrupt_gate(0, 228, &trap228); 1295 set_interrupt_gate(0, 229, &trap229); 1296 set_interrupt_gate(0, 230, &trap230); 1297 set_interrupt_gate(0, 231, &trap231); 1298 set_interrupt_gate(0, 232, &trap232); 1299 set_interrupt_gate(0, 233, &trap233); 1300 set_interrupt_gate(0, 234, &trap234); 1301 set_interrupt_gate(0, 235, &trap235); 1302 set_interrupt_gate(0, 236, &trap236); 1303 set_interrupt_gate(0, 237, &trap237); 1304 set_interrupt_gate(0, 238, &trap238); 1305 set_interrupt_gate(0, 239, &trap239); 1306 set_interrupt_gate(0, 240, &trap240); 1307 set_interrupt_gate(0, 241, &trap241); 1308 set_interrupt_gate(0, 242, &trap242); 1309 set_interrupt_gate(0, 243, &trap243); 1310 set_interrupt_gate(0, 244, &trap244); 1311 set_interrupt_gate(0, 245, &trap245); 1312 set_interrupt_gate(0, 246, &trap246); 1313 set_interrupt_gate(0, 247, &trap247); 1314 set_interrupt_gate(0, 248, &trap248); 1315 set_interrupt_gate(0, 249, &trap249); 1316 set_interrupt_gate(0, 250, &trap250); 1317 1318 // smp / apic local interrupts 1319 set_interrupt_gate(0, 251, &trap251); 1320 set_interrupt_gate(0, 252, &trap252); 1321 set_interrupt_gate(0, 253, &trap253); 1322 set_interrupt_gate(0, 254, &trap254); 1323 set_interrupt_gate(0, 255, &trap255); 1324 1325 // init interrupt handler table 1326 table = gInterruptHandlerTable; 1327 1328 // defaults 1329 for (i = 0; i < ARCH_INTERRUPT_BASE; i++) 1330 table[i] = invalid_exception; 1331 for (i = ARCH_INTERRUPT_BASE; i < INTERRUPT_HANDLER_TABLE_SIZE; i++) 1332 table[i] = hardware_interrupt; 1333 1334 table[0] = unexpected_exception; // Divide Error Exception (#DE) 1335 table[1] = x86_handle_debug_exception; // Debug Exception (#DB) 1336 table[2] = fatal_exception; // NMI Interrupt 1337 table[3] = x86_handle_breakpoint_exception; // Breakpoint Exception (#BP) 1338 table[4] = unexpected_exception; // Overflow Exception (#OF) 1339 table[5] = unexpected_exception; // BOUND Range Exceeded Exception (#BR) 1340 table[6] = unexpected_exception; // Invalid Opcode Exception (#UD) 1341 table[7] = fatal_exception; // Device Not Available Exception (#NM) 1342 table[8] = x86_double_fault_exception; // Double Fault Exception (#DF) 1343 table[9] = fatal_exception; // Coprocessor Segment Overrun 1344 table[10] = fatal_exception; // Invalid TSS Exception (#TS) 1345 table[11] = fatal_exception; // Segment Not Present (#NP) 1346 table[12] = fatal_exception; // Stack Fault Exception (#SS) 1347 table[13] = unexpected_exception; // General Protection Exception (#GP) 1348 table[14] = page_fault_exception; // Page-Fault Exception (#PF) 1349 table[16] = unexpected_exception; // x87 FPU Floating-Point Error (#MF) 1350 table[17] = unexpected_exception; // Alignment Check Exception (#AC) 1351 table[18] = fatal_exception; // Machine-Check Exception (#MC) 1352 table[19] = unexpected_exception; // SIMD Floating-Point Exception (#XF) 1353 1354 return B_OK; 1355 } 1356 1357 1358 status_t 1359 arch_int_init_post_vm(struct kernel_args *args) 1360 { 1361 // Always init the local apic as it can be used for timers even if we 1362 // don't end up using the io apic 1363 apic_init(args); 1364 1365 // We need to map in the I/O APIC here, since we would lose the already 1366 // wired mapping before arch_int_init_io() is called. 1367 ioapic_map(args); 1368 1369 // create IDT area for the boot CPU 1370 area_id area = create_area("idt", (void**)&sIDTs[0], B_EXACT_ADDRESS, 1371 B_PAGE_SIZE, B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); 1372 if (area < 0) 1373 return area; 1374 1375 // create IDTs for the off-boot CPU 1376 size_t idtSize = 256 * 8; 1377 // 256 8 bytes-sized descriptors 1378 int32 cpuCount = smp_get_num_cpus(); 1379 if (cpuCount > 0) { 1380 size_t areaSize = ROUNDUP(cpuCount * idtSize, B_PAGE_SIZE); 1381 desc_table* idt; 1382 virtual_address_restrictions virtualRestrictions = {}; 1383 virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS; 1384 physical_address_restrictions physicalRestrictions = {}; 1385 area = create_area_etc(B_SYSTEM_TEAM, "idt", areaSize, B_CONTIGUOUS, 1386 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 1387 &virtualRestrictions, &physicalRestrictions, (void**)&idt); 1388 if (area < 0) 1389 return area; 1390 1391 for (int32 i = 1; i < cpuCount; i++) { 1392 sIDTs[i] = idt; 1393 memcpy(idt, sIDTs[0], idtSize); 1394 idt += 256; 1395 // The CPU's IDTR will be set in arch_cpu_init_percpu(). 1396 } 1397 } 1398 1399 return area >= B_OK ? B_OK : area; 1400 } 1401 1402 1403 status_t 1404 arch_int_init_io(kernel_args* args) 1405 { 1406 ioapic_init(args); 1407 return B_OK; 1408 } 1409 1410 1411 status_t 1412 arch_int_init_post_device_manager(struct kernel_args *args) 1413 { 1414 return B_OK; 1415 } 1416