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 31 /* 32 * This code implements a `root nexus' for Arm Architecture 33 * machines. The function of the root nexus is to serve as an 34 * attachment point for both processors and buses, and to manage 35 * resources which are common to all of them. In particular, 36 * this code implements the core resource managers for interrupt 37 * requests and I/O memory address space. 38 */ 39 40 #include "opt_acpi.h" 41 #include "opt_platform.h" 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/bus.h> 46 #include <sys/interrupt.h> 47 #include <sys/kernel.h> 48 #include <sys/malloc.h> 49 #include <sys/module.h> 50 #include <sys/rman.h> 51 #include <sys/sysctl.h> 52 53 #include <vm/vm.h> 54 #include <vm/pmap.h> 55 56 #include <machine/bus.h> 57 #include <machine/intr.h> 58 #include <machine/machdep.h> 59 #include <machine/pcb.h> 60 #include <machine/resource.h> 61 #include <machine/vmparam.h> 62 63 #ifdef FDT 64 #include <dev/ofw/ofw_bus_subr.h> 65 #include <dev/ofw/ofw_bus.h> 66 #include <dev/ofw/openfirm.h> 67 #include "ofw_bus_if.h" 68 #endif 69 #ifdef DEV_ACPI 70 #include <contrib/dev/acpica/include/acpi.h> 71 #include <dev/acpica/acpivar.h> 72 #include "acpi_bus_if.h" 73 #endif 74 75 extern struct bus_space memmap_bus; 76 77 static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device"); 78 79 struct nexus_device { 80 struct resource_list nx_resources; 81 }; 82 83 static int force_np; 84 SYSCTL_INT(_kern, OID_AUTO, force_nonposted, CTLFLAG_RDTUN, &force_np, 0, 85 "Force all devices to use non-posted device memory"); 86 87 #define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev)) 88 89 static struct rman mem_rman; 90 static struct rman irq_rman; 91 92 static int nexus_attach(device_t); 93 94 #ifdef FDT 95 static device_probe_t nexus_fdt_probe; 96 static device_attach_t nexus_fdt_attach; 97 static bus_activate_resource_t nexus_fdt_activate_resource; 98 #endif 99 #ifdef DEV_ACPI 100 static device_probe_t nexus_acpi_probe; 101 static device_attach_t nexus_acpi_attach; 102 #endif 103 104 static bus_add_child_t nexus_add_child; 105 static bus_print_child_t nexus_print_child; 106 107 static bus_activate_resource_t nexus_activate_resource; 108 static bus_alloc_resource_t nexus_alloc_resource; 109 static bus_deactivate_resource_t nexus_deactivate_resource; 110 static bus_get_resource_list_t nexus_get_reslist; 111 static bus_get_rman_t nexus_get_rman; 112 static bus_map_resource_t nexus_map_resource; 113 static bus_unmap_resource_t nexus_unmap_resource; 114 115 #ifdef SMP 116 static bus_bind_intr_t nexus_bind_intr; 117 #endif 118 static bus_config_intr_t nexus_config_intr; 119 static bus_describe_intr_t nexus_describe_intr; 120 static bus_setup_intr_t nexus_setup_intr; 121 static bus_teardown_intr_t nexus_teardown_intr; 122 123 static bus_get_bus_tag_t nexus_get_bus_tag; 124 125 #ifdef FDT 126 static ofw_bus_map_intr_t nexus_ofw_map_intr; 127 #endif 128 129 static device_method_t nexus_methods[] = { 130 /* Bus interface */ 131 DEVMETHOD(bus_add_child, nexus_add_child), 132 DEVMETHOD(bus_print_child, nexus_print_child), 133 DEVMETHOD(bus_activate_resource, nexus_activate_resource), 134 DEVMETHOD(bus_adjust_resource, bus_generic_rman_adjust_resource), 135 DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), 136 DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), 137 DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), 138 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 139 DEVMETHOD(bus_get_resource_list, nexus_get_reslist), 140 DEVMETHOD(bus_get_rman, nexus_get_rman), 141 DEVMETHOD(bus_map_resource, nexus_map_resource), 142 DEVMETHOD(bus_release_resource, bus_generic_rman_release_resource), 143 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 144 DEVMETHOD(bus_unmap_resource, nexus_unmap_resource), 145 #ifdef SMP 146 DEVMETHOD(bus_bind_intr, nexus_bind_intr), 147 #endif 148 DEVMETHOD(bus_config_intr, nexus_config_intr), 149 DEVMETHOD(bus_describe_intr, nexus_describe_intr), 150 DEVMETHOD(bus_setup_intr, nexus_setup_intr), 151 DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), 152 DEVMETHOD(bus_get_bus_tag, nexus_get_bus_tag), 153 154 DEVMETHOD_END 155 }; 156 157 static driver_t nexus_driver = { 158 "nexus", 159 nexus_methods, 160 1 /* no softc */ 161 }; 162 163 static int 164 nexus_attach(device_t dev) 165 { 166 167 mem_rman.rm_start = 0; 168 mem_rman.rm_end = BUS_SPACE_MAXADDR; 169 mem_rman.rm_type = RMAN_ARRAY; 170 mem_rman.rm_descr = "I/O memory addresses"; 171 if (rman_init(&mem_rman) || 172 rman_manage_region(&mem_rman, 0, BUS_SPACE_MAXADDR)) 173 panic("nexus_attach mem_rman"); 174 irq_rman.rm_start = 0; 175 irq_rman.rm_end = ~0; 176 irq_rman.rm_type = RMAN_ARRAY; 177 irq_rman.rm_descr = "Interrupts"; 178 if (rman_init(&irq_rman) || rman_manage_region(&irq_rman, 0, ~0)) 179 panic("nexus_attach irq_rman"); 180 181 bus_generic_probe(dev); 182 bus_generic_attach(dev); 183 184 return (0); 185 } 186 187 static int 188 nexus_print_child(device_t bus, device_t child) 189 { 190 int retval = 0; 191 192 retval += bus_print_child_header(bus, child); 193 retval += printf("\n"); 194 195 return (retval); 196 } 197 198 static device_t 199 nexus_add_child(device_t bus, u_int order, const char *name, int unit) 200 { 201 device_t child; 202 struct nexus_device *ndev; 203 204 ndev = malloc(sizeof(struct nexus_device), M_NEXUSDEV, M_NOWAIT|M_ZERO); 205 if (!ndev) 206 return (0); 207 resource_list_init(&ndev->nx_resources); 208 209 child = device_add_child_ordered(bus, order, name, unit); 210 211 /* should we free this in nexus_child_detached? */ 212 device_set_ivars(child, ndev); 213 214 return (child); 215 } 216 217 static struct rman * 218 nexus_get_rman(device_t bus, int type, u_int flags) 219 { 220 221 switch (type) { 222 case SYS_RES_IRQ: 223 return (&irq_rman); 224 case SYS_RES_MEMORY: 225 case SYS_RES_IOPORT: 226 return (&mem_rman); 227 default: 228 return (NULL); 229 } 230 } 231 232 /* 233 * Allocate a resource on behalf of child. NB: child is usually going to be a 234 * child of one of our descendants, not a direct child of nexus0. 235 */ 236 static struct resource * 237 nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, 238 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 239 { 240 struct nexus_device *ndev = DEVTONX(child); 241 struct resource_list_entry *rle; 242 243 /* 244 * If this is an allocation of the "default" range for a given 245 * RID, and we know what the resources for this device are 246 * (ie. they aren't maintained by a child bus), then work out 247 * the start/end values. 248 */ 249 if (RMAN_IS_DEFAULT_RANGE(start, end) && (count == 1)) { 250 if (device_get_parent(child) != bus || ndev == NULL) 251 return (NULL); 252 rle = resource_list_find(&ndev->nx_resources, type, *rid); 253 if (rle == NULL) 254 return (NULL); 255 start = rle->start; 256 end = rle->end; 257 count = rle->count; 258 } 259 260 return (bus_generic_rman_alloc_resource(bus, child, type, rid, start, 261 end, count, flags)); 262 } 263 264 static int 265 nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, 266 enum intr_polarity pol) 267 { 268 269 /* 270 * On arm64 (due to INTRNG), ACPI interrupt configuration is 271 * done in nexus_acpi_map_intr(). 272 */ 273 return (0); 274 } 275 276 static int 277 nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, 278 driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) 279 { 280 int error; 281 282 if ((rman_get_flags(res) & RF_SHAREABLE) == 0) 283 flags |= INTR_EXCL; 284 285 /* We depend here on rman_activate_resource() being idempotent. */ 286 error = rman_activate_resource(res); 287 if (error) 288 return (error); 289 290 error = intr_setup_irq(child, res, filt, intr, arg, flags, cookiep); 291 292 return (error); 293 } 294 295 static int 296 nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih) 297 { 298 299 return (intr_teardown_irq(child, r, ih)); 300 } 301 302 static int 303 nexus_describe_intr(device_t dev, device_t child, struct resource *irq, 304 void *cookie, const char *descr) 305 { 306 307 return (intr_describe_irq(child, irq, cookie, descr)); 308 } 309 310 #ifdef SMP 311 static int 312 nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu) 313 { 314 315 return (intr_bind_irq(child, irq, cpu)); 316 } 317 #endif 318 319 static bus_space_tag_t 320 nexus_get_bus_tag(device_t bus __unused, device_t child __unused) 321 { 322 323 return (&memmap_bus); 324 } 325 326 static int 327 nexus_activate_resource_flags(device_t bus, device_t child, int type, int rid, 328 struct resource *r, int flags) 329 { 330 struct resource_map_request args; 331 struct resource_map map; 332 int err, use_np; 333 334 if ((err = rman_activate_resource(r)) != 0) 335 return (err); 336 337 /* 338 * If this is a memory resource, map it into the kernel. 339 */ 340 switch (type) { 341 case SYS_RES_IOPORT: 342 case SYS_RES_MEMORY: 343 if ((rman_get_flags(r) & RF_UNMAPPED) == 0) { 344 resource_init_map_request(&args); 345 use_np = (flags & BUS_SPACE_MAP_NONPOSTED) != 0 || 346 force_np; 347 if (!use_np) 348 resource_int_value(device_get_name(child), 349 device_get_unit(child), "force_nonposted", 350 &use_np); 351 if (use_np) 352 args.memattr = VM_MEMATTR_DEVICE_NP; 353 err = nexus_map_resource(bus, child, type, r, &args, 354 &map); 355 if (err != 0) { 356 rman_deactivate_resource(r); 357 return (err); 358 } 359 360 rman_set_mapping(r, &map); 361 } 362 break; 363 case SYS_RES_IRQ: 364 err = intr_activate_irq(child, r); 365 if (err != 0) { 366 rman_deactivate_resource(r); 367 return (err); 368 } 369 } 370 return (0); 371 } 372 373 static int 374 nexus_activate_resource(device_t dev, device_t child, int type, int rid, 375 struct resource *r) 376 { 377 return (nexus_activate_resource_flags(dev, child, type, rid, r, 0)); 378 } 379 380 static struct resource_list * 381 nexus_get_reslist(device_t dev, device_t child) 382 { 383 struct nexus_device *ndev = DEVTONX(child); 384 385 return (&ndev->nx_resources); 386 } 387 388 static int 389 nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, 390 struct resource *r) 391 { 392 int error; 393 394 switch (type) { 395 case SYS_RES_MEMORY: 396 case SYS_RES_IOPORT: 397 return (bus_generic_rman_deactivate_resource(bus, child, type, 398 rid, r)); 399 case SYS_RES_IRQ: 400 error = rman_deactivate_resource(r); 401 if (error) 402 return (error); 403 intr_deactivate_irq(child, r); 404 return (0); 405 default: 406 return (EINVAL); 407 } 408 } 409 410 static int 411 nexus_map_resource(device_t bus, device_t child, int type, struct resource *r, 412 struct resource_map_request *argsp, struct resource_map *map) 413 { 414 struct resource_map_request args; 415 rman_res_t length, start; 416 int error; 417 418 /* Resources must be active to be mapped. */ 419 if ((rman_get_flags(r) & RF_ACTIVE) == 0) 420 return (ENXIO); 421 422 /* Mappings are only supported on I/O and memory resources. */ 423 switch (type) { 424 case SYS_RES_IOPORT: 425 case SYS_RES_MEMORY: 426 break; 427 default: 428 return (EINVAL); 429 } 430 431 resource_init_map_request(&args); 432 error = resource_validate_map_request(r, argsp, &args, &start, &length); 433 if (error) 434 return (error); 435 436 map->r_vaddr = pmap_mapdev_attr(start, length, args.memattr); 437 map->r_bustag = &memmap_bus; 438 map->r_size = length; 439 440 /* 441 * The handle is the virtual address. 442 */ 443 map->r_bushandle = (bus_space_handle_t)map->r_vaddr; 444 return (0); 445 } 446 447 static int 448 nexus_unmap_resource(device_t bus, device_t child, int type, struct resource *r, 449 struct resource_map *map) 450 { 451 452 switch (type) { 453 case SYS_RES_MEMORY: 454 case SYS_RES_IOPORT: 455 pmap_unmapdev(map->r_vaddr, map->r_size); 456 return (0); 457 default: 458 return (EINVAL); 459 } 460 } 461 462 #ifdef FDT 463 static device_method_t nexus_fdt_methods[] = { 464 /* Device interface */ 465 DEVMETHOD(device_probe, nexus_fdt_probe), 466 DEVMETHOD(device_attach, nexus_fdt_attach), 467 468 /* Bus interface */ 469 DEVMETHOD(bus_activate_resource, nexus_fdt_activate_resource), 470 471 /* OFW interface */ 472 DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr), 473 474 DEVMETHOD_END, 475 }; 476 477 #define nexus_baseclasses nexus_fdt_baseclasses 478 DEFINE_CLASS_1(nexus, nexus_fdt_driver, nexus_fdt_methods, 1, nexus_driver); 479 #undef nexus_baseclasses 480 481 EARLY_DRIVER_MODULE(nexus_fdt, root, nexus_fdt_driver, 0, 0, 482 BUS_PASS_BUS + BUS_PASS_ORDER_FIRST); 483 484 static int 485 nexus_fdt_probe(device_t dev) 486 { 487 488 if (arm64_bus_method != ARM64_BUS_FDT) 489 return (ENXIO); 490 491 device_quiet(dev); 492 return (BUS_PROBE_DEFAULT); 493 } 494 495 static int 496 nexus_fdt_attach(device_t dev) 497 { 498 499 nexus_add_child(dev, 10, "ofwbus", 0); 500 return (nexus_attach(dev)); 501 } 502 503 static int 504 nexus_fdt_activate_resource(device_t bus, device_t child, int type, int rid, 505 struct resource *r) 506 { 507 phandle_t node, parent; 508 int flags; 509 510 flags = 0; 511 switch (type) { 512 case SYS_RES_MEMORY: 513 case SYS_RES_IOPORT: 514 /* 515 * If the fdt parent has the nonposted-mmio property we 516 * need to use non-posted IO to access the device. When 517 * we find this property set the BUS_SPACE_MAP_NONPOSTED 518 * flag to be passed to bus_space_map. 519 */ 520 node = ofw_bus_get_node(child); 521 if (node != -1) { 522 parent = OF_parent(node); 523 if (parent != 0 && 524 OF_hasprop(parent, "nonposted-mmio")) { 525 flags |= BUS_SPACE_MAP_NONPOSTED; 526 } 527 } 528 break; 529 default: 530 break; 531 } 532 533 return (nexus_activate_resource_flags(bus, child, type, rid, r, flags)); 534 } 535 536 static int 537 nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells, 538 pcell_t *intr) 539 { 540 u_int irq; 541 struct intr_map_data_fdt *fdt_data; 542 size_t len; 543 544 len = sizeof(*fdt_data) + icells * sizeof(pcell_t); 545 fdt_data = (struct intr_map_data_fdt *)intr_alloc_map_data( 546 INTR_MAP_DATA_FDT, len, M_WAITOK | M_ZERO); 547 fdt_data->iparent = iparent; 548 fdt_data->ncells = icells; 549 memcpy(fdt_data->cells, intr, icells * sizeof(pcell_t)); 550 irq = intr_map_irq(NULL, iparent, (struct intr_map_data *)fdt_data); 551 return (irq); 552 } 553 #endif 554 555 #ifdef DEV_ACPI 556 static int nexus_acpi_map_intr(device_t dev, device_t child, u_int irq, int trig, int pol); 557 558 static device_method_t nexus_acpi_methods[] = { 559 /* Device interface */ 560 DEVMETHOD(device_probe, nexus_acpi_probe), 561 DEVMETHOD(device_attach, nexus_acpi_attach), 562 563 /* ACPI interface */ 564 DEVMETHOD(acpi_bus_map_intr, nexus_acpi_map_intr), 565 566 DEVMETHOD_END, 567 }; 568 569 #define nexus_baseclasses nexus_acpi_baseclasses 570 DEFINE_CLASS_1(nexus, nexus_acpi_driver, nexus_acpi_methods, 1, 571 nexus_driver); 572 #undef nexus_baseclasses 573 574 EARLY_DRIVER_MODULE(nexus_acpi, root, nexus_acpi_driver, 0, 0, 575 BUS_PASS_BUS + BUS_PASS_ORDER_FIRST); 576 577 static int 578 nexus_acpi_probe(device_t dev) 579 { 580 581 if (arm64_bus_method != ARM64_BUS_ACPI || acpi_identify() != 0) 582 return (ENXIO); 583 584 device_quiet(dev); 585 return (BUS_PROBE_LOW_PRIORITY); 586 } 587 588 static int 589 nexus_acpi_attach(device_t dev) 590 { 591 592 nexus_add_child(dev, 10, "acpi", 0); 593 return (nexus_attach(dev)); 594 } 595 596 static int 597 nexus_acpi_map_intr(device_t dev, device_t child, u_int irq, int trig, int pol) 598 { 599 struct intr_map_data_acpi *acpi_data; 600 size_t len; 601 602 len = sizeof(*acpi_data); 603 acpi_data = (struct intr_map_data_acpi *)intr_alloc_map_data( 604 INTR_MAP_DATA_ACPI, len, M_WAITOK | M_ZERO); 605 acpi_data->irq = irq; 606 acpi_data->pol = pol; 607 acpi_data->trig = trig; 608 609 /* 610 * TODO: This will only handle a single interrupt controller. 611 * ACPI will map multiple controllers into a single virtual IRQ 612 * space. Each controller has a System Vector Base to hold the 613 * first irq it handles in this space. As such the correct way 614 * to handle interrupts with ACPI is to search through the 615 * controllers for the largest base value that is no larger than 616 * the IRQ value. 617 */ 618 irq = intr_map_irq(NULL, ACPI_INTR_XREF, 619 (struct intr_map_data *)acpi_data); 620 return (irq); 621 } 622 #endif 623