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