mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 15:15:44 +00:00
2006-04-24 Jiri Gaisler <jiri@gaisler.com>
Edvin Catovic <edvin@gaisler.com> PR bsps/972 * ChangeLog, Makefile.am, configure.ac, amba/amba.c, clock/ckinit.c, console/Makefile.am, console/console.c, console/debugputs.c, include/Makefile.am, include/amba.h, include/bsp.h, include/leon.h, leon_smc91111/leon_smc91111.c, startup/bspstart.c, timer/timer.c, tools/Makefile.am, wrapup/Makefile.am: Added Shared Memory Support Driver. Added Leon Gaisler Research Ethernet support. Enhanced AMBA bus support. * console/debugprintf.c, console/spacewire.c, include/spacewire.h, leon_greth/.cvsignore, leon_greth/Makefile.am, leon_greth/leon_greth.c, shmsupp/.cvsignore, shmsupp/Makefile.am, shmsupp/addrconv.c, shmsupp/getcfg.c, shmsupp/lock.c, shmsupp/mpisr.c: New files.
This commit is contained in:
@@ -1,3 +1,21 @@
|
||||
2006-04-24 Jiri Gaisler <jiri@gaisler.com>
|
||||
Edvin Catovic <edvin@gaisler.com>
|
||||
|
||||
|
||||
PR bsps/972
|
||||
* ChangeLog, Makefile.am, configure.ac, amba/amba.c, clock/ckinit.c,
|
||||
console/Makefile.am, console/console.c, console/debugputs.c,
|
||||
include/Makefile.am, include/amba.h, include/bsp.h, include/leon.h,
|
||||
leon_smc91111/leon_smc91111.c, startup/bspstart.c, timer/timer.c,
|
||||
tools/Makefile.am, wrapup/Makefile.am: Added Shared Memory Support
|
||||
Driver. Added Leon Gaisler Research Ethernet support. Enhanced AMBA
|
||||
bus support.
|
||||
* console/debugprintf.c, console/spacewire.c, include/spacewire.h,
|
||||
leon_greth/.cvsignore, leon_greth/Makefile.am,
|
||||
leon_greth/leon_greth.c, shmsupp/.cvsignore, shmsupp/Makefile.am,
|
||||
shmsupp/addrconv.c, shmsupp/getcfg.c, shmsupp/lock.c,
|
||||
shmsupp/mpisr.c: New files.
|
||||
|
||||
2005-10-05 Jiri Gaisler <jiri@gaisler.com>
|
||||
Edvin Catovic <edvin@gaisler.com>
|
||||
Konrad Eisele <konrad@gaisler.com>
|
||||
|
||||
@@ -53,8 +53,13 @@ extern int rtems_leon_open_eth_driver_attach (struct rtems_bsdnet_ifconfig *conf
|
||||
extern int rtems_smc91111_driver_attach_leon2(struct rtems_bsdnet_ifconfig *config);
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_NAME "open_eth1"
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH_OPENETH rtems_leon_open_eth_driver_attach
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_NAME_SMC91111 "smc_eth1"
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH_SMC91111 rtems_smc91111_driver_attach_leon2
|
||||
|
||||
#ifndef RTEMS_BSP_NETWORK_DRIVER_NAME
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_NAME RTEMS_BSP_NETWORK_DRIVER_NAME_OPENETH
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define the time limits for RTEMS Test Suite test durations.
|
||||
* Long test and short test duration limits are provided. These
|
||||
|
||||
@@ -33,7 +33,7 @@ scmv91111_configuration_t leon_scmv91111_configuration = {
|
||||
SMC91111_BASE_ADDR, /* base address */
|
||||
SMC91111_BASE_IRQ, /* vector number */
|
||||
SMC91111_BASE_PIO, /* PIO */
|
||||
10, /* 10b */
|
||||
100, /* 100b */
|
||||
1, /* fulldx */
|
||||
1 /* autoneg */
|
||||
};
|
||||
@@ -49,16 +49,13 @@ int _rtems_smc91111_driver_attach(
|
||||
int rtems_smc91111_driver_attach_leon2(struct rtems_bsdnet_ifconfig *config)
|
||||
{
|
||||
|
||||
if (LEON_REG.Scaler_Reload >= 49)
|
||||
leon_scmv91111_configuration.ctl_rspeed = 100;
|
||||
|
||||
/* activate io area */
|
||||
DEBUG_puts("Activating Leon2 io port\n");
|
||||
|
||||
/*configure pio */
|
||||
*((volatile unsigned int *)0x80000000) |= 0x10f80000;
|
||||
*((volatile unsigned int *)0x800000A8) |=
|
||||
(0xe0 | leon_scmv91111_configuration.vector)
|
||||
<< (8 * (leon_scmv91111_configuration.pio - 4));
|
||||
(0xe0 | leon_scmv91111_configuration.pio)
|
||||
<< (8 * ((leon_scmv91111_configuration.vector & 0x0f) - 4));
|
||||
|
||||
return _rtems_smc91111_driver_attach(config,&leon_scmv91111_configuration);
|
||||
|
||||
|
||||
@@ -5,16 +5,15 @@
|
||||
ACLOCAL_AMFLAGS = -I ../../../../../../../aclocal
|
||||
|
||||
transform =
|
||||
bsptools_bindir = ${exec_prefix}/@RTEMS_BSP@/tests
|
||||
bsptools_bindir = $(PROJECT_ROOT)/@RTEMS_BSP@/tests
|
||||
bsptools_bin_SCRIPTS = runtest
|
||||
|
||||
TMPINSTALL_FILES = $(PROJECT_ROOT)/@RTEMS_BSP@/tests \
|
||||
$(PROJECT_ROOT)/@RTEMS_BSP@/tests/runtest
|
||||
TMPINSTALL_FILES = $(bsptools_bindir) $(bsptools_bindir)/runtest
|
||||
|
||||
$(PROJECT_ROOT)/@RTEMS_BSP@:
|
||||
$(bsptools_bindir):
|
||||
$(mkinstalldirs) $@
|
||||
|
||||
$(PROJECT_ROOT)/@RTEMS_BSP@/runtest: runtest
|
||||
$(bsptools_bindir)/runtest: runtest
|
||||
$(INSTALL_SCRIPT) $< $@
|
||||
|
||||
all-local: $(TMPINSTALL_FILES)
|
||||
|
||||
@@ -6,8 +6,11 @@ ACLOCAL_AMFLAGS = -I ../../../../../../aclocal
|
||||
|
||||
# wrapup is the one that actually builds and installs the library
|
||||
# from the individual .rel files built in other directories
|
||||
|
||||
SHMSUPP_DIR = shmsupp
|
||||
|
||||
SUBDIRS = . include start startup gnatsupp amba console clock timer \
|
||||
leon_open_eth leon_smc91111 wrapup tools
|
||||
leon_open_eth leon_smc91111 leon_greth shmsupp wrapup tools leon_greth
|
||||
|
||||
include $(top_srcdir)/../../bsp.am
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <leon.h>
|
||||
#include <bsp.h>
|
||||
|
||||
#define amba_insert_device(tab, address) \
|
||||
{ \
|
||||
@@ -31,6 +31,9 @@ amba_confarea_type amba_conf;
|
||||
/* Pointers to Interrupt Controller configuration registers */
|
||||
volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs;
|
||||
|
||||
int LEON3_Cpu_Index = 0;
|
||||
static int apb_init = 0;
|
||||
|
||||
/*
|
||||
* bsp_leon3_predriver_hook
|
||||
*
|
||||
@@ -41,12 +44,23 @@ volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs;
|
||||
* amba_ahb_masters, amba_ahb_slaves and amba.
|
||||
*/
|
||||
|
||||
unsigned int getasr17();
|
||||
|
||||
asm(" .text \n"
|
||||
"getasr17: \n"
|
||||
"retl \n"
|
||||
"mov %asr17, %o0\n"
|
||||
);
|
||||
|
||||
|
||||
extern rtems_configuration_table Configuration;
|
||||
|
||||
void bsp_leon3_predriver_hook(void)
|
||||
{
|
||||
unsigned int *cfg_area; /* address to configuration area */
|
||||
unsigned int mbar, iobar, conf;
|
||||
int i, j;
|
||||
unsigned int tmp;
|
||||
|
||||
amba_conf.ahbmst.devnr = 0; amba_conf.ahbslv.devnr = 0; amba_conf.apbslv.devnr = 0;
|
||||
cfg_area = (unsigned int *) (LEON3_IO_AREA | LEON3_CONF_AREA);
|
||||
@@ -68,7 +82,8 @@ void bsp_leon3_predriver_hook(void)
|
||||
{
|
||||
conf = amba_get_confword(amba_conf.ahbslv, i, 0);
|
||||
mbar = amba_ahb_get_membar(amba_conf.ahbslv, i, 0);
|
||||
if ((amba_vendor(conf) == VENDOR_GAISLER) && (amba_device(conf) == GAISLER_APBMST))
|
||||
if ((amba_vendor(conf) == VENDOR_GAISLER) && (amba_device(conf) == GAISLER_APBMST) &&
|
||||
(apb_init == 0))
|
||||
{
|
||||
amba_conf.apbmst = amba_membar_start(mbar);
|
||||
cfg_area = (unsigned int *) (amba_conf.apbmst | LEON3_CONF_AREA);
|
||||
@@ -77,6 +92,7 @@ void bsp_leon3_predriver_hook(void)
|
||||
amba_insert_device(&amba_conf.apbslv, cfg_area);
|
||||
cfg_area += LEON3_APB_CONF_WORDS;
|
||||
}
|
||||
apb_init = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +105,12 @@ void bsp_leon3_predriver_hook(void)
|
||||
{
|
||||
iobar = amba_apb_get_membar(amba_conf.apbslv, i);
|
||||
LEON3_IrqCtrl_Regs = (volatile LEON3_IrqCtrl_Regs_Map *) amba_iobar_start(amba_conf.apbmst, iobar);
|
||||
/* asm("mov %%asr17, %0": : "r" (tmp)); */
|
||||
if (Configuration.User_multiprocessing_table != NULL)
|
||||
{
|
||||
tmp = getasr17();
|
||||
LEON3_Cpu_Index = (tmp >> 28) & 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
* The Real Time Clock Counter Timer uses this trap type.
|
||||
*/
|
||||
|
||||
extern rtems_configuration_table Configuration;
|
||||
|
||||
#define LEON3_CLOCK_INDEX (Configuration.User_multiprocessing_table ? LEON3_Cpu_Index : 0)
|
||||
|
||||
#define CLOCK_VECTOR LEON_TRAP_TYPE( LEON_INTERRUPT_TIMER1 )
|
||||
|
||||
/*
|
||||
@@ -145,12 +149,18 @@ void Install_clock(
|
||||
|
||||
clkirq = (LEON3_Timer_Regs->status & 0xfc) >> 3;
|
||||
|
||||
/* MP */
|
||||
if (Configuration.User_multiprocessing_table != NULL)
|
||||
{
|
||||
clkirq += LEON3_Cpu_Index;
|
||||
}
|
||||
|
||||
if ( BSP_Configuration.ticks_per_timeslice ) {
|
||||
Old_ticker = (rtems_isr_entry) set_vector( clock_isr, LEON_TRAP_TYPE(clkirq), 1 );
|
||||
|
||||
LEON3_Timer_Regs->reload_t0 = CPU_SPARC_CLICKS_PER_TICK - 1;
|
||||
LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX].reload = CPU_SPARC_CLICKS_PER_TICK - 1;
|
||||
|
||||
LEON3_Timer_Regs->conf_t0 = LEON3_GPTIMER_EN | LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN;
|
||||
LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX].conf = LEON3_GPTIMER_EN | LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN;
|
||||
|
||||
atexit( Clock_exit );
|
||||
}
|
||||
@@ -176,7 +186,7 @@ void Clock_exit( void )
|
||||
if ( BSP_Configuration.ticks_per_timeslice ) {
|
||||
LEON_Mask_interrupt(LEON_TRAP_TYPE(clkirq));
|
||||
|
||||
LEON3_Timer_Regs->conf_t0 = 0;
|
||||
LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX].conf = 0;
|
||||
|
||||
/* do not restore old vector */
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ RTEMS_CANONICALIZE_TOOLS
|
||||
RTEMS_CHECK_NETWORKING
|
||||
|
||||
AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
|
||||
AM_CONDITIONAL(HAS_MP,test "$HAS_MP" = "yes")
|
||||
|
||||
RTEMS_CONFIG_BUILD_SUBDIRS(tools)
|
||||
|
||||
@@ -41,10 +42,12 @@ AC_CONFIG_FILES([Makefile
|
||||
amba/Makefile
|
||||
clock/Makefile
|
||||
console/Makefile
|
||||
leon_greth/Makefile
|
||||
leon_open_eth/Makefile
|
||||
leon_smc91111/Makefile
|
||||
gnatsupp/Makefile
|
||||
include/Makefile
|
||||
shmsupp/Makefile
|
||||
start/Makefile
|
||||
startup/Makefile
|
||||
timer/Makefile
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
PGM = $(ARCH)/console.rel
|
||||
|
||||
C_FILES = console.c consolereserveresources.c debugputs.c
|
||||
C_FILES = console.c spacewire.c consolereserveresources.c debugputs.c debugprintf.c
|
||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
||||
|
||||
OBJS = $(C_O_FILES)
|
||||
|
||||
@@ -85,9 +85,30 @@ int console_write_support (int minor, const char *buf, int len)
|
||||
* Console Device Driver Entry Points
|
||||
*
|
||||
*/
|
||||
|
||||
int uarts = 0;
|
||||
static int isinit = 0;
|
||||
volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
|
||||
|
||||
int scan_uarts() {
|
||||
unsigned int iobar, conf;
|
||||
int i;
|
||||
if (isinit == 0) {
|
||||
i = 0; uarts = 0;
|
||||
while (i < amba_conf.apbslv.devnr) {
|
||||
conf = amba_get_confword(amba_conf.apbslv, i, 0);
|
||||
if ((amba_vendor(conf) == VENDOR_GAISLER) && (amba_device(conf) == GAISLER_APBUART)){
|
||||
iobar = amba_apb_get_membar(amba_conf.apbslv, i);
|
||||
LEON3_Console_Uart[uarts] = (volatile LEON3_UART_Regs_Map *) amba_iobar_start(amba_conf.apbmst, iobar);
|
||||
uarts++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
isinit = 1;
|
||||
}
|
||||
return uarts;
|
||||
}
|
||||
|
||||
|
||||
rtems_device_driver console_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
@@ -95,53 +116,49 @@ rtems_device_driver console_initialize(
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
unsigned int iobar, conf;
|
||||
int i, uarts;
|
||||
int i;
|
||||
char *console_name = "/dev/console_a";
|
||||
|
||||
extern rtems_configuration_table Configuration;
|
||||
int uart0;
|
||||
|
||||
rtems_termios_initialize();
|
||||
|
||||
/* Find UARTs */
|
||||
scan_uarts();
|
||||
|
||||
i = 0; uarts = 0;
|
||||
while (i < amba_conf.apbslv.devnr)
|
||||
{
|
||||
conf = amba_get_confword(amba_conf.apbslv, i, 0);
|
||||
if ((amba_vendor(conf) == VENDOR_GAISLER) && (amba_device(conf) == GAISLER_APBUART))
|
||||
{
|
||||
iobar = amba_apb_get_membar(amba_conf.apbslv, i);
|
||||
LEON3_Console_Uart[uarts] = (volatile LEON3_UART_Regs_Map *) amba_iobar_start(amba_conf.apbmst, iobar);
|
||||
uarts++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (Configuration.User_multiprocessing_table != NULL)
|
||||
uart0 = LEON3_Cpu_Index;
|
||||
else
|
||||
uart0 = 0;
|
||||
|
||||
/* Register Device Names */
|
||||
|
||||
if (uarts)
|
||||
if (uarts && (uart0 < uarts))
|
||||
{
|
||||
status = rtems_io_register_name( "/dev/console", major, 0 );
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
rtems_fatal_error_occurred(status);
|
||||
|
||||
for (i = 1; i < uarts; i++)
|
||||
for (i = uart0+1; i < uarts; i++)
|
||||
{
|
||||
console_name[13]++;
|
||||
status = rtems_io_register_name( console_name, major, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize Hardware
|
||||
*/
|
||||
|
||||
for (i = 0; i < uarts; i++)
|
||||
if ((Configuration.User_multiprocessing_table == NULL) ||
|
||||
((Configuration.User_multiprocessing_table)->node == 1))
|
||||
{
|
||||
for (i = uart0; i < uarts; i++)
|
||||
{
|
||||
LEON3_Console_Uart[i]->ctrl |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE;
|
||||
LEON3_Console_Uart[i]->status = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
180
c/src/lib/libbsp/sparc/leon3/console/debugprintf.c
Normal file
180
c/src/lib/libbsp/sparc/leon3/console/debugprintf.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* Modified for LEON3 BSP.
|
||||
* COPYRIGHT (c) 2004.
|
||||
* Gaisler Research.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
static size_t lo_strnlen(const char * s, size_t count)
|
||||
{
|
||||
const char *sc;
|
||||
|
||||
for (sc = s; count-- && *sc != '\0'; ++sc)
|
||||
/* nothing */;
|
||||
return sc - s;
|
||||
}
|
||||
|
||||
static int lo_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
|
||||
{
|
||||
int len;
|
||||
unsigned long long num;
|
||||
int i,j,n;
|
||||
char *str, *end, c;
|
||||
const char *s;
|
||||
int flags;
|
||||
int field_width;
|
||||
int precision;
|
||||
int qualifier;
|
||||
|
||||
str = buf;
|
||||
end = buf + size - 1;
|
||||
|
||||
if (end < buf - 1) {
|
||||
end = ((void *) -1);
|
||||
size = end - buf + 1;
|
||||
}
|
||||
|
||||
for (; *fmt ; ++fmt) {
|
||||
if (*fmt != '%') {
|
||||
if (str <= end)
|
||||
*str = *fmt;
|
||||
++str;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* process flags */
|
||||
flags = 0;
|
||||
/* get field width */
|
||||
field_width = -1;
|
||||
/* get the precision */
|
||||
precision = -1;
|
||||
/* get the conversion qualifier */
|
||||
qualifier = 'l';
|
||||
|
||||
++fmt;
|
||||
/* default base */
|
||||
switch (*fmt) {
|
||||
case 'c':
|
||||
c = (unsigned char) va_arg(args, int);
|
||||
if (str <= end)
|
||||
*str = c;
|
||||
++str;
|
||||
while (--field_width > 0) {
|
||||
if (str <= end)
|
||||
*str = ' ';
|
||||
++str;
|
||||
}
|
||||
continue;
|
||||
|
||||
case 's':
|
||||
s = va_arg(args, char *);
|
||||
if (!s)
|
||||
s = "<NULL>";
|
||||
|
||||
len = lo_strnlen(s, precision);
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
if (str <= end)
|
||||
*str = *s;
|
||||
++str; ++s;
|
||||
}
|
||||
while (len < field_width--) {
|
||||
if (str <= end)
|
||||
*str = ' ';
|
||||
++str;
|
||||
}
|
||||
continue;
|
||||
|
||||
|
||||
case '%':
|
||||
if (str <= end)
|
||||
*str = '%';
|
||||
++str;
|
||||
continue;
|
||||
|
||||
case 'x':
|
||||
break;
|
||||
|
||||
default:
|
||||
if (str <= end)
|
||||
*str = '%';
|
||||
++str;
|
||||
if (*fmt) {
|
||||
if (str <= end)
|
||||
*str = *fmt;
|
||||
++str;
|
||||
} else {
|
||||
--fmt;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
num = va_arg(args, unsigned long);
|
||||
for (j=0,i=0;i<8 && str <= end;i++) {
|
||||
if ( (n = ((unsigned long)(num & (0xf0000000ul>>(i*4)))) >> ((7-i)*4)) || j != 0) {
|
||||
j = 1;
|
||||
if (n >= 10)
|
||||
n += 'a'-10;
|
||||
else
|
||||
n += '0';
|
||||
*str = n;
|
||||
++str;
|
||||
}
|
||||
}
|
||||
if (j == 0 && str <= end) {
|
||||
*str = '0';
|
||||
++str;
|
||||
}
|
||||
}
|
||||
if (str <= end)
|
||||
*str = '\0';
|
||||
else if (size > 0)
|
||||
/* don't write out a null byte if the buf size is zero */
|
||||
*end = '\0';
|
||||
/* the trailing null byte doesn't count towards the total
|
||||
* ++str;
|
||||
*/
|
||||
return str-buf;
|
||||
}
|
||||
|
||||
int DEBUG_sprintf(char *buf, size_t size, const char *fmt, ...) {
|
||||
va_list args;
|
||||
int printed_len;
|
||||
|
||||
va_start(args, fmt);
|
||||
printed_len = lo_vsnprintf(buf, size, fmt, args);
|
||||
va_end(args);
|
||||
return printed_len;
|
||||
}
|
||||
|
||||
int scan_uarts();
|
||||
void DEBUG_puts( char *string );
|
||||
int DEBUG_printf(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int printed_len;
|
||||
char printk_buf[1024+1];
|
||||
|
||||
/* Emit the output into the temporary buffer */
|
||||
va_start(args, fmt);
|
||||
printed_len = lo_vsnprintf(printk_buf, sizeof(printk_buf)-1, fmt, args);
|
||||
printk_buf[printed_len] = 0;
|
||||
va_end(args);
|
||||
|
||||
scan_uarts();
|
||||
/*DEBUG_puts(printk_buf);*/
|
||||
return printed_len;
|
||||
}
|
||||
@@ -35,8 +35,8 @@ void console_outbyte_polled(
|
||||
{
|
||||
if ((port >= 0) && (port <= CONFIGURE_NUMBER_OF_TERMIOS_PORTS))
|
||||
{
|
||||
while ( (LEON3_Console_Uart[port]->status & LEON_REG_UART_STATUS_THE) == 0 );
|
||||
LEON3_Console_Uart[port]->data = (unsigned int) ch;
|
||||
while ( (LEON3_Console_Uart[LEON3_Cpu_Index+port]->status & LEON_REG_UART_STATUS_THE) == 0 );
|
||||
LEON3_Console_Uart[LEON3_Cpu_Index+port]->data = (unsigned int) ch;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,13 +52,13 @@ int console_inbyte_nonblocking( int port )
|
||||
if ((port >=0) && (port < CONFIGURE_NUMBER_OF_TERMIOS_PORTS))
|
||||
{
|
||||
|
||||
if (LEON3_Console_Uart[port]->status & LEON_REG_UART_STATUS_ERR) {
|
||||
LEON3_Console_Uart[port]->status = ~LEON_REG_UART_STATUS_ERR;
|
||||
if (LEON3_Console_Uart[LEON3_Cpu_Index+port]->status & LEON_REG_UART_STATUS_ERR) {
|
||||
LEON3_Console_Uart[LEON3_Cpu_Index+port]->status = ~LEON_REG_UART_STATUS_ERR;
|
||||
}
|
||||
|
||||
if ((LEON3_Console_Uart[port]->status & LEON_REG_UART_STATUS_DR) == 0)
|
||||
if ((LEON3_Console_Uart[LEON3_Cpu_Index+port]->status & LEON_REG_UART_STATUS_DR) == 0)
|
||||
return -1;
|
||||
return (int) LEON3_Console_Uart[port]->data;
|
||||
return (int) LEON3_Console_Uart[LEON3_Cpu_Index+port]->data;
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
677
c/src/lib/libbsp/sparc/leon3/console/spacewire.c
Normal file
677
c/src/lib/libbsp/sparc/leon3/console/spacewire.c
Normal file
@@ -0,0 +1,677 @@
|
||||
/*
|
||||
* This file contains the TTY driver for the spacewire port on the LEON.
|
||||
*
|
||||
* This driver uses the termios pseudo driver.
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1998.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* Modified for LEON3 BSP.
|
||||
* COPYRIGHT (c) 2005.
|
||||
* Gaisler Research.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* spacewire.c,v 1.1.2.1 2005/11/02 19:25:59 jiri Exp
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <sched.h>
|
||||
#include <ctype.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#define DBGSPW_IOCALLS 1
|
||||
#define DBGSPW_TX 2
|
||||
#define DBGSPW_RX 4
|
||||
#define DBGSPW_IOCTRL 8
|
||||
#define DBGSPW_DUMP 16
|
||||
#define DEBUG_SPACEWIRE_FLAGS -1
|
||||
|
||||
/*#define DEBUG_SPACEWIRE_ONOFF*/
|
||||
|
||||
#ifdef DEBUG_SPACEWIRE_ONOFF
|
||||
int DEBUG_printf(const char *fmt, ...);
|
||||
#define SPACEWIRE_DBG(fmt, args...) \
|
||||
do { \
|
||||
{ printf(" : %03d @ %18s()]:" fmt , __LINE__,__FUNCTION__,## args); } \
|
||||
} while(0)
|
||||
#define SPACEWIRE_DBG2(fmt) \
|
||||
do { \
|
||||
{ printf(" : %03d @ %18s()]:" fmt , __LINE__,__FUNCTION__); } \
|
||||
} while(0)
|
||||
#define SPACEWIRE_DBGC(c,fmt, args...) \
|
||||
do { \
|
||||
if (DEBUG_SPACEWIRE_FLAGS&c) { \
|
||||
printf(" : %03d @ %18s()]:" fmt , __LINE__,__FUNCTION__,## args); \
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
#define SPACEWIRE_DBG(fmt, args...)
|
||||
#define SPACEWIRE_DBG2(fmt, args...)
|
||||
#define SPACEWIRE_DBGC(fmt, args...)
|
||||
#endif
|
||||
|
||||
int spacewire_hw_init(int minor);
|
||||
void spacewire_hw_send(int minor,unsigned char *b,int c);
|
||||
int spacewire_hw_receive(int minor,unsigned char *b,int c);
|
||||
int spacewire_hw_startup (int minor);
|
||||
int spacewire_hw_stop (int minor);
|
||||
void spacewire_hw_waitlink (int minor);
|
||||
void spacewire_rxnext(int minor);
|
||||
|
||||
int _SPW_READ(void *addr) {
|
||||
int tmp;
|
||||
asm(" lda [%1]1, %0 "
|
||||
: "=r"(tmp)
|
||||
: "r"(addr)
|
||||
);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
rtems_device_driver spacewire_console_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
);
|
||||
rtems_device_driver spacewire_console_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
);
|
||||
rtems_device_driver spacewire_console_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
);
|
||||
rtems_device_driver spacewire_console_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
);
|
||||
rtems_device_driver spacewire_console_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
);
|
||||
rtems_device_driver spacewire_console_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
);
|
||||
|
||||
#define SPWCEWIRE_CONSOLE_DRIVER_TABLE_ENTRY \
|
||||
{ spacewire_console_initialize, spacewire_console_open, \
|
||||
spacewire_console_close, spacewire_console_read, \
|
||||
spacewire_console_write, spacewire_console_control }
|
||||
|
||||
static rtems_driver_address_table
|
||||
spacewire_driver = SPWCEWIRE_CONSOLE_DRIVER_TABLE_ENTRY;
|
||||
|
||||
void spacewire_register()
|
||||
{
|
||||
rtems_status_code r;
|
||||
rtems_device_major_number m;
|
||||
|
||||
SPACEWIRE_DBG2("register driver\n");
|
||||
if ((r = rtems_io_register_driver(
|
||||
0,
|
||||
&spacewire_driver,
|
||||
&m)) == RTEMS_SUCCESSFUL) {
|
||||
SPACEWIRE_DBG2("success\n");
|
||||
} else {
|
||||
switch(r) {
|
||||
case RTEMS_TOO_MANY:
|
||||
SPACEWIRE_DBG2("failed RTEMS_TOO_MANY\n"); break;
|
||||
case RTEMS_INVALID_NUMBER:
|
||||
SPACEWIRE_DBG2("failed RTEMS_INVALID_NUMBER\n"); break;
|
||||
case RTEMS_RESOURCE_IN_USE:
|
||||
SPACEWIRE_DBG2("failed RTEMS_RESOURCE_IN_USE\n"); break;
|
||||
default:
|
||||
SPACEWIRE_DBG("failed %i\n",r); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SPW_BUFMALLOC
|
||||
void spacewire_buffer_alloc(int minor) {
|
||||
if (SPW_PARAM(minor).ptr_rxbuf0) {
|
||||
free(SPW_PARAM(minor).ptr_rxbuf0);
|
||||
}
|
||||
if (SPW_PARAM(minor).ptr_txbuf0) {
|
||||
free(SPW_PARAM(minor).ptr_txbuf0);
|
||||
}
|
||||
SPW_PARAM(minor).ptr_rxbuf0 =
|
||||
(char *) malloc(SPW_PARAM(minor).rxbufsize * SPW_PARAM(minor).rxbufcnt);
|
||||
SPW_PARAM(minor).ptr_txbuf0 =
|
||||
(char *) malloc(SPW_PARAM(minor).txbufsize * SPW_PARAM(minor).txbufcnt);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Console Device Driver Entry Points
|
||||
*
|
||||
*/
|
||||
|
||||
SPACEWIRE_PARAM LEON3_Spacewire[SPACEWIRE_MAX_CORENR];
|
||||
|
||||
rtems_device_driver spacewire_console_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
unsigned int iobar, conf;
|
||||
int i, uarts;
|
||||
char *console_name = "/dev/spacewire_a";
|
||||
SPACEWIRE_DBG2("spacewire driver inizialisation\n");
|
||||
|
||||
rtems_termios_initialize();
|
||||
|
||||
/* Find spacewire cores */
|
||||
i = 0; uarts = 0;
|
||||
while (i < amba_conf.apbslv.devnr && uarts < SPACEWIRE_MAX_CORENR)
|
||||
{
|
||||
conf = amba_get_confword(amba_conf.apbslv, i, 0);
|
||||
if ((amba_vendor(conf) == VENDOR_GAISLER) &&
|
||||
(amba_device(conf) == GAISLER_SPACEWIRE))
|
||||
{
|
||||
iobar = amba_apb_get_membar(amba_conf.apbslv, i);
|
||||
LEON3_Spacewire[uarts].regs =
|
||||
(LEON3_SPACEWIRE_Regs_Map *) amba_iobar_start(amba_conf.apbmst, iobar);
|
||||
LEON3_Spacewire[uarts].irq = amba_irq(conf);
|
||||
|
||||
SPACEWIRE_DBG("spacewire code at [0x%x]\n",
|
||||
(unsigned int)LEON3_Spacewire[uarts].regs);
|
||||
|
||||
/* initialize the code with some resonable values,
|
||||
actual initialization is done later using ioctl(fd)
|
||||
on the opened device */
|
||||
LEON3_Spacewire[uarts].nodeaddr = 0x14;
|
||||
LEON3_Spacewire[uarts].destkey = 0xBF;
|
||||
LEON3_Spacewire[uarts].maxfreq = 1;
|
||||
LEON3_Spacewire[uarts].clkdiv = 0;
|
||||
LEON3_Spacewire[uarts].rxmaxlen = SPACEWIRE_RXPCK_SIZE;
|
||||
LEON3_Spacewire[uarts].txbufsize = SPACEWIRE_TXPCK_SIZE;
|
||||
LEON3_Spacewire[uarts].rxbufsize = SPACEWIRE_RXPCK_SIZE;
|
||||
LEON3_Spacewire[uarts].txbufcnt = SPACEWIRE_TXBUFS_NR;
|
||||
LEON3_Spacewire[uarts].rxbufcnt = SPACEWIRE_RXBUFS_NR;
|
||||
|
||||
#ifndef SPW_BUFMALLOC
|
||||
LEON3_Spacewire[uarts].ptr_rxbuf0 = &LEON3_Spacewire[uarts]._rxbuf0;
|
||||
LEON3_Spacewire[uarts].ptr_txbuf0 = &LEON3_Spacewire[uarts]._txbuf0;
|
||||
#else
|
||||
LEON3_Spacewire[uarts].ptr_rxbuf0 = 0;
|
||||
LEON3_Spacewire[uarts].ptr_txbuf0 = 0;
|
||||
spacewire_buffer_alloc(uarts);
|
||||
#endif
|
||||
uarts++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Register Device Names, /dev/spacewire, /dev/spacewire_b ... */
|
||||
if (uarts) {
|
||||
SPACEWIRE_DBG2("registering minor 0 as /dev/spacewire\n");
|
||||
status = rtems_io_register_name( "/dev/spacewire", major, 0 );
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
rtems_fatal_error_occurred(status);
|
||||
for (i = 1; i < uarts; i++) {
|
||||
console_name[15]++;
|
||||
SPACEWIRE_DBG("registering minor %i as %s\n",i,console_name);
|
||||
status = rtems_io_register_name( console_name, major, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize Hardware */
|
||||
for (i = 0; i < uarts; i++) {
|
||||
spacewire_hw_init(i);
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
int spacewire_setattibutes(int minor, int nodeaddr, int proto, int dest) {
|
||||
if ( minor >= SPACEWIRE_MAX_CORENR ) {
|
||||
printf("minor %i too big\n",minor);
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
SPW_PARAM(minor).nodeaddr = nodeaddr;
|
||||
SPW_PARAM(minor).proto = proto;
|
||||
SPW_PARAM(minor).destnodeaddr = dest;
|
||||
/*set node address*/
|
||||
SPW_WRITE(&SPW_REG(minor,nodeaddr),SPW_PARAM(minor).nodeaddr);
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver spacewire_console_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
){
|
||||
SPACEWIRE_DBGC(DBGSPW_IOCALLS,"open [%i,%i]\n",major, minor);
|
||||
if ( minor >= SPACEWIRE_MAX_CORENR ) {
|
||||
SPACEWIRE_DBG("minor %i too big\n",minor);
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
return spacewire_hw_startup(minor);
|
||||
}
|
||||
|
||||
rtems_device_driver spacewire_console_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
SPACEWIRE_DBGC(DBGSPW_IOCALLS,"close [%i,%i]\n",major, minor);
|
||||
spacewire_hw_stop(minor);
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver spacewire_console_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
rtems_libio_rw_args_t *rw_args;
|
||||
unsigned32 count = 0;
|
||||
rw_args = (rtems_libio_rw_args_t *) arg;
|
||||
|
||||
SPACEWIRE_DBGC(DBGSPW_IOCALLS,"read [%i,%i]: buf:0x%x len:%i \n",
|
||||
major, minor, (unsigned int)rw_args->buffer,rw_args->count);
|
||||
|
||||
count = spacewire_hw_receive(minor,rw_args->buffer,rw_args->count);
|
||||
|
||||
#ifdef DEBUG_SPACEWIRE_ONOFF
|
||||
if (DEBUG_SPACEWIRE_FLAGS & DBGSPW_DUMP) {
|
||||
int k;
|
||||
for (k = 0;k < count;k++){
|
||||
if (k % 16 == 0) {
|
||||
printf ("\n");
|
||||
}
|
||||
printf ("%.2x(%c) ",rw_args->buffer[k] & 0xff,
|
||||
isprint(rw_args->buffer[k] & 0xff) ? rw_args->buffer[k] & 0xff : ' ');
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
rw_args->bytes_moved = count;
|
||||
return RTEMS_SUCCESSFUL;
|
||||
|
||||
}
|
||||
|
||||
rtems_device_driver spacewire_console_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
rtems_libio_rw_args_t *rw_args;
|
||||
int count = 0;
|
||||
rw_args = (rtems_libio_rw_args_t *) arg;
|
||||
SPACEWIRE_DBGC(DBGSPW_IOCALLS,"write [%i,%i]: buf:0x%x len:%i\n",
|
||||
major, minor, (unsigned int)rw_args->buffer,rw_args->count);
|
||||
|
||||
while (rw_args->count > 0) {
|
||||
int c = rw_args->count;
|
||||
if (c > SPW_PARAM(minor).txbufsize-2) {
|
||||
c = SPW_PARAM(minor).txbufsize-2;
|
||||
}
|
||||
spacewire_hw_send(minor,rw_args->buffer,c);
|
||||
rw_args->count -= c;
|
||||
rw_args->buffer += c;
|
||||
count += c;
|
||||
}
|
||||
|
||||
if (count >= 0) {
|
||||
rw_args->bytes_moved = count;
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
return RTEMS_UNSATISFIED;
|
||||
}
|
||||
|
||||
rtems_device_driver spacewire_console_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t *)arg;
|
||||
SPACEWIRE_DBGC(DBGSPW_IOCALLS,"ctrl [%i,%i]\n",major, minor);
|
||||
|
||||
if (!ioarg)
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
|
||||
switch(ioarg->command) {
|
||||
case SPACEWIRE_IOCTRL_SET_NODEADDR:
|
||||
SPACEWIRE_DBGC(DBGSPW_IOCTRL,"SPACEWIRE_IOCTRL_SET_NODEADDR %i\n",
|
||||
ioarg->buffer);
|
||||
SPW_PARAM(minor).nodeaddr = (unsigned int) ioarg->buffer;
|
||||
/*set node address*/
|
||||
SPW_WRITE(&SPW_REG(minor,nodeaddr),SPW_PARAM(minor).nodeaddr);
|
||||
break;
|
||||
case SPACEWIRE_IOCTRL_SET_PROTOCOL:
|
||||
SPACEWIRE_DBGC(DBGSPW_IOCTRL,"SPACEWIRE_IOCTRL_SET_PROTOCOL %i\n",
|
||||
ioarg->buffer);
|
||||
SPW_PARAM(minor).proto = (unsigned int) ioarg->buffer;
|
||||
break;
|
||||
case SPACEWIRE_IOCTRL_SET_DESTNODEADDR:
|
||||
SPACEWIRE_DBGC(DBGSPW_IOCTRL,"SPACEWIRE_IOCTRL_SET_DESTNODEADDR %i\n",
|
||||
ioarg->buffer);
|
||||
SPW_PARAM(minor).destnodeaddr = (unsigned int) ioarg->buffer;
|
||||
break;
|
||||
case SPACEWIRE_IOCTRL_GET_COREBASEADDR:
|
||||
SPACEWIRE_DBGC(DBGSPW_IOCTRL,"SPACEWIRE_IOCTRL_GET_BASEADDR=%i\n",
|
||||
(unsigned int)SPW_PARAM(minor).regs);
|
||||
*(unsigned int *)ioarg->buffer = (unsigned int )SPW_PARAM(minor).regs;
|
||||
break;
|
||||
case SPACEWIRE_IOCTRL_GET_COREIRQ:
|
||||
SPACEWIRE_DBGC(DBGSPW_IOCTRL,"SPACEWIRE_IOCTRL_GET_COREIRQ=%i\n",
|
||||
(unsigned int)SPW_PARAM(minor).irq);
|
||||
*(unsigned int *)ioarg->buffer = (unsigned int )SPW_PARAM(minor).irq;
|
||||
break;
|
||||
#ifdef SPW_BUFMALLOC
|
||||
case SPACEWIRE_IOCTRL_SET_PACKETSIZE:
|
||||
{
|
||||
spw_ioctl_packetsize *ps = (spw_ioctl_packetsize*)ioarg->buffer;
|
||||
SPACEWIRE_DBGC(DBGSPW_IOCTRL,"SPACEWIRE_IOCTRL_SET_RXPACKETSIZE \n",
|
||||
ioarg->buffer);
|
||||
spacewire_hw_stop(minor);
|
||||
SPW_PARAM(minor).rxbufsize = ps->rxsize;
|
||||
SPW_PARAM(minor).txbufsize = ps->txsize;
|
||||
SPW_PARAM(minor).rxmaxlen = SPW_PARAM(minor).rxbufsize;
|
||||
spacewire_buffer_alloc(minor);
|
||||
spacewire_hw_startup(minor);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case SPACEWIRE_IOCTRL_GETPACKET: {
|
||||
spw_ioctl_packet *p = (spw_ioctl_packet*)ioarg->buffer;
|
||||
p->ret_size = spacewire_hw_receive(minor,p->buf,p->buf_size);
|
||||
}
|
||||
break;
|
||||
case SPACEWIRE_IOCTRL_PUTPACKET:{
|
||||
spw_ioctl_packet *p = (spw_ioctl_packet*)ioarg->buffer;
|
||||
spacewire_hw_send(minor,p->buf,p->buf_size);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return RTEMS_NOT_DEFINED;
|
||||
}
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
/* ========================================================================== */
|
||||
|
||||
int spacewire_set_rxmaxlen(int minor) {
|
||||
unsigned int rxmax;
|
||||
/*set rx maxlength*/
|
||||
SPW_WRITE(&SPW_REG(minor,dma0rxmax),SPW_PARAM(minor).rxmaxlen);
|
||||
rxmax = SPW_READ(&SPW_REG(minor,dma0rxmax));
|
||||
if (rxmax != SPW_PARAM(minor).rxmaxlen) {
|
||||
printf("spacewire: error initializing rx max len (0x%x, read: 0x%x)\n",
|
||||
SPW_PARAM(minor).rxmaxlen,rxmax);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int spacewire_hw_init(int minor) {
|
||||
unsigned int dma0ctrl;
|
||||
int ctrl = SPW_CTRL_READ(minor);
|
||||
|
||||
SPW_PARAM(minor).rx = (SPACEWIRE_RXBD *)
|
||||
SPW_ALIGN(&SPW_PARAM(minor)._rxtable,SPACEWIRE_BDTABLE_SIZE);
|
||||
SPW_PARAM(minor).tx = (SPACEWIRE_TXBD *)
|
||||
SPW_ALIGN(&SPW_PARAM(minor)._txtable,SPACEWIRE_BDTABLE_SIZE);
|
||||
|
||||
SPACEWIRE_DBG("hw_init [minor %i]\n", minor);
|
||||
|
||||
SPW_PARAM(minor).is_rmap = ctrl & SPACEWIRE_CTRL_RA;
|
||||
SPW_PARAM(minor).is_rxunaligned = ctrl & SPACEWIRE_CTRL_RX;
|
||||
SPW_PARAM(minor).is_rmapcrc = ctrl & SPACEWIRE_CTRL_RC;
|
||||
|
||||
/*set node address*/
|
||||
SPW_WRITE(&SPW_REG(minor,nodeaddr),SPW_PARAM(minor).nodeaddr);
|
||||
|
||||
/*set clock divisor*/
|
||||
SPW_WRITE(&SPW_REG(minor,clockdiv),SPW_PARAM(minor).clkdiv);
|
||||
if (SPW_PARAM(minor).is_rmap) {
|
||||
SPW_WRITE(&SPW_REG(minor,destkey),SPW_PARAM(minor).destkey);
|
||||
}
|
||||
SPW_WRITE(
|
||||
&SPW_REG(minor,dma0ctrl),
|
||||
/*clear status, set ctrl for dma chan*/
|
||||
SPACEWIRE_DMACTRL_PS|SPACEWIRE_DMACTRL_PR|
|
||||
SPACEWIRE_DMACTRL_TA|SPACEWIRE_DMACTRL_RA
|
||||
);
|
||||
if ((dma0ctrl = SPW_READ(&SPW_REG(minor,dma0ctrl))) != 0) {
|
||||
printf("spacewire: error initializing dma ctrl (0x%x)\n",dma0ctrl);
|
||||
}
|
||||
|
||||
SPW_CTRL_WRITE(minor, SPACEWIRE_CTRL_RESET ); /*set ctrl*/
|
||||
SPW_CTRL_WRITE(minor,
|
||||
SPACEWIRE_CTRL_LINKSTART | (SPW_PARAM(minor).maxfreq << 5)); /*set ctrl*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spacewire_hw_waitlink (int minor) {
|
||||
int j;
|
||||
while (SPW_LINKSTATE(SPW_STATUS_READ(minor)) != 5) {
|
||||
rtems_task_wake_after(100);
|
||||
sched_yield();
|
||||
printf("timeout loop dev %i\n",minor);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
int spacewire_hw_startup (int minor) {
|
||||
int i,j;
|
||||
unsigned int dmactrl;
|
||||
SPW_STATUS_WRITE(minor,0xFF); /*clear status*/
|
||||
SPW_CTRL_WRITE(minor, SPACEWIRE_CTRL_RESET ); /*set ctrl*/
|
||||
SPW_CTRL_WRITE(minor,
|
||||
SPACEWIRE_CTRL_LINKSTART | (SPW_PARAM(minor).maxfreq << 5)); /*set ctrl*/
|
||||
sched_yield();
|
||||
j = 0; i = 0;
|
||||
spacewire_hw_waitlink(minor);
|
||||
|
||||
/* prepare transmit buffers */
|
||||
for (i = 0; i < SPW_PARAM(minor).txbufcnt;i++) {
|
||||
if (i+1 == SPW_PARAM(minor).txbufcnt) {
|
||||
SPW_PARAM(minor).tx[i].ctrl = 0|SPACEWIRE_TXBD_WR;
|
||||
} else {
|
||||
SPW_PARAM(minor).tx[i].ctrl = 0;
|
||||
}
|
||||
SPW_PARAM(minor).tx[i].addr_data =
|
||||
((unsigned int)&SPW_PARAM(minor).ptr_txbuf0[0]) +
|
||||
(i * SPW_PARAM(minor).txbufsize);
|
||||
}
|
||||
SPW_PARAM(minor).txcur = 0;
|
||||
|
||||
/* prepare receive buffers */
|
||||
for (i = 0; i < SPW_PARAM(minor).rxbufcnt;i++) {
|
||||
if (i+1 == SPW_PARAM(minor).rxbufcnt) {
|
||||
SPW_PARAM(minor).rx[i].ctrl = SPACEWIRE_RXBD_EN|SPACEWIRE_RXBD_WR;
|
||||
} else {
|
||||
SPW_PARAM(minor).rx[i].ctrl = SPACEWIRE_RXBD_EN;
|
||||
}
|
||||
SPW_PARAM(minor).rx[i].addr =
|
||||
((unsigned int)&SPW_PARAM(minor).ptr_rxbuf0[0]) +
|
||||
(i * SPW_PARAM(minor).rxbufsize);
|
||||
}
|
||||
SPW_PARAM(minor).rxcur = 0;
|
||||
SPW_PARAM(minor).rxbufcur = -1;
|
||||
spacewire_set_rxmaxlen(minor);
|
||||
|
||||
SPW_WRITE(&SPW_REG(minor,dma0txdesc),(unsigned int)SPW_PARAM(minor).tx);
|
||||
SPW_WRITE(&SPW_REG(minor,dma0rxdesc),(unsigned int)SPW_PARAM(minor).rx);
|
||||
|
||||
/* start RX */
|
||||
dmactrl = SPW_READ(&SPW_REG(minor,dma0ctrl));
|
||||
SPW_WRITE(&SPW_REG(minor,dma0ctrl),
|
||||
(dmactrl & SPACEWIRE_PREPAREMASK_RX) |
|
||||
SPACEWIRE_DMACTRL_RD | SPACEWIRE_DMACTRL_RXEN);
|
||||
|
||||
SPACEWIRE_DBGC(DBGSPW_TX,"0x%x: setup complete\n",SPW_PARAM(minor).regs);
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
int spacewire_hw_stop (int minor) {
|
||||
unsigned int dmactrl;
|
||||
|
||||
/* stop RX */
|
||||
dmactrl = SPW_READ(&SPW_REG(minor,dma0ctrl));
|
||||
SPW_WRITE(&SPW_REG(minor,dma0ctrl),
|
||||
(dmactrl & SPACEWIRE_PREPAREMASK_RX) &
|
||||
~(SPACEWIRE_DMACTRL_RD |SPACEWIRE_DMACTRL_RXEN));
|
||||
|
||||
/* stop link */
|
||||
SPW_CTRL_WRITE(minor,
|
||||
(SPW_CTRL_READ(minor) & 0x3FD) | SPACEWIRE_CTRL_LINKDISABLE);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
void spacewire_hw_send(int minor,unsigned char *b,int c) {
|
||||
|
||||
unsigned int dmactrl, ctrl;
|
||||
unsigned int cur = SPW_PARAM(minor).txcur;
|
||||
char *txb = SPW_PARAM(minor).ptr_txbuf0 + (cur * SPW_PARAM(minor).txbufsize);
|
||||
|
||||
sched_yield();
|
||||
memcpy(&txb[2],b,c);
|
||||
|
||||
txb[0] = SPW_PARAM(minor).destnodeaddr;
|
||||
txb[1] = SPW_PARAM(minor).proto;
|
||||
|
||||
#ifdef DEBUG_SPACEWIRE_ONOFF
|
||||
if (DEBUG_SPACEWIRE_FLAGS & DBGSPW_DUMP) {
|
||||
int k;
|
||||
for (k = 0;k < c+2;k++){
|
||||
if (k % 16 == 0) {
|
||||
printf ("\n");
|
||||
}
|
||||
printf ("%.2x(%c) ",txb[k] & 0xff,
|
||||
isprint(txb[k] & 0xff) ? txb[k] & 0xff : ' ');
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
do {
|
||||
SPW_PARAM(minor).tx[0].addr_header = 0;
|
||||
SPW_PARAM(minor).tx[0].len = c+2;
|
||||
SPW_PARAM(minor).tx[0].addr_data = (unsigned int)txb;
|
||||
SPW_PARAM(minor).tx[0].ctrl = SPACEWIRE_TXBD_WR|SPACEWIRE_TXBD_EN;
|
||||
|
||||
dmactrl = SPW_READ(&SPW_REG(minor,dma0ctrl));
|
||||
SPW_WRITE(&SPW_REG(minor,dma0ctrl),
|
||||
(dmactrl & SPACEWIRE_PREPAREMASK_TX) | SPACEWIRE_DMACTRL_TXEN);
|
||||
|
||||
while((ctrl = SPW_READ((volatile void *)&SPW_PARAM(minor).tx[0].ctrl)) &
|
||||
SPACEWIRE_TXBD_EN) {
|
||||
sched_yield();
|
||||
}
|
||||
if (ctrl & SPACEWIRE_TXBD_LE) {
|
||||
printf("tx error: SPACEWIRE_TXBD_LE, link error\n");
|
||||
}
|
||||
} while(ctrl & SPACEWIRE_TXBD_ERROR);
|
||||
|
||||
SPACEWIRE_DBGC(DBGSPW_TX,"0x%x: transmitted <%i> bytes\n",
|
||||
SPW_PARAM(minor).regs,c+2);
|
||||
}
|
||||
|
||||
int spacewire_hw_receive(int minor,unsigned char *b,int c) {
|
||||
unsigned int count = 0, len, rxlen, ctrl;
|
||||
unsigned int cur = SPW_PARAM(minor).rxcur;
|
||||
char *rxb = SPW_PARAM(minor).ptr_rxbuf0 + (cur * SPW_PARAM(minor).rxbufsize);
|
||||
|
||||
SPACEWIRE_DBGC(DBGSPW_RX,"0x%x: waitin packet at pos %i\n",
|
||||
SPW_PARAM(minor).regs,cur);
|
||||
|
||||
sched_yield();
|
||||
|
||||
while(1) {
|
||||
ctrl = SPW_READ((volatile void *)&SPW_PARAM(minor).rx[cur].ctrl);
|
||||
if (!(ctrl & SPACEWIRE_RXBD_EN)) {
|
||||
break;
|
||||
}
|
||||
if (SPW_LINKSTATE(SPW_STATUS_READ(minor)) != 5) {
|
||||
return 0;
|
||||
}
|
||||
sched_yield();
|
||||
}
|
||||
SPACEWIRE_DBGC(DBGSPW_RX,"checking packet\n",0);
|
||||
|
||||
len = SPACEWIRE_RXBD_LENGTH(ctrl);
|
||||
if (!(ctrl & (SPACEWIRE_RXBD_ERROR & ~SPACEWIRE_RXBD_RMAPERROR))) {
|
||||
|
||||
if (SPW_PARAM(minor).rxbufcur == -1) {
|
||||
SPACEWIRE_DBGC(DBGSPW_RX,"incoming packet len %i\n",len);
|
||||
SPW_PARAM(minor).rxbufcur = 2;
|
||||
}
|
||||
rxlen = len - SPW_PARAM(minor).rxbufcur;
|
||||
if (rxlen > c) {
|
||||
rxlen = c;
|
||||
}
|
||||
memcpy(b,rxb+SPW_PARAM(minor).rxbufcur,rxlen);
|
||||
count += rxlen;
|
||||
b += rxlen;
|
||||
c -= rxlen;
|
||||
SPW_PARAM(minor).rxbufcur += rxlen;
|
||||
} else {
|
||||
if (ctrl & SPACEWIRE_RXBD_EEP) {
|
||||
printf("rx error: SPACEWIRE_RXBD_EEP, error end of packet\n");
|
||||
}
|
||||
if (ctrl & SPACEWIRE_RXBD_EHC) {
|
||||
printf("rx error: SPACEWIRE_RXBD_EHC, header crc error\n");
|
||||
}
|
||||
if (ctrl & SPACEWIRE_RXBD_EDC) {
|
||||
printf("rx error: SPACEWIRE_RXBD_EDC, crc error\n");
|
||||
}
|
||||
if (ctrl & SPACEWIRE_RXBD_ETR) {
|
||||
printf("rx error: SPACEWIRE_RXBD_ETR, truncated\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (SPW_PARAM(minor).rxbufcur == len ||
|
||||
(ctrl & (SPACEWIRE_RXBD_ERROR & ~SPACEWIRE_RXBD_RMAPERROR))) {
|
||||
spacewire_rxnext(minor);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void spacewire_rxnext(int minor) {
|
||||
|
||||
unsigned int dmactrl;
|
||||
unsigned int cur = SPW_PARAM(minor).rxcur;
|
||||
unsigned int ctrl = SPW_READ((volatile void *)&SPW_PARAM(minor).rx[cur].ctrl);
|
||||
int cur2 = cur;
|
||||
cur++;
|
||||
if (cur >= SPACEWIRE_RXBUFS_NR) {
|
||||
cur = 0;
|
||||
ctrl |= SPACEWIRE_RXBD_WR;
|
||||
}
|
||||
SPW_PARAM(minor).rx[cur2].ctrl = ctrl | SPACEWIRE_RXBD_EN;
|
||||
|
||||
SPW_PARAM(minor).rxcur = cur;
|
||||
SPW_PARAM(minor).rxbufcur = -1;
|
||||
|
||||
/* start RX */
|
||||
dmactrl = SPW_READ(&SPW_REG(minor,dma0ctrl));
|
||||
SPW_WRITE(&SPW_REG(minor,dma0ctrl),
|
||||
(dmactrl & SPACEWIRE_PREPAREMASK_RX) | SPACEWIRE_DMACTRL_RD |
|
||||
SPACEWIRE_DMACTRL_RXEN);
|
||||
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
##
|
||||
|
||||
|
||||
include_HEADERS = amba.h bsp.h coverhd.h leon.h bspopts.h
|
||||
include_HEADERS = amba.h bsp.h coverhd.h leon.h bspopts.h spacewire.h
|
||||
|
||||
$(PROJECT_INCLUDE):
|
||||
$(mkinstalldirs) $@
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
#define LEON3_AHB_CONF_WORDS 8
|
||||
#define LEON3_APB_CONF_WORDS 2
|
||||
#define LEON3_AHB_MASTERS 8
|
||||
#define LEON3_AHB_SLAVES 8
|
||||
#define LEON3_AHB_MASTERS 64
|
||||
#define LEON3_AHB_SLAVES 64
|
||||
#define LEON3_APB_SLAVES 16
|
||||
#define LEON3_APBUARTS 8
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
#define GAISLER_PCITRACE 0x15
|
||||
#define GAISLER_DMACTRL 0x16
|
||||
#define GAISLER_PIOPORT 0x1A
|
||||
#define GAISLER_ETHMAC 0x1D
|
||||
|
||||
#define GAISLER_SPACEWIRE 0x01f
|
||||
|
||||
/* European Space Agency device id's */
|
||||
#define ESA_LEON2 0x2
|
||||
|
||||
@@ -44,6 +44,11 @@ extern "C" {
|
||||
#define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 2
|
||||
#define CONFIGURE_INTERRUPT_STACK_MEMORY (16 * 1024)
|
||||
|
||||
/* add a entry to the device driver table so that I can call rtems_io_register_driver */
|
||||
#define CONFIGURE_NUMBER_OF_DRIVERS_LEON3 \
|
||||
(((sizeof(Device_drivers) / sizeof(rtems_driver_address_table))) + 1)
|
||||
#define CONFIGURE_MAXIMUM_DRIVERS CONFIGURE_NUMBER_OF_DRIVERS_LEON3
|
||||
|
||||
/*
|
||||
* Network driver configuration
|
||||
*/
|
||||
@@ -57,10 +62,22 @@ extern int rtems_smc91111_driver_attach_leon3(
|
||||
struct rtems_bsdnet_ifconfig *config,
|
||||
int attach
|
||||
);
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_NAME "open_eth1"
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH_OPENETH rtems_leon_open_eth_driver_attach
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH_SMC91111 rtems_smc91111_driver_attach_leon3
|
||||
extern int rtems_leon_greth_driver_attach(
|
||||
struct rtems_bsdnet_ifconfig *config,
|
||||
int attach
|
||||
);
|
||||
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_NAME_OPENETH "open_eth1"
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH_OPENETH rtems_leon_open_eth_driver_attach
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_NAME_SMC91111 "smc_eth1"
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH_SMC91111 rtems_smc91111_driver_attach_leon3
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_NAME_GRETH "gr_eth1"
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH_GRETH rtems_leon_greth_driver_attach
|
||||
|
||||
#ifndef RTEMS_BSP_NETWORK_DRIVER_NAME
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_NAME RTEMS_BSP_NETWORK_DRIVER_NAME_GRETH
|
||||
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH RTEMS_BSP_NETWORK_DRIVER_ATTACH_GRETH
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define the time limits for RTEMS Test Suite test durations.
|
||||
|
||||
@@ -116,7 +116,7 @@ typedef struct {
|
||||
volatile unsigned int ipend;
|
||||
volatile unsigned int iforce;
|
||||
volatile unsigned int iclear;
|
||||
volatile unsigned int notused00;
|
||||
volatile unsigned int mpstat;
|
||||
volatile unsigned int notused01;
|
||||
volatile unsigned int notused02;
|
||||
volatile unsigned int notused03;
|
||||
@@ -128,65 +128,24 @@ typedef struct {
|
||||
volatile unsigned int notused21;
|
||||
volatile unsigned int notused22;
|
||||
volatile unsigned int notused23;
|
||||
volatile unsigned int mask_p0;
|
||||
volatile unsigned int mask_p1;
|
||||
volatile unsigned int mask_p2;
|
||||
volatile unsigned int mask_p3;
|
||||
volatile unsigned int mask_p4;
|
||||
volatile unsigned int mask_p5;
|
||||
volatile unsigned int mask_p6;
|
||||
volatile unsigned int mask_p7;
|
||||
volatile unsigned int mask_p8;
|
||||
volatile unsigned int mask_p9;
|
||||
volatile unsigned int mask_p10;
|
||||
volatile unsigned int mask_p11;
|
||||
volatile unsigned int mask_p12;
|
||||
volatile unsigned int mask_p13;
|
||||
volatile unsigned int mask_p14;
|
||||
volatile unsigned int mask_p15;
|
||||
volatile unsigned int mask[16];
|
||||
volatile unsigned int force[16];
|
||||
} LEON3_IrqCtrl_Regs_Map;
|
||||
|
||||
/*
|
||||
typedef struct {
|
||||
volatile unsigned int value;
|
||||
volatile unsigned int reload;
|
||||
volatile unsigned int conf;
|
||||
volatile unsigned int notused;
|
||||
} LEON3_Timer_SubType;
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned int scaler_value; /* common timer registers */
|
||||
volatile unsigned int scaler_reload;
|
||||
volatile unsigned int status;
|
||||
volatile unsigned int notused;
|
||||
volatile unsigned int value_t0; /* timer 0 */
|
||||
volatile unsigned int reload_t0;
|
||||
volatile unsigned int conf_t0;
|
||||
volatile unsigned int notused0;
|
||||
volatile unsigned int value_t1; /* timer 1 */
|
||||
volatile unsigned int reload_t1;
|
||||
volatile unsigned int conf_t1;
|
||||
volatile unsigned int notused1;
|
||||
volatile unsigned int value_t2; /* timer 2 */
|
||||
volatile unsigned int reload_t2;
|
||||
volatile unsigned int conf_t2;
|
||||
volatile unsigned int notused2;
|
||||
volatile unsigned int value_t3; /* timer 3 */
|
||||
volatile unsigned int reload_t3;
|
||||
volatile unsigned int conf_t3;
|
||||
volatile unsigned int notused3;
|
||||
volatile unsigned int value_t4; /* timer 4 */
|
||||
volatile unsigned int reload_t4;
|
||||
volatile unsigned int conf_t4;
|
||||
volatile unsigned int notused4;
|
||||
volatile unsigned int value_t5; /* timer 5 */
|
||||
volatile unsigned int reload_t5;
|
||||
volatile unsigned int conf_t5;
|
||||
volatile unsigned int notused5;
|
||||
volatile unsigned int value_t6; /* timer 6 */
|
||||
volatile unsigned int reload_t6;
|
||||
volatile unsigned int conf_t6;
|
||||
LEON3_Timer_SubType timer[8];
|
||||
} LEON3_Timer_Regs_Map;
|
||||
|
||||
typedef struct {
|
||||
@@ -295,6 +254,8 @@ extern volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs; /* LEON3 Interrupt
|
||||
extern volatile LEON3_Timer_Regs_Map *LEON3_Timer_Regs; /* LEON3 GP Timer */
|
||||
extern volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
|
||||
|
||||
extern int LEON3_Cpu_Index;
|
||||
|
||||
/* Macros used for manipulating bits in LEON3 GP Timer Control Register */
|
||||
|
||||
#define LEON3_GPTIMER_EN 1
|
||||
@@ -302,6 +263,8 @@ extern volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
|
||||
#define LEON3_GPTIMER_LD 4
|
||||
#define LEON3_GPTIMER_IRQEN 8
|
||||
|
||||
#define LEON3_MP_IRQ 14 /* Irq used by shared memory driver */
|
||||
|
||||
#ifndef ASM
|
||||
|
||||
/*
|
||||
@@ -328,23 +291,24 @@ extern volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
|
||||
(LEON3_IrqCtrl_Regs.ipend & (1 << (_source)))
|
||||
|
||||
#define LEON_Is_interrupt_masked( _source ) \
|
||||
(LEON3_IrqCtrl_Regs.mask_p0 & (1 << (_source)))
|
||||
do {\
|
||||
(LEON3_IrqCtrl_Regs.mask[LEON3_Cpu_Index] & (1 << (_source))); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define LEON_Mask_interrupt( _source ) \
|
||||
do { \
|
||||
unsigned32 _level; \
|
||||
\
|
||||
_level = sparc_disable_interrupts(); \
|
||||
LEON3_IrqCtrl_Regs->mask_p0 &= ~(1 << (_source)); \
|
||||
LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] &= ~(1 << (_source)); \
|
||||
sparc_enable_interrupts( _level ); \
|
||||
} while (0)
|
||||
|
||||
#define LEON_Unmask_interrupt( _source ) \
|
||||
do { \
|
||||
unsigned32 _level; \
|
||||
\
|
||||
_level = sparc_disable_interrupts(); \
|
||||
LEON3_IrqCtrl_Regs->mask_p0 |= (1 << (_source)); \
|
||||
LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] |= (1 << (_source)); \
|
||||
sparc_enable_interrupts( _level ); \
|
||||
} while (0)
|
||||
|
||||
@@ -352,10 +316,9 @@ extern volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
|
||||
do { \
|
||||
unsigned32 _level; \
|
||||
unsigned32 _mask = 1 << (_source); \
|
||||
\
|
||||
_level = sparc_disable_interrupts(); \
|
||||
(_previous) = LEON3_IrqCtrl_Regs->mask_p0; \
|
||||
LEON3_IrqCtrl_Regs->mask_p0 = _previous & ~_mask; \
|
||||
(_previous) = LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index]; \
|
||||
LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] = _previous & ~_mask; \
|
||||
sparc_enable_interrupts( _level ); \
|
||||
(_previous) &= _mask; \
|
||||
} while (0)
|
||||
@@ -364,13 +327,13 @@ extern volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
|
||||
do { \
|
||||
unsigned32 _level; \
|
||||
unsigned32 _mask = 1 << (_source); \
|
||||
\
|
||||
_level = sparc_disable_interrupts(); \
|
||||
LEON3_IrqCtrl_Regs->mask_p0 = \
|
||||
(LEON3_IrqCtrl_Regs->mask_p0 & ~_mask) | (_previous); \
|
||||
LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] = \
|
||||
(LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] & ~_mask) | (_previous); \
|
||||
sparc_enable_interrupts( _level ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Each timer control register is organized as follows:
|
||||
*
|
||||
@@ -402,6 +365,8 @@ extern volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
|
||||
#define LEON_REG_TIMER_COUNTER_DEFINED_MASK 0x00000003
|
||||
#define LEON_REG_TIMER_COUNTER_CURRENT_MODE_MASK 0x00000003
|
||||
|
||||
#include "spacewire.h"
|
||||
|
||||
#endif /* !ASM */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
186
c/src/lib/libbsp/sparc/leon3/include/spacewire.h
Normal file
186
c/src/lib/libbsp/sparc/leon3/include/spacewire.h
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Macros used for Spacewire bus
|
||||
*
|
||||
* COPYRIGHT (c) 2004.
|
||||
* Gaisler Research
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __SPACEWIRE_h
|
||||
#define __SPACEWIRE_h
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned int ctrl;
|
||||
volatile unsigned int status;
|
||||
volatile unsigned int nodeaddr;
|
||||
volatile unsigned int clockdiv;
|
||||
volatile unsigned int destkey;
|
||||
volatile unsigned int pad1,pad2,pad3;
|
||||
|
||||
volatile unsigned int dma0ctrl; /* 0x20 */
|
||||
volatile unsigned int dma0rxmax;
|
||||
volatile unsigned int dma0txdesc;
|
||||
volatile unsigned int dma0rxdesc;
|
||||
} LEON3_SPACEWIRE_Regs_Map;
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned int ctrl;
|
||||
volatile unsigned int addr;
|
||||
} SPACEWIRE_RXBD;
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned int ctrl;
|
||||
volatile unsigned int addr_header;
|
||||
volatile unsigned int len;
|
||||
volatile unsigned int addr_data;
|
||||
} SPACEWIRE_TXBD;
|
||||
|
||||
#define SPACEWIRE_BDTABLE_SIZE 0x400
|
||||
#define SPACEWIRE_TXPCK_SIZE 1024
|
||||
#define SPACEWIRE_RXPCK_SIZE 1024
|
||||
#define SPACEWIRE_TXBUFS_NR 1
|
||||
#define SPACEWIRE_RXBUFS_NR 2
|
||||
#define SPW_BUFMALLOC 1
|
||||
|
||||
#define SPW_ALIGN(p,c) ((((unsigned int)(p))+((c)-1))&~((c)-1))
|
||||
|
||||
int spacewire_setattibutes(int minor, int nodeaddr, int proto, int dest);
|
||||
|
||||
typedef struct {
|
||||
unsigned int nodeaddr;
|
||||
unsigned int destnodeaddr;
|
||||
unsigned int proto;
|
||||
unsigned int destkey;
|
||||
unsigned int maxfreq;
|
||||
unsigned int clkdiv;
|
||||
unsigned int rxmaxlen;
|
||||
|
||||
unsigned int is_rmap,is_rxunaligned,is_rmapcrc;
|
||||
|
||||
unsigned int txcur,rxcur,rxbufcur;
|
||||
unsigned int txbufsize,rxbufsize;
|
||||
unsigned int txbufcnt,rxbufcnt;
|
||||
char *ptr_rxbuf0,*ptr_txbuf0;
|
||||
unsigned int irq;
|
||||
|
||||
SPACEWIRE_RXBD *rx;
|
||||
SPACEWIRE_TXBD *tx;
|
||||
|
||||
char _rxtable[SPACEWIRE_BDTABLE_SIZE*2];
|
||||
char _txtable[SPACEWIRE_BDTABLE_SIZE*2];
|
||||
|
||||
#ifndef SPW_BUFMALLOC
|
||||
char _rxbuf0[SPACEWIRE_RXPCK_SIZE*SPACEWIRE_RXBUFS_NR];
|
||||
char _txbuf0[SPACEWIRE_TXPCK_SIZE*SPACEWIRE_TXBUFS_NR];
|
||||
#endif
|
||||
|
||||
volatile LEON3_SPACEWIRE_Regs_Map *regs;
|
||||
} SPACEWIRE_PARAM;
|
||||
|
||||
int _SPW_READ(void *addr);
|
||||
#define SPW_READ(addr) _SPW_READ((void *)(addr))
|
||||
#define SPW_WRITE(addr,v) *addr=v
|
||||
|
||||
#define SPACEWIRE_MAX_CORENR 2
|
||||
extern SPACEWIRE_PARAM LEON3_Spacewire[SPACEWIRE_MAX_CORENR];
|
||||
|
||||
#define SPW_PARAM(c) (LEON3_Spacewire[c])
|
||||
#define SPW_REG(c,r) (SPW_PARAM(c).regs->r)
|
||||
#define SPW_REG_CTRL(c) SPW_REG(c,ctrl)
|
||||
#define SPW_REG_STATUS(c) SPW_REG(c,status)
|
||||
#define SPW_REG_NODEADDR(c) SPW_REG(c,nodeaddr)
|
||||
|
||||
#define SPW_CTRL_READ(c) SPW_READ(&SPW_REG_CTRL(c))
|
||||
#define SPW_CTRL_WRITE(c,v) SPW_WRITE(&SPW_REG_CTRL(c),v)
|
||||
#define SPW_STATUS_READ(c) SPW_READ(&SPW_REG_STATUS(c))
|
||||
#define SPW_STATUS_WRITE(c,v) SPW_WRITE(&SPW_REG_STATUS(c),v)
|
||||
|
||||
#define SPW_LINKSTATE(c) (((c) >> 21) & 0x7)
|
||||
|
||||
#define SPW_NODEADDR_READ(c) SPW_BYPASSCACHE(&SPW_NODEADDR(c))
|
||||
#define SPW_NODEADDR_WRITE(c,v) SPW_NODEADDR(c) = v
|
||||
|
||||
#define SPACEWIRE_RXNR(c) ((c&~(SPACEWIRE_BDTABLE_SIZE-1))>>3)
|
||||
#define SPACEWIRE_TXNR(c) ((c&~(SPACEWIRE_BDTABLE_SIZE-1))>>4)
|
||||
|
||||
#define SPACEWIRE_RXBD_LENGTH 0x1ffffff
|
||||
#define SPACEWIRE_RXBD_EN (1<<25)
|
||||
#define SPACEWIRE_RXBD_WR (1<<26)
|
||||
#define SPACEWIRE_RXBD_IE (1<<27)
|
||||
|
||||
#define SPACEWIRE_RXBD_EEP (1<<28)
|
||||
#define SPACEWIRE_RXBD_EHC (1<<29)
|
||||
#define SPACEWIRE_RXBD_EDC (1<<30)
|
||||
#define SPACEWIRE_RXBD_ETR (1<<31)
|
||||
|
||||
#define SPACEWIRE_RXBD_ERROR (SPACEWIRE_RXBD_EEP | \
|
||||
SPACEWIRE_RXBD_EHC | \
|
||||
SPACEWIRE_RXBD_EDC | \
|
||||
SPACEWIRE_RXBD_ETR)
|
||||
|
||||
#define SPACEWIRE_RXBD_RMAPERROR (SPACEWIRE_RXBD_EHC | SPACEWIRE_RXBD_EDC)
|
||||
|
||||
#define SPACEWIRE_RXBD_LENGTH(c) ((c)&0xffffff)
|
||||
#define SPACEWIRE_PCKHEAD 2
|
||||
|
||||
#define SPACEWIRE_TXBD_LENGTH 0xffffff
|
||||
|
||||
#define SPACEWIRE_TXBD_EN (1<<12)
|
||||
#define SPACEWIRE_TXBD_WR (1<<13)
|
||||
#define SPACEWIRE_TXBD_IE (1<<14)
|
||||
|
||||
#define SPACEWIRE_TXBD_LE (1<<15)
|
||||
|
||||
#define SPACEWIRE_TXBD_ERROR (SPACEWIRE_TXBD_LE)
|
||||
|
||||
#define SPACEWIRE_CTRL_RA (1<<31)
|
||||
#define SPACEWIRE_CTRL_RX (1<<30)
|
||||
#define SPACEWIRE_CTRL_RC (1<<29)
|
||||
|
||||
#define SPACEWIRE_CTRL_RESET (1<<6)
|
||||
#define SPACEWIRE_CTRL_LINKSTART (1<<1)
|
||||
#define SPACEWIRE_CTRL_LINKDISABLE (1<<0)
|
||||
|
||||
#define SPACEWIRE_DMACTRL_TXEN (1<<0)
|
||||
#define SPACEWIRE_DMACTRL_RXEN (1<<1)
|
||||
#define SPACEWIRE_DMACTRL_TXIE (1<<2)
|
||||
#define SPACEWIRE_DMACTRL_RXIE (1<<3)
|
||||
|
||||
#define SPACEWIRE_DMACTRL_AI (1<<4)
|
||||
#define SPACEWIRE_DMACTRL_PS (1<<5)
|
||||
#define SPACEWIRE_DMACTRL_PR (1<<6)
|
||||
#define SPACEWIRE_DMACTRL_TA (1<<7)
|
||||
#define SPACEWIRE_DMACTRL_RA (1<<8)
|
||||
|
||||
#define SPACEWIRE_DMACTRL_RD (1<<11)
|
||||
#define SPACEWIRE_DMACTRL_NS (1<<12)
|
||||
|
||||
#define SPACEWIRE_PREPAREMASK_TX (SPACEWIRE_DMACTRL_RXEN | SPACEWIRE_DMACTRL_RXIE | SPACEWIRE_DMACTRL_PS | SPACEWIRE_DMACTRL_TA | SPACEWIRE_DMACTRL_RD)
|
||||
#define SPACEWIRE_PREPAREMASK_RX (SPACEWIRE_DMACTRL_TXEN | SPACEWIRE_DMACTRL_TXIE | SPACEWIRE_DMACTRL_AI | SPACEWIRE_DMACTRL_PR | SPACEWIRE_DMACTRL_RA)
|
||||
|
||||
|
||||
#define SPACEWIRE_IOCTRL_SET_NODEADDR 1
|
||||
#define SPACEWIRE_IOCTRL_SET_PROTOCOL 2
|
||||
#define SPACEWIRE_IOCTRL_SET_DESTNODEADDR 3
|
||||
#define SPACEWIRE_IOCTRL_GET_COREBASEADDR 4
|
||||
#define SPACEWIRE_IOCTRL_GET_COREIRQ 5
|
||||
#define SPACEWIRE_IOCTRL_SET_PACKETSIZE 6
|
||||
#define SPACEWIRE_IOCTRL_GETPACKET 7
|
||||
#define SPACEWIRE_IOCTRL_PUTPACKET 8
|
||||
|
||||
typedef struct {
|
||||
unsigned int txsize, rxsize;
|
||||
} spw_ioctl_packetsize;
|
||||
|
||||
typedef struct {
|
||||
char *buf;
|
||||
int buf_size;
|
||||
int ret_size;
|
||||
} spw_ioctl_packet;
|
||||
|
||||
#endif
|
||||
2
c/src/lib/libbsp/sparc/leon3/leon_greth/.cvsignore
Normal file
2
c/src/lib/libbsp/sparc/leon3/leon_greth/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
35
c/src/lib/libbsp/sparc/leon3/leon_greth/Makefile.am
Normal file
35
c/src/lib/libbsp/sparc/leon3/leon_greth/Makefile.am
Normal file
@@ -0,0 +1,35 @@
|
||||
##
|
||||
## Makefile.am,v 1.1.2.1 2005/10/05 19:26:00 joel Exp
|
||||
##
|
||||
|
||||
|
||||
PGM = $(ARCH)/leon_greth.rel
|
||||
|
||||
C_FILES = leon_greth.c
|
||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
||||
|
||||
OBJS = $(C_O_FILES)
|
||||
|
||||
include $(top_srcdir)/../../../../../../automake/compile.am
|
||||
include $(top_srcdir)/../../../../../../automake/lib.am
|
||||
|
||||
#
|
||||
# (OPTIONAL) Add local stuff here using +=
|
||||
#
|
||||
|
||||
AM_CPPFLAGS += -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
|
||||
|
||||
$(PGM): $(OBJS)
|
||||
$(make-rel)
|
||||
|
||||
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
|
||||
|
||||
if HAS_NETWORKING
|
||||
all-local: $(ARCH) $(OBJS) $(PGM)
|
||||
endif
|
||||
|
||||
.PRECIOUS: $(PGM)
|
||||
|
||||
EXTRA_DIST = leon_greth.c
|
||||
|
||||
include $(top_srcdir)/../../../../../../automake/local.am
|
||||
71
c/src/lib/libbsp/sparc/leon3/leon_greth/leon_greth.c
Normal file
71
c/src/lib/libbsp/sparc/leon3/leon_greth/leon_greth.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* LEON3 Opencores Ethernet MAC Configuration Information
|
||||
*
|
||||
* COPYRIGHT (c) 2004.
|
||||
* Gaisler Research
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* leon_open_eth.c,v 1.1.2.1 2005/10/05 19:26:00 joel Exp
|
||||
*/
|
||||
|
||||
|
||||
#include <bsp.h>
|
||||
#include <libchip/greth.h>
|
||||
/*#if (GRETH_DEBUG & GRETH_DEBUG_PRINT_REGISTERS)*/
|
||||
#include <stdio.h>
|
||||
/*#endif*/
|
||||
|
||||
/*
|
||||
* Default sizes of transmit and receive descriptor areas
|
||||
*/
|
||||
#define RDA_COUNT 32
|
||||
#define TDA_COUNT 32
|
||||
|
||||
greth_configuration_t leon_greth_configuration;
|
||||
|
||||
int rtems_leon_greth_driver_attach(
|
||||
struct rtems_bsdnet_ifconfig *config,
|
||||
int attach
|
||||
)
|
||||
{
|
||||
int device_found = 0;
|
||||
int i;
|
||||
unsigned int conf, iobar;
|
||||
unsigned int base_addr = 0; /* avoid warnings */
|
||||
unsigned int eth_irq = 0; /* avoid warnings */
|
||||
|
||||
/* Scan for MAC AHB slave interface */
|
||||
for (i = 0; i < amba_conf.apbslv.devnr; i++)
|
||||
{
|
||||
conf = amba_get_confword(amba_conf.apbslv, i, 0);
|
||||
if ((amba_vendor(conf) == VENDOR_GAISLER) &&
|
||||
(amba_device(conf) == GAISLER_ETHMAC))
|
||||
{
|
||||
iobar = amba_apb_get_membar(amba_conf.apbslv, i);
|
||||
base_addr = amba_iobar_start(amba_conf.apbmst, iobar);
|
||||
eth_irq = amba_irq(conf) + 0x10;
|
||||
device_found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (device_found)
|
||||
{
|
||||
/* clear control register and reset NIC */
|
||||
*(volatile int *) base_addr = 0;
|
||||
*(volatile int *) base_addr = GRETH_CTRL_RST;
|
||||
*(volatile int *) base_addr = 0;
|
||||
leon_greth_configuration.base_address = base_addr;
|
||||
leon_greth_configuration.vector = eth_irq;
|
||||
leon_greth_configuration.txd_count = TDA_COUNT;
|
||||
leon_greth_configuration.rxd_count = RDA_COUNT;
|
||||
if (rtems_greth_driver_attach( config, &leon_greth_configuration )) {
|
||||
LEON_Clear_interrupt(leon_greth_configuration.vector);
|
||||
LEON_Unmask_interrupt(leon_greth_configuration.vector);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -15,7 +15,7 @@ scmv91111_configuration_t leon_scmv91111_configuration = {
|
||||
SMC91111_BASE_ADDR, /* base address */
|
||||
LEON_TRAP_TYPE(SMC91111_BASE_IRQ), /* vector number */
|
||||
SMC91111_BASE_PIO, /* PIO */
|
||||
10, /* 10b */
|
||||
100, /* 100b */
|
||||
1, /* fulldx */
|
||||
1 /* autoneg */
|
||||
};
|
||||
@@ -37,7 +37,7 @@ int rtems_smc91111_driver_attach_leon3 (
|
||||
|
||||
{
|
||||
unsigned long irq_pio, irq_mctrl, addr_pio = 0;
|
||||
unsigned long addr_mctrl = 0, addr_timer = 0;
|
||||
unsigned long addr_mctrl = 0;
|
||||
|
||||
i = 0;
|
||||
while (i < amba_conf.apbslv.devnr)
|
||||
@@ -56,25 +56,14 @@ int rtems_smc91111_driver_attach_leon3 (
|
||||
irq_mctrl = amba_irq(conf);
|
||||
iobar = amba_apb_get_membar(amba_conf.apbslv, i);
|
||||
addr_mctrl = (unsigned long) amba_iobar_start(amba_conf.apbmst, iobar);
|
||||
}
|
||||
else if ((amba_vendor(conf) == VENDOR_GAISLER) &&
|
||||
(amba_device(conf) == GAISLER_GPTIMER))
|
||||
{
|
||||
iobar = amba_apb_get_membar(amba_conf.apbslv, i);
|
||||
addr_timer = (unsigned long) amba_iobar_start(amba_conf.apbmst, iobar);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (addr_timer) {
|
||||
LEON3_Timer_Regs_Map *timer = (LEON3_Timer_Regs_Map *)addr_timer;
|
||||
if (timer->scaler_reload >= 49)
|
||||
leon_scmv91111_configuration.ctl_rspeed = 100;
|
||||
}
|
||||
|
||||
if (addr_pio && addr_mctrl) {
|
||||
|
||||
LEON3_IOPORT_Regs_Map *io = (LEON3_IOPORT_Regs_Map *) addr_pio;
|
||||
/*
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
@@ -84,6 +73,7 @@ int rtems_smc91111_driver_attach_leon3 (
|
||||
(unsigned int)addr_mctrl);
|
||||
DEBUG_puts(buf);
|
||||
}
|
||||
*/
|
||||
|
||||
*((volatile unsigned int *)addr_mctrl) |= 0x10f80000; /*mctrl ctrl 1 */
|
||||
io->irqmask |= (1 << leon_scmv91111_configuration.pio);
|
||||
|
||||
2
c/src/lib/libbsp/sparc/leon3/shmsupp/.cvsignore
Normal file
2
c/src/lib/libbsp/sparc/leon3/shmsupp/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
32
c/src/lib/libbsp/sparc/leon3/shmsupp/Makefile.am
Normal file
32
c/src/lib/libbsp/sparc/leon3/shmsupp/Makefile.am
Normal file
@@ -0,0 +1,32 @@
|
||||
##
|
||||
## Makefile.am,v 1.4 2002/12/14 08:17:17 ralf Exp
|
||||
##
|
||||
|
||||
|
||||
PGM = $(ARCH)/shmsupp.rel
|
||||
|
||||
C_FILES = addrconv.c getcfg.c lock.c mpisr.c
|
||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
||||
|
||||
OBJS = $(C_O_FILES)
|
||||
|
||||
include $(top_srcdir)/../../../../../../automake/compile.am
|
||||
include $(top_srcdir)/../../../../../../automake/lib.am
|
||||
|
||||
#
|
||||
# (OPTIONAL) Add local stuff here using +=
|
||||
#
|
||||
|
||||
$(PGM): $(OBJS)
|
||||
$(make-rel)
|
||||
|
||||
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
|
||||
|
||||
if HAS_MP
|
||||
all-local: $(ARCH) $(OBJS) $(PGM)
|
||||
endif
|
||||
|
||||
.PRECIOUS: $(PGM)
|
||||
|
||||
EXTRA_DIST = addrconv.c getcfg.c lock.c mpisr.c
|
||||
include $(top_srcdir)/../../../../../../automake/local.am
|
||||
30
c/src/lib/libbsp/sparc/leon3/shmsupp/addrconv.c
Normal file
30
c/src/lib/libbsp/sparc/leon3/shmsupp/addrconv.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/* Shm_Convert_address
|
||||
*
|
||||
* No address range conversion is required.
|
||||
*
|
||||
* Input parameters:
|
||||
* address - address to convert
|
||||
*
|
||||
* Output parameters:
|
||||
* returns - converted address
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* addrconv.c,v 1.7.8.1 2003/09/04 18:44:55 joel Exp
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include <shm_driver.h>
|
||||
|
||||
void *Shm_Convert_address(
|
||||
void *address
|
||||
)
|
||||
{
|
||||
return ( address );
|
||||
}
|
||||
134
c/src/lib/libbsp/sparc/leon3/shmsupp/getcfg.c
Normal file
134
c/src/lib/libbsp/sparc/leon3/shmsupp/getcfg.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/* void Shm_Get_configuration( localnode, &shmcfg )
|
||||
*
|
||||
* This routine initializes, if necessary, and returns a pointer
|
||||
* to the Shared Memory Configuration Table for the XXX target.
|
||||
*
|
||||
* INPUT PARAMETERS:
|
||||
* localnode - local node number
|
||||
* shmcfg - address of pointer to SHM Config Table
|
||||
*
|
||||
* OUTPUT PARAMETERS:
|
||||
* *shmcfg - pointer to SHM Config Table
|
||||
*
|
||||
XXX: FIX THE COMMENTS BELOW WHEN THE CPU IS KNOWN
|
||||
* NOTES: The XYZ does not have an interprocessor interrupt.
|
||||
*
|
||||
* The following table illustrates the configuration limitations:
|
||||
*
|
||||
* BUS MAX
|
||||
* MODE ENDIAN NODES
|
||||
* ========= ====== =======
|
||||
* POLLED BIG 2+
|
||||
* INTERRUPT **** NOT SUPPORTED ****
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* getcfg.c,v 1.7.8.1 2003/09/04 18:44:56 joel Exp
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include <shm_driver.h>
|
||||
|
||||
/* multiprocessor communications interface (MPCI) table */
|
||||
|
||||
|
||||
extern rtems_mpci_entry Shm_Get_packet(
|
||||
rtems_packet_prefix **
|
||||
);
|
||||
|
||||
rtems_mpci_entry Shm_Initialization( void );
|
||||
|
||||
extern rtems_mpci_entry Shm_Receive_packet(
|
||||
rtems_packet_prefix **
|
||||
);
|
||||
|
||||
extern rtems_mpci_entry Shm_Return_packet(
|
||||
rtems_packet_prefix *
|
||||
);
|
||||
|
||||
extern rtems_mpci_entry Shm_Send_packet(
|
||||
rtems_unsigned32,
|
||||
rtems_packet_prefix *
|
||||
);
|
||||
|
||||
|
||||
/* rtems_mpci_table MPCI_table = { */
|
||||
/* 100000, /\* default timeout value in ticks *\/ */
|
||||
/* MAX_PACKET_SIZE, /\* maximum packet size *\/ */
|
||||
/* Shm_Initialization, /\* initialization procedure *\/ */
|
||||
/* Shm_Get_packet, /\* get packet procedure *\/ */
|
||||
/* Shm_Return_packet, /\* return packet procedure *\/ */
|
||||
/* Shm_Send_packet, /\* packet send procedure *\/ */
|
||||
/* Shm_Receive_packet /\* packet receive procedure *\/ */
|
||||
/* }; */
|
||||
|
||||
|
||||
/*
|
||||
* configured if currently polling of interrupt driven
|
||||
*/
|
||||
|
||||
#define INTERRUPT 0 /* XXX: */
|
||||
#define POLLING 1 /* XXX: fix me -- is polling ONLY!!! */
|
||||
|
||||
|
||||
shm_config_table BSP_shm_cfgtbl;
|
||||
|
||||
void Shm_Get_configuration(
|
||||
rtems_unsigned32 localnode,
|
||||
shm_config_table **shmcfg
|
||||
)
|
||||
{
|
||||
extern rtems_configuration_table Configuration;
|
||||
int i;
|
||||
unsigned int tmp, ncpu;
|
||||
|
||||
BSP_shm_cfgtbl.base = 0x40000000;
|
||||
BSP_shm_cfgtbl.length = 0x00001000;
|
||||
BSP_shm_cfgtbl.format = SHM_BIG;
|
||||
|
||||
/*
|
||||
* Override cause_intr or shm_isr if your target has
|
||||
* special requirements.
|
||||
*/
|
||||
|
||||
BSP_shm_cfgtbl.cause_intr = Shm_Cause_interrupt;
|
||||
|
||||
#ifdef NEUTRAL_BIG
|
||||
BSP_shm_cfgtbl.convert = NULL_CONVERT;
|
||||
#else
|
||||
BSP_shm_cfgtbl.convert = CPU_swap_u32;
|
||||
#endif
|
||||
|
||||
BSP_shm_cfgtbl.poll_intr = INTR_MODE;
|
||||
BSP_shm_cfgtbl.Intr.address = (vol_u32) &(LEON3_IrqCtrl_Regs->force[LEON3_Cpu_Index]);
|
||||
BSP_shm_cfgtbl.Intr.value = 1 << LEON3_MP_IRQ ;
|
||||
BSP_shm_cfgtbl.Intr.length = 4;
|
||||
|
||||
if (LEON3_Cpu_Index == 0)
|
||||
{
|
||||
tmp = 0; /* ncpu = (((LEON3_IrqCtrl_Regs->mpstat) >> 28) & 0xf) + 1; */
|
||||
for (i = 1; i < (Configuration.User_multiprocessing_table)->maximum_nodes+1; i++)
|
||||
tmp |= (1 << i);
|
||||
LEON3_IrqCtrl_Regs->mpstat = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
if ((Configuration.User_multiprocessing_table)->node == 1)
|
||||
{
|
||||
tmp = 0;
|
||||
for (i = 1; i < (Configuration.User_multiprocessing_table)->maximum_nodes; i++)
|
||||
{
|
||||
tmp = tmp | (1 << (LEON3_Cpu_Index + i));
|
||||
}
|
||||
LEON3_IrqCtrl_Regs->mpstat = tmp;
|
||||
}
|
||||
*/
|
||||
|
||||
*shmcfg = &BSP_shm_cfgtbl;
|
||||
}
|
||||
97
c/src/lib/libbsp/sparc/leon3/shmsupp/lock.c
Normal file
97
c/src/lib/libbsp/sparc/leon3/shmsupp/lock.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/* Shared Memory Lock Routines
|
||||
*
|
||||
* This shared memory locked queue support routine need to be
|
||||
* able to lock the specified locked queue. Interrupts are
|
||||
* disabled while the queue is locked to prevent preemption
|
||||
* and deadlock when two tasks poll for the same lock.
|
||||
* previous level.
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* lock.c,v 1.9.4.1 2003/09/04 18:44:56 joel Exp
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include <shm_driver.h>
|
||||
|
||||
|
||||
/*
|
||||
* Shm_Initialize_lock
|
||||
*
|
||||
* Initialize the lock for the specified locked queue.
|
||||
*/
|
||||
|
||||
void Shm_Initialize_lock(
|
||||
Shm_Locked_queue_Control *lq_cb
|
||||
)
|
||||
{
|
||||
lq_cb->lock = LQ_UNLOCKED;
|
||||
}
|
||||
|
||||
/* void _Shm_Lock( &lq_cb )
|
||||
*
|
||||
* This shared memory locked queue support routine locks the
|
||||
* specified locked queue. It disables interrupts to prevent
|
||||
* a deadlock condition.
|
||||
*/
|
||||
|
||||
asm(
|
||||
".text\n"
|
||||
".align 4\n"
|
||||
"LEON3_Atomic_Swap:\n"
|
||||
" retl\n"
|
||||
" swapa [%o1] 1, %o0\n"
|
||||
);
|
||||
|
||||
|
||||
|
||||
void Shm_Lock(
|
||||
Shm_Locked_queue_Control *lq_cb
|
||||
)
|
||||
{
|
||||
rtems_unsigned32 isr_level;
|
||||
rtems_unsigned32 *lockptr = (rtems_unsigned32 *) &lq_cb->lock;
|
||||
rtems_unsigned32 lock_value;
|
||||
|
||||
lock_value = SHM_LOCK_VALUE;
|
||||
rtems_interrupt_disable( isr_level );
|
||||
|
||||
Shm_isrstat = isr_level;
|
||||
while ( lock_value ) {
|
||||
lock_value = LEON3_Atomic_Swap(lock_value, lockptr);
|
||||
/* asm volatile( "" */
|
||||
/* : "=r" (lockptr), "=r" (lock_value) */
|
||||
/* : "0" (lockptr), "1" (lock_value) */
|
||||
/* ); */
|
||||
/*
|
||||
* If not available, then may want to delay to reduce load on lock.
|
||||
*/
|
||||
|
||||
/* if ( lock_value ) */
|
||||
/* rtems_bsp_delay( 10 ); /\* approximately 10 microseconds *\/ */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Shm_Unlock
|
||||
*
|
||||
* Unlock the lock for the specified locked queue.
|
||||
*/
|
||||
|
||||
void Shm_Unlock(
|
||||
Shm_Locked_queue_Control *lq_cb
|
||||
)
|
||||
{
|
||||
rtems_unsigned32 isr_level;
|
||||
|
||||
lq_cb->lock = SHM_UNLOCK_VALUE;
|
||||
isr_level = Shm_isrstat;
|
||||
rtems_interrupt_enable( isr_level );
|
||||
}
|
||||
|
||||
48
c/src/lib/libbsp/sparc/leon3/shmsupp/mpisr.c
Normal file
48
c/src/lib/libbsp/sparc/leon3/shmsupp/mpisr.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/* Shm_isr_nobsp()
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* mpisr.c,v 1.7.8.1 2003/09/04 18:44:56 joel Exp
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include <shm_driver.h>
|
||||
|
||||
rtems_isr Shm_isr_nobsp( void )
|
||||
{
|
||||
/*
|
||||
* If this routine has to do anything other than the mpisr.c
|
||||
* found in the generic driver, then copy the contents of the generic
|
||||
* mpisr.c and augment it to satisfy this particular board. Typically,
|
||||
* you need to have a board specific mpisr.c when the interrupt
|
||||
* must be cleared.
|
||||
*
|
||||
* If the generic mpisr.c satisifies your requirements, then
|
||||
* remove this routine from your target's shmsupp/mpisb.c file.
|
||||
* Then simply install the generic Shm_isr in the Shm_setvec
|
||||
* routine below.
|
||||
*/
|
||||
}
|
||||
|
||||
/* Shm_setvec
|
||||
*
|
||||
* This driver routine sets the SHM interrupt vector to point to the
|
||||
* driver's SHM interrupt service routine.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*/
|
||||
|
||||
|
||||
void Shm_setvec( void )
|
||||
{
|
||||
LEON_Unmask_interrupt(LEON3_MP_IRQ);
|
||||
set_vector(Shm_isr, LEON_TRAP_TYPE(LEON3_MP_IRQ), 1);
|
||||
}
|
||||
@@ -22,6 +22,13 @@
|
||||
|
||||
#include <bsp.h>
|
||||
|
||||
extern rtems_configuration_table Configuration;
|
||||
|
||||
#define LEON3_TIMER_INDEX \
|
||||
(Configuration.User_multiprocessing_table ? \
|
||||
(Configuration.User_multiprocessing_table)->maximum_nodes + \
|
||||
(Configuration.User_multiprocessing_table)->node - 1 : 1)
|
||||
|
||||
rtems_boolean Timer_driver_Find_average_overhead;
|
||||
|
||||
rtems_boolean Timer_driver_Is_initialized = FALSE;
|
||||
@@ -36,12 +43,12 @@ void Timer_initialize()
|
||||
if (LEON3_Timer_Regs) {
|
||||
if ( Timer_driver_Is_initialized == FALSE ) {
|
||||
/* approximately 1 us per countdown */
|
||||
LEON3_Timer_Regs->reload_t1 = 0xffffff;
|
||||
LEON3_Timer_Regs->value_t1 = 0xffffff;
|
||||
LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].reload = 0xffffff;
|
||||
LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].value = 0xffffff;
|
||||
} else {
|
||||
Timer_driver_Is_initialized = TRUE;
|
||||
}
|
||||
LEON3_Timer_Regs->conf_t1 = LEON3_GPTIMER_EN | LEON3_GPTIMER_LD;
|
||||
LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].conf = LEON3_GPTIMER_EN | LEON3_GPTIMER_LD;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +61,7 @@ int Read_timer()
|
||||
rtems_unsigned32 total;
|
||||
|
||||
if (LEON3_Timer_Regs) {
|
||||
total = LEON3_Timer_Regs->value_t1;
|
||||
total = LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].value;
|
||||
|
||||
total = 0xffffff - total;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
ACLOCAL_AMFLAGS = -I ../../../../../../../aclocal
|
||||
|
||||
transform =
|
||||
bsptools_bindir = ${exec_prefix}/@RTEMS_BSP@/tests
|
||||
bsptools_bindir = $(PROJECT_ROOT)/@RTEMS_BSP@/tests
|
||||
bsptools_bin_SCRIPTS = runtest
|
||||
|
||||
TMPINSTALL_FILES = $(bsptools_bindir) $(bsptools_bindir)/runtest
|
||||
|
||||
@@ -4,16 +4,29 @@
|
||||
|
||||
# We only build the networking device driver if HAS_NETWORKING was defined
|
||||
if HAS_NETWORKING
|
||||
NETWORKING_DRIVER = leon_open_eth leon_smc91111
|
||||
NETWORKING_DRIVER = leon_open_eth leon_smc91111 leon_greth
|
||||
endif
|
||||
|
||||
BSP_PIECES = startup amba console clock timer gnatsupp $(NETWORKING_DRIVER)
|
||||
if HAS_MP
|
||||
GENERIC_MP_REL_FILES = shmdr
|
||||
endif
|
||||
GENERIC_FILES = $(GENERIC_MP_REL_FILES)
|
||||
|
||||
|
||||
if HAS_MP
|
||||
BSP_MP_O_FILES = shmsupp
|
||||
endif
|
||||
BSP_PIECES = startup amba console clock $(BSP_MP_O_FILES) timer \
|
||||
gnatsupp $(NETWORKING_DRIVER)
|
||||
# pieces to pick up out of libcpu/sparc
|
||||
CPU_PIECES = cache reg_win syscall
|
||||
|
||||
# bummer; have to use $foreach since % pattern subst rules only replace 1x
|
||||
OBJS = $(foreach piece, $(BSP_PIECES), $(wildcard ../$(piece)/$(ARCH)/*.$(OBJEXT))) \
|
||||
$(foreach piece, $(CPU_PIECES), ../../../../libcpu/$(RTEMS_CPU)/$(piece)/$(ARCH)/*.$(OBJEXT))
|
||||
OBJS = \
|
||||
$(foreach piece, $(BSP_PIECES), $(wildcard ../$(piece)/$(ARCH)/*.$(OBJEXT))) \
|
||||
$(foreach piece, $(GENERIC_FILES), ../../../$(piece)/$(ARCH)/$(piece).rel) \
|
||||
$(foreach piece, $(CPU_PIECES), \
|
||||
../../../../libcpu/$(RTEMS_CPU)/$(piece)/$(ARCH)/*.$(OBJEXT))
|
||||
LIB = $(ARCH)/libbsp.a
|
||||
|
||||
include $(top_srcdir)/../../../../../../automake/compile.am
|
||||
@@ -29,3 +42,5 @@ $(LIB): $(OBJS)
|
||||
all-local: $(ARCH) $(LIB)
|
||||
|
||||
include $(top_srcdir)/../../../../../../automake/local.am
|
||||
|
||||
../../../shmdr/o-optimize/shmdr.rel:
|
||||
|
||||
Reference in New Issue
Block a user