In some non-standard designs GRLIB peripherals are used together
LEON2. This patch adds a GRLIB amba Plug&Play driver so that AMBA
devices can be found from Plug&Play the same way as with the LEON3
BSP.
The user is required to add an AMBA-PnP device entry into the LEON2
bus configuration, so that the driver manager unite this driver
with the "fake" device and start scanning after AMBA PnP devices.
---
 c/src/lib/libbsp/sparc/Makefile.am                 |    1 +
 c/src/lib/libbsp/sparc/leon2/Makefile.am           |    1 +
 .../libbsp/sparc/shared/drvmgr/ambapp_bus_leon2.c  |  265 ++++++++++++++++++++
 3 files changed, 267 insertions(+), 0 deletions(-)
 create mode 100644 c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus_leon2.c

diff --git a/c/src/lib/libbsp/sparc/Makefile.am 
b/c/src/lib/libbsp/sparc/Makefile.am
index 0d61a41..3f0854e 100644
--- a/c/src/lib/libbsp/sparc/Makefile.am
+++ b/c/src/lib/libbsp/sparc/Makefile.am
@@ -89,6 +89,7 @@ EXTRA_DIST += shared/include/i2cmst.h
 # Driver Manager
 EXTRA_DIST += shared/drvmgr/ambapp_bus.c
 EXTRA_DIST += shared/drvmgr/ambapp_bus_grlib.c
+EXTRA_DIST += shared/drvmgr/ambapp_bus_leon2.c
 EXTRA_DIST += shared/drvmgr/leon2_amba_bus.c
 
 EXTRA_DIST += shared/include/drvmgr/ambapp_bus_grlib.h
diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am 
b/c/src/lib/libbsp/sparc/leon2/Makefile.am
index ba98665..e923025 100644
--- a/c/src/lib/libbsp/sparc/leon2/Makefile.am
+++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am
@@ -147,6 +147,7 @@ include_drvmgrdir = $(includedir)/drvmgr
 include_drvmgr_HEADERS = ../../sparc/shared/include/drvmgr/ambapp_bus.h
 include_drvmgr_HEADERS += ../../sparc/shared/include/drvmgr/leon2_amba_bus.h
 libbsp_a_SOURCES += ../../sparc/shared/drvmgr/ambapp_bus.c
+libbsp_a_SOURCES += ../../sparc/shared/drvmgr/ambapp_bus_leon2.c
 libbsp_a_SOURCES += ../../sparc/shared/drvmgr/leon2_amba_bus.c
 
 if HAS_SMP
