1 /*- 2 * Copyright 1998 Massachusetts Institute of Technology 3 * 4 * Permission to use, copy, modify, and distribute this software and 5 * its documentation for any purpose and without fee is hereby 6 * granted, provided that both the above copyright notice and this 7 * permission notice appear in all copies, that both the above 8 * copyright notice and this permission notice appear in all 9 * supporting documentation, and that the name of M.I.T. not be used 10 * in advertising or publicity pertaining to distribution of the 11 * software without specific, written prior permission. M.I.T. makes 12 * no representations about the suitability of this software for any 13 * purpose. It is provided "as is" without express or implied 14 * warranty. 15 * 16 * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS 17 * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, 18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT 20 * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 /* 34 * This code implements a `root nexus' for Intel Architecture 35 * machines. The function of the root nexus is to serve as an 36 * attachment point for both processors and buses, and to manage 37 * resources which are common to all of them. In particular, 38 * this code implements the core resource managers for interrupt 39 * requests, DMA requests (which rightfully should be a part of the 40 * ISA code but it's easier to do it here for now), I/O port addresses, 41 * and I/O memory address space. 42 */ 43 44 #ifdef __amd64__ 45 #define DEV_APIC 46 #else 47 #include "opt_apic.h" 48 #endif 49 #include "opt_isa.h" 50 #include "opt_pci.h" 51 52 #include <sys/param.h> 53 #include <sys/systm.h> 54 #include <sys/bus.h> 55 #include <sys/interrupt.h> 56 #include <sys/kernel.h> 57 #include <sys/linker.h> 58 #include <sys/malloc.h> 59 #include <sys/module.h> 60 #include <sys/rman.h> 61 62 #include <vm/vm.h> 63 #include <vm/vm_param.h> 64 #include <vm/vm_page.h> 65 #include <vm/vm_phys.h> 66 #include <vm/vm_dumpset.h> 67 #include <vm/pmap.h> 68 69 #include <machine/bus.h> 70 #include <machine/intr_machdep.h> 71 #include <machine/md_var.h> 72 #include <machine/metadata.h> 73 #include <machine/nexusvar.h> 74 #include <machine/pc/bios.h> 75 #include <machine/resource.h> 76 77 #ifdef DEV_APIC 78 #include "pcib_if.h" 79 #endif 80 81 #ifdef DEV_ISA 82 #include <isa/isavar.h> 83 #include <isa/isareg.h> 84 #endif 85 86 #define ELF_KERN_STR ("elf"__XSTRING(__ELF_WORD_SIZE)" kernel") 87 88 static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device"); 89 90 #define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev)) 91 92 struct rman irq_rman, drq_rman, port_rman, mem_rman; 93 94 static int nexus_print_all_resources(device_t dev); 95 96 static device_probe_t nexus_probe; 97 static device_attach_t nexus_attach; 98 99 static bus_add_child_t nexus_add_child; 100 static bus_print_child_t nexus_print_child; 101 102 static bus_activate_resource_t nexus_activate_resource; 103 static bus_adjust_resource_t nexus_adjust_resource; 104 static bus_alloc_resource_t nexus_alloc_resource; 105 static bus_deactivate_resource_t nexus_deactivate_resource; 106 static bus_delete_resource_t nexus_delete_resource; 107 static bus_get_resource_t nexus_get_resource; 108 static bus_get_resource_list_t nexus_get_reslist; 109 static bus_map_resource_t nexus_map_resource; 110 static bus_release_resource_t nexus_release_resource; 111 static bus_set_resource_t nexus_set_resource; 112 static bus_unmap_resource_t nexus_unmap_resource; 113 114 #ifdef SMP 115 static bus_bind_intr_t nexus_bind_intr; 116 #endif 117 static bus_config_intr_t nexus_config_intr; 118 static bus_describe_intr_t nexus_describe_intr; 119 static bus_resume_intr_t nexus_resume_intr; 120 static bus_setup_intr_t nexus_setup_intr; 121 static bus_suspend_intr_t nexus_suspend_intr; 122 static bus_teardown_intr_t nexus_teardown_intr; 123 124 static bus_get_cpus_t nexus_get_cpus; 125 126 #if defined(DEV_APIC) && defined(DEV_PCI) 127 static pcib_alloc_msi_t nexus_alloc_msi; 128 static pcib_release_msi_t nexus_release_msi; 129 static pcib_alloc_msix_t nexus_alloc_msix; 130 static pcib_release_msix_t nexus_release_msix; 131 static pcib_map_msi_t nexus_map_msi; 132 #endif 133 134 static device_method_t nexus_methods[] = { 135 /* Device interface */ 136 DEVMETHOD(device_probe, nexus_probe), 137 DEVMETHOD(device_attach, nexus_attach), 138 DEVMETHOD(device_detach, bus_generic_detach), 139 DEVMETHOD(device_shutdown, bus_generic_shutdown), 140 DEVMETHOD(device_suspend, bus_generic_suspend), 141 DEVMETHOD(device_resume, bus_generic_resume), 142 143 /* Bus interface */ 144 DEVMETHOD(bus_print_child, nexus_print_child), 145 DEVMETHOD(bus_add_child, nexus_add_child), 146 DEVMETHOD(bus_activate_resource, nexus_activate_resource), 147 DEVMETHOD(bus_adjust_resource, nexus_adjust_resource), 148 DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), 149 DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), 150 DEVMETHOD(bus_get_resource, nexus_get_resource), 151 DEVMETHOD(bus_get_resource_list, nexus_get_reslist), 152 DEVMETHOD(bus_delete_resource, nexus_delete_resource), 153 DEVMETHOD(bus_map_resource, nexus_map_resource), 154 DEVMETHOD(bus_release_resource, nexus_release_resource), 155 DEVMETHOD(bus_set_resource, nexus_set_resource), 156 DEVMETHOD(bus_unmap_resource, nexus_unmap_resource), 157 #ifdef SMP 158 DEVMETHOD(bus_bind_intr, nexus_bind_intr), 159 #endif 160 DEVMETHOD(bus_config_intr, nexus_config_intr), 161 DEVMETHOD(bus_describe_intr, nexus_describe_intr), 162 DEVMETHOD(bus_resume_intr, nexus_resume_intr), 163 DEVMETHOD(bus_setup_intr, nexus_setup_intr), 164 DEVMETHOD(bus_suspend_intr, nexus_suspend_intr), 165 DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), 166 DEVMETHOD(bus_get_cpus, nexus_get_cpus), 167 168 /* pcib interface */ 169 #if defined(DEV_APIC) && defined(DEV_PCI) 170 DEVMETHOD(pcib_alloc_msi, nexus_alloc_msi), 171 DEVMETHOD(pcib_release_msi, nexus_release_msi), 172 DEVMETHOD(pcib_alloc_msix, nexus_alloc_msix), 173 DEVMETHOD(pcib_release_msix, nexus_release_msix), 174 DEVMETHOD(pcib_map_msi, nexus_map_msi), 175 #endif 176 DEVMETHOD_END 177 }; 178 179 DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, 1); 180 181 DRIVER_MODULE(nexus, root, nexus_driver, 0, 0); 182 183 static int 184 nexus_probe(device_t dev) 185 { 186 187 device_quiet(dev); /* suppress attach message for neatness */ 188 return (BUS_PROBE_GENERIC); 189 } 190 191 void 192 nexus_init_resources(void) 193 { 194 int irq; 195 196 /* 197 * XXX working notes: 198 * 199 * - IRQ resource creation should be moved to the PIC/APIC driver. 200 * - DRQ resource creation should be moved to the DMAC driver. 201 * - The above should be sorted to probe earlier than any child buses. 202 * 203 * - Leave I/O and memory creation here, as child probes may need them. 204 * (especially eg. ACPI) 205 */ 206 207 /* 208 * IRQ's are on the mainboard on old systems, but on the ISA part 209 * of PCI->ISA bridges. There would be multiple sets of IRQs on 210 * multi-ISA-bus systems. PCI interrupts are routed to the ISA 211 * component, so in a way, PCI can be a partial child of an ISA bus(!). 212 * APIC interrupts are global though. 213 */ 214 irq_rman.rm_start = 0; 215 irq_rman.rm_type = RMAN_ARRAY; 216 irq_rman.rm_descr = "Interrupt request lines"; 217 irq_rman.rm_end = num_io_irqs - 1; 218 if (rman_init(&irq_rman)) 219 panic("nexus_init_resources irq_rman"); 220 221 /* 222 * We search for regions of existing IRQs and add those to the IRQ 223 * resource manager. 224 */ 225 for (irq = 0; irq < num_io_irqs; irq++) 226 if (intr_lookup_source(irq) != NULL) 227 if (rman_manage_region(&irq_rman, irq, irq) != 0) 228 panic("nexus_init_resources irq_rman add"); 229 230 /* 231 * ISA DMA on PCI systems is implemented in the ISA part of each 232 * PCI->ISA bridge and the channels can be duplicated if there are 233 * multiple bridges. (eg: laptops with docking stations) 234 */ 235 drq_rman.rm_start = 0; 236 drq_rman.rm_end = 7; 237 drq_rman.rm_type = RMAN_ARRAY; 238 drq_rman.rm_descr = "DMA request lines"; 239 /* XXX drq 0 not available on some machines */ 240 if (rman_init(&drq_rman) 241 || rman_manage_region(&drq_rman, 242 drq_rman.rm_start, drq_rman.rm_end)) 243 panic("nexus_init_resources drq_rman"); 244 245 /* 246 * However, IO ports and Memory truely are global at this level, 247 * as are APIC interrupts (however many IO APICS there turn out 248 * to be on large systems..) 249 */ 250 port_rman.rm_start = 0; 251 port_rman.rm_end = 0xffff; 252 port_rman.rm_type = RMAN_ARRAY; 253 port_rman.rm_descr = "I/O ports"; 254 if (rman_init(&port_rman) 255 || rman_manage_region(&port_rman, 0, 0xffff)) 256 panic("nexus_init_resources port_rman"); 257 258 mem_rman.rm_start = 0; 259 mem_rman.rm_end = cpu_getmaxphyaddr(); 260 mem_rman.rm_type = RMAN_ARRAY; 261 mem_rman.rm_descr = "I/O memory addresses"; 262 if (rman_init(&mem_rman) 263 || rman_manage_region(&mem_rman, 0, mem_rman.rm_end)) 264 panic("nexus_init_resources mem_rman"); 265 } 266 267 static int 268 nexus_attach(device_t dev) 269 { 270 271 nexus_init_resources(); 272 bus_generic_probe(dev); 273 274 /* 275 * Explicitly add the legacy0 device here. Other platform 276 * types (such as ACPI), use their own nexus(4) subclass 277 * driver to override this routine and add their own root bus. 278 */ 279 if (BUS_ADD_CHILD(dev, 10, "legacy", 0) == NULL) 280 panic("legacy: could not attach"); 281 bus_generic_attach(dev); 282 return (0); 283 } 284 285 static int 286 nexus_print_all_resources(device_t dev) 287 { 288 struct nexus_device *ndev = DEVTONX(dev); 289 struct resource_list *rl = &ndev->nx_resources; 290 int retval = 0; 291 292 if (STAILQ_FIRST(rl)) 293 retval += printf(" at"); 294 295 retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#jx"); 296 retval += resource_list_print_type(rl, "iomem", SYS_RES_MEMORY, "%#jx"); 297 retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%jd"); 298 299 return (retval); 300 } 301 302 static int 303 nexus_print_child(device_t bus, device_t child) 304 { 305 int retval = 0; 306 307 retval += bus_print_child_header(bus, child); 308 retval += nexus_print_all_resources(child); 309 if (device_get_flags(child)) 310 retval += printf(" flags %#x", device_get_flags(child)); 311 retval += printf("\n"); 312 313 return (retval); 314 } 315 316 static device_t 317 nexus_add_child(device_t bus, u_int order, const char *name, int unit) 318 { 319 device_t child; 320 struct nexus_device *ndev; 321 322 ndev = malloc(sizeof(struct nexus_device), M_NEXUSDEV, M_NOWAIT|M_ZERO); 323 if (!ndev) 324 return (0); 325 resource_list_init(&ndev->nx_resources); 326 327 child = device_add_child_ordered(bus, order, name, unit); 328 329 /* should we free this in nexus_child_detached? */ 330 device_set_ivars(child, ndev); 331 332 return (child); 333 } 334 335 static struct rman * 336 nexus_rman(int type) 337 { 338 switch (type) { 339 case SYS_RES_IRQ: 340 return (&irq_rman); 341 case SYS_RES_DRQ: 342 return (&drq_rman); 343 case SYS_RES_IOPORT: 344 return (&port_rman); 345 case SYS_RES_MEMORY: 346 return (&mem_rman); 347 default: 348 return (NULL); 349 } 350 } 351 352 /* 353 * Allocate a resource on behalf of child. NB: child is usually going to be a 354 * child of one of our descendants, not a direct child of nexus0. 355 */ 356 static struct resource * 357 nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, 358 rman_res_t start, rman_res_t end, rman_res_t count, 359 u_int flags) 360 { 361 struct nexus_device *ndev = DEVTONX(child); 362 struct resource *rv; 363 struct resource_list_entry *rle; 364 struct rman *rm; 365 int needactivate = flags & RF_ACTIVE; 366 367 /* 368 * If this is an allocation of the "default" range for a given 369 * RID, and we know what the resources for this device are 370 * (ie. they aren't maintained by a child bus), then work out 371 * the start/end values. 372 */ 373 if (RMAN_IS_DEFAULT_RANGE(start, end) && (count == 1)) { 374 if (device_get_parent(child) != bus || ndev == NULL) 375 return (NULL); 376 rle = resource_list_find(&ndev->nx_resources, type, *rid); 377 if (rle == NULL) 378 return (NULL); 379 start = rle->start; 380 end = rle->end; 381 count = rle->count; 382 } 383 384 flags &= ~RF_ACTIVE; 385 rm = nexus_rman(type); 386 if (rm == NULL) 387 return (NULL); 388 389 rv = rman_reserve_resource(rm, start, end, count, flags, child); 390 if (rv == NULL) 391 return (0); 392 rman_set_rid(rv, *rid); 393 394 if (needactivate) { 395 if (bus_activate_resource(child, type, *rid, rv)) { 396 rman_release_resource(rv); 397 return (0); 398 } 399 } 400 401 return (rv); 402 } 403 404 static int 405 nexus_adjust_resource(device_t bus, device_t child, int type, 406 struct resource *r, rman_res_t start, rman_res_t end) 407 { 408 struct rman *rm; 409 410 rm = nexus_rman(type); 411 if (rm == NULL) 412 return (ENXIO); 413 if (!rman_is_region_manager(r, rm)) 414 return (EINVAL); 415 return (rman_adjust_resource(r, start, end)); 416 } 417 418 static int 419 nexus_activate_resource(device_t bus, device_t child, int type, int rid, 420 struct resource *r) 421 { 422 struct resource_map map; 423 int error; 424 425 error = rman_activate_resource(r); 426 if (error != 0) 427 return (error); 428 429 if (!(rman_get_flags(r) & RF_UNMAPPED) && 430 (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT)) { 431 error = nexus_map_resource(bus, child, type, r, NULL, &map); 432 if (error) { 433 rman_deactivate_resource(r); 434 return (error); 435 } 436 437 rman_set_mapping(r,&map); 438 } 439 return (0); 440 } 441 442 static int 443 nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, 444 struct resource *r) 445 { 446 struct resource_map map; 447 int error; 448 449 error = rman_deactivate_resource(r); 450 if (error) 451 return (error); 452 453 if (!(rman_get_flags(r) & RF_UNMAPPED) && 454 (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT)) { 455 rman_get_mapping(r, &map); 456 nexus_unmap_resource(bus, child, type, r, &map); 457 } 458 return (0); 459 } 460 461 static int 462 nexus_map_resource(device_t bus, device_t child, int type, struct resource *r, 463 struct resource_map_request *argsp, struct resource_map *map) 464 { 465 struct resource_map_request args; 466 rman_res_t end, length, start; 467 468 /* Resources must be active to be mapped. */ 469 if (!(rman_get_flags(r) & RF_ACTIVE)) 470 return (ENXIO); 471 472 /* Mappings are only supported on I/O and memory resources. */ 473 switch (type) { 474 case SYS_RES_IOPORT: 475 case SYS_RES_MEMORY: 476 break; 477 default: 478 return (EINVAL); 479 } 480 481 resource_init_map_request(&args); 482 if (argsp != NULL) 483 bcopy(argsp, &args, imin(argsp->size, args.size)); 484 start = rman_get_start(r) + args.offset; 485 if (args.length == 0) 486 length = rman_get_size(r); 487 else 488 length = args.length; 489 end = start + length - 1; 490 if (start > rman_get_end(r) || start < rman_get_start(r)) 491 return (EINVAL); 492 if (end > rman_get_end(r) || end < start) 493 return (EINVAL); 494 495 /* 496 * If this is a memory resource, map it into the kernel. 497 */ 498 switch (type) { 499 case SYS_RES_IOPORT: 500 map->r_bushandle = start; 501 map->r_bustag = X86_BUS_SPACE_IO; 502 map->r_size = length; 503 map->r_vaddr = NULL; 504 break; 505 case SYS_RES_MEMORY: 506 map->r_vaddr = pmap_mapdev_attr(start, length, args.memattr); 507 map->r_bustag = X86_BUS_SPACE_MEM; 508 map->r_size = length; 509 510 /* 511 * The handle is the virtual address. 512 */ 513 map->r_bushandle = (bus_space_handle_t)map->r_vaddr; 514 break; 515 } 516 return (0); 517 } 518 519 static int 520 nexus_unmap_resource(device_t bus, device_t child, int type, struct resource *r, 521 struct resource_map *map) 522 { 523 524 /* 525 * If this is a memory resource, unmap it. 526 */ 527 switch (type) { 528 case SYS_RES_MEMORY: 529 pmap_unmapdev(map->r_vaddr, map->r_size); 530 /* FALLTHROUGH */ 531 case SYS_RES_IOPORT: 532 break; 533 default: 534 return (EINVAL); 535 } 536 return (0); 537 } 538 539 static int 540 nexus_release_resource(device_t bus, device_t child, int type, int rid, 541 struct resource *r) 542 { 543 int error; 544 545 if (rman_get_flags(r) & RF_ACTIVE) { 546 error = bus_deactivate_resource(child, type, rid, r); 547 if (error != 0) 548 return (error); 549 } 550 return (rman_release_resource(r)); 551 } 552 553 /* 554 * Currently this uses the really grody interface from kern/kern_intr.c 555 * (which really doesn't belong in kern/anything.c). Eventually, all of 556 * the code in kern_intr.c and machdep_intr.c should get moved here, since 557 * this is going to be the official interface. 558 */ 559 static int 560 nexus_setup_intr(device_t bus, device_t child, struct resource *irq, 561 int flags, driver_filter_t filter, void (*ihand)(void *), 562 void *arg, void **cookiep) 563 { 564 int error, domain; 565 566 /* somebody tried to setup an irq that failed to allocate! */ 567 if (irq == NULL) 568 panic("nexus_setup_intr: NULL irq resource!"); 569 570 *cookiep = NULL; 571 if ((rman_get_flags(irq) & RF_SHAREABLE) == 0) 572 flags |= INTR_EXCL; 573 574 /* 575 * We depend here on rman_activate_resource() being idempotent. 576 */ 577 error = rman_activate_resource(irq); 578 if (error != 0) 579 return (error); 580 if (bus_get_domain(child, &domain) != 0) 581 domain = 0; 582 583 error = intr_add_handler(device_get_nameunit(child), 584 rman_get_start(irq), filter, ihand, arg, flags, cookiep, domain); 585 if (error == 0) 586 rman_set_irq_cookie(irq, *cookiep); 587 588 return (error); 589 } 590 591 static int 592 nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih) 593 { 594 int error; 595 596 error = intr_remove_handler(ih); 597 if (error == 0) 598 rman_set_irq_cookie(r, NULL); 599 return (error); 600 } 601 602 static int 603 nexus_suspend_intr(device_t dev, device_t child, struct resource *irq) 604 { 605 return (intr_event_suspend_handler(rman_get_irq_cookie(irq))); 606 } 607 608 static int 609 nexus_resume_intr(device_t dev, device_t child, struct resource *irq) 610 { 611 return (intr_event_resume_handler(rman_get_irq_cookie(irq))); 612 } 613 614 #ifdef SMP 615 static int 616 nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu) 617 { 618 return (intr_bind(rman_get_start(irq), cpu)); 619 } 620 #endif 621 622 static int 623 nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, 624 enum intr_polarity pol) 625 { 626 return (intr_config_intr(irq, trig, pol)); 627 } 628 629 static int 630 nexus_describe_intr(device_t dev, device_t child, struct resource *irq, 631 void *cookie, const char *descr) 632 { 633 634 return (intr_describe(rman_get_start(irq), cookie, descr)); 635 } 636 637 static struct resource_list * 638 nexus_get_reslist(device_t dev, device_t child) 639 { 640 struct nexus_device *ndev = DEVTONX(child); 641 642 return (&ndev->nx_resources); 643 } 644 645 static int 646 nexus_set_resource(device_t dev, device_t child, int type, int rid, 647 rman_res_t start, rman_res_t count) 648 { 649 struct nexus_device *ndev = DEVTONX(child); 650 struct resource_list *rl = &ndev->nx_resources; 651 652 /* XXX this should return a success/failure indicator */ 653 resource_list_add(rl, type, rid, start, start + count - 1, count); 654 return (0); 655 } 656 657 static int 658 nexus_get_resource(device_t dev, device_t child, int type, int rid, 659 rman_res_t *startp, rman_res_t *countp) 660 { 661 struct nexus_device *ndev = DEVTONX(child); 662 struct resource_list *rl = &ndev->nx_resources; 663 struct resource_list_entry *rle; 664 665 rle = resource_list_find(rl, type, rid); 666 if (!rle) 667 return (ENOENT); 668 if (startp) 669 *startp = rle->start; 670 if (countp) 671 *countp = rle->count; 672 return (0); 673 } 674 675 static void 676 nexus_delete_resource(device_t dev, device_t child, int type, int rid) 677 { 678 struct nexus_device *ndev = DEVTONX(child); 679 struct resource_list *rl = &ndev->nx_resources; 680 681 resource_list_delete(rl, type, rid); 682 } 683 684 static int 685 nexus_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsize, 686 cpuset_t *cpuset) 687 { 688 689 switch (op) { 690 #ifdef SMP 691 case INTR_CPUS: 692 if (setsize != sizeof(cpuset_t)) 693 return (EINVAL); 694 *cpuset = intr_cpus; 695 return (0); 696 #endif 697 default: 698 return (bus_generic_get_cpus(dev, child, op, setsize, cpuset)); 699 } 700 } 701 702 /* Called from the MSI code to add new IRQs to the IRQ rman. */ 703 void 704 nexus_add_irq(u_long irq) 705 { 706 707 if (rman_manage_region(&irq_rman, irq, irq) != 0) 708 panic("%s: failed", __func__); 709 } 710 711 #if defined(DEV_APIC) && defined(DEV_PCI) 712 static int 713 nexus_alloc_msix(device_t pcib, device_t dev, int *irq) 714 { 715 716 return (msix_alloc(dev, irq)); 717 } 718 719 static int 720 nexus_release_msix(device_t pcib, device_t dev, int irq) 721 { 722 723 return (msix_release(irq)); 724 } 725 726 static int 727 nexus_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs) 728 { 729 730 return (msi_alloc(dev, count, maxcount, irqs)); 731 } 732 733 static int 734 nexus_release_msi(device_t pcib, device_t dev, int count, int *irqs) 735 { 736 737 return (msi_release(irqs, count)); 738 } 739 740 static int 741 nexus_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, uint32_t *data) 742 { 743 744 return (msi_map(irq, addr, data)); 745 } 746 #endif /* DEV_APIC && DEV_PCI */ 747 748 /* Placeholder for system RAM. */ 749 static void 750 ram_identify(driver_t *driver, device_t parent) 751 { 752 753 if (resource_disabled("ram", 0)) 754 return; 755 if (BUS_ADD_CHILD(parent, 0, "ram", 0) == NULL) 756 panic("ram_identify"); 757 } 758 759 static int 760 ram_probe(device_t dev) 761 { 762 763 device_quiet(dev); 764 device_set_desc(dev, "System RAM"); 765 return (0); 766 } 767 768 static int 769 ram_attach(device_t dev) 770 { 771 struct bios_smap *smapbase, *smap, *smapend; 772 struct resource *res; 773 rman_res_t length; 774 vm_paddr_t *p; 775 caddr_t kmdp; 776 uint32_t smapsize; 777 int error, rid; 778 779 /* Retrieve the system memory map from the loader. */ 780 kmdp = preload_search_by_type("elf kernel"); 781 if (kmdp == NULL) 782 kmdp = preload_search_by_type(ELF_KERN_STR); 783 smapbase = (struct bios_smap *)preload_search_info(kmdp, 784 MODINFO_METADATA | MODINFOMD_SMAP); 785 if (smapbase != NULL) { 786 smapsize = *((u_int32_t *)smapbase - 1); 787 smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize); 788 789 rid = 0; 790 for (smap = smapbase; smap < smapend; smap++) { 791 if (smap->type != SMAP_TYPE_MEMORY || 792 smap->length == 0) 793 continue; 794 if (smap->base > mem_rman.rm_end) 795 continue; 796 length = smap->base + smap->length > mem_rman.rm_end ? 797 mem_rman.rm_end - smap->base : smap->length; 798 error = bus_set_resource(dev, SYS_RES_MEMORY, rid, 799 smap->base, length); 800 if (error) 801 panic( 802 "ram_attach: resource %d failed set with %d", 803 rid, error); 804 res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 805 0); 806 if (res == NULL) 807 panic("ram_attach: resource %d failed to attach", 808 rid); 809 rid++; 810 } 811 return (0); 812 } 813 814 /* 815 * If the system map is not available, fall back to using 816 * dump_avail[]. We use the dump_avail[] array rather than 817 * phys_avail[] for the memory map as phys_avail[] contains 818 * holes for kernel memory, page 0, the message buffer, and 819 * the dcons buffer. We test the end address in the loop 820 * instead of the start since the start address for the first 821 * segment is 0. 822 */ 823 for (rid = 0, p = dump_avail; p[1] != 0; rid++, p += 2) { 824 if (p[0] > mem_rman.rm_end) 825 break; 826 length = (p[1] > mem_rman.rm_end ? mem_rman.rm_end : p[1]) - 827 p[0]; 828 error = bus_set_resource(dev, SYS_RES_MEMORY, rid, p[0], 829 length); 830 if (error) 831 panic("ram_attach: resource %d failed set with %d", rid, 832 error); 833 res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0); 834 if (res == NULL) 835 panic("ram_attach: resource %d failed to attach", rid); 836 } 837 return (0); 838 } 839 840 static device_method_t ram_methods[] = { 841 /* Device interface */ 842 DEVMETHOD(device_identify, ram_identify), 843 DEVMETHOD(device_probe, ram_probe), 844 DEVMETHOD(device_attach, ram_attach), 845 846 DEVMETHOD_END 847 }; 848 849 static driver_t ram_driver = { 850 "ram", 851 ram_methods, 852 1, /* no softc */ 853 }; 854 855 DRIVER_MODULE(ram, nexus, ram_driver, 0, 0); 856 857 #ifdef DEV_ISA 858 /* 859 * Placeholder which claims PnP 'devices' which describe system 860 * resources. 861 */ 862 static struct isa_pnp_id sysresource_ids[] = { 863 { 0x010cd041 /* PNP0c01 */, "System Memory" }, 864 { 0x020cd041 /* PNP0c02 */, "System Resource" }, 865 { 0 } 866 }; 867 868 static int 869 sysresource_probe(device_t dev) 870 { 871 int result; 872 873 if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, sysresource_ids)) <= 0) { 874 device_quiet(dev); 875 } 876 return (result); 877 } 878 879 static int 880 sysresource_attach(device_t dev) 881 { 882 return (0); 883 } 884 885 static device_method_t sysresource_methods[] = { 886 /* Device interface */ 887 DEVMETHOD(device_probe, sysresource_probe), 888 DEVMETHOD(device_attach, sysresource_attach), 889 DEVMETHOD(device_detach, bus_generic_detach), 890 DEVMETHOD(device_shutdown, bus_generic_shutdown), 891 DEVMETHOD(device_suspend, bus_generic_suspend), 892 DEVMETHOD(device_resume, bus_generic_resume), 893 894 DEVMETHOD_END 895 }; 896 897 static driver_t sysresource_driver = { 898 "sysresource", 899 sysresource_methods, 900 1, /* no softc */ 901 }; 902 903 DRIVER_MODULE(sysresource, isa, sysresource_driver, 0, 0); 904 ISA_PNP_INFO(sysresource_ids); 905 #endif /* DEV_ISA */ 906