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 51 #include <sys/param.h> 52 #include <sys/systm.h> 53 #include <sys/bus.h> 54 #include <sys/kernel.h> 55 #include <sys/linker.h> 56 #include <sys/malloc.h> 57 #include <sys/module.h> 58 #include <machine/bus.h> 59 #include <machine/intr_machdep.h> 60 #include <sys/rman.h> 61 #include <sys/interrupt.h> 62 63 #include <machine/vmparam.h> 64 #include <vm/vm.h> 65 #include <vm/pmap.h> 66 #include <machine/pmap.h> 67 68 #include <machine/metadata.h> 69 #include <machine/nexusvar.h> 70 #include <machine/resource.h> 71 #include <machine/pc/bios.h> 72 73 #ifdef DEV_APIC 74 #include "pcib_if.h" 75 #endif 76 77 #ifdef DEV_ISA 78 #include <isa/isavar.h> 79 #ifdef PC98 80 #include <pc98/cbus/cbus.h> 81 #else 82 #include <x86/isa/isa.h> 83 #endif 84 #endif 85 #include <sys/rtprio.h> 86 87 #define ELF_KERN_STR ("elf"__XSTRING(__ELF_WORD_SIZE)" kernel") 88 89 static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device"); 90 91 #define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev)) 92 93 struct rman irq_rman, drq_rman, port_rman, mem_rman; 94 95 static int nexus_probe(device_t); 96 static int nexus_attach(device_t); 97 static int nexus_print_all_resources(device_t dev); 98 static int nexus_print_child(device_t, device_t); 99 static device_t nexus_add_child(device_t bus, u_int order, const char *name, 100 int unit); 101 static struct resource *nexus_alloc_resource(device_t, device_t, int, int *, 102 u_long, u_long, u_long, u_int); 103 #ifdef SMP 104 static int nexus_bind_intr(device_t, device_t, struct resource *, int); 105 #endif 106 static int nexus_config_intr(device_t, int, enum intr_trigger, 107 enum intr_polarity); 108 static int nexus_describe_intr(device_t dev, device_t child, 109 struct resource *irq, void *cookie, 110 const char *descr); 111 static int nexus_activate_resource(device_t, device_t, int, int, 112 struct resource *); 113 static int nexus_deactivate_resource(device_t, device_t, int, int, 114 struct resource *); 115 static int nexus_release_resource(device_t, device_t, int, int, 116 struct resource *); 117 static int nexus_setup_intr(device_t, device_t, struct resource *, int flags, 118 driver_filter_t filter, void (*)(void *), void *, 119 void **); 120 static int nexus_teardown_intr(device_t, device_t, struct resource *, 121 void *); 122 static struct resource_list *nexus_get_reslist(device_t dev, device_t child); 123 static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long); 124 static int nexus_get_resource(device_t, device_t, int, int, u_long *, u_long *); 125 static void nexus_delete_resource(device_t, device_t, int, int); 126 #ifdef DEV_APIC 127 static int nexus_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs); 128 static int nexus_release_msi(device_t pcib, device_t dev, int count, int *irqs); 129 static int nexus_alloc_msix(device_t pcib, device_t dev, int *irq); 130 static int nexus_release_msix(device_t pcib, device_t dev, int irq); 131 static int nexus_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, uint32_t *data); 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_alloc_resource, nexus_alloc_resource), 147 DEVMETHOD(bus_release_resource, nexus_release_resource), 148 DEVMETHOD(bus_activate_resource, nexus_activate_resource), 149 DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), 150 DEVMETHOD(bus_setup_intr, nexus_setup_intr), 151 DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), 152 #ifdef SMP 153 DEVMETHOD(bus_bind_intr, nexus_bind_intr), 154 #endif 155 DEVMETHOD(bus_config_intr, nexus_config_intr), 156 DEVMETHOD(bus_describe_intr, nexus_describe_intr), 157 DEVMETHOD(bus_get_resource_list, nexus_get_reslist), 158 DEVMETHOD(bus_set_resource, nexus_set_resource), 159 DEVMETHOD(bus_get_resource, nexus_get_resource), 160 DEVMETHOD(bus_delete_resource, nexus_delete_resource), 161 162 /* pcib interface */ 163 #ifdef DEV_APIC 164 DEVMETHOD(pcib_alloc_msi, nexus_alloc_msi), 165 DEVMETHOD(pcib_release_msi, nexus_release_msi), 166 DEVMETHOD(pcib_alloc_msix, nexus_alloc_msix), 167 DEVMETHOD(pcib_release_msix, nexus_release_msix), 168 DEVMETHOD(pcib_map_msi, nexus_map_msi), 169 #endif 170 171 { 0, 0 } 172 }; 173 174 DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, 1); 175 static devclass_t nexus_devclass; 176 177 DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0); 178 179 static int 180 nexus_probe(device_t dev) 181 { 182 183 device_quiet(dev); /* suppress attach message for neatness */ 184 return (BUS_PROBE_GENERIC); 185 } 186 187 void 188 nexus_init_resources(void) 189 { 190 int irq; 191 192 /* 193 * XXX working notes: 194 * 195 * - IRQ resource creation should be moved to the PIC/APIC driver. 196 * - DRQ resource creation should be moved to the DMAC driver. 197 * - The above should be sorted to probe earlier than any child busses. 198 * 199 * - Leave I/O and memory creation here, as child probes may need them. 200 * (especially eg. ACPI) 201 */ 202 203 /* 204 * IRQ's are on the mainboard on old systems, but on the ISA part 205 * of PCI->ISA bridges. There would be multiple sets of IRQs on 206 * multi-ISA-bus systems. PCI interrupts are routed to the ISA 207 * component, so in a way, PCI can be a partial child of an ISA bus(!). 208 * APIC interrupts are global though. 209 */ 210 irq_rman.rm_start = 0; 211 irq_rman.rm_type = RMAN_ARRAY; 212 irq_rman.rm_descr = "Interrupt request lines"; 213 irq_rman.rm_end = NUM_IO_INTS - 1; 214 if (rman_init(&irq_rman)) 215 panic("nexus_init_resources irq_rman"); 216 217 /* 218 * We search for regions of existing IRQs and add those to the IRQ 219 * resource manager. 220 */ 221 for (irq = 0; irq < NUM_IO_INTS; irq++) 222 if (intr_lookup_source(irq) != NULL) 223 if (rman_manage_region(&irq_rman, irq, irq) != 0) 224 panic("nexus_init_resources irq_rman add"); 225 226 /* 227 * ISA DMA on PCI systems is implemented in the ISA part of each 228 * PCI->ISA bridge and the channels can be duplicated if there are 229 * multiple bridges. (eg: laptops with docking stations) 230 */ 231 drq_rman.rm_start = 0; 232 #ifdef PC98 233 drq_rman.rm_end = 3; 234 #else 235 drq_rman.rm_end = 7; 236 #endif 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 = ~0u; 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, ~0)) 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, "%#lx"); 296 retval += resource_list_print_type(rl, "iomem", SYS_RES_MEMORY, "%#lx"); 297 retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld"); 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(" on motherboard\n"); /* XXX "motherboard", ick */ 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 /* 336 * Allocate a resource on behalf of child. NB: child is usually going to be a 337 * child of one of our descendants, not a direct child of nexus0. 338 * (Exceptions include npx.) 339 */ 340 static struct resource * 341 nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, 342 u_long start, u_long end, u_long count, u_int flags) 343 { 344 struct nexus_device *ndev = DEVTONX(child); 345 struct resource *rv; 346 struct resource_list_entry *rle; 347 struct rman *rm; 348 int needactivate = flags & RF_ACTIVE; 349 350 /* 351 * If this is an allocation of the "default" range for a given RID, and 352 * we know what the resources for this device are (ie. they aren't maintained 353 * by a child bus), then work out the start/end values. 354 */ 355 if ((start == 0UL) && (end == ~0UL) && (count == 1)) { 356 if (ndev == NULL) 357 return(NULL); 358 rle = resource_list_find(&ndev->nx_resources, type, *rid); 359 if (rle == NULL) 360 return(NULL); 361 start = rle->start; 362 end = rle->end; 363 count = rle->count; 364 } 365 366 flags &= ~RF_ACTIVE; 367 368 switch (type) { 369 case SYS_RES_IRQ: 370 rm = &irq_rman; 371 break; 372 373 case SYS_RES_DRQ: 374 rm = &drq_rman; 375 break; 376 377 case SYS_RES_IOPORT: 378 rm = &port_rman; 379 break; 380 381 case SYS_RES_MEMORY: 382 rm = &mem_rman; 383 break; 384 385 default: 386 return 0; 387 } 388 389 rv = rman_reserve_resource(rm, start, end, count, flags, child); 390 if (rv == 0) 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_activate_resource(device_t bus, device_t child, int type, int rid, 406 struct resource *r) 407 { 408 #ifdef PC98 409 bus_space_handle_t bh; 410 int error; 411 #endif 412 void *vaddr; 413 414 /* 415 * If this is a memory resource, map it into the kernel. 416 */ 417 switch (type) { 418 case SYS_RES_IOPORT: 419 #ifdef PC98 420 error = i386_bus_space_handle_alloc(X86_BUS_SPACE_IO, 421 rman_get_start(r), rman_get_size(r), &bh); 422 if (error) 423 return (error); 424 rman_set_bushandle(r, bh); 425 #else 426 rman_set_bushandle(r, rman_get_start(r)); 427 #endif 428 rman_set_bustag(r, X86_BUS_SPACE_IO); 429 break; 430 case SYS_RES_MEMORY: 431 #ifdef PC98 432 error = i386_bus_space_handle_alloc(X86_BUS_SPACE_MEM, 433 rman_get_start(r), rman_get_size(r), &bh); 434 if (error) 435 return (error); 436 #endif 437 vaddr = pmap_mapdev(rman_get_start(r), rman_get_size(r)); 438 rman_set_virtual(r, vaddr); 439 rman_set_bustag(r, X86_BUS_SPACE_MEM); 440 #ifdef PC98 441 /* PC-98: the type of bus_space_handle_t is the structure. */ 442 bh->bsh_base = (bus_addr_t) vaddr; 443 rman_set_bushandle(r, bh); 444 #else 445 /* IBM-PC: the type of bus_space_handle_t is u_int */ 446 rman_set_bushandle(r, (bus_space_handle_t) vaddr); 447 #endif 448 } 449 return (rman_activate_resource(r)); 450 } 451 452 static int 453 nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, 454 struct resource *r) 455 { 456 457 /* 458 * If this is a memory resource, unmap it. 459 */ 460 if (type == SYS_RES_MEMORY) { 461 pmap_unmapdev((vm_offset_t)rman_get_virtual(r), 462 rman_get_size(r)); 463 } 464 #ifdef PC98 465 if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { 466 bus_space_handle_t bh; 467 468 bh = rman_get_bushandle(r); 469 i386_bus_space_handle_free(rman_get_bustag(r), bh, bh->bsh_sz); 470 } 471 #endif 472 return (rman_deactivate_resource(r)); 473 } 474 475 static int 476 nexus_release_resource(device_t bus, device_t child, int type, int rid, 477 struct resource *r) 478 { 479 if (rman_get_flags(r) & RF_ACTIVE) { 480 int error = bus_deactivate_resource(child, type, rid, r); 481 if (error) 482 return error; 483 } 484 return (rman_release_resource(r)); 485 } 486 487 /* 488 * Currently this uses the really grody interface from kern/kern_intr.c 489 * (which really doesn't belong in kern/anything.c). Eventually, all of 490 * the code in kern_intr.c and machdep_intr.c should get moved here, since 491 * this is going to be the official interface. 492 */ 493 static int 494 nexus_setup_intr(device_t bus, device_t child, struct resource *irq, 495 int flags, driver_filter_t filter, void (*ihand)(void *), 496 void *arg, void **cookiep) 497 { 498 int error; 499 500 /* somebody tried to setup an irq that failed to allocate! */ 501 if (irq == NULL) 502 panic("nexus_setup_intr: NULL irq resource!"); 503 504 *cookiep = 0; 505 if ((rman_get_flags(irq) & RF_SHAREABLE) == 0) 506 flags |= INTR_EXCL; 507 508 /* 509 * We depend here on rman_activate_resource() being idempotent. 510 */ 511 error = rman_activate_resource(irq); 512 if (error) 513 return (error); 514 515 error = intr_add_handler(device_get_nameunit(child), 516 rman_get_start(irq), filter, ihand, arg, flags, cookiep); 517 518 return (error); 519 } 520 521 static int 522 nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih) 523 { 524 return (intr_remove_handler(ih)); 525 } 526 527 #ifdef SMP 528 static int 529 nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu) 530 { 531 return (intr_bind(rman_get_start(irq), cpu)); 532 } 533 #endif 534 535 static int 536 nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, 537 enum intr_polarity pol) 538 { 539 return (intr_config_intr(irq, trig, pol)); 540 } 541 542 static int 543 nexus_describe_intr(device_t dev, device_t child, struct resource *irq, 544 void *cookie, const char *descr) 545 { 546 547 return (intr_describe(rman_get_start(irq), cookie, descr)); 548 } 549 550 static struct resource_list * 551 nexus_get_reslist(device_t dev, device_t child) 552 { 553 struct nexus_device *ndev = DEVTONX(child); 554 555 return (&ndev->nx_resources); 556 } 557 558 static int 559 nexus_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count) 560 { 561 struct nexus_device *ndev = DEVTONX(child); 562 struct resource_list *rl = &ndev->nx_resources; 563 564 /* XXX this should return a success/failure indicator */ 565 resource_list_add(rl, type, rid, start, start + count - 1, count); 566 return(0); 567 } 568 569 static int 570 nexus_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, u_long *countp) 571 { 572 struct nexus_device *ndev = DEVTONX(child); 573 struct resource_list *rl = &ndev->nx_resources; 574 struct resource_list_entry *rle; 575 576 rle = resource_list_find(rl, type, rid); 577 if (!rle) 578 return(ENOENT); 579 if (startp) 580 *startp = rle->start; 581 if (countp) 582 *countp = rle->count; 583 return(0); 584 } 585 586 static void 587 nexus_delete_resource(device_t dev, device_t child, int type, int rid) 588 { 589 struct nexus_device *ndev = DEVTONX(child); 590 struct resource_list *rl = &ndev->nx_resources; 591 592 resource_list_delete(rl, type, rid); 593 } 594 595 /* Called from the MSI code to add new IRQs to the IRQ rman. */ 596 void 597 nexus_add_irq(u_long irq) 598 { 599 600 if (rman_manage_region(&irq_rman, irq, irq) != 0) 601 panic("%s: failed", __func__); 602 } 603 604 #ifdef DEV_APIC 605 static int 606 nexus_alloc_msix(device_t pcib, device_t dev, int *irq) 607 { 608 609 return (msix_alloc(dev, irq)); 610 } 611 612 static int 613 nexus_release_msix(device_t pcib, device_t dev, int irq) 614 { 615 616 return (msix_release(irq)); 617 } 618 619 static int 620 nexus_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs) 621 { 622 623 return (msi_alloc(dev, count, maxcount, irqs)); 624 } 625 626 static int 627 nexus_release_msi(device_t pcib, device_t dev, int count, int *irqs) 628 { 629 630 return (msi_release(irqs, count)); 631 } 632 633 static int 634 nexus_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, uint32_t *data) 635 { 636 637 return (msi_map(irq, addr, data)); 638 } 639 #endif 640 641 /* Placeholder for system RAM. */ 642 static void 643 ram_identify(driver_t *driver, device_t parent) 644 { 645 646 if (resource_disabled("ram", 0)) 647 return; 648 if (BUS_ADD_CHILD(parent, 0, "ram", 0) == NULL) 649 panic("ram_identify"); 650 } 651 652 static int 653 ram_probe(device_t dev) 654 { 655 656 device_quiet(dev); 657 device_set_desc(dev, "System RAM"); 658 return (0); 659 } 660 661 static int 662 ram_attach(device_t dev) 663 { 664 struct bios_smap *smapbase, *smap, *smapend; 665 struct resource *res; 666 vm_paddr_t *p; 667 caddr_t kmdp; 668 uint32_t smapsize; 669 int error, rid; 670 671 /* Retrieve the system memory map from the loader. */ 672 kmdp = preload_search_by_type("elf kernel"); 673 if (kmdp == NULL) 674 kmdp = preload_search_by_type(ELF_KERN_STR); 675 if (kmdp != NULL) 676 smapbase = (struct bios_smap *)preload_search_info(kmdp, 677 MODINFO_METADATA | MODINFOMD_SMAP); 678 else 679 smapbase = NULL; 680 if (smapbase != NULL) { 681 smapsize = *((u_int32_t *)smapbase - 1); 682 smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize); 683 684 rid = 0; 685 for (smap = smapbase; smap < smapend; smap++) { 686 if (smap->type != SMAP_TYPE_MEMORY || 687 smap->length == 0) 688 continue; 689 #ifdef __i386__ 690 /* 691 * Resources use long's to track resources, so 692 * we can't include memory regions above 4GB. 693 */ 694 if (smap->base > ~0ul) 695 continue; 696 #endif 697 error = bus_set_resource(dev, SYS_RES_MEMORY, rid, 698 smap->base, smap->length); 699 if (error) 700 panic( 701 "ram_attach: resource %d failed set with %d", 702 rid, error); 703 res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 704 0); 705 if (res == NULL) 706 panic("ram_attach: resource %d failed to attach", 707 rid); 708 rid++; 709 } 710 return (0); 711 } 712 713 /* 714 * If the system map is not available, fall back to using 715 * dump_avail[]. We use the dump_avail[] array rather than 716 * phys_avail[] for the memory map as phys_avail[] contains 717 * holes for kernel memory, page 0, the message buffer, and 718 * the dcons buffer. We test the end address in the loop 719 * instead of the start since the start address for the first 720 * segment is 0. 721 */ 722 for (rid = 0, p = dump_avail; p[1] != 0; rid++, p += 2) { 723 #ifdef PAE 724 /* 725 * Resources use long's to track resources, so we can't 726 * include memory regions above 4GB. 727 */ 728 if (p[0] > ~0ul) 729 break; 730 #endif 731 error = bus_set_resource(dev, SYS_RES_MEMORY, rid, p[0], 732 p[1] - p[0]); 733 if (error) 734 panic("ram_attach: resource %d failed set with %d", rid, 735 error); 736 res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0); 737 if (res == NULL) 738 panic("ram_attach: resource %d failed to attach", rid); 739 } 740 return (0); 741 } 742 743 static device_method_t ram_methods[] = { 744 /* Device interface */ 745 DEVMETHOD(device_identify, ram_identify), 746 DEVMETHOD(device_probe, ram_probe), 747 DEVMETHOD(device_attach, ram_attach), 748 { 0, 0 } 749 }; 750 751 static driver_t ram_driver = { 752 "ram", 753 ram_methods, 754 1, /* no softc */ 755 }; 756 757 static devclass_t ram_devclass; 758 759 DRIVER_MODULE(ram, nexus, ram_driver, ram_devclass, 0, 0); 760 761 #ifdef DEV_ISA 762 /* 763 * Placeholder which claims PnP 'devices' which describe system 764 * resources. 765 */ 766 static struct isa_pnp_id sysresource_ids[] = { 767 { 0x010cd041 /* PNP0c01 */, "System Memory" }, 768 { 0x020cd041 /* PNP0c02 */, "System Resource" }, 769 { 0 } 770 }; 771 772 static int 773 sysresource_probe(device_t dev) 774 { 775 int result; 776 777 if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, sysresource_ids)) <= 0) { 778 device_quiet(dev); 779 } 780 return(result); 781 } 782 783 static int 784 sysresource_attach(device_t dev) 785 { 786 return(0); 787 } 788 789 static device_method_t sysresource_methods[] = { 790 /* Device interface */ 791 DEVMETHOD(device_probe, sysresource_probe), 792 DEVMETHOD(device_attach, sysresource_attach), 793 DEVMETHOD(device_detach, bus_generic_detach), 794 DEVMETHOD(device_shutdown, bus_generic_shutdown), 795 DEVMETHOD(device_suspend, bus_generic_suspend), 796 DEVMETHOD(device_resume, bus_generic_resume), 797 { 0, 0 } 798 }; 799 800 static driver_t sysresource_driver = { 801 "sysresource", 802 sysresource_methods, 803 1, /* no softc */ 804 }; 805 806 static devclass_t sysresource_devclass; 807 808 DRIVER_MODULE(sysresource, isa, sysresource_driver, sysresource_devclass, 0, 0); 809 #endif /* DEV_ISA */ 810