Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153150196
D6850.id17593.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
18 KB
Referenced Files
None
Subscribers
None
D6850.id17593.diff
View Options
Index: sys/dev/bhnd/siba/siba.c
===================================================================
--- sys/dev/bhnd/siba/siba.c
+++ sys/dev/bhnd/siba/siba.c
@@ -70,7 +70,6 @@
for (int i = 0; i < ndevs; i++) {
struct siba_addrspace *addrspace;
- struct siba_port *port;
dinfo = device_get_ivars(devs[i]);
@@ -79,14 +78,10 @@
"not be suspended before siba_attach()"));
/* Fetch the core register address space */
- port = siba_dinfo_get_port(dinfo, BHND_PORT_DEVICE, 0);
- if (port == NULL) {
- error = ENXIO;
- goto cleanup;
- }
-
- addrspace = siba_find_port_addrspace(port, SIBA_ADDRSPACE_CORE);
+ addrspace = siba_find_addrspace(dinfo, BHND_PORT_DEVICE, 0, 0);
if (addrspace == NULL) {
+ device_printf(dev,
+ "missing device registers for core %d\n", i);
error = ENXIO;
goto cleanup;
}
@@ -94,7 +89,7 @@
/*
* Map the per-core configuration blocks
*/
- KASSERT(dinfo->core_id.num_cfg_blocks <= SIBA_CFG_NUM_MAX,
+ KASSERT(dinfo->core_id.num_cfg_blocks <= SIBA_MAX_CFG,
("config block count %u out of range",
dinfo->core_id.num_cfg_blocks));
@@ -285,32 +280,25 @@
type));
dinfo = device_get_ivars(child);
-
- /* We advertise exactly one port of any type */
- if (siba_dinfo_get_port(dinfo, type, 0) != NULL)
- return (1);
-
- return (0);
+ return (siba_addrspace_port_count(dinfo));
}
static u_int
siba_get_region_count(device_t dev, device_t child, bhnd_port_type type,
- u_int port_num)
+ u_int port)
{
struct siba_devinfo *dinfo;
- struct siba_port *port;
/* delegate non-bus-attached devices to our parent */
if (device_get_parent(child) != dev)
return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), child,
- type, port_num));
+ type, port));
dinfo = device_get_ivars(child);
- port = siba_dinfo_get_port(dinfo, type, port_num);
- if (port == NULL)
+ if (!siba_is_port_valid(dinfo, type, port))
return (0);
- return (port->sp_num_addrs);
+ return (siba_addrspace_region_count(dinfo, port));
}
static int
@@ -318,7 +306,6 @@
u_int port_num, u_int region_num)
{
struct siba_devinfo *dinfo;
- struct siba_port *port;
struct siba_addrspace *addrspace;
/* delegate non-bus-attached devices to our parent */
@@ -327,17 +314,11 @@
port_type, port_num, region_num));
dinfo = device_get_ivars(child);
- port = siba_dinfo_get_port(dinfo, port_type, port_num);
- if (port == NULL)
+ addrspace = siba_find_addrspace(dinfo, port_type, port_num, region_num);
+ if (addrspace == NULL)
return (-1);
- STAILQ_FOREACH(addrspace, &port->sp_addrs, sa_link) {
- if (addrspace->sa_region_num == region_num)
- return (addrspace->sa_rid);
- }
-
- /* not found */
- return (-1);
+ return (addrspace->sa_rid);
}
static int
@@ -345,8 +326,6 @@
bhnd_port_type *port_type, u_int *port_num, u_int *region_num)
{
struct siba_devinfo *dinfo;
- struct siba_port *port;
- struct siba_addrspace *addrspace;
/* delegate non-bus-attached devices to our parent */
if (device_get_parent(child) != dev)
@@ -359,29 +338,17 @@
if (type != SYS_RES_MEMORY)
return (EINVAL);
- /* Starting with the most likely device list, search all three port
- * lists */
- bhnd_port_type types[] = {
- BHND_PORT_DEVICE,
- BHND_PORT_AGENT,
- BHND_PORT_BRIDGE
- };
-
- for (int i = 0; i < nitems(types); i++) {
- port = siba_dinfo_get_port(dinfo, types[i], 0);
- if (port == NULL)
+ for (int i = 0; i < dinfo->core_id.num_addrspace; i++) {
+ if (dinfo->addrspace[i].sa_rid != rid)
continue;
-
- STAILQ_FOREACH(addrspace, &port->sp_addrs, sa_link) {
- if (addrspace->sa_rid != rid)
- continue;
-
- *port_type = port->sp_type;
- *port_num = port->sp_num;
- *region_num = addrspace->sa_region_num;
- }
+
+ *port_type = BHND_PORT_DEVICE;
+ *port_num = siba_addrspace_port(i);
+ *region_num = siba_addrspace_region(i);
+ return (0);
}
+ /* Not found */
return (ENOENT);
}
@@ -390,7 +357,6 @@
u_int port_num, u_int region_num, bhnd_addr_t *addr, bhnd_size_t *size)
{
struct siba_devinfo *dinfo;
- struct siba_port *port;
struct siba_addrspace *addrspace;
/* delegate non-bus-attached devices to our parent */
@@ -400,20 +366,13 @@
}
dinfo = device_get_ivars(child);
- port = siba_dinfo_get_port(dinfo, port_type, port_num);
- if (port == NULL)
+ addrspace = siba_find_addrspace(dinfo, port_type, port_num, region_num);
+ if (addrspace == NULL)
return (ENOENT);
- STAILQ_FOREACH(addrspace, &port->sp_addrs, sa_link) {
- if (addrspace->sa_region_num != region_num)
- continue;
-
- *addr = addrspace->sa_base;
- *size = addrspace->sa_size - addrspace->sa_bus_reserved;
- return (0);
- }
-
- return (ENOENT);
+ *addr = addrspace->sa_base;
+ *size = addrspace->sa_size - addrspace->sa_bus_reserved;
+ return (0);
}
@@ -432,26 +391,21 @@
struct siba_core_id *cid;
uint32_t addr;
uint32_t size;
- u_int region_num;
int error;
cid = &di->core_id;
- /* Region numbers must be assigned in order, but our siba address
- * space IDs may be sparsely allocated; thus, we track
- * the region index separately. */
- region_num = 0;
/* Register the device address space entries */
- for (uint8_t sid = 0; sid < di->core_id.num_addrspace; sid++) {
+ for (uint8_t i = 0; i < di->core_id.num_addrspace; i++) {
uint32_t adm;
u_int adm_offset;
uint32_t bus_reserved;
/* Determine the register offset */
- adm_offset = siba_admatch_offset(sid);
+ adm_offset = siba_admatch_offset(i);
if (adm_offset == 0) {
- device_printf(dev, "addrspace %hhu is unsupported", sid);
+ device_printf(dev, "addrspace %hhu is unsupported", i);
return (ENODEV);
}
@@ -469,17 +423,14 @@
* reserve the Sonics configuration register blocks for the
* use of our bus. */
bus_reserved = 0;
- if (sid == SIBA_ADDRSPACE_CORE)
+ if (i == SIBA_CORE_ADDRSPACE)
bus_reserved = cid->num_cfg_blocks * SIBA_CFG_SIZE;
/* Append the region info */
- error = siba_append_dinfo_region(di, BHND_PORT_DEVICE, 0,
- region_num, sid, addr, size, bus_reserved);
+ error = siba_append_dinfo_region(di, i, addr, size,
+ bus_reserved);
if (error)
return (error);
-
-
- region_num++;
}
return (0);
Index: sys/dev/bhnd/siba/siba_subr.c
===================================================================
--- sys/dev/bhnd/siba/siba_subr.c
+++ sys/dev/bhnd/siba/siba_subr.c
@@ -106,35 +106,6 @@
}
/**
- * Initialize new port descriptor.
- *
- * @param port_num Port number.
- * @param port_type Port type.
- */
-static void
-siba_init_port(struct siba_port *port, bhnd_port_type port_type, u_int port_num)
-{
- port->sp_num = port_num;
- port->sp_type = port_type;
- port->sp_num_addrs = 0;
- STAILQ_INIT(&port->sp_addrs);
-}
-
-/**
- * Deallocate all resources associated with the given port descriptor.
- *
- * @param port Port descriptor to be deallocated.
- */
-static void
-siba_release_port(struct siba_port *port) {
- struct siba_addrspace *as, *as_next;
-
- STAILQ_FOREACH_SAFE(as, &port->sp_addrs, sa_link, as_next) {
- free(as, M_BHND);
- }
-}
-
-/**
* Allocate and initialize new device info structure, copying the
* provided core id.
*
@@ -157,76 +128,153 @@
dinfo->cfg_rid[i] = -1;
}
- siba_init_port(&dinfo->device_port, BHND_PORT_DEVICE, 0);
resource_list_init(&dinfo->resources);
return dinfo;
}
/**
- * Return the @p dinfo port instance for @p type, or NULL.
+ * Map an addrspace index to its corresponding bhnd(4) port number.
*
- * @param dinfo The siba device info.
- * @param type The requested port type.
+ * @param addrspace Address space index.
+ */
+u_int
+siba_addrspace_port(u_int addrspace)
+{
+ /* The first addrspace is always mapped to device0; the remainder
+ * are mapped to device1 */
+ if (addrspace == 0)
+ return (0);
+ else
+ return (1);
+}
+
+/**
+ * Map an addrspace index to its corresponding bhnd(4) region number.
*
- * @retval siba_port If @p port_type and @p port_num are defined on @p dinfo.
- * @retval NULL If the requested port is not defined on @p dinfo.
+ * @param addrspace Address space index.
*/
-struct siba_port *
-siba_dinfo_get_port(struct siba_devinfo *dinfo, bhnd_port_type port_type,
- u_int port_num)
+u_int
+siba_addrspace_region(u_int addrspace)
{
- /* We only define a single port for any given type. */
- if (port_num != 0)
- return (NULL);
+ /* The first addrspace is always mapped to device0.0; the remainder
+ * are mapped to device1.0 + (n - 1) */
+ if (addrspace == 0)
+ return (0);
+ else
+ return (addrspace - 1);
+}
- switch (port_type) {
- case BHND_PORT_DEVICE:
- return (&dinfo->device_port);
- case BHND_PORT_BRIDGE:
- return (NULL);
- case BHND_PORT_AGENT:
- return (NULL);
- default:
- printf("%s: unknown port_type (%d)\n",
- __func__,
- port_type);
- return (NULL);
- }
+/**
+ * Return the number of bhnd(4) ports to advertise for the given
+ * @p dinfo.
+ *
+ * @param dinfo The device info to query.
+ */
+u_int
+siba_addrspace_port_count(struct siba_devinfo *dinfo)
+{
+ /* 0, 1, or 2 ports */
+ return min(dinfo->core_id.num_addrspace, 2);
}
+/**
+ * Return the number of bhnd(4) regions to advertise on @p port
+ * given the provided @p num_addrspace address space count.
+ *
+ * @param num_addrspace The number of core-mapped siba(4) Sonics/OCP address
+ * spaces.
+ */
+u_int
+siba_addrspace_region_count(struct siba_devinfo *dinfo, u_int port)
+{
+ u_int num_addrspace = dinfo->core_id.num_addrspace;
+
+ /* The first address space, if any, is mapped to device0.0 */
+ if (port == 0)
+ return (min(num_addrspace, 1));
+
+ /* All remaining address spaces are mapped to device0.(n - 1) */
+ if (port == 1 && num_addrspace >= 2)
+ return (num_addrspace - 1);
+
+ /* No region mapping */
+ return (0);
+}
/**
- * Find an address space with @p sid on @p port.
+ * Return true if @p port is defined on @p dinfo, false otherwise.
+ *
+ * Refer to the siba_find_addrspace() function for information on siba's
+ * mapping of bhnd(4) port and region identifiers.
*
- * @param port The port to search for a matching address space.
- * @param sid The siba-assigned address space ID to search for.
+ * @param dinfo The device info to verify the port against.
+ * @param type The bhnd(4) port type.
+ * @param port The bhnd(4) port number.
*/
-struct siba_addrspace *
-siba_find_port_addrspace(struct siba_port *port, uint8_t sid)
+bool
+siba_is_port_valid(struct siba_devinfo *dinfo, bhnd_port_type type, u_int port)
{
- struct siba_addrspace *addrspace;
+ /* Only device ports are supported */
+ if (type != BHND_PORT_DEVICE)
+ return (false);
- STAILQ_FOREACH(addrspace, &port->sp_addrs, sa_link) {
- if (addrspace->sa_sid == sid)
- return (addrspace);
- }
+ /* Verify the index against the port count */
+ if (siba_addrspace_port_count(dinfo) <= port)
+ return (false);
- /* not found */
- return (NULL);
+ return (true);
}
/**
- * Append a new address space entry to @p port_num of type @p port_type
- * in @p dinfo.
+ * Map an bhnd(4) type/port/region triplet to its associated address space
+ * entry, if any.
+ *
+ * For compatibility with bcma(4), we map address spaces to port/region
+ * identifiers as follows:
+ *
+ * [port] [addrspace]
+ * device0.0 0
+ * device1.0 1
+ * device1.1 2
+ * device1.2 3
+ *
+ * The only supported port type is BHND_PORT_DEVICE.
*
- * The range will also be registered in @p dinfo resource list.
+ * @param dinfo The device info to search for a matching address space.
+ * @param type The bhnd(4) port type.
+ * @param port The bhnd(4) port number.
+ * @param region The bhnd(4) port region.
+ */
+struct siba_addrspace *
+siba_find_addrspace(struct siba_devinfo *dinfo, bhnd_port_type type, u_int port,
+ u_int region)
+{
+ u_int addridx;
+
+ if (!siba_is_port_valid(dinfo, type, port))
+ return (NULL);
+
+ if (port == 0)
+ addridx = region;
+ else if (port == 1)
+ addridx = region + 1;
+ else
+ return (NULL);
+
+ /* Out of range? */
+ if (addridx >= dinfo->core_id.num_addrspace)
+ return (NULL);
+
+ /* Found */
+ return (&dinfo->addrspace[addridx]);
+}
+
+/**
+ * Append an address space entry to @p dinfo.
*
* @param dinfo The device info entry to update.
- * @param port_type The port type.
- * @param port_num The port number.
- * @param region_num The region index number.
- * @param sid The siba-assigned core-unique address space identifier.
+ * @param addridx The address space index.
* @param base The mapping's base address.
* @param size The mapping size.
* @param bus_reserved Number of bytes to reserve in @p size for bus use
@@ -237,12 +285,10 @@
* @retval non-zero An error occurred appending the entry.
*/
int
-siba_append_dinfo_region(struct siba_devinfo *dinfo, bhnd_port_type port_type,
- u_int port_num, u_int region_num, uint8_t sid, uint32_t base, uint32_t size,
- uint32_t bus_reserved)
+siba_append_dinfo_region(struct siba_devinfo *dinfo, uint8_t addridx,
+ uint32_t base, uint32_t size, uint32_t bus_reserved)
{
struct siba_addrspace *sa;
- struct siba_port *port;
rman_res_t r_size;
/* Verify that base + size will not overflow */
@@ -257,20 +303,14 @@
if (size == 0)
return (EINVAL);
- /* Determine target port */
- port = siba_dinfo_get_port(dinfo, port_type, port_num);
- if (port == NULL)
+ /* Must not exceed addrspace array size */
+ if (addridx >= nitems(dinfo->addrspace))
return (EINVAL);
- /* Allocate new addrspace entry */
- sa = malloc(sizeof(*sa), M_BHND, M_NOWAIT|M_ZERO);
- if (sa == NULL)
- return (ENOMEM);
-
+ /* Initialize new addrspace entry */
+ sa = &dinfo->addrspace[addridx];
sa->sa_base = base;
sa->sa_size = size;
- sa->sa_sid = sid;
- sa->sa_region_num = region_num;
sa->sa_bus_reserved = bus_reserved;
/* Populate the resource list */
@@ -278,10 +318,6 @@
sa->sa_rid = resource_list_add_next(&dinfo->resources, SYS_RES_MEMORY,
base, base + (r_size - 1), r_size);
- /* Append to target port */
- STAILQ_INSERT_TAIL(&port->sp_addrs, sa, sa_link);
- port->sp_num_addrs++;
-
return (0);
}
@@ -294,8 +330,6 @@
void
siba_free_dinfo(device_t dev, struct siba_devinfo *dinfo)
{
- siba_release_port(&dinfo->device_port);
-
resource_list_free(&dinfo->resources);
/* Free all mapped configuration blocks */
Index: sys/dev/bhnd/siba/sibareg.h
===================================================================
--- sys/dev/bhnd/siba/sibareg.h
+++ sys/dev/bhnd/siba/sibareg.h
@@ -51,9 +51,6 @@
#define SIBA_MAX_CORES \
(SIBA_ENUM_SIZE/SIBA_CORE_SIZE) /**< Maximum number of cores */
-#define SIBA_ADDRSPACE_CORE 0 /**< address space identifier of the
- core enumeration block. */
-
/**< Evaluates to the bus address of the @p idx core register block */
#define SIBA_CORE_ADDR(idx) \
(SIBA_ENUM_ADDR + ((idx) * SIBA_CORE_SIZE))
@@ -175,7 +172,7 @@
#define SIBA_IMCH_BEM_MASK 0xc0 /* bus error mode */
#define SIBA_IMCH_BEM_SHIFT 6
-/* sbadmatch0 */
+/* sbadmatch0-4 */
#define SIBA_AM_TYPE_MASK 0x3 /* address type */
#define SIBA_AM_TYPE_SHIFT 0x0
#define SIBA_AM_AD64 0x4 /* reserved */
Index: sys/dev/bhnd/siba/sibavar.h
===================================================================
--- sys/dev/bhnd/siba/sibavar.h
+++ sys/dev/bhnd/siba/sibavar.h
@@ -47,7 +47,6 @@
struct siba_addrspace;
struct siba_devinfo;
-struct siba_port;
struct siba_core_id;
int siba_probe(device_t dev);
@@ -69,47 +68,53 @@
void siba_free_dinfo(device_t dev,
struct siba_devinfo *dinfo);
-struct siba_port *siba_dinfo_get_port(struct siba_devinfo *dinfo,
- bhnd_port_type port_type, u_int port_num);
+u_int siba_addrspace_port_count(struct siba_devinfo *dinfo);
+u_int siba_addrspace_region_count(struct siba_devinfo *dinfo,
+ u_int port);
-struct siba_addrspace *siba_find_port_addrspace(struct siba_port *port,
- uint8_t sid);
+u_int siba_addrspace_port(u_int addrspace);
+u_int siba_addrspace_region(u_int addrspace);
+
+bool siba_is_port_valid(struct siba_devinfo *dinfo,
+ bhnd_port_type type, u_int port);
+
+struct siba_addrspace *siba_find_addrspace(struct siba_devinfo *dinfo,
+ bhnd_port_type type, u_int port, u_int region);
int siba_append_dinfo_region(struct siba_devinfo *dinfo,
- bhnd_port_type port_type, u_int port_num,
- u_int region_num, uint8_t sid, uint32_t base,
- uint32_t size, uint32_t bus_reserved);
+ uint8_t sid, uint32_t base, uint32_t size,
+ uint32_t bus_reserved);
u_int siba_admatch_offset(uint8_t addrspace);
int siba_parse_admatch(uint32_t am, uint32_t *addr,
uint32_t *size);
+
/* Sonics configuration register blocks */
#define SIBA_CFG_NUM_2_2 1 /**< sonics <= 2.2 maps SIBA_CFG0. */
#define SIBA_CFG_NUM_2_3 2 /**< sonics <= 2.3 maps SIBA_CFG0 and SIBA_CFG1 */
-#define SIBA_CFG_NUM_MAX SIBA_CFG_NUM_2_3 /**< maximum number of supported config
+#define SIBA_MAX_CFG SIBA_CFG_NUM_2_3 /**< maximum number of supported config
register blocks */
+/* Sonics/OCP address space mappings */
+#define SIBA_CORE_ADDRSPACE 0 /**< Address space mapping the primary
+ device registers */
+
+#define SIBA_MAX_ADDRSPACE 4 /**< Maximum number of Sonics/OCP
+ * address space mappings for a
+ * single core. */
+
+/* bhnd(4) (port,region) representation of siba address space mappings */
+#define SIBA_MAX_PORT 2 /**< maximum number of advertised
+ * bhnd(4) ports */
+
/** siba(4) address space descriptor */
struct siba_addrspace {
uint32_t sa_base; /**< base address */
uint32_t sa_size; /**< size */
- u_int sa_region_num; /**< bhnd region id */
- uint8_t sa_sid; /**< siba-assigned address space ID */
int sa_rid; /**< bus resource id */
uint32_t sa_bus_reserved;/**< number of bytes at high end of
* address space reserved for the bus */
-
- STAILQ_ENTRY(siba_addrspace) sa_link;
-};
-
-/** siba(4) port descriptor */
-struct siba_port {
- bhnd_port_type sp_type; /**< port type */
- u_int sp_num; /**< port number */
- u_int sp_num_addrs; /**< number of address space mappings */
-
- STAILQ_HEAD(, siba_addrspace) sp_addrs; /**< address spaces mapped to this port */
};
/**
@@ -133,16 +138,10 @@
struct siba_devinfo {
struct resource_list resources; /**< per-core memory regions. */
struct siba_core_id core_id; /**< core identification info */
+ struct siba_addrspace addrspace[SIBA_MAX_ADDRSPACE]; /**< memory map descriptors */
- struct siba_port device_port; /**< device port holding ownership
- * of all siba address space
- * entries for this core. */
-
- /** SIBA_CFG* register blocks */
- struct bhnd_resource *cfg[SIBA_CFG_NUM_MAX];
-
- /** SIBA_CFG* resource IDs */
- int cfg_rid[SIBA_CFG_NUM_MAX];
+ struct bhnd_resource *cfg[SIBA_MAX_CFG]; /**< SIBA_CFG_* registers */
+ int cfg_rid[SIBA_MAX_CFG]; /**< SIBA_CFG_* resource IDs */
};
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 20, 11:57 AM (10 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31837809
Default Alt Text
D6850.id17593.diff (18 KB)
Attached To
Mode
D6850: siba(4): Adopt a bcma-compatible mapping of bhnd(4) port/region identifiers.
Attached
Detach File
Event Timeline
Log In to Comment