Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153177698
D5633.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
32 KB
Referenced Files
None
Subscribers
None
D5633.id.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D5633: [BHND] MIPS fixes: C99, optional hostb, fixed windows, replacement of ctz & popcount functions
Attached
Detach File
Event Timeline
Log In to Comment