Page MenuHomeFreeBSD

D5633.id.diff
No OneTemporary

D5633.id.diff

Index: sys/dev/bhnd/bhndb/bhndb.h
===================================================================
--- sys/dev/bhnd/bhndb/bhndb.h
+++ sys/dev/bhnd/bhndb/bhndb.h
@@ -46,6 +46,7 @@
extern devclass_t bhndb_devclass;
int bhndb_attach_bridge(device_t parent, device_t *bhndb, int unit);
+int bhndb_attach_by_class(device_t parent, device_t *child, int unit, devclass_t child_devclass);
/**
* bhndb register window types.
@@ -54,6 +55,7 @@
BHNDB_REGWIN_T_CORE, /**< Fixed mapping of a core port region. */
BHNDB_REGWIN_T_SPROM, /**< Fixed mapping of device SPROM */
BHNDB_REGWIN_T_DYN, /**< A dynamically configurable window */
+ BHNDB_REGWIN_T_FIXED, /**< Memory mapped direct window */
BHNDB_REGWIN_T_INVALID /**< Invalid type */
} bhndb_regwin_type_t;
@@ -64,7 +66,8 @@
*/
#define BHNDB_REGWIN_T_IS_STATIC(_rt) \
((_rt) == BHNDB_REGWIN_T_CORE || \
- (_rt) == BHNDB_REGWIN_T_SPROM)
+ (_rt) == BHNDB_REGWIN_T_SPROM || \
+ (_rt) == BHNDB_REGWIN_T_FIXED)
/**
* bhndb register window definition.
@@ -80,8 +83,8 @@
int rid; /**< resource id */
} res;
-
- union {
+ /** changed from unnamed to named to meet C99 */
+ union specific {
/** Core-specific register window (BHNDB_REGWIN_T_CORE). */
struct {
bhnd_devclass_t class; /**< mapped core's class */
@@ -91,6 +94,9 @@
u_int region; /**< mapped region number */
} core;
+ /** Fixed memory mapped bus windows */
+ struct{} direct;
+
/** SPROM register window (BHNDB_REGWIN_T_SPROM). */
struct {} sprom;
@@ -98,7 +104,7 @@
struct {
bus_size_t cfg_offset; /**< window address config offset. */
} dyn;
- };
+ } win_spec;
};
#define BHNDB_REGWIN_TABLE_END { BHNDB_REGWIN_T_INVALID, 0, 0, { 0, 0 } }
@@ -110,6 +116,7 @@
* via which those mappings may be accessed.
*/
struct bhndb_hwcfg {
+ bool is_hostb_required;
const struct resource_spec *resource_specs;
const struct bhndb_regwin *register_windows;
};
@@ -170,4 +177,4 @@
#define BHNDB_HW_PRIORITY_TABLE_END { {}, BHNDB_PRIORITY_NONE, NULL, 0 }
-#endif /* _BHND_BHNDB_H_ */
\ No newline at end of file
+#endif /* _BHND_BHNDB_H_ */
Index: sys/dev/bhnd/bhndb/bhndb.c
===================================================================
--- sys/dev/bhnd/bhndb/bhndb.c
+++ sys/dev/bhnd/bhndb/bhndb.c
@@ -257,8 +257,8 @@
/* Fetch the base address of the mapped port. */
error = bhnd_get_region_addr(child,
- regw->core.port_type, regw->core.port,
- regw->core.region, &addr, &size);
+ regw->win_spec.core.port_type, regw->win_spec.core.port,
+ regw->win_spec.core.region, &addr, &size);
if (error)
return (error);
@@ -614,9 +614,12 @@
}
if (hostb == NULL) {
- device_printf(sc->dev, "no host bridge core found\n");
- error = ENODEV;
- goto cleanup;
+ if(sc->bus_res->cfg->is_hostb_required){
+ device_printf(sc->dev, "no host bridge core found\n");
+ error = ENODEV;
+ goto cleanup;
+ }
+ device_printf(sc->dev, "WARNING: no host bridge core found\n");
}
/* Find our full register window configuration */
@@ -1080,8 +1083,8 @@
if (error) {
device_printf(dev,
"failed to activate entry %#x type %d for "
- "child %s\n",
- *rid, type, device_get_nameunit(child));
+ "child %s: %d\n",
+ *rid, type, device_get_nameunit(child), error);
rman_release_resource(rv);
@@ -1342,17 +1345,37 @@
/* Look for a bus region matching the resource's address range */
r_start = rman_get_start(r);
r_size = rman_get_size(r);
+
+ if(bootverbose){
+ device_printf(sc->dev, "%s: trying to activate %p (%ld) : rid=%d for %s\n",
+ __func__,
+ (void *)(uintptr_t)r_start, r_size, rid, device_get_nameunit(child));
+
+ bhndb_print_resources(sc->bus_res);
+ }
+
region = bhndb_find_resource_region(sc->bus_res, r_start, r_size);
if (region != NULL)
dw_priority = region->priority;
+ if(bootverbose){
+ if(region == NULL){
+ device_printf(sc->dev, "%s: no region found\n", __func__);
+ }else{
+ device_printf(sc->dev, "%s: found %s region %p (%lld)\n", __func__ ,
+ ((region->static_regwin) ? "static" : "dynamic"),
+ (void *)(uintptr_t)region->addr, region->size);
+ }
+ }
+
/* Prefer static mappings over consuming a dynamic windows. */
if (region && region->static_regwin) {
error = bhndb_activate_static_region(sc, region, child, type,
rid, r);
if (error)
- device_printf(sc->dev, "static window allocation "
+ device_printf(sc->dev, "%s: static window allocation "
"for 0x%llx-0x%llx failed\n",
+ __func__,
(unsigned long long) r_start,
(unsigned long long) r_start + r_size - 1);
return (error);
@@ -1361,18 +1384,25 @@
/* A dynamic window will be required; is this resource high enough
* priority to be reserved a dynamic window? */
if (dw_priority < sc->bus_res->min_prio) {
+ device_printf(sc->dev, "%s: priority %d is lower than min priority %d\n",
+ __func__, dw_priority, sc->bus_res->min_prio);
if (indirect)
*indirect = true;
return (ENOMEM);
}
+ if(bootverbose){
+ device_printf(sc->dev, "%s: trying to find and retain window...\n", __func__);
+ }
+
/* Find and retain a usable window */
BHNDB_LOCK(sc); {
dwa = bhndb_retain_dynamic_window(sc, r);
} BHNDB_UNLOCK(sc);
if (dwa == NULL) {
+ device_printf(sc->dev, "%s: no window is found...\n", __func__);
if (indirect)
*indirect = true;
return (ENOMEM);
@@ -1382,6 +1412,10 @@
parent_offset = dwa->win->win_offset;
parent_offset += r_start - dwa->target;
+ if(bootverbose){
+ device_printf(sc->dev, "%s: parent_offset=%p\n", __func__ , (void*)(uintptr_t)parent_offset);
+ }
+
error = bhndb_init_child_resource(r, dwa->parent_res, parent_offset,
dwa->win->win_size);
if (error)
@@ -1922,7 +1956,7 @@
DEVMETHOD(bhnd_bus_alloc_resource, bhndb_alloc_bhnd_resource),
DEVMETHOD(bhnd_bus_release_resource, bhndb_release_bhnd_resource),
DEVMETHOD(bhnd_bus_activate_resource, bhndb_activate_bhnd_resource),
- DEVMETHOD(bhnd_bus_activate_resource, bhndb_deactivate_bhnd_resource),
+ DEVMETHOD(bhnd_bus_deactivate_resource, bhndb_deactivate_bhnd_resource),
DEVMETHOD(bhnd_bus_read_1, bhndb_bus_read_1),
DEVMETHOD(bhnd_bus_read_2, bhndb_bus_read_2),
DEVMETHOD(bhnd_bus_read_4, bhndb_bus_read_4),
Index: sys/dev/bhnd/bhndb/bhndb_pci.c
===================================================================
--- sys/dev/bhnd/bhndb/bhndb_pci.c
+++ sys/dev/bhnd/bhndb/bhndb_pci.c
@@ -775,7 +775,7 @@
if ((error = bhndb_pci_fast_setregwin(sc, rw, addr)))
return (error);
- if (pci_read_config(parent, rw->dyn.cfg_offset, 4) == addr)
+ if (pci_read_config(parent, rw->win_spec.dyn.cfg_offset, 4) == addr)
return (0);
DELAY(10);
@@ -805,7 +805,7 @@
if (addr % rw->win_size != 0)
return (EINVAL);
- pci_write_config(parent, rw->dyn.cfg_offset, addr, 4);
+ pci_write_config(parent, rw->win_spec.dyn.cfg_offset, addr, 4);
break;
default:
return (ENODEV);
Index: sys/dev/bhnd/bhndb/bhndb_pci_hwdata.c
===================================================================
--- sys/dev/bhnd/bhndb/bhndb_pci_hwdata.c
+++ sys/dev/bhnd/bhndb/bhndb_pci_hwdata.c
@@ -82,6 +82,7 @@
* at the default enumeration address (0x18000000).
*/
const struct bhndb_hwcfg bhndb_pci_siba_generic_hwcfg = {
+ .is_hostb_required = true,
.resource_specs = (const struct resource_spec[]) {
{ SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE },
{ -1, 0, 0 }
@@ -93,7 +94,7 @@
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V1_BAR0_WIN0_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_WIN0_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL,
+ .win_spec.dyn.cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL,
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
BHNDB_REGWIN_TABLE_END
@@ -111,6 +112,7 @@
* - Compatible with both siba(4) and bcma(4) bus enumeration.
*/
const struct bhndb_hwcfg bhndb_pci_bcma_generic_hwcfg = {
+ .is_hostb_required = true,
.resource_specs = (const struct resource_spec[]) {
{ SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE },
{ -1, 0, 0 }
@@ -122,7 +124,7 @@
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V1_BAR0_WIN0_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_WIN0_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL,
+ .win_spec.dyn.cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL,
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -131,7 +133,7 @@
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V1_BAR0_CCREGS_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_CCREGS_SIZE,
- .core = {
+ .win_spec.core = {
.class = BHND_DEVCLASS_CC,
.unit = 0,
.port = 0,
@@ -316,6 +318,7 @@
* - PCI (cid=0x804, revision <= 12)
*/
static const struct bhndb_hwcfg bhndb_pci_hwcfg_v0 = {
+ .is_hostb_required = true,
.resource_specs = (const struct resource_spec[]) {
{ SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE },
{ -1, 0, 0 }
@@ -327,7 +330,7 @@
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V0_BAR0_WIN0_OFFSET,
.win_size = BHNDB_PCI_V0_BAR0_WIN0_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V0_BAR0_WIN0_CONTROL,
+ .win_spec.dyn.cfg_offset = BHNDB_PCI_V0_BAR0_WIN0_CONTROL,
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -344,7 +347,7 @@
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V0_BAR0_PCIREG_OFFSET,
.win_size = BHNDB_PCI_V0_BAR0_PCIREG_SIZE,
- .core = {
+ .win_spec.core = {
.class = BHND_DEVCLASS_PCI,
.unit = 0,
.port = 0,
@@ -364,6 +367,7 @@
* - PCI (cid=0x804, revision >= 13)
*/
static const struct bhndb_hwcfg bhndb_pci_hwcfg_v1_pci = {
+ .is_hostb_required = true,
.resource_specs = (const struct resource_spec[]) {
{ SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE },
{ -1, 0, 0 }
@@ -375,7 +379,7 @@
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V1_BAR0_WIN0_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_WIN0_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL,
+ .win_spec.dyn.cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL,
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -392,7 +396,7 @@
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V1_BAR0_PCIREG_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_PCIREG_SIZE,
- .core = {
+ .win_spec.core = {
.class = BHND_DEVCLASS_PCI,
.unit = 0,
.port = 0,
@@ -407,7 +411,7 @@
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V1_BAR0_CCREGS_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_CCREGS_SIZE,
- .core = {
+ .win_spec.core = {
.class = BHND_DEVCLASS_CC,
.unit = 0,
.port = 0,
@@ -428,6 +432,7 @@
* - PCIE (cid=0x820) with ChipCommon (revision <= 31)
*/
static const struct bhndb_hwcfg bhndb_pci_hwcfg_v1_pcie = {
+ .is_hostb_required = true,
.resource_specs = (const struct resource_spec[]) {
{ SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE },
{ -1, 0, 0 }
@@ -439,7 +444,7 @@
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V1_BAR0_WIN0_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_WIN0_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL,
+ .win_spec.dyn.cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL,
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -456,7 +461,7 @@
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V1_BAR0_PCIREG_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_PCIREG_SIZE,
- .core = {
+ .win_spec.core = {
.class = BHND_DEVCLASS_PCIE,
.unit = 0,
.port = 0,
@@ -471,7 +476,7 @@
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V1_BAR0_CCREGS_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_CCREGS_SIZE,
- .core = {
+ .win_spec.core = {
.class = BHND_DEVCLASS_CC,
.unit = 0,
.port = 0,
@@ -492,6 +497,7 @@
* - PCIE (cid=0x820) with ChipCommon (revision >= 32)
*/
static const struct bhndb_hwcfg bhndb_pci_hwcfg_v2 = {
+ .is_hostb_required = true,
.resource_specs = (const struct resource_spec[]) {
{ SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE },
{ -1, 0, 0 }
@@ -503,7 +509,7 @@
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V2_BAR0_WIN0_OFFSET,
.win_size = BHNDB_PCI_V2_BAR0_WIN0_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V2_BAR0_WIN0_CONTROL,
+ .win_spec.dyn.cfg_offset = BHNDB_PCI_V2_BAR0_WIN0_CONTROL,
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -512,7 +518,7 @@
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V2_BAR0_WIN1_OFFSET,
.win_size = BHNDB_PCI_V2_BAR0_WIN1_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V2_BAR0_WIN1_CONTROL,
+ .win_spec.dyn.cfg_offset = BHNDB_PCI_V2_BAR0_WIN1_CONTROL,
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -521,7 +527,7 @@
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V2_BAR0_PCIREG_OFFSET,
.win_size = BHNDB_PCI_V2_BAR0_PCIREG_SIZE,
- .core = {
+ .win_spec.core = {
.class = BHND_DEVCLASS_PCIE,
.unit = 0,
.port = 0,
@@ -536,7 +542,7 @@
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V2_BAR0_CCREGS_OFFSET,
.win_size = BHNDB_PCI_V2_BAR0_CCREGS_SIZE,
- .core = {
+ .win_spec.core = {
.class = BHND_DEVCLASS_CC,
.unit = 0,
.port = 0,
@@ -557,6 +563,7 @@
* - PCIE2 (cid=0x83c)
*/
static const struct bhndb_hwcfg bhndb_pci_hwcfg_v3 = {
+ .is_hostb_required = true,
.resource_specs = (const struct resource_spec[]) {
{ SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE },
{ -1, 0, 0 }
@@ -568,7 +575,7 @@
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V3_BAR0_WIN0_OFFSET,
.win_size = BHNDB_PCI_V3_BAR0_WIN0_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V3_BAR0_WIN0_CONTROL,
+ .win_spec.dyn.cfg_offset = BHNDB_PCI_V3_BAR0_WIN0_CONTROL,
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -577,7 +584,7 @@
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V3_BAR0_WIN1_OFFSET,
.win_size = BHNDB_PCI_V3_BAR0_WIN1_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V3_BAR0_WIN1_CONTROL,
+ .win_spec.dyn.cfg_offset = BHNDB_PCI_V3_BAR0_WIN1_CONTROL,
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -586,7 +593,7 @@
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V3_BAR0_PCIREG_OFFSET,
.win_size = BHNDB_PCI_V3_BAR0_PCIREG_SIZE,
- .core = {
+ .win_spec.core = {
.class = BHND_DEVCLASS_PCIE,
.unit = 0,
.port = 0,
@@ -601,7 +608,7 @@
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V3_BAR0_CCREGS_OFFSET,
.win_size = BHNDB_PCI_V3_BAR0_CCREGS_SIZE,
- .core = {
+ .win_spec.core = {
.class = BHND_DEVCLASS_CC,
.unit = 0,
.port = 0,
Index: sys/dev/bhnd/bhndb/bhndb_private.h
===================================================================
--- sys/dev/bhnd/bhndb/bhndb_private.h
+++ sys/dev/bhnd/bhndb/bhndb_private.h
@@ -124,6 +124,8 @@
const struct bhndb_hw_priority *table,
device_t device);
+void bhndb_print_resources(struct bhndb_resources* res);
+char* bhndb_print_class(bhnd_devclass_t class);
/**
* Dynamic register window allocation reference.
@@ -189,6 +191,37 @@
return (br->dwa_freelist == 0);
}
+#define CTZ32_BSEARCH(x, n, MASK, SHIFT) if( (x & MASK) == 0){ x<<= SHIFT; n+= SHIFT; }
+static inline int bhndb_ctz32(u_int32_t y){
+ int n = 0;
+ if(y == 0) return 32;
+
+ int x = y;
+
+ CTZ32_BSEARCH(x, n, 0x0000FFFF, 16);
+ CTZ32_BSEARCH(x, n, 0x000000FF, 8);
+ CTZ32_BSEARCH(x, n, 0x0000000F, 4);
+ CTZ32_BSEARCH(x, n, 0x00000003, 2);
+ CTZ32_BSEARCH(x, n, 0x00000001, 1);
+
+ return n;
+}
+
+static inline int bhndb_popcount(u_int32_t y)
+{
+ u_int32_t x = y;
+ x = x - ((x >> 1) & 0x55555555);
+ /* Every 2 bits holds the sum of every pair of bits */
+ x = ((x >> 2) & 0x33333333) + (x & 0x33333333); // 0011001100110011
+ /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) */
+ x = (x + (x >> 4)) & 0x0F0F0F0F;
+ /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) */
+ x = (x + (x >> 16));
+ /* The lower 16 bits hold two 8 bit sums (5 significant bits).*/
+ /* Upper 16 bits are garbage */
+ return (x + (x >> 8)) & 0x0000003F; /* (6 significant bits) */
+}
+
/**
* Find the next free dynamic window region in @p br.
*
@@ -202,7 +235,7 @@
if (bhndb_dw_exhausted(br))
return (NULL);
- dw_free = &br->dw_alloc[__builtin_ctz(br->dwa_freelist)];
+ dw_free = &br->dw_alloc[bhndb_ctz32(br->dwa_freelist)];
KASSERT(LIST_EMPTY(&dw_free->refs),
("free list out of sync with refs"));
Index: sys/dev/bhnd/bhndb/bhndb_subr.c
===================================================================
--- sys/dev/bhnd/bhndb/bhndb_subr.c
+++ sys/dev/bhnd/bhndb/bhndb_subr.c
@@ -33,39 +33,49 @@
#include <sys/param.h>
#include <sys/kernel.h>
+#include <dev/bhnd/bhnd_types.h>
#include "bhndb_private.h"
#include "bhndbvar.h"
+
+int
+bhndb_attach_by_class(device_t parent, device_t *child, int unit, devclass_t child_devclass)
+{
+ int error;
+
+ *child = device_add_child(parent, devclass_get_name(child_devclass),
+ unit);
+ if (*child == NULL)
+ return (ENXIO);
+
+ if (!(error = device_probe_and_attach(*child)))
+ return (0);
+
+ if ((device_delete_child(parent, *child)))
+ device_printf(parent, "failed to detach bhndb child\n");
+
+ return (error);
+
+}
+
/**
* Attach a BHND bridge device to @p parent.
- *
+ *
* @param parent A parent PCI device.
* @param[out] bhndb On success, the probed and attached bhndb bridge device.
* @param unit The device unit number, or -1 to select the next available unit
* number.
- *
+ *
* @retval 0 success
* @retval non-zero Failed to attach the bhndb device.
*/
int
bhndb_attach_bridge(device_t parent, device_t *bhndb, int unit)
{
- int error;
-
- *bhndb = device_add_child(parent, devclass_get_name(bhndb_devclass),
- unit);
- if (*bhndb == NULL)
- return (ENXIO);
-
- if (!(error = device_probe_and_attach(*bhndb)))
- return (0);
-
- if ((device_delete_child(parent, *bhndb)))
- device_printf(parent, "failed to detach bhndb child\n");
-
- return (error);
+ return bhndb_attach_by_class(parent, bhndb, unit, bhndb_devclass);
}
+
/*
* Call BHNDB_SUSPEND_RESOURCE() for all resources in @p rl.
*/
@@ -88,15 +98,15 @@
/**
* Helper function for implementing BUS_RESUME_CHILD() on bridged
* bhnd(4) buses.
- *
+ *
* This implementation of BUS_RESUME_CHILD() uses BUS_GET_RESOURCE_LIST()
* to find the child's resources and call BHNDB_SUSPEND_RESOURCE() for all
* child resources, ensuring that the device's allocated bridge resources
* will be available to other devices during bus resumption.
- *
- * Before suspending any resources, @p child is suspended by
+ *
+ * Before suspending any resources, @p child is suspended by
* calling bhnd_generic_suspend_child().
- *
+ *
* If @p child is not a direct child of @p dev, suspension is delegated to
* the @p dev parent.
*/
@@ -130,13 +140,13 @@
/**
* Helper function for implementing BUS_RESUME_CHILD() on bridged
* bhnd(4) bus devices.
- *
+ *
* This implementation of BUS_RESUME_CHILD() uses BUS_GET_RESOURCE_LIST()
* to find the child's resources and call BHNDB_RESUME_RESOURCE() for all
* child resources, before delegating to bhnd_generic_resume_child().
- *
+ *
* If resource resumption fails, @p child will not be resumed.
- *
+ *
* If @p child is not a direct child of @p dev, suspension is delegated to
* the @p dev parent.
*/
@@ -146,7 +156,7 @@
struct resource_list *rl;
struct resource_list_entry *rle;
int error;
-
+
if (device_get_parent(child) != dev)
BUS_RESUME_CHILD(device_get_parent(dev), child);
@@ -184,10 +194,10 @@
/**
* Find the resource containing @p win.
- *
+ *
* @param br The bhndb resource state to search.
* @param win A register window.
- *
+ *
* @retval resource the resource containing @p win.
* @retval NULL if no resource containing @p win can be found.
*/
@@ -198,7 +208,7 @@
const struct resource_spec *rspecs;
rspecs = br->cfg->resource_specs;
- for (u_int i = 0; rspecs[i].type != -1; i++) {
+ for (u_int i = 0; rspecs[i].type != -1; i++) {
if (win->res.type != rspecs[i].type)
continue;
@@ -219,7 +229,7 @@
/**
* Allocate and initialize a new resource state structure, allocating
* bus resources from @p parent_dev according to @p cfg.
- *
+ *
* @param dev The bridge device.
* @param parent_dev The parent device from which resources will be allocated.
* @param cfg The hardware configuration to be used.
@@ -248,7 +258,7 @@
r->cfg = cfg;
r->min_prio = BHNDB_PRIORITY_NONE;
STAILQ_INIT(&r->bus_regions);
-
+
/* Determine our bridge resource count from the hardware config. */
res_num = 0;
for (size_t i = 0; cfg->resource_specs[i].type != -1; i++)
@@ -265,7 +275,7 @@
/* Initialize and terminate the table */
for (size_t i = 0; i < res_num; i++)
r->res_spec[i] = cfg->resource_specs[i];
-
+
r->res_spec[res_num].type = -1;
/* Allocate space for our resource references */
@@ -292,7 +302,7 @@
device_printf(r->dev, "max dynamic regwin count exceeded\n");
goto failed;
}
-
+
/* Allocate the dynamic window allocation table. */
r->dw_alloc = malloc(sizeof(r->dw_alloc[0]) * r->dwa_count, M_BHND,
M_NOWAIT);
@@ -308,9 +318,18 @@
{
struct bhndb_dw_alloc *dwa;
- /* Skip non-DYN windows */
- if (win->win_type != BHNDB_REGWIN_T_DYN)
+ /* Skip non-DYN windows and process FIXED windows */
+ if (win->win_type != BHNDB_REGWIN_T_DYN){
+ if(win->win_type != BHNDB_REGWIN_T_FIXED)
+ continue;
+
+ int error = bhndb_add_resource_region(r,
+ win->win_offset,win->win_size, BHNDB_PRIORITY_DEFAULT, win);
+ if(error)
+ goto failed;
+
continue;
+ }
/* Validate the window size */
if (win->win_size == 0) {
@@ -320,13 +339,13 @@
} else if (last_window_size == 0) {
last_window_size = win->win_size;
} else if (last_window_size != win->win_size) {
- /*
+ /*
* No existing hardware should trigger this.
- *
+ *
* If you run into this in the future, the dynamic
* window allocator and the resource priority system
* will need to be extended to support multiple register
- * window allocation pools.
+ * window allocation pools.
*/
device_printf(r->dev, "devices that vend multiple "
"dynamic register window sizes are not currently "
@@ -339,7 +358,7 @@
dwa->parent_res = NULL;
dwa->rnid = rnid;
dwa->target = 0x0;
-
+
LIST_INIT(&dwa->refs);
/* Find and validate corresponding resource. */
@@ -388,7 +407,7 @@
/**
* Deallocate the given bridge resource structure and any associated resources.
- *
+ *
* @param br Resource state to be deallocated.
*/
void
@@ -399,7 +418,7 @@
struct bhndb_dw_rentry *dwr, *dwr_next;
/* No window regions may still be held */
- if (__builtin_popcount(br->dwa_freelist) != br->dwa_count) {
+ if (bhndb_popcount(br->dwa_freelist) != br->dwa_count) {
device_printf(br->dev, "leaked %llu dynamic register regions\n",
(unsigned long long) br->dwa_count - br->dwa_freelist);
}
@@ -416,7 +435,7 @@
free(dwr, M_BHND);
}
}
-
+
/* Release bus regions */
STAILQ_FOREACH_SAFE(region, &br->bus_regions, link, r_next) {
STAILQ_REMOVE(&br->bus_regions, region, bhndb_region, link);
@@ -431,7 +450,7 @@
/**
* Add a bus region entry to @p r for the given base @p addr and @p size.
- *
+ *
* @param br The resource state to which the bus region entry will be added.
* @param addr The base address of this region.
* @param size The size of this region.
@@ -439,7 +458,7 @@
* made within this bus region.
* @param static_regwin If available, a static register window mapping this
* bus region entry. If not available, NULL.
- *
+ *
* @retval 0 success
* @retval non-zero if adding the bus region fails.
*/
@@ -469,11 +488,11 @@
/**
* Find a bus region that maps @p size bytes at @p addr.
- *
+ *
* @param br The resource state to search.
* @param addr The requested starting address.
* @param size The requested size.
- *
+ *
* @retval bhndb_region A region that fully contains the requested range.
* @retval NULL If no mapping region can be found.
*/
@@ -500,7 +519,7 @@
/**
* Find the entry matching @p r in @p dwa's references, if any.
- *
+ *
* @param dwa The dynamic window allocation to search
* @param r The resource to search for in @p dwa.
*/
@@ -530,10 +549,10 @@
/**
* Find the dynamic region allocated for @p r, if any.
- *
+ *
* @param br The resource state to search.
* @param r The resource to search for.
- *
+ *
* @retval bhndb_dw_alloc The allocation record for @p r.
* @retval NULL if no dynamic window is allocated for @p r.
*/
@@ -560,11 +579,11 @@
/**
* Find an existing dynamic window mapping @p size bytes
* at @p addr. The window may or may not be free.
- *
+ *
* @param br The resource state to search.
* @param addr The requested starting address.
* @param size The requested size.
- *
+ *
* @retval bhndb_dw_alloc A window allocation that fully contains the requested
* range.
* @retval NULL If no mapping region can be found.
@@ -598,11 +617,11 @@
/**
* Retain a reference to @p dwa for use by @p res.
- *
+ *
* @param br The resource state owning @p dwa.
* @param dwa The allocation record to be retained.
* @param res The resource that will own a reference to @p dwa.
- *
+ *
* @retval 0 success
* @retval ENOMEM Failed to allocate a new reference structure.
*/
@@ -626,7 +645,7 @@
/* Update the free list */
br->dwa_freelist &= ~(1 << (dwa->rnid));
-
+
return (0);
}
@@ -634,7 +653,7 @@
* Release a reference to @p dwa previously retained by @p res. If the
* reference count of @p dwa reaches zero, it will be added to the
* free list.
- *
+ *
* @param br The resource state owning @p dwa.
* @param dwa The allocation record to be released.
* @param res The resource that currently owns a reference to @p dwa.
@@ -660,11 +679,11 @@
/**
* Attempt to set (or reset) the target address of @p dwa to map @p size bytes
* at @p addr.
- *
+ *
* This will apply any necessary window alignment and verify that
* the window is capable of mapping the requested range prior to modifying
* therecord.
- *
+ *
* @param dev The device on which to issue the BHNDB_SET_WINDOW_ADDR() request.
* @param br The resource state owning @p dwa.
* @param dwa The allocation record to be configured.
@@ -694,7 +713,7 @@
/* Verify that the window is large enough for the full target */
if (rw->win_size - offset < size)
return (ENOMEM);
-
+
/* Update the window target */
error = BHNDB_SET_WINDOW_ADDR(dev, dwa->win, dwa->target);
if (error) {
@@ -707,7 +726,7 @@
/**
* Return the count of @p type register windows in @p table.
- *
+ *
* @param table The table to search.
* @param type The required window type, or BHNDB_REGWIN_T_INVALID to
* count all register window types.
@@ -730,13 +749,13 @@
/**
* Search @p table for the first window with the given @p type.
- *
+ *
* @param table The table to search.
* @param type The required window type.
* @param min_size The minimum window size.
- *
+ *
* @retval bhndb_regwin The first matching window.
- * @retval NULL If no window of the requested type could be found.
+ * @retval NULL If no window of the requested type could be found.
*/
const struct bhndb_regwin *
bhndb_regwin_find_type(const struct bhndb_regwin *table,
@@ -755,7 +774,7 @@
/**
* Search @p windows for the first matching core window.
- *
+ *
* @param table The table to search.
* @param class The required core class.
* @param unit The required core unit, or -1.
@@ -764,32 +783,32 @@
* @param region The required region.
*
* @retval bhndb_regwin The first matching window.
- * @retval NULL If no matching window was found.
+ * @retval NULL If no matching window was found.
*/
const struct bhndb_regwin *
bhndb_regwin_find_core(const struct bhndb_regwin *table, bhnd_devclass_t class,
int unit, bhnd_port_type port_type, u_int port, u_int region)
{
const struct bhndb_regwin *rw;
-
+
for (rw = table; rw->win_type != BHNDB_REGWIN_T_INVALID; rw++)
{
if (rw->win_type != BHNDB_REGWIN_T_CORE)
continue;
- if (rw->core.class != class)
+ if (rw->win_spec.core.class != class)
continue;
-
- if (unit != -1 && rw->core.unit != unit)
+
+ if (unit != -1 && rw->win_spec.core.unit != unit)
continue;
- if (rw->core.port_type != port_type)
+ if (rw->win_spec.core.port_type != port_type)
continue;
- if (rw->core.port != port)
+ if (rw->win_spec.core.port != port)
continue;
-
- if (rw->core.region != region)
+
+ if (rw->win_spec.core.region != region)
continue;
return (rw);
@@ -800,11 +819,11 @@
/**
* Search @p windows for the best available window of at least @p min_size.
- *
+ *
* Search order:
* - BHND_REGWIN_T_CORE
* - BHND_REGWIN_T_DYN
- *
+ *
* @param table The table to search.
* @param class The required core class.
* @param unit The required core unit, or -1.
@@ -814,7 +833,7 @@
* @param min_size The minimum window size.
*
* @retval bhndb_regwin The first matching window.
- * @retval NULL If no matching window was found.
+ * @retval NULL If no matching window was found.
*/
const struct bhndb_regwin *
bhndb_regwin_find_best(const struct bhndb_regwin *table,
@@ -836,7 +855,7 @@
/**
* Return true if @p regw defines a static port register window, and
* the mapped port is actually defined on @p dev.
- *
+ *
* @param regw A register window to match against.
* @param dev A bhnd(4) bus device.
*/
@@ -848,16 +867,16 @@
return (false);
/* Device class must match */
- if (bhnd_get_class(dev) != regw->core.class)
+ if (bhnd_get_class(dev) != regw->win_spec.core.class)
return (false);
/* Device unit must match */
- if (bhnd_get_core_unit(dev) != regw->core.unit)
+ if (bhnd_get_core_unit(dev) != regw->win_spec.core.unit)
return (false);
-
+
/* The regwin port/region must be defined. */
- if (!bhnd_is_region_valid(dev, regw->core.port_type, regw->core.port,
- regw->core.region))
+ if (!bhnd_is_region_valid(dev, regw->win_spec.core.port_type, regw->win_spec.core.port,
+ regw->win_spec.core.region))
{
return (false);
}
@@ -869,7 +888,7 @@
/**
* Search for a core resource priority descriptor in @p table that matches
* @p device.
- *
+ *
* @param table The table to search.
* @param device A bhnd(4) bus device.
*/
@@ -887,3 +906,88 @@
/* not found */
return (NULL);
}
+
+
+char* bhndb_print_class(bhnd_devclass_t class){
+ switch (class) {
+ case BHND_DEVCLASS_CC:
+ return "ChipCommon IO controller";
+ case BHND_DEVCLASS_CC_B:
+ return "ChipCommon Auxiliary controller";
+ case BHND_DEVCLASS_PMU:
+ return "PMU Controller";
+ case BHND_DEVCLASS_PCI:
+ return "PCI host/device bridge";
+ case BHND_DEVCLASS_PCIE:
+ return "pcie host/device bridge";
+ case BHND_DEVCLASS_PCCARD:
+ return "pcmcia host/device bridge";
+ case BHND_DEVCLASS_RAM:
+ return "internal RAM/SRAM";
+ case BHND_DEVCLASS_MEMC:
+ return "memory controller";
+ case BHND_DEVCLASS_ENET:
+ return "802.3 MAC/PHY";
+ case BHND_DEVCLASS_ENET_MAC:
+ return "802.3 MAC ";
+ case BHND_DEVCLASS_ENET_PHY:
+ return "802.3 PHY ";
+ case BHND_DEVCLASS_WLAN:
+ return "802.11 MAC/PHY/Radio ";
+ case BHND_DEVCLASS_WLAN_MAC:
+ return "802.11 MAC ";
+ case BHND_DEVCLASS_WLAN_PHY:
+ return "802.11 PHY ";
+ case BHND_DEVCLASS_CPU:
+ return "cpu core ";
+ case BHND_DEVCLASS_SOC_ROUTER:
+ return "interconnect router ";
+ case BHND_DEVCLASS_SOC_BRIDGE:
+ return "interconnect host bridge ";
+ case BHND_DEVCLASS_EROM:
+ return "bus device enumeration ROM ";
+ case BHND_DEVCLASS_NVRAM:
+ return "nvram/flash controller ";
+ case BHND_DEVCLASS_OTHER:
+ return "other / unknown ";
+ default:
+ return "invalid";
+ }
+}
+
+void bhndb_print_resources(struct bhndb_resources* res){
+
+ device_t dev = res->dev;
+ device_t parent = res->parent_dev;
+ const struct bhndb_hwcfg* cfg = res->cfg;
+
+ printf("============ DUMP bridge resources ===========\n");
+ printf(" owner %s / parent %s =\n", device_get_nameunit(dev), device_get_nameunit(parent));
+ printf("--------------- Configurations ---------------\n");
+ const struct resource_spec* res_spec = cfg->resource_specs;
+ while(res_spec->type >= 0 ){
+ printf(" -> %d (type %d)\n", res_spec->rid, res_spec->type);
+ res_spec++;
+ }
+
+ const struct bhndb_regwin* rw = cfg->register_windows;
+ while(rw->win_type != BHNDB_REGWIN_T_INVALID){
+ printf(" -> [%p-%p]", (void*)rw->win_offset, (void*)(rw->win_offset + rw->win_size));
+ if(rw->win_type == BHNDB_REGWIN_T_CORE){
+ printf("(core %s port %d)", bhndb_print_class(rw->win_spec.core.class), rw->win_spec.core.port);
+ }
+ printf("\n");
+ rw++;
+ }
+
+ //TODO: print cfg and other fields
+
+ printf("--------------- Bus regions ------------------\n");
+ struct bhndb_region *region;
+ STAILQ_FOREACH(region, &res->bus_regions, link){
+ printf(" * %p-%p (%s prio=%d)\n",
+ (void*)(uintptr_t)region->addr, (void*)(uintptr_t)(region->addr+region->size-1),
+ ((region->static_regwin) ? "static" : ""), region->priority);
+ }
+ printf("==============================================\n");
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 20, 3:20 PM (2 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31847810
Default Alt Text
D5633.id.diff (32 KB)

Event Timeline