From owner-p4-projects@FreeBSD.ORG Wed Jan 6 21:54:05 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 3ED061065704; Wed, 6 Jan 2010 21:54:05 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 02BEE1065700 for ; Wed, 6 Jan 2010 21:54:05 +0000 (UTC) (envelope-from raj@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id E3E2C8FC17 for ; Wed, 6 Jan 2010 21:54:04 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o06Ls49G041403 for ; Wed, 6 Jan 2010 21:54:04 GMT (envelope-from raj@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o06Ls4rA041401 for perforce@freebsd.org; Wed, 6 Jan 2010 21:54:04 GMT (envelope-from raj@freebsd.org) Date: Wed, 6 Jan 2010 21:54:04 GMT Message-Id: <201001062154.o06Ls4rA041401@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to raj@freebsd.org using -f From: Rafal Jaworowski To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 172675 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 Jan 2010 21:54:05 -0000 http://p4web.freebsd.org/chv.cgi?CH=172675 Change 172675 by raj@raj_fdt on 2010/01/06 21:53:13 Refactor simplebus and MPC85XX definitions. - Merge sys/powerpc/include/ocpbus.h into mpc85xx.h (this is the first step towards recycling ocbush.h) - Factor out a fdt_common.c from simplebus.c so that routines could be used by other FDT drivers as well (the upcoming LBC rework) - Imrove fdtbus driver a bit. - Temporarily disconnect LBC driver from the build. Affected files ... .. //depot/projects/fdt/sys/conf/files.powerpc#10 edit .. //depot/projects/fdt/sys/powerpc/booke/machdep.c#4 edit .. //depot/projects/fdt/sys/powerpc/booke/platform_bare.c#2 edit .. //depot/projects/fdt/sys/powerpc/mpc85xx/atpic.c#2 edit .. //depot/projects/fdt/sys/powerpc/mpc85xx/fdt_common.c#1 add .. //depot/projects/fdt/sys/powerpc/mpc85xx/fdt_common.h#1 add .. //depot/projects/fdt/sys/powerpc/mpc85xx/fdtbus.c#4 edit .. //depot/projects/fdt/sys/powerpc/mpc85xx/i2c.c#3 edit .. //depot/projects/fdt/sys/powerpc/mpc85xx/mpc85xx.h#2 edit .. //depot/projects/fdt/sys/powerpc/mpc85xx/ocpbus.c#2 edit .. //depot/projects/fdt/sys/powerpc/mpc85xx/simplebus.c#5 edit Differences ... ==== //depot/projects/fdt/sys/conf/files.powerpc#10 (text+ko) ==== @@ -119,10 +119,11 @@ powerpc/mpc85xx/atpic.c optional mpc85xx isa powerpc/mpc85xx/ds1553_bus_lbc.c optional ds1553 mpc85xx powerpc/mpc85xx/ds1553_core.c optional ds1553 +powerpc/mpc85xx/fdt_common.c optional fdt powerpc/mpc85xx/fdtbus.c optional fdt powerpc/mpc85xx/i2c.c optional iicbus fdt powerpc/mpc85xx/isa.c optional mpc85xx isa -powerpc/mpc85xx/lbc.c optional mpc85xx +#powerpc/mpc85xx/lbc.c optional mpc85xx powerpc/mpc85xx/mpc85xx.c optional mpc85xx powerpc/mpc85xx/nexus.c optional mpc85xx powerpc/mpc85xx/ocpbus.c optional mpc85xx ==== //depot/projects/fdt/sys/powerpc/booke/machdep.c#4 (text+ko) ==== @@ -137,7 +137,6 @@ #include -#include #include #ifdef DDB ==== //depot/projects/fdt/sys/powerpc/booke/platform_bare.c#2 (text+ko) ==== @@ -46,7 +46,6 @@ #include #include -#include #include "platform_if.h" ==== //depot/projects/fdt/sys/powerpc/mpc85xx/atpic.c#2 (text+ko) ==== @@ -39,7 +39,7 @@ #include #include -#include +#include #include ==== //depot/projects/fdt/sys/powerpc/mpc85xx/fdtbus.c#4 (text+ko) ==== @@ -43,6 +43,7 @@ #include +#include "fdt_common.h" #include "ofw_bus_if.h" #define DEBUG @@ -60,10 +61,14 @@ extern struct bus_space bs_be_tag; struct fdtbus_devinfo { - phandle_t di_node; - const char *di_name; - const char *di_type; - const char *di_compat; + phandle_t di_node; + char *di_name; + char *di_type; + char *di_compat; + struct resource_list di_res; + + /* Interrupts sense-level info for this device */ + struct sense_level di_intr_sl[DI_MAX_INTR_NUM]; }; struct fdtbus_softc { @@ -77,6 +82,7 @@ static int fdtbus_probe(device_t); static int fdtbus_attach(device_t); +static int fdtbus_print_child(device_t, device_t); static struct resource *fdtbus_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); static int fdtbus_release_resource(device_t, device_t, int, int, @@ -113,6 +119,7 @@ DEVMETHOD(device_resume, bus_generic_resume), /* Bus interface */ + DEVMETHOD(bus_print_child, fdtbus_print_child), DEVMETHOD(bus_alloc_resource, fdtbus_alloc_resource), DEVMETHOD(bus_release_resource, fdtbus_release_resource), DEVMETHOD(bus_activate_resource, fdtbus_activate_resource), @@ -143,7 +150,7 @@ fdtbus_probe(device_t dev) { - device_set_desc(dev, "FDTbus"); + device_set_desc(dev, "FDT main bus"); if (!bootverbose) device_quiet(dev); return (BUS_PROBE_DEFAULT); @@ -203,8 +210,6 @@ return (error); } - debugf("rmans initialized\n"); - /* * Walk the FDT root node and add top-level devices as our children. */ @@ -214,6 +219,16 @@ return (bus_generic_attach(dev)); } +static int +fdtbus_print_child(device_t bus, device_t child) +{ + int rv; + + rv = bus_print_child_header(bus, child); + rv += printf("\n"); + return (rv); +} + /* * These FDT nodes do not need a corresponding newbus device object. */ @@ -223,6 +238,21 @@ NULL }; +static void +newbus_device_destroy(device_t dev) +{ + struct fdtbus_devinfo *di; + + di = device_get_ivars(dev); + + free(di->di_name, M_OFWPROP); + free(di->di_type, M_OFWPROP); + free(di->di_compat, M_OFWPROP); + + resource_list_free(&di->di_res); + free(di, M_FDTBUS); +} + static device_t newbus_device_from_fdt_node(device_t parent, phandle_t node) { @@ -249,8 +279,33 @@ di->di_name = name; di->di_type = type; di->di_compat = compat; - device_set_ivars(child, di); - debugf("added child name='%s', node=%p\n", name, (void *)node); + + resource_list_init(&di->di_res); + + /* + * XXX this 0x1ef00000 offset is a gross hack, which assumes: + * - physical addresses in the DTS are 0xe0000000 range, and + * - virtual CCSR base in kernel is 0xfef00000 + */ + if (fdt_reg_to_rl(node, &di->di_res, 0x1ef00000)) { + device_printf(child, "could not process 'reg' " + "property\n"); + newbus_device_destroy(child); + child = NULL; + } + + if (fdt_intr_to_rl(node, &di->di_res, di->di_intr_sl)) { + device_printf(child, "could not process 'interrupts' " + "property\n"); + newbus_device_destroy(child); + child = NULL; + } + + if (child != NULL) { + device_set_ivars(child, di); + debugf("added child name='%s', node=%p\n", name, + (void *)node); + } } else { free(name, M_OFWPROP); free(type, M_OFWPROP); @@ -267,8 +322,32 @@ struct fdtbus_softc *sc; struct resource *res; struct rman *rm; + struct fdtbus_devinfo *di; + struct resource_list_entry *rle; int needactivate; + /* + * Request for the default allocation with a given rid: use resource + * list stored in the local device info. + */ + if ((start == 0UL) && (end == ~0UL)) { + if ((di = device_get_ivars(child)) == NULL) + return (NULL); + + if (type == SYS_RES_IOPORT) + type = SYS_RES_MEMORY; + + rle = resource_list_find(&di->di_res, type, *rid); + if (rle == NULL) { + device_printf(bus, "no default resources for " + "rid = %d, type = %d\n", *rid, type); + return (NULL); + } + start = rle->start; + end = rle->end; + count = rle->count; + } + sc = device_get_softc(bus); needactivate = flags & RF_ACTIVE; ==== //depot/projects/fdt/sys/powerpc/mpc85xx/i2c.c#3 (text+ko) ==== @@ -36,7 +36,6 @@ #include #include -#include #include #include ==== //depot/projects/fdt/sys/powerpc/mpc85xx/mpc85xx.h#2 (text+ko) ==== @@ -1,5 +1,6 @@ /*- * Copyright (C) 2008 Semihalf, Rafal Jaworowski + * Copyright 2006 by Juniper Networks. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,6 +30,109 @@ #ifndef _MPC85XX_H_ #define _MPC85XX_H_ +/* + * Configuration control and status registers + */ +#define OCP85XX_CCSRBAR (CCSRBAR_VA + 0x0) +#define OCP85XX_BPTR (CCSRBAR_VA + 0x20) + +/* + * E500 Coherency Module registers + */ +#define OCP85XX_EEBPCR (CCSRBAR_VA + 0x1010) + +/* + * Local access registers + */ +#define OCP85XX_LAWBAR(n) (CCSRBAR_VA + 0xc08 + 0x20 * (n)) +#define OCP85XX_LAWSR(n) (CCSRBAR_VA + 0xc10 + 0x20 * (n)) + +#define OCP85XX_TGTIF_PCI0 2 +#define OCP85XX_TGTIF_PCI1 1 +#define OCP85XX_TGTIF_PCI2 0 +#if 0 +#define OCP85XX_TGTIF_PCI0 0 +#define OCP85XX_TGTIF_PCI1 1 +#define OCP85XX_TGTIF_PCI2 2 +#endif + +#define OCP85XX_TGTIF_LBC 4 +#define OCP85XX_TGTIF_RAM_INTL 11 +#define OCP85XX_TGTIF_RIO 12 +#define OCP85XX_TGTIF_RAM1 15 +#define OCP85XX_TGTIF_RAM2 22 + +/* + * L2 cache registers + */ +#define OCP85XX_L2CTL (CCSRBAR_VA + 0x20000) + +/* + * Power-On Reset configuration + */ +#define OCP85XX_PORDEVSR (CCSRBAR_VA + 0xe000c) +#define OCP85XX_PORDEVSR_IO_SEL 0x00780000 +#define OCP85XX_PORDEVSR_IO_SEL_SHIFT 19 + +#define OCP85XX_PORDEVSR2 (CCSRBAR_VA + 0xe0014) + +#define OCP85XX_DEVDISR (CCSRBAR_VA + 0xe0070) +#define OCP85XX_DEVDISR_PCIE0 0x20000000 +#define OCP85XX_DEVDISR_PCIE1 0x04000000 +#define OCP85XX_DEVDISR_PCIE2 0x02000000 + +/* + * Status Registers. + */ +#define OCP85XX_RSTCR (CCSRBAR_VA + 0xe00b0) + +/* + * OCP Bus Definitions + */ +#define OCP85XX_I2C0_OFF 0x03000 +#define OCP85XX_I2C1_OFF 0x03100 +#define OCP85XX_I2C_SIZE 0x16 +#define OCP85XX_UART0_OFF 0x04500 +#define OCP85XX_UART1_OFF 0x04600 +#define OCP85XX_UART_SIZE 0x10 +#define OCP85XX_LBC_OFF 0x05000 +#define OCP85XX_LBC_SIZE 0x1000 + +#define OCP85XX_PCI0_OFF 0x0A000 +#define OCP85XX_PCI1_OFF 0x09000 +#define OCP85XX_PCI2_OFF 0x08000 +#if 0 +#define OCP85XX_PCI0_OFF 0x08000 +#define OCP85XX_PCI1_OFF 0x09000 +#define OCP85XX_PCI2_OFF 0x0A000 +#endif + +#define OCP85XX_PCI_SIZE 0x1000 +#define OCP85XX_TSEC0_OFF 0x24000 +#define OCP85XX_TSEC1_OFF 0x25000 +#define OCP85XX_TSEC2_OFF 0x26000 +#define OCP85XX_TSEC3_OFF 0x27000 +#define OCP85XX_TSEC_SIZE 0x1000 +#define OCP85XX_OPENPIC_OFF 0x40000 +#define OCP85XX_OPENPIC_SIZE 0x200B4 +#define OCP85XX_QUICC_OFF 0x80000 +#define OCP85XX_QUICC_SIZE 0x20000 +#define OCP85XX_SEC_OFF 0x30000 +#define OCP85XX_SEC_SIZE 0x10000 + +/* + * PIC definitions + */ +#define ISA_IRQ_START 0 +#define PIC_IRQ_START (ISA_IRQ_START + 16) + +#define ISA_IRQ(n) (ISA_IRQ_START + (n)) +#define PIC_IRQ_EXT(n) (PIC_IRQ_START + (n)) +#define PIC_IRQ_INT(n) (PIC_IRQ_START + 16 + (n)) + +/* + * Prototypes. + */ uint32_t ccsr_read4(uintptr_t addr); void ccsr_write4(uintptr_t addr, uint32_t val); int law_enable(int trgt, u_long addr, u_long size); ==== //depot/projects/fdt/sys/powerpc/mpc85xx/ocpbus.c#2 (text+ko) ==== @@ -45,7 +45,6 @@ #include #include -#include #include #include "pic_if.h" ==== //depot/projects/fdt/sys/powerpc/mpc85xx/simplebus.c#5 (text+ko) ==== @@ -48,7 +48,7 @@ #include "ofw_bus_if.h" -#include "../../contrib/dtc/libfdt/libfdt_env.h" +#include "fdt_common.h" #define DEBUG #undef DEBUG @@ -70,27 +70,14 @@ u_long sc_size; }; -struct sense_level { - enum intr_trigger trig; - enum intr_polarity pol; -}; - -#define DI_MAX_INTR_NUM 8 - struct simplebus_devinfo { struct ofw_bus_devinfo di_ofw; struct resource_list di_res; - /* Interrupt-parent phandle */ - phandle_t di_intr_par; - int di_intr_cells; - /* Interrupts sense-level info for this device */ struct sense_level di_intr_sl[DI_MAX_INTR_NUM]; - int di_intr_num; }; - /* * Prototypes. */ @@ -155,371 +142,30 @@ { if (ofw_bus_is_compatible(dev, "simple-bus")) { - device_set_desc(dev, "Flattened Device Tree simple bus"); + device_set_desc(dev, "Flattened device tree simple bus"); return (BUS_PROBE_DEFAULT); } return (ENXIO); } -static int -fdt_parent_addr_cells(phandle_t node) -{ - pcell_t addr_cells; - - /* Find out #address-cells of the superior bus. */ - if (OF_searchprop(node, "#address-cells", &addr_cells, - sizeof(addr_cells)) <= 0) - addr_cells = 1; - - return ((int)addr_cells); -} - -static void -fdt_ranges_dump(pcell_t *ranges, int tuples, int par_addr_cells, - int this_addr_cells, int this_size_cells) -{ -#ifdef DEBUG - int i, n; - - for (i = 0; i < tuples; i++) { - printf("par addr = "); - for (n = 0; n < par_addr_cells; n++) - printf("%x ", ranges[n]); - printf("\n"); - - printf("this addr = "); - for (; n < par_addr_cells + this_addr_cells; n++) - printf("%x ", ranges[n]); - printf("\n"); - - printf("this size = "); - for (; n < par_addr_cells + this_addr_cells + this_size_cells; - n++) - printf("%x ", ranges[n]); - printf("\n"); - } -#endif -} - -static int -fdt_data_verify(void *data, int cells) -{ - uint64_t d64; - - if (cells > 1) { - d64 = fdt64_to_cpu(*((uint64_t *)data)); - if (((d64 > 32) & 0xffffffffull) != 0) - return (ERANGE); - } - - return (0); -} - -static u_long -fdt_data_get(void *data, int cells) -{ - - if (cells == 1) - return (fdt32_to_cpu(*((uint32_t *)data))); - - return (fdt64_to_cpu(*((uint64_t *)data))); -} - -static int -fdt_ranges_verify(pcell_t *ranges, int tuples, int par_addr_cells, - int this_addr_cells, int this_size_cells) -{ - int i, rv, ulsz; - - if (par_addr_cells > 2 || this_addr_cells > 2 || this_size_cells > 2) - return (ERANGE); - - /* - * This is the max size the resource manager can handle for addresses - * and sizes. - */ - ulsz = sizeof(u_long); - if (par_addr_cells <= ulsz && this_addr_cells <= ulsz && - this_size_cells <= ulsz) - /* We can handle everything */ - return (0); - - rv = 0; - for (i = 0; i < tuples; i++) { - - if (fdt_data_verify((void *)ranges, par_addr_cells)) - goto err; - ranges += par_addr_cells; - - if (fdt_data_verify((void *)ranges, this_addr_cells)) - goto err; - ranges += this_addr_cells; - - if (fdt_data_verify((void *)ranges, this_size_cells)) - goto err; - ranges += this_size_cells; - } - - return (0); - -err: - printf("using address range >%d-bit not supported\n", ulsz * 8); - return (ERANGE); -} - -static int -simplebus_add_reg(phandle_t node, struct simplebus_devinfo *di, - struct simplebus_softc *sc) -{ - pcell_t *reg; - u_long start, end, count; - int tuple_size, tuples; - int i; - - /* XXX free reg prop? */ - tuple_size = sizeof(pcell_t) * (sc->sc_addr_cells + sc->sc_size_cells); - tuples = OF_getprop_alloc(node, "reg", tuple_size, (void **)®); - if (tuples <= 0) - /* No 'reg' property in this node. */ - return (0); - - for (i = 0; i < tuples; i++) { - /* Address portion. */ - if (fdt_data_verify((void *)reg, sc->sc_addr_cells)) { - debugf("tuple #%d: unsupported addr value in 'reg' " - "property\n", i); - goto err; - } - start = fdt_data_get((void *)reg, sc->sc_addr_cells); - reg += sc->sc_addr_cells; - - /* Size portion. */ - if (fdt_data_verify((void *)reg, sc->sc_size_cells)) { - debugf("tuple #%d: unsupported size value in 'reg' " - "property\n", i); - goto err; - } - count = fdt_data_get((void *)reg, sc->sc_size_cells); - reg += sc->sc_size_cells; - - /* Calculate address range relative to simple-bus VA base. */ - start = sc->sc_start_va + start; - end = start + count - 1; - - debugf("reg addr start = %lx, end = %lx, count = %lx\n", start, - end, count); - - if (end > sc->sc_start_va + sc->sc_size) { - debugf("end out of simple-bus range: %lx\n", end); - goto err; - } - - resource_list_add(&di->di_res, SYS_RES_MEMORY, i, start, end, - count); - } - return (0); - -err: - resource_list_free(&di->di_res); - return (ERANGE); -} - -static int -fdt_pic_decode_iic(phandle_t node, pcell_t *intr, int intr_cells, - int *interrupt, int *trig, int *pol) -{ - - /* TODO */ - return (ENXIO); -} - -static int -fdt_pic_decode_openpic(phandle_t node, pcell_t *intr, int intr_cells, - int *interrupt, int *trig, int *pol) -{ - char *compat; - ssize_t prop_len; - int rv; - - prop_len = OF_getprop_alloc(node, "compatible", 1, (void **)&compat); - if (prop_len <= 0) - return (ENXIO); - - rv = 0; - if (strncmp("open-pic", compat, 8) < 0) { - rv = ENXIO; - goto out; - } - - /* - * XXX The interrupt number read out from the device tree is already - * offset by 16 to reflect the 'internal' IRQ range shift on the - * OpenPIC. We still however need to account for the ISA IRQ block, - * potentially in use as well. - */ - *interrupt = ISA_IRQ_COUNT + intr[0]; - - if (intr_cells == 2) - switch (intr[1]) { - case 0: - /* L to H edge */ - *trig = INTR_TRIGGER_EDGE; - *pol = INTR_POLARITY_HIGH; - break; - case 1: - /* Active L level */ - *trig = INTR_TRIGGER_LEVEL; - *pol = INTR_POLARITY_LOW; - break; - case 2: - /* Active H level */ - *trig = INTR_TRIGGER_LEVEL; - *pol = INTR_POLARITY_HIGH; - break; - case 3: - /* H to L edge */ - *trig = INTR_TRIGGER_EDGE; - *pol = INTR_POLARITY_LOW; - break; - default: - *trig = INTR_TRIGGER_CONFORM; - *pol = INTR_POLARITY_CONFORM; - } - else { - *trig = INTR_TRIGGER_CONFORM; - *pol = INTR_POLARITY_CONFORM; - } - -out: - free(compat, M_OFWPROP); - return (rv); -} - -typedef int (*fdt_pic_decode_t)(phandle_t, pcell_t *, int, int *, int *, - int *); - -static fdt_pic_decode_t fdt_pic_table[] = { - &fdt_pic_decode_iic, - &fdt_pic_decode_openpic, - NULL -}; - -static int -fdt_intr_decode(struct simplebus_devinfo *di, pcell_t *intr, - int *interrupt, int *trig, int *pol) -{ - fdt_pic_decode_t intr_decode; - int i, rv; - - for (i = 0; fdt_pic_table[i] != NULL; i++) { - - /* XXX check if pic_handle has interrupt-controller prop? */ - - intr_decode = fdt_pic_table[i]; - rv = intr_decode(di->di_intr_par, intr, di->di_intr_cells, - interrupt, trig, pol); - - if (rv == 0) - /* This was recognized as our PIC and decoded. */ - return (0); - } - - return (ENXIO); -} - -static int -simplebus_add_one_intr(struct simplebus_devinfo *di, pcell_t *intr) -{ - int interrupt, trig, pol; - int intr_num; - - intr_num = di->di_intr_num; - - if (intr_num > DI_MAX_INTR_NUM) { - debugf("max intr num reached: %d\n", DI_MAX_INTR_NUM); - return (ENOMEM); - } - - interrupt = trig = pol = 0; - - if (fdt_intr_decode(di, intr, &interrupt, &trig, &pol) != 0) - return (ENXIO); - - if (interrupt <= 0) - return (ERANGE); - - debugf("decoded intr = %d, trig = %d, pol = %d\n", interrupt, trig, - pol); - - di->di_intr_sl[intr_num].trig = trig; - di->di_intr_sl[intr_num].pol = pol; - - resource_list_add(&di->di_res, SYS_RES_IRQ, intr_num, - interrupt, interrupt, 1); - - di->di_intr_num++; - - return (0); -} - -static int -simplebus_add_intr(phandle_t node, struct simplebus_devinfo *di) -{ - phandle_t intr_par; - ihandle_t iph; - pcell_t *intr; - pcell_t intr_cells; - int i, intr_num, rv; - - if (OF_getproplen(node, "interrupts") <= 0) - /* Node does not have 'interrupts' property. */ - return (0); - - /* - * Find #interrupt-cells of the interrupt domain. - */ - if (OF_getprop(node, "interrupt-parent", &iph, sizeof(iph)) <= 0) { - debugf("no intr-parent phandle\n"); - intr_par = OF_parent(node); - } else - intr_par = OF_instance_to_package(iph); - - if (OF_getprop(intr_par, "#interrupt-cells", &intr_cells, - sizeof(intr_cells)) <= 0) { - debugf("no intr-cells defined, defaulting to 1\n"); - intr_cells = 1; - } - - intr_num = OF_getprop_alloc(node, "interrupts", - intr_cells * sizeof(pcell_t), (void **)&intr); - if (intr_num <= 0) - return (ERANGE); - - rv = 0; - di->di_intr_num = 0; - di->di_intr_par = intr_par; - di->di_intr_cells = intr_cells; - for (i = 0; i < intr_num; i++) { - rv = simplebus_add_one_intr(di, &intr[i * intr_cells]); - if (rv != 0) { - /* XXX resource_list_free(&di->di_res); ??? */ - goto out; - } - } - -out: - free(intr, M_OFWPROP); - return (rv); -} - static void simplebus_fixup(phandle_t node) { - phandle_t cpus, child; + phandle_t cpus, child, root; + char *model; pcell_t freq; + int len; - /* XXX this whole fixup should depend on 8555 SOC */ + /* Fixup handling is platform specific. */ + if ((root = OF_finddevice("/")) == 0) + panic("simplebus: no root node"); + len = OF_getprop_alloc(root, "model", 1, (void **)&model); + if (len <= 0) + return; + if (!(strcmp(model, "fsl,MPC8572DS") == 0 || + strcmp(model, "MPC8555CDS") == 0)) + goto out; if ((cpus = OF_finddevice("/cpus")) == 0) panic("simplebus: no /cpus node"); @@ -532,6 +178,8 @@ return; OF_setprop(node, "bus-frequency", (void *)&freq, sizeof(freq)); +out: + free(model, M_OFWPROP); } static int @@ -543,34 +191,19 @@ struct simplebus_devinfo *di; struct simplebus_softc *sc; phandle_t node, child; - pcell_t cell; - ssize_t prop_len; - int cell_size, tuple_size, tuples; + int tuple_size, tuples; int par_addr_cells; sc = device_get_softc(dev); node = ofw_bus_get_node(dev); - cell_size = sizeof(cell); + + if ((fdt_addrsize_cells(node, &sc->sc_addr_cells, + &sc->sc_size_cells)) != 0) + return (ENXIO); simplebus_fixup(node); /* - * Retrieve #{address,size}-cells. - */ - if (OF_getprop(node, "#address-cells", &cell, cell_size) < cell_size) - cell = 2; - sc->sc_addr_cells = (int)cell; - - if (OF_getprop(node, "#size-cells", &cell, cell_size) < cell_size) - cell = 1; - sc->sc_size_cells = (int)cell; - - if (sc->sc_addr_cells > 2 || sc->sc_size_cells > 2) { - device_printf(dev, "unsupported # of cells\n"); - return (ERANGE); - } - - /* * Process 'ranges' property. */ par_addr_cells = fdt_parent_addr_cells(node); @@ -578,22 +211,16 @@ device_printf(dev, "unsupported parent #addr-cells\n"); return (ERANGE); } - tuple_size = cell_size * (sc->sc_addr_cells + par_addr_cells + + tuple_size = sizeof(pcell_t) * (sc->sc_addr_cells + par_addr_cells + sc->sc_size_cells); - /* XXX free ranges prop? */ - prop_len = OF_getprop_alloc(node, "ranges", 1, (void **)&ranges); + /* TODO free ranges prop */ + tuples = OF_getprop_alloc(node, "ranges", tuple_size, + (void **)&ranges); start = 0; size = 0; - if (prop_len >= 0) { - - if (prop_len % tuple_size) { - device_printf(dev, "inconsistent 'ranges' property\n"); - return (ENXIO); - } - tuples = prop_len / tuple_size; - + if (tuples > 0) { fdt_ranges_dump(ranges, tuples, par_addr_cells, sc->sc_addr_cells, sc->sc_size_cells); @@ -631,14 +258,15 @@ resource_list_init(&di->di_res); - if (simplebus_add_reg(child, di, sc)) { + if (fdt_reg_to_rl(child, &di->di_res, sc->sc_start_va)) { device_printf(dev, "could not process 'reg' " "property\n"); ofw_bus_gen_destroy_devinfo(&di->di_ofw); free(di, M_SIMPLEBUS); continue; } - if (simplebus_add_intr(child, di)) { + + if (fdt_intr_to_rl(child, &di->di_res, di->di_intr_sl)) { device_printf(dev, "could not process 'interrupts' " "property\n"); resource_list_free(&di->di_res);