forked from Imagelibrary/rtems
grlib: Customizable allocation in ambapp_scan()
Make the memory allocations in ambapp_scan() customizable via the new struct ambapp_context parameter which generalizes the memory copy handler.
This commit is contained in:
@@ -15,6 +15,15 @@
|
|||||||
#ifndef __AMBAPP_H__
|
#ifndef __AMBAPP_H__
|
||||||
#define __AMBAPP_H__
|
#define __AMBAPP_H__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* Include VENDOR and DEVICE definitions */
|
||||||
|
#include "ambapp_ids.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup amba AMBA
|
* @defgroup amba AMBA
|
||||||
*
|
*
|
||||||
@@ -25,13 +34,6 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Include VENDOR and DEVICE definitions */
|
|
||||||
#include "ambapp_ids.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Max supported AHB buses */
|
/* Max supported AHB buses */
|
||||||
#define AHB_BUS_MAX 6
|
#define AHB_BUS_MAX 6
|
||||||
|
|
||||||
@@ -181,6 +183,11 @@ typedef void *(*ambapp_memcpy_t)(
|
|||||||
struct ambapp_bus *abus /* Optional AMBA Bus pointer */
|
struct ambapp_bus *abus /* Optional AMBA Bus pointer */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
struct ambapp_context {
|
||||||
|
ambapp_memcpy_t copy_from_device;
|
||||||
|
void *(*alloc)(size_t);
|
||||||
|
};
|
||||||
|
|
||||||
/* Scan a AMBA Plug & Play bus and create all device structures describing the
|
/* Scan a AMBA Plug & Play bus and create all device structures describing the
|
||||||
* the devices. The devices will form a tree, where every node describes one
|
* the devices. The devices will form a tree, where every node describes one
|
||||||
* interface. The resulting tree is placed in the location pointed to by root.
|
* interface. The resulting tree is placed in the location pointed to by root.
|
||||||
@@ -188,16 +195,16 @@ typedef void *(*ambapp_memcpy_t)(
|
|||||||
* Since it the tree is located in RAM it is easier to work with AMBA buses
|
* Since it the tree is located in RAM it is easier to work with AMBA buses
|
||||||
* that is located over PCI and SpaceWire etc.
|
* that is located over PCI and SpaceWire etc.
|
||||||
*
|
*
|
||||||
|
* \param abus Resulting device node tree root is stored here.
|
||||||
* \param ioarea The IO-AREA where Plug & Play information can be found.
|
* \param ioarea The IO-AREA where Plug & Play information can be found.
|
||||||
* \param parent Used internally when recursing down a bridge. Set to NULL.
|
* \param ctx The scan context. May be NULL.
|
||||||
* \param mmaps Is used to perform address translation if needed.
|
* \param mmaps Is used to perform address translation if needed.
|
||||||
* \param root Resulting device node tree root is stored here.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
extern int ambapp_scan(
|
extern int ambapp_scan(
|
||||||
struct ambapp_bus *abus,
|
struct ambapp_bus *abus,
|
||||||
unsigned int ioarea,
|
unsigned int ioarea,
|
||||||
ambapp_memcpy_t memfunc,
|
const struct ambapp_context *ctx,
|
||||||
struct ambapp_mmap *mmaps
|
struct ambapp_mmap *mmaps
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,8 @@
|
|||||||
#define AMBA_APB_SLAVES 16
|
#define AMBA_APB_SLAVES 16
|
||||||
|
|
||||||
/* Allocate one AMBA device */
|
/* Allocate one AMBA device */
|
||||||
static struct ambapp_dev *ambapp_alloc_dev_struct(int dev_type)
|
static struct ambapp_dev *
|
||||||
|
ambapp_alloc_dev_struct(const struct ambapp_context *ctx, int dev_type)
|
||||||
{
|
{
|
||||||
struct ambapp_dev *dev;
|
struct ambapp_dev *dev;
|
||||||
size_t size = sizeof(*dev);
|
size_t size = sizeof(*dev);
|
||||||
@@ -32,9 +33,11 @@ static struct ambapp_dev *ambapp_alloc_dev_struct(int dev_type)
|
|||||||
size += sizeof(struct ambapp_apb_info);
|
size += sizeof(struct ambapp_apb_info);
|
||||||
else
|
else
|
||||||
size += sizeof(struct ambapp_ahb_info); /* AHB */
|
size += sizeof(struct ambapp_ahb_info); /* AHB */
|
||||||
dev = grlib_calloc(1, size);
|
dev = (*ctx->alloc)(size);
|
||||||
if (dev != NULL)
|
if (dev != NULL) {
|
||||||
|
dev = memset(dev, 0, size);
|
||||||
dev->dev_type = dev_type;
|
dev->dev_type = dev_type;
|
||||||
|
}
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +148,7 @@ static int ambapp_add_ahbbus(
|
|||||||
static int ambapp_scan2(
|
static int ambapp_scan2(
|
||||||
struct ambapp_bus *abus,
|
struct ambapp_bus *abus,
|
||||||
unsigned int ioarea,
|
unsigned int ioarea,
|
||||||
ambapp_memcpy_t memfunc,
|
const struct ambapp_context *ctx,
|
||||||
struct ambapp_dev *parent,
|
struct ambapp_dev *parent,
|
||||||
struct ambapp_dev **root
|
struct ambapp_dev **root
|
||||||
)
|
)
|
||||||
@@ -176,12 +179,12 @@ static int ambapp_scan2(
|
|||||||
/* AHB MASTERS */
|
/* AHB MASTERS */
|
||||||
ahb = (struct ambapp_pnp_ahb *) (ioarea | AMBA_CONF_AREA);
|
ahb = (struct ambapp_pnp_ahb *) (ioarea | AMBA_CONF_AREA);
|
||||||
for (i = 0; i < maxloops; i++, ahb++) {
|
for (i = 0; i < maxloops; i++, ahb++) {
|
||||||
memfunc(&ahb_buf, ahb, sizeof(struct ambapp_pnp_ahb), abus);
|
(*ctx->copy_from_device)(&ahb_buf, ahb, sizeof(struct ambapp_pnp_ahb), abus);
|
||||||
if (ahb_buf.id == 0)
|
if (ahb_buf.id == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* An AHB device present here */
|
/* An AHB device present here */
|
||||||
dev = ambapp_alloc_dev_struct(DEV_AHB_MST);
|
dev = ambapp_alloc_dev_struct(ctx, DEV_AHB_MST);
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -200,12 +203,12 @@ static int ambapp_scan2(
|
|||||||
ahb = (struct ambapp_pnp_ahb *)
|
ahb = (struct ambapp_pnp_ahb *)
|
||||||
(ioarea | AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA);
|
(ioarea | AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA);
|
||||||
for (i = 0; i < maxloops; i++, ahb++) {
|
for (i = 0; i < maxloops; i++, ahb++) {
|
||||||
memfunc(&ahb_buf, ahb, sizeof(struct ambapp_pnp_ahb), abus);
|
(*ctx->copy_from_device)(&ahb_buf, ahb, sizeof(struct ambapp_pnp_ahb), abus);
|
||||||
if (ahb_buf.id == 0)
|
if (ahb_buf.id == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* An AHB device present here */
|
/* An AHB device present here */
|
||||||
dev = ambapp_alloc_dev_struct(DEV_AHB_SLV);
|
dev = ambapp_alloc_dev_struct(ctx, DEV_AHB_SLV);
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -235,7 +238,7 @@ static int ambapp_scan2(
|
|||||||
bridge_adr = ambapp_addr_from(abus->mmaps,
|
bridge_adr = ambapp_addr_from(abus->mmaps,
|
||||||
ahb_info->custom[1]);
|
ahb_info->custom[1]);
|
||||||
/* Scan next bus if not already scanned */
|
/* Scan next bus if not already scanned */
|
||||||
if (ambapp_scan2(abus, bridge_adr, memfunc, dev,
|
if (ambapp_scan2(abus, bridge_adr, ctx, dev,
|
||||||
&dev->children))
|
&dev->children))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -251,11 +254,11 @@ static int ambapp_scan2(
|
|||||||
apb = (struct ambapp_pnp_apb *)
|
apb = (struct ambapp_pnp_apb *)
|
||||||
(apbbase | AMBA_CONF_AREA);
|
(apbbase | AMBA_CONF_AREA);
|
||||||
for (j=0; j<AMBA_APB_SLAVES; j++, apb++) {
|
for (j=0; j<AMBA_APB_SLAVES; j++, apb++) {
|
||||||
memfunc(&apb_buf, apb, sizeof(*apb), abus);
|
(*ctx->copy_from_device)(&apb_buf, apb, sizeof(*apb), abus);
|
||||||
if (apb_buf.id == 0)
|
if (apb_buf.id == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
apbdev = ambapp_alloc_dev_struct(DEV_APB_SLV);
|
apbdev = ambapp_alloc_dev_struct(ctx, DEV_APB_SLV);
|
||||||
if (!apbdev)
|
if (!apbdev)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -279,22 +282,28 @@ static int ambapp_scan2(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct ambapp_context default_ctx = {
|
||||||
|
.copy_from_device = (ambapp_memcpy_t)memcpy,
|
||||||
|
.alloc = rtems_malloc
|
||||||
|
};
|
||||||
|
|
||||||
/* Build AMBA Plug & Play device graph */
|
/* Build AMBA Plug & Play device graph */
|
||||||
int ambapp_scan(
|
int ambapp_scan(
|
||||||
struct ambapp_bus *abus,
|
struct ambapp_bus *abus,
|
||||||
unsigned int ioarea,
|
unsigned int ioarea,
|
||||||
ambapp_memcpy_t memfunc,
|
const struct ambapp_context *ctx,
|
||||||
struct ambapp_mmap *mmaps
|
struct ambapp_mmap *mmaps
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
memset(abus, 0, sizeof(*abus));
|
memset(abus, 0, sizeof(*abus));
|
||||||
abus->mmaps = mmaps;
|
abus->mmaps = mmaps;
|
||||||
|
|
||||||
/* Default to memcpy() */
|
if (ctx == NULL) {
|
||||||
if (!memfunc)
|
ctx = &default_ctx;
|
||||||
memfunc = (ambapp_memcpy_t)memcpy;
|
}
|
||||||
|
|
||||||
return ambapp_scan2(abus, ioarea, memfunc, NULL, &abus->root);
|
return ambapp_scan2(abus, ioarea, ctx, NULL, &abus->root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Match search options againt device */
|
/* Match search options againt device */
|
||||||
|
|||||||
Reference in New Issue
Block a user