summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Hellstrom <daniel@gaisler.com>2011-12-15 17:31:17 +0100
committerDaniel Hellstrom <daniel@gaisler.com>2015-04-17 01:10:16 +0200
commit3db9e5b03dc8cf115f1796d45fa9f1e432d4389b (patch)
tree093eb18c22765b7c40879fc3e5c004fe8df66069
parentLEON3: implemented AMBA PnP Bus Driver for Driver Manager (diff)
downloadrtems-3db9e5b03dc8cf115f1796d45fa9f1e432d4389b.tar.bz2
LEON2: implemented AMBA Bus Driver for Driver Manager
-rw-r--r--c/src/lib/libbsp/sparc/Makefile.am2
-rw-r--r--c/src/lib/libbsp/sparc/leon2/Makefile.am7
-rw-r--r--c/src/lib/libbsp/sparc/leon2/include/bsp.h7
-rw-r--r--c/src/lib/libbsp/sparc/leon2/preinstall.am13
-rw-r--r--c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c70
-rw-r--r--c/src/lib/libbsp/sparc/shared/drvmgr/leon2_amba_bus.c459
-rw-r--r--c/src/lib/libbsp/sparc/shared/include/drvmgr/leon2_amba_bus.h95
7 files changed, 653 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/sparc/Makefile.am b/c/src/lib/libbsp/sparc/Makefile.am
index eb20f37efe..59a212c624 100644
--- a/c/src/lib/libbsp/sparc/Makefile.am
+++ b/c/src/lib/libbsp/sparc/Makefile.am
@@ -76,9 +76,11 @@ 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/leon2_amba_bus.c
EXTRA_DIST += shared/include/drvmgr/ambapp_bus_grlib.h
EXTRA_DIST += shared/include/drvmgr/ambapp_bus.h
+EXTRA_DIST += shared/include/drvmgr/leon2_amba_bus.h
include $(top_srcdir)/../../../automake/subdirs.am
include $(top_srcdir)/../../../automake/local.am
diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am
index efcb286601..bb30517dd0 100644
--- a/c/src/lib/libbsp/sparc/leon2/Makefile.am
+++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am
@@ -131,6 +131,13 @@ libbsp_a_SOURCES += ../../sparc/shared/i2c/i2cmst.c
# timer
libbsp_a_SOURCES += timer/timer.c
+# Driver Manager
+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/leon2_amba_bus.c
+
if HAS_SMP
libbsp_a_SOURCES += ../../shared/bspsmp.c
libbsp_a_SOURCES += ../../shared/bspsmpgetcurrentprocessor.c
diff --git a/c/src/lib/libbsp/sparc/leon2/include/bsp.h b/c/src/lib/libbsp/sparc/leon2/include/bsp.h
index 48c4b680cf..dce8bea661 100644
--- a/c/src/lib/libbsp/sparc/leon2/include/bsp.h
+++ b/c/src/lib/libbsp/sparc/leon2/include/bsp.h
@@ -220,6 +220,13 @@ int cchip1_register(void);
/* AT697 has PCI defined as big endian */
#define BSP_PCI_BIG_ENDIAN
+/* Common driver build-time configurations. On small systems undefine
+ * [DRIVER]_INFO_AVAIL to avoid info routines get dragged in. It is good
+ * for debugging and printing information about the system, but makes the
+ * image bigger.
+ */
+#define AMBAPPBUS_INFO_AVAIL /* AMBAPP Bus driver */
+
#ifdef __cplusplus
}
#endif
diff --git a/c/src/lib/libbsp/sparc/leon2/preinstall.am b/c/src/lib/libbsp/sparc/leon2/preinstall.am
index a3bcae5683..7260f63767 100644
--- a/c/src/lib/libbsp/sparc/leon2/preinstall.am
+++ b/c/src/lib/libbsp/sparc/leon2/preinstall.am
@@ -173,3 +173,16 @@ $(PROJECT_INCLUDE)/i2cmst.h: ../../sparc/shared/include/i2cmst.h $(PROJECT_INCLU
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/i2cmst.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/i2cmst.h
+$(PROJECT_INCLUDE)/drvmgr/$(dirstamp):
+ @$(MKDIR_P) $(PROJECT_INCLUDE)/drvmgr
+ @: > $(PROJECT_INCLUDE)/drvmgr/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/drvmgr/$(dirstamp)
+
+$(PROJECT_INCLUDE)/drvmgr/ambapp_bus.h: ../../sparc/shared/include/drvmgr/ambapp_bus.h $(PROJECT_INCLUDE)/drvmgr/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/drvmgr/ambapp_bus.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/drvmgr/ambapp_bus.h
+
+$(PROJECT_INCLUDE)/drvmgr/leon2_amba_bus.h: ../../sparc/shared/include/drvmgr/leon2_amba_bus.h $(PROJECT_INCLUDE)/drvmgr/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/drvmgr/leon2_amba_bus.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/drvmgr/leon2_amba_bus.h
+
diff --git a/c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c b/c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c
index 58493df288..260c57f57b 100644
--- a/c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c
+++ b/c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c
@@ -17,10 +17,80 @@
#include <bsp.h>
#include <bsp/bootcard.h>
+/* If RTEMS_DRVMGR_STARTUP is defined extra code is added that
+ * registers the LEON2 AMBA bus driver as root driver into the
+ * driver manager.
+ *
+ * The structues here are declared weak so that the user can override
+ * the configuration and add custom cores in the RTEMS project.
+ */
+#ifdef RTEMS_DRVMGR_STARTUP
+#include <drvmgr/leon2_amba_bus.h>
+
+/* All drivers included by BSP, this is overridden by the user by including
+ * the devmgr_confdefs.h. No specifc drivers needed by BSP since IRQ/TIMER/UART
+ * is not drvmgr drivers.
+ */
+struct drvmgr_drv_reg_func drvmgr_drivers[] __attribute__((weak)) =
+{
+ {NULL} /* End array with NULL */
+};
+
+/* Defines what cores are avilable on the bus in addition to the standard
+ * LEON2 peripherals.
+ */
+struct leon2_core leon2_amba_custom_cores[] __attribute__((weak)) =
+{
+ EMPTY_LEON2_CORE
+};
+
+/* Configure LEON2 Root bus driver */
+struct leon2_bus leon2_bus_config __attribute__((weak)) =
+{
+ &leon2_std_cores[0], /* The standard cores, defined by driver */
+ &leon2_amba_custom_cores[0], /* custom cores, defined by us */
+ DRVMGR_TRANSLATE_ONE2ONE,
+ DRVMGR_TRANSLATE_ONE2ONE,
+};
+
+/* Driver resources on LEON2 AMBA bus. Used to set options for particular
+ * LEON2 cores, it is up to the driver to look at the configuration paramters
+ * once started.
+ */
+struct drvmgr_bus_res leon2_amba_res __attribute__((weak)) =
+{
+ .next = NULL,
+ .resource = {
+ RES_EMPTY
+ },
+};
+
+/*
+ * bsp_driver_level_hook
+ *
+ * BSP driver level hook. Called just after drivers have reached initialization
+ * level 'level' (1,2,3,4). See exinit.c for meaning of the every level.
+ */
+void bsp_driver_level_hook( int level )
+{
+}
+
+#endif
+
+/*
+ * bsp_predriver_hook
+ *
+ * BSP predriver hook. Called just before drivers are initialized.
+ * Is used to initialize shared interrupt handling.
+ */
void bsp_predriver_hook( void )
{
/* Initialize shared interrupt handling, must be done after IRQ
* controller has been found and initialized.
*/
BSP_shared_interrupt_init();
+
+#ifdef RTEMS_DRVMGR_STARTUP
+ leon2_root_register(&leon2_bus_config, &leon2_amba_res);
+#endif
}
diff --git a/c/src/lib/libbsp/sparc/shared/drvmgr/leon2_amba_bus.c b/c/src/lib/libbsp/sparc/shared/drvmgr/leon2_amba_bus.c
new file mode 100644
index 0000000000..f4ff89ff38
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/drvmgr/leon2_amba_bus.c
@@ -0,0 +1,459 @@
+/* LEON2 Hardcoded bus driver.
+ *
+ * COPYRIGHT (c) 2008.
+ * Cobham Gaisler AB.
+ *
+ * Bus driver for a hardcoded setup. LEON2 systems have some
+ * cores always present, here called "Standard Cores". In
+ * addtion to the standard cores there are often extra cores
+ * that can be defined using the "Custom Cores" mechanism.
+ *
+ * A Core is described by assigning a base register and
+ * IRQ0..IRQ15 using the leon2_core structure.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <drvmgr/drvmgr.h>
+#include <drvmgr/leon2_amba_bus.h>
+
+#include <bsp.h>
+
+#define DBG(args...)
+/*#define DBG(args...) printk(args)*/
+
+struct drvmgr_drv leon2_bus_drv;
+
+int leon2_amba_bus_init1(struct drvmgr_bus *bus);
+int leon2_amba_unite(struct drvmgr_drv *drv, struct drvmgr_dev *dev);
+int leon2_amba_int_register(
+ struct drvmgr_dev *dev,
+ int index,
+ const char *info,
+ drvmgr_isr isr,
+ void *arg);
+int leon2_amba_int_unregister(
+ struct drvmgr_dev *dev,
+ int index,
+ drvmgr_isr isr,
+ void *arg);
+int leon2_amba_int_clear(
+ struct drvmgr_dev *dev,
+ int index);
+int leon2_amba_int_mask(
+ struct drvmgr_dev *dev,
+ int index);
+int leon2_amba_int_unmask(
+ struct drvmgr_dev *dev,
+ int index);
+
+/* LEON2 bus operations */
+struct drvmgr_bus_ops leon2_amba_bus_ops =
+{
+ .init = {
+ leon2_amba_bus_init1,
+ NULL,
+ NULL,
+ NULL
+ },
+ .remove = NULL,
+ .unite = leon2_amba_unite,
+ .int_register = leon2_amba_int_register,
+ .int_unregister = leon2_amba_int_unregister,
+ .int_clear = leon2_amba_int_clear,
+ .int_mask = leon2_amba_int_mask,
+ .int_unmask = leon2_amba_int_unmask,
+ .get_params = NULL,
+};
+
+struct leon2_isr_handler {
+ void (*handler)(int irq, void *arg);
+ void *arg;
+};
+
+/* Interrupt handlers */
+struct leon2_isr_handler leon2_isrs[16];
+
+/* Standard LEON2 configuration */
+
+struct drvmgr_key leon2_timers[] =
+{
+ {"REG0", KEY_TYPE_INT, {0x80000040}},
+ {"IRQ0", KEY_TYPE_INT, {8}},
+ {"IRQ1", KEY_TYPE_INT, {9}},
+ KEY_EMPTY
+};
+
+struct drvmgr_key leon2_uart1[] =
+{
+ {"REG0", KEY_TYPE_INT, {0x80000070}},
+ {"IRQ0", KEY_TYPE_INT, {3}},
+ KEY_EMPTY
+};
+
+struct drvmgr_key leon2_uart2[] =
+{
+ {"REG0", KEY_TYPE_INT, {0x80000080}},
+ {"IRQ0", KEY_TYPE_INT, {2}},
+ KEY_EMPTY
+};
+
+struct drvmgr_key leon2_irqctrl[] =
+{
+ {"REG0", KEY_TYPE_INT, {0x80000090}},
+ KEY_EMPTY
+};
+
+struct drvmgr_key leon2_gpio0[] =
+{
+ {"REG0", KEY_TYPE_INT, {0x800000A0}},
+ {"IRQ0", KEY_TYPE_INT, {4}},
+ {"IRQ1", KEY_TYPE_INT, {5}},
+ {"IRQ2", KEY_TYPE_INT, {6}},
+ {"IRQ3", KEY_TYPE_INT, {7}},
+ KEY_EMPTY
+};
+
+struct leon2_core leon2_std_cores[] =
+{
+ {{LEON2_AMBA_TIMER_ID}, "Timers", &leon2_timers[0]},
+ {{LEON2_AMBA_UART_ID}, "Uart1", &leon2_uart1[0]},
+ {{LEON2_AMBA_UART_ID}, "Uart2", &leon2_uart2[0]},
+ {{LEON2_AMBA_IRQCTRL_ID}, "IRQCtrl", &leon2_irqctrl[0]},
+ {{LEON2_AMBA_GPIO_ID}, "GPIO", &leon2_gpio0[0]},
+ EMPTY_LEON2_CORE
+};
+
+static struct leon2_bus *leon2_bus_config = NULL;
+static struct drvmgr_bus_res *leon2_bus_res = NULL;
+
+int leon2_root_register(struct leon2_bus *bus_config, struct drvmgr_bus_res *resources)
+{
+ /* Save the configuration for later */
+ leon2_bus_config = bus_config;
+ leon2_bus_res = resources;
+
+ /* Register root device driver */
+ drvmgr_root_drv_register(&leon2_bus_drv);
+
+ return 0;
+}
+
+int leon2_amba_dev_register(struct drvmgr_bus *bus, struct leon2_core *core, int index)
+{
+ struct drvmgr_dev *newdev;
+ struct leon2_amba_dev_info *info;
+ union drvmgr_key_value *value;
+ char irq_name[8];
+ int i;
+
+ /* Allocate new device and businfo */
+ drvmgr_alloc_dev(&newdev, sizeof(struct leon2_amba_dev_info));
+ info = (struct leon2_amba_dev_info *)(newdev + 1);
+
+ /* Set Core ID */
+ info->core_id = core->id.core_id;
+
+ /* Get information from bus configuration */
+ value = drvmgr_key_val_get(core->keys, "REG0", KEY_TYPE_INT);
+ if ( !value ) {
+ printk("leon2_amba_dev_register: Failed getting resource REG0\n");
+ info->reg_base = 0x00000000;
+ } else {
+ DBG("leon2_amba_dev_register: REG0: 0x%08x\n", value->i);
+ info->reg_base = value->i;
+ }
+
+ strcpy(irq_name, "IRQ");
+ for(i=0; i<16; i++){
+ if ( i < 10 ){
+ irq_name[3] = '0' + i;
+ irq_name[4] = '\0';
+ } else {
+ irq_name[3] = '1';
+ irq_name[4] = '0' + (i-10);
+ irq_name[5] = '\0';
+ }
+
+ value = drvmgr_key_val_get(core->keys, irq_name, KEY_TYPE_INT);
+ if ( !value ) {
+ DBG("leon2_amba_dev_register: Failed getting resource IRQ%d for REG 0x%x\n", i, info->reg_base);
+ info->irqs[i] = 0;
+ } else {
+ DBG("leon2_amba_dev_register: IRQ%d: %d\n", i, value->i);
+ info->irqs[i] = value->i;
+ }
+ }
+
+ /* Init new device */
+ newdev->next = NULL;
+ newdev->parent = bus; /* Ourselfs */
+ newdev->minor_drv = 0;
+ newdev->minor_bus = 0;
+ newdev->businfo = (void *)info;
+ newdev->priv = NULL;
+ newdev->drv = NULL;
+ newdev->name = core->name;
+ newdev->next_in_drv = NULL;
+ newdev->bus = NULL;
+
+ /* Register new device */
+ drvmgr_dev_register(newdev);
+
+ return 0;
+}
+
+int leon2_amba_init1(struct drvmgr_dev *dev)
+{
+ /* Init our own device */
+ dev->priv = NULL;
+ dev->name = "LEON2 AMBA";
+
+ memset(leon2_isrs, 0, sizeof(leon2_isrs));
+
+ /* Init the bus */
+ drvmgr_alloc_bus(&dev->bus, 0);
+ dev->bus->bus_type = DRVMGR_BUS_TYPE_LEON2_AMBA;
+ dev->bus->next = NULL;
+ dev->bus->dev = dev;
+ dev->bus->priv = NULL;
+ dev->bus->children = NULL;
+ dev->bus->ops = &leon2_amba_bus_ops;
+ dev->bus->dev_cnt = 0;
+ dev->bus->reslist = NULL;
+ dev->bus->maps_up = leon2_bus_config->maps_up;
+ dev->bus->maps_down = leon2_bus_config->maps_down;
+ drvmgr_bus_register(dev->bus);
+
+ return DRVMGR_OK;
+}
+
+int leon2_amba_init2(struct drvmgr_dev *dev)
+{
+ return DRVMGR_OK;
+}
+
+int leon2_amba_remove(struct drvmgr_dev *dev)
+{
+ return DRVMGR_OK;
+}
+
+int leon2_amba_bus_init1(struct drvmgr_bus *bus)
+{
+ struct leon2_core *core;
+ int i;
+
+ if ( leon2_bus_res )
+ drvmgr_bus_res_add(bus, leon2_bus_res);
+
+ /**** REGISTER NEW DEVICES ****/
+ i=0;
+ core = leon2_bus_config->std_cores;
+ if ( core ) {
+ while ( core->id.core_id ) {
+ if ( leon2_amba_dev_register(bus, core, i) ) {
+ return RTEMS_UNSATISFIED;
+ }
+ i++;
+ core++;
+ }
+ }
+ core = leon2_bus_config->custom_cores;
+ if ( core ) {
+ while ( core->id.core_id ) {
+ if ( leon2_amba_dev_register(bus, core, i) ) {
+ return RTEMS_UNSATISFIED;
+ }
+ i++;
+ core++;
+ }
+ }
+
+ return 0;
+}
+
+int leon2_amba_unite(struct drvmgr_drv *drv, struct drvmgr_dev *dev)
+{
+ struct leon2_amba_dev_info *info;
+ struct leon2_amba_drv_info *adrv;
+ struct leon2_amba_dev_id *id;
+
+ if ( !drv || !dev || !dev->parent )
+ return 0;
+
+ if ( (drv->bus_type!=DRVMGR_BUS_TYPE_LEON2_AMBA) || (dev->parent->bus_type != DRVMGR_BUS_TYPE_LEON2_AMBA) ) {
+ return 0;
+ }
+
+ info = (struct leon2_amba_dev_info *)dev->businfo;
+ if ( !info )
+ return 0;
+
+ /* Get LEON2 AMBA driver info */
+ adrv = (struct leon2_amba_drv_info *)drv;
+ id = adrv->ids;
+ if ( !id )
+ return 0;
+
+ while ( id->core_id ) {
+ if ( id->core_id == info->core_id ) {
+ /* Driver is suitable for device, Unite them */
+ return 1;
+ }
+ id++;
+ }
+
+ return 0;
+}
+
+rtems_isr leon2_amba_isr(rtems_vector_number v)
+{
+ int irq = v - 0x10; /* Convert Vector number to Interrupt number */
+ struct leon2_isr_handler *isr;
+
+ isr = &leon2_isrs[irq];
+ if ( isr->handler ) {
+ isr->handler(irq, isr->arg);
+ }
+}
+
+int leon2_amba_get_irq(struct drvmgr_dev *dev, int index)
+{
+ int irq;
+ struct leon2_amba_dev_info *info;
+
+ if ( !dev || (index > 15) )
+ return -1;
+
+ /* Relative (positive) or absolute (negative) IRQ number */
+ if ( index >= 0 ) {
+ /* IRQ Index relative to Cores base IRQ */
+
+ /* Get IRQ array configured by user */
+ info = (struct leon2_amba_dev_info *)dev->businfo;
+ irq = info->irqs[index];
+ if ( irq == 0 )
+ return -1;
+ } else {
+ /* Absolute IRQ number */
+ irq = -index;
+ }
+ return irq;
+}
+
+int leon2_amba_int_register
+ (
+ struct drvmgr_dev *dev,
+ int index,
+ const char *info,
+ drvmgr_isr isr,
+ void *arg
+ )
+{
+ int irq;
+
+ irq = leon2_amba_get_irq(dev, index);
+ if ( irq < 0 )
+ return -1;
+
+ DBG("Registering IRQ %d to func 0x%x arg 0x%x\n", irq, (unsigned int)isr, (unsigned int)arg);
+
+ return BSP_shared_interrupt_register(irq, info, isr, arg);
+}
+
+int leon2_amba_int_unregister
+ (
+ struct drvmgr_dev *dev,
+ int index,
+ drvmgr_isr isr,
+ void *arg
+ )
+{
+ int irq;
+
+ irq = leon2_amba_get_irq(dev, index);
+ if ( irq < 0 )
+ return -1;
+
+ DBG("Unregistering IRQ %d to func 0x%x arg 0x%x\n", irq, (unsigned int)handler, (unsigned int)arg);
+
+ return BSP_shared_interrupt_unregister(irq, isr, arg);
+}
+
+int leon2_amba_int_clear
+ (
+ struct drvmgr_dev *dev,
+ int index
+ )
+{
+ int irq;
+
+ irq = leon2_amba_get_irq(dev, index);
+ if ( irq < 0 )
+ return -1;
+
+ BSP_shared_interrupt_clear(irq);
+
+ return DRVMGR_OK;
+}
+
+int leon2_amba_int_mask
+ (
+ struct drvmgr_dev *dev,
+ int index
+ )
+{
+ int irq;
+
+ irq = leon2_amba_get_irq(dev, index);
+ if ( irq < 0 )
+ return -1;
+
+ BSP_shared_interrupt_mask(irq);
+
+ return DRVMGR_OK;
+}
+
+int leon2_amba_int_unmask
+ (
+ struct drvmgr_dev *dev,
+ int index
+ )
+{
+ int irq;
+
+ irq = leon2_amba_get_irq(dev, index);
+ if ( irq < 0 )
+ return -1;
+
+ BSP_shared_interrupt_unmask(irq);
+
+ return DRVMGR_OK;
+}
+
+struct drvmgr_drv_ops leon2_amba_ops =
+{
+ .init = {leon2_amba_init1, leon2_amba_init2, NULL, NULL},
+ .remove = leon2_amba_remove,
+ .info = NULL
+};
+
+struct drvmgr_drv leon2_bus_drv =
+{
+ DRVMGR_OBJ_DRV, /* Driver */
+ NULL, /* Next driver */
+ NULL, /* Device list */
+ DRIVER_LEON2_AMBA_ID, /* Driver ID */
+ "LEON2_AMBA_DRV", /* Must be placed at top bus */
+ DRVMGR_BUS_TYPE_ROOT, /* Bus Type */
+ &leon2_amba_ops, /* Bus Operations */
+ NULL, /* Funcs */
+ 0, /* Device Count */
+ 0, /* Private structure size */
+};
diff --git a/c/src/lib/libbsp/sparc/shared/include/drvmgr/leon2_amba_bus.h b/c/src/lib/libbsp/sparc/shared/include/drvmgr/leon2_amba_bus.h
new file mode 100644
index 0000000000..440e870c9c
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/include/drvmgr/leon2_amba_bus.h
@@ -0,0 +1,95 @@
+/* LEON2 Hardcoded bus driver interface.
+ *
+ * COPYRIGHT (c) 2008.
+ * Cobham Gaisler AB.
+ *
+ * Bus driver for a hardcoded setup. LEON2 systems have some
+ * cores always present, here called "Standard Cores". In
+ * addtion to the standard cores there are often extra cores
+ * that can be defined using the "Custom Cores" mechanism.
+ *
+ * A Core is described by assigning a base register and
+ * IRQ0..IRQ15 using the leon2_core structure.
+ *
+ * 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.
+ */
+
+#ifndef __LEON2_AMBA_BUS_H__
+#define __LEON2_AMBA_BUS_H__
+
+/*** Cores location and IRQs hardcoded ***/
+
+#include <drvmgr/drvmgr.h>
+#include <ambapp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* LEON2 AMBA Driver ID generation */
+#define DRIVER_LEON2_AMBA(id) DRIVER_ID(DRVMGR_BUS_TYPE_LEON2_AMBA, id)
+
+/* LEON2 Cores (any unique 48-bit number will do) */
+#define LEON2_AMBA_NONE_ID 0
+#define LEON2_AMBA_TIMER_ID 1
+#define LEON2_AMBA_UART_ID 2
+#define LEON2_AMBA_GPIO_ID 3
+#define LEON2_AMBA_IRQCTRL_ID 4
+
+#define LEON2_AMBA_AT697PCI_ID 100
+#define LEON2_AMBA_AMBAPP_ID 0xfff0
+
+/* LEON2 driver IDs */
+#define DRIVER_LEON2_AMBA_TIMER DRIVER_LEON2_AMBA(LEON2_AMBA_TIMER_ID)
+#define DRIVER_LEON2_AMBA_UART DRIVER_LEON2_AMBA(LEON2_AMBA_UART_ID)
+#define DRIVER_LEON2_AMBA_AT697PCI DRIVER_LEON2_AMBA(LEON2_AMBA_AT697PCI_ID)
+#define DRIVER_LEON2_AMBA_AMBAPP DRIVER_LEON2_AMBA(LEON2_AMBA_AMBAPP_ID)
+
+struct leon2_amba_dev_id {
+ unsigned short core_id;
+};
+
+#define EMPTY_LEON2_CORE {{LEON2_AMBA_NONE_ID}, NULL, NULL}
+struct leon2_core {
+ struct leon2_amba_dev_id id; /* Core ID */
+ char *name; /* Name of Core */
+ struct drvmgr_key *keys; /* Core setup (location, IRQs) */
+};
+
+struct leon2_bus {
+ struct leon2_core *std_cores; /* The LEON2 standard cores */
+ struct leon2_core *custom_cores; /* Custom cores on the same bus */
+ struct drvmgr_map_entry *maps_up; /* Memory map ip-stream */
+ struct drvmgr_map_entry *maps_down; /* Memory map down-stream */
+};
+
+extern struct leon2_core leon2_std_cores[];
+
+/* Data structure drivers can access */
+struct leon2_amba_dev_info {
+ unsigned short core_id; /* Core ID */
+ unsigned int reg_base; /* Register base */
+ char irqs[16]; /* 16 irqs */
+};
+
+struct leon2_amba_drv_info {
+ struct drvmgr_drv general; /* General bus info */
+ /* AMBA specific bus information */
+ struct leon2_amba_dev_id *ids; /* Supported hardware */
+};
+
+/* Initialize LEON2 bus with a configuration
+ * bus_config - What cores, their location and irqs
+ * resources - Driver configuration for the cores specified bus_config
+ */
+int leon2_root_register(
+ struct leon2_bus *bus_config,
+ struct drvmgr_bus_res *resources);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif