int fdt_immr_addr(vm_offset_t immr_va) { phandle_t node; u_long base, size; int r; /* * Try to access the SOC node directly i.e. through /aliases/. */ if ((node = OF_finddevice("soc")) != 0) if (fdt_is_compatible(node, "simple-bus")) goto moveon; /* * Find the node the long way. */ if ((node = OF_finddevice("/")) == 0) return (ENXIO); if ((node = fdt_find_compatible(node, "simple-bus", 0)) == 0) return (ENXIO); moveon: if ((r = fdt_get_range(node, 0, &base, &size)) == 0) { fdt_immr_pa = base; fdt_immr_va = immr_va; fdt_immr_size = size; } return (r); }
int mv_msi_data(int irq, uint64_t *addr, uint32_t *data) { u_long phys, base, size; phandle_t node; int error; node = ofw_bus_get_node(mv_mpic_sc->sc_dev); /* Get physical addres of register space */ error = fdt_get_range(OF_parent(node), 0, &phys, &size); if (error) { printf("%s: Cannot get register physical address, err:%d", __func__, error); return (error); } /* Get offset of MPIC register space */ error = fdt_regsize(node, &base, &size); if (error) { printf("%s: Cannot get MPIC register offset, err:%d", __func__, error); return (error); } *addr = phys + base + MPIC_SOFT_INT; *data = MPIC_SOFT_INT_DRBL1 | irq; return (0); }
int fdt_reg_to_rl(phandle_t node, struct resource_list *rl) { u_long end, count, start; pcell_t *reg, *regptr; pcell_t addr_cells, size_cells; int tuple_size, tuples; int i, rv; long busaddr, bussize; if (fdt_addrsize_cells(OF_parent(node), &addr_cells, &size_cells) != 0) return (ENXIO); if (fdt_get_range(OF_parent(node), 0, &busaddr, &bussize)) { busaddr = 0; bussize = 0; } tuple_size = sizeof(pcell_t) * (addr_cells + size_cells); tuples = OF_getprop_alloc(node, "reg", tuple_size, (void **)®); debugf("addr_cells = %d, size_cells = %d\n", addr_cells, size_cells); debugf("tuples = %d, tuple size = %d\n", tuples, tuple_size); if (tuples <= 0) /* No 'reg' property in this node. */ return (0); regptr = reg; for (i = 0; i < tuples; i++) { rv = fdt_data_to_res(reg, addr_cells, size_cells, &start, &count); if (rv != 0) { resource_list_free(rl); goto out; } reg += addr_cells + size_cells; /* Calculate address range relative to base. */ start += busaddr; end = start + count - 1; debugf("reg addr start = %lx, end = %lx, count = %lx\n", start, end, count); resource_list_add(rl, SYS_RES_MEMORY, i, start, end, count); } rv = 0; out: free(regptr, M_OFWPROP); return (rv); }
static int alloc_resource_for_node(phandle_t node, struct resource *res, u_long *size) { int err; u_long pbase, psize; u_long start; if ((err = fdt_get_range(OF_parent(node), 0, &pbase, &psize)) != 0 || (err = fdt_regsize(node, &start, size)) != 0) return (err); start += pbase; memset(res, 0, sizeof(*res)); res->r_bustag = fdtbus_bs_tag; err = bus_space_map(res->r_bustag, start, *size, 0, &res->r_bushandle); return (err); }
int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { char buf[64]; struct uart_class *class; phandle_t node, chosen; pcell_t shift, br, rclk; u_long start, size, pbase, psize; int err; uart_bus_space_mem = fdtbus_bs_tag; uart_bus_space_io = NULL; /* Allow overriding the FDT uning the environment. */ class = &uart_ns8250_class; err = uart_getenv(devtype, di, class); if (!err) return (0); if (devtype != UART_DEV_CONSOLE) return (ENXIO); /* * Retrieve /chosen/std{in,out}. */ if ((chosen = OF_finddevice("/chosen")) == -1) return (ENXIO); if (OF_getprop(chosen, "stdin", buf, sizeof(buf)) <= 0) return (ENXIO); if ((node = OF_finddevice(buf)) == -1) return (ENXIO); if (OF_getprop(chosen, "stdout", buf, sizeof(buf)) <= 0) return (ENXIO); if (OF_finddevice(buf) != node) /* Only stdin == stdout is supported. */ return (ENXIO); /* * Retrieve serial attributes. */ uart_fdt_get_shift(node, &shift); if (OF_getprop(node, "current-speed", &br, sizeof(br)) <= 0) br = 0; br = fdt32_to_cpu(br); if ((err = uart_fdt_get_clock(node, &rclk)) != 0) return (err); /* * Finalize configuration. */ if (fdt_is_compatible(node, "quicc")) class = &uart_quicc_class; if (fdt_is_compatible(node, "lpc")) class = &uart_lpc_class; if (fdt_is_compatible(node, "ns16550")) class = &uart_ns8250_class; if (fdt_is_compatible(node, "arm,pl011")) class = &uart_pl011_class; di->bas.chan = 0; di->bas.regshft = (u_int)shift; di->baudrate = br; di->bas.rclk = (u_int)rclk; di->ops = uart_getops(class); di->databits = 8; di->stopbits = 1; di->parity = UART_PARITY_NONE; di->bas.bst = uart_bus_space_mem; err = fdt_regsize(node, &start, &size); if (err) return (ENXIO); err = fdt_get_range(OF_parent(node), 0, &pbase, &psize); if (err) pbase = 0; start += pbase; return (bus_space_map(di->bas.bst, start, size, 0, &di->bas.bsh)); }