diff --git a/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus_leon2.c 
b/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus_leon2.c
new file mode 100644
index 0000000..12034dc
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/drvmgr/ambapp_bus_leon2.c
@@ -0,0 +1,265 @@
+/*  LEON2 GRLIB AMBA Plug & Play bus driver.
+ *
+ *  COPYRIGHT (c) 2008.
+ *  Cobham Gaisler AB.
+ *
+ *  This is driver is a wrapper for the general AMBA Plug & Play bus
+ *  driver. This is a bus driver for LEON2-GRLIB systems providing a
+ *  AMBA Plug & Play bus, the parent bus must be a LEON2 hardcoded
+ *  Bus. All IRQs must be routed to this bus driver in order for IRQs
+ *  to work. The PnP information is used to extract IRQs and base
+ *  register addresses.
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#include <bsp.h>
+
+#ifdef LEON2
+#include <stdlib.h>
+#include <stdio.h>
+#include <libcpu/access.h>
+#include <drvmgr/drvmgr.h>
+#include <drvmgr/ambapp_bus.h>
+#include <drvmgr/leon2_amba_bus.h>
+
+#define DBG(args...)
+
+int ambapp_leon2_int_register(
+       struct drvmgr_dev *dev,
+       int index,
+       const char *info,
+       drvmgr_isr isr,
+       void *arg);
+int ambapp_leon2_int_unregister(
+       struct drvmgr_dev *dev,
+       int index,
+       drvmgr_isr isr,
+       void *arg);
+int ambapp_leon2_int_clear(
+       struct drvmgr_dev *dev,
+       int index);
+int ambapp_leon2_int_mask(
+       struct drvmgr_dev *dev,
+       int irq);
+int ambapp_leon2_int_unmask(
+       struct drvmgr_dev *dev,
+       int irq);
+int ambapp_leon2_get_params(
+       struct drvmgr_dev *dev,
+       struct drvmgr_bus_params *params);
+
+int ambapp_leon2_init1(struct drvmgr_dev *dev);
+int ambapp_leon2_init2(struct drvmgr_dev *dev);
+int ambapp_leon2_remove(struct drvmgr_dev *dev);
+void ambapp_leon2_register(void);
+
+/* READ/WRITE access to SpaceWire target over RMAP */
+void *ambapp_leon2_rw_arg(struct drvmgr_dev *dev);
+
+struct ambappl2_priv {
+       struct ambapp_bus abus;
+       struct ambapp_config config;
+};
+
+struct ambapp_ops ambapp_leon2_ops = {
+       .int_register = ambapp_leon2_int_register,
+       .int_unregister = ambapp_leon2_int_unregister,
+       .int_clear = ambapp_leon2_int_clear,
+       .int_mask = ambapp_leon2_int_mask,
+       .int_unmask = ambapp_leon2_int_unmask,
+       .get_params = ambapp_leon2_get_params
+};
+
+struct drvmgr_func ambapp_leon2_funcs[] = {
+       DRVMGR_FUNC(AMBAPP_RW_ARG, ambapp_leon2_rw_arg),
+
+       DRVMGR_FUNC(AMBAPP_R8,  _ld8),
+       DRVMGR_FUNC(AMBAPP_R16, _ld16),
+       DRVMGR_FUNC(AMBAPP_R32, _ld32),
+       DRVMGR_FUNC(AMBAPP_R64, _ld64),
+
+       DRVMGR_FUNC(AMBAPP_W8,  _st8),
+       DRVMGR_FUNC(AMBAPP_W16, _st16),
+       DRVMGR_FUNC(AMBAPP_W32, _st32),
+       DRVMGR_FUNC(AMBAPP_W64, _st64),
+
+       DRVMGR_FUNC(AMBAPP_RMEM, memcpy),
+       DRVMGR_FUNC(AMBAPP_WMEM, memcpy),
+
+       DRVMGR_FUNC_END
+};
+
+struct drvmgr_drv_ops ambapp_ops = {
+       .init = {ambapp_leon2_init1, ambapp_leon2_init2, NULL, NULL},
+       .remove = ambapp_leon2_remove,
+       .info = NULL,
+};
+
+struct leon2_amba_dev_id ambapp_leon2_ids[] = {
+       {LEON2_AMBA_AMBAPP_ID},
+       {0}
+};
+
+struct leon2_amba_drv_info ambapp_bus_drv_leon2 = {
+       {
+               DRVMGR_OBJ_DRV,                 /* Driver */
+               NULL,                           /* Next driver */
+               NULL,                           /* Device list */
+               DRIVER_LEON2_AMBA_AMBAPP,       /* Driver ID */
+               "AMBAPP_LEON2_DRV",             /* Driver Name */
+               DRVMGR_BUS_TYPE_LEON2_AMBA,     /* Bus Type */
+               &ambapp_ops,
+               NULL,                           /* Funcs */
+               0,
+               sizeof(struct ambappl2_priv),   /* Let DrvMgr allocate priv */
+       },
+       &ambapp_leon2_ids[0]
+};
+
+void ambapp_leon2_register(void)
+{
+       drvmgr_drv_register(&ambapp_bus_drv_leon2.general);
+}
+
+/* Function called from a hard configuration */
+int ambapp_leon2_init1(struct drvmgr_dev *dev)
+{
+       union drvmgr_key_value *value;
+       struct ambappl2_priv *priv = dev->priv;
+       struct leon2_amba_dev_info *devinfo;
+       struct ambapp_config *config;
+       unsigned int ioarea;
+       unsigned int freq_hz;
+       LEON_Register_Map *regs;
+
+       dev->name = "LEON2 AMBA PnP";
+
+       if (!priv)
+               return DRVMGR_NOMEM;
+
+       config = &priv->config;
+       config->abus = &priv->abus;
+       config->ops = &ambapp_leon2_ops;
+       config->maps_up = DRVMGR_TRANSLATE_ONE2ONE;
+       config->maps_down = DRVMGR_TRANSLATE_ONE2ONE;
+       config->funcs = ambapp_leon2_funcs;
+       config->bus_type = DRVMGR_BUS_TYPE_LEON2_AMBA;
+
+       /* Get AMBA PnP Area from REG0 */
+       devinfo = (struct leon2_amba_dev_info *)dev->businfo;
+       ioarea = devinfo->reg_base;
+
+       /* Scan AMBA PnP Bus. ABUS has already been cleared with memset() */
+       ambapp_scan(&priv->abus, ioarea, NULL, NULL);
+
+       /* Try to get Configuration from resource configuration */
+
+       value = drvmgr_dev_key_get(dev, "busFreq", KEY_TYPE_INT);
+       if (value) {
+               /* Set frequency of AMBA bus if specified by user. The frequency
+                * must be for AHB bus which IOAREA matches (AHB bus 0).
+                */
+               freq_hz = value->i;
+       } else {
+               /* Get Bus/LEON2 Frequency from timer prescaler,
+                * the hardcoded address is used to get to timer
+                */
+               regs = (LEON_Register_Map *) 0x80000000;
+               freq_hz = (regs->Scaler_Reload + 1) * 1000 * 1000;
+       }
+       /* Note that this can be overrided by a driver on the AMBA PnP bus.*/
+       ambapp_freq_init(&priv->abus, NULL, freq_hz);
+
+       value = drvmgr_dev_key_get(dev, "drvRes", KEY_TYPE_POINTER);
+       if (!value) {
+               DBG("ambapp_leon2_init1: Failed getting resource drvRes\n");
+               config->resources = NULL;
+       } else {
+               DBG("ambapp_leon2_init1: drvRes: 0x%08x\n", (unsigned 
int)value->ptr);
+               config->resources = (struct drvmgr_bus_res *)value->ptr;
+       }
+
+       /* Initialize the AMBA Bus */
+       return ambapp_bus_register(dev, config);
+}
+
+int ambapp_leon2_init2(struct drvmgr_dev *dev)
+{
+       return 0;
+}
+
+int ambapp_leon2_remove(struct drvmgr_dev *dev)
+{
+       return 0;
+}
+
+void *ambapp_leon2_rw_arg(struct drvmgr_dev *dev)
+{
+       return dev; /* No argument really needed, by for debug */
+}
+
+int ambapp_leon2_int_register
+       (
+       struct drvmgr_dev *dev,
+       int index,
+       const char *info,
+       drvmgr_isr isr,
+       void *arg
+       )
+{
+       /* Let LEON2 bus handle interrupt requests */
+       return drvmgr_interrupt_register(dev->parent->dev, index, info, isr, 
arg);
+}
+
+int ambapp_leon2_int_unregister
+       (
+       struct drvmgr_dev *dev,
+       int index,
+       drvmgr_isr isr,
+       void *arg
+       )
+{
+       /* Let LEON2 bus handle interrupt requests */
+       return drvmgr_interrupt_unregister(dev->parent->dev, index, isr, arg);
+}
+
+int ambapp_leon2_int_clear
+       (
+       struct drvmgr_dev *dev,
+       int index
+       )
+{
+       /* Let LEON2 bus handle interrupt requests */
+       return drvmgr_interrupt_clear(dev->parent->dev, index);
+}
+
+int ambapp_leon2_int_mask
+       (
+       struct drvmgr_dev *dev,
+       int index
+       )
+{
+       /* Let LEON2 bus handle interrupt requests */
+       return drvmgr_interrupt_mask(dev->parent->dev, index);
+}
+
+int ambapp_leon2_int_unmask
+       (
+       struct drvmgr_dev *dev,
+       int index
+       )
+{
+       /* Let LEON2 bus handle interrupt requests */
+       return drvmgr_interrupt_unmask(dev->parent->dev, index);
+}
+
+int ambapp_leon2_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params 
*params)
+{
+       params->dev_prefix = "";
+       return 0;
+}
+
+#endif
-- 
1.7.0.4

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to