forked from Imagelibrary/rtems
LEON2: implemented AMBA Bus Driver for Driver Manager
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
459
c/src/lib/libbsp/sparc/shared/drvmgr/leon2_amba_bus.c
Normal file
459
c/src/lib/libbsp/sparc/shared/drvmgr/leon2_amba_bus.c
Normal file
@@ -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 */
|
||||
};
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user