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:
Joel Sherrill
2006-04-24 16:58:41 +00:00
parent 4f5a5985a9
commit cadb5d1641
32 changed files with 1709 additions and 144 deletions

View File

@@ -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> 2005-10-05 Jiri Gaisler <jiri@gaisler.com>
Edvin Catovic <edvin@gaisler.com> Edvin Catovic <edvin@gaisler.com>
Konrad Eisele <konrad@gaisler.com> Konrad Eisele <konrad@gaisler.com>

View File

@@ -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); 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_NAME "open_eth1"
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH_OPENETH rtems_leon_open_eth_driver_attach #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 #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. * Define the time limits for RTEMS Test Suite test durations.
* Long test and short test duration limits are provided. These * Long test and short test duration limits are provided. These

View File

@@ -33,7 +33,7 @@ scmv91111_configuration_t leon_scmv91111_configuration = {
SMC91111_BASE_ADDR, /* base address */ SMC91111_BASE_ADDR, /* base address */
SMC91111_BASE_IRQ, /* vector number */ SMC91111_BASE_IRQ, /* vector number */
SMC91111_BASE_PIO, /* PIO */ SMC91111_BASE_PIO, /* PIO */
10, /* 10b */ 100, /* 100b */
1, /* fulldx */ 1, /* fulldx */
1 /* autoneg */ 1 /* autoneg */
}; };
@@ -49,16 +49,13 @@ int _rtems_smc91111_driver_attach(
int rtems_smc91111_driver_attach_leon2(struct rtems_bsdnet_ifconfig *config) 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 */ /* activate io area */
DEBUG_puts("Activating Leon2 io port\n");
/*configure pio */ /*configure pio */
*((volatile unsigned int *)0x80000000) |= 0x10f80000; *((volatile unsigned int *)0x80000000) |= 0x10f80000;
*((volatile unsigned int *)0x800000A8) |= *((volatile unsigned int *)0x800000A8) |=
(0xe0 | leon_scmv91111_configuration.vector) (0xe0 | leon_scmv91111_configuration.pio)
<< (8 * (leon_scmv91111_configuration.pio - 4)); << (8 * ((leon_scmv91111_configuration.vector & 0x0f) - 4));
return _rtems_smc91111_driver_attach(config,&leon_scmv91111_configuration); return _rtems_smc91111_driver_attach(config,&leon_scmv91111_configuration);

View File

@@ -5,16 +5,15 @@
ACLOCAL_AMFLAGS = -I ../../../../../../../aclocal ACLOCAL_AMFLAGS = -I ../../../../../../../aclocal
transform = transform =
bsptools_bindir = ${exec_prefix}/@RTEMS_BSP@/tests bsptools_bindir = $(PROJECT_ROOT)/@RTEMS_BSP@/tests
bsptools_bin_SCRIPTS = runtest bsptools_bin_SCRIPTS = runtest
TMPINSTALL_FILES = $(PROJECT_ROOT)/@RTEMS_BSP@/tests \ TMPINSTALL_FILES = $(bsptools_bindir) $(bsptools_bindir)/runtest
$(PROJECT_ROOT)/@RTEMS_BSP@/tests/runtest
$(PROJECT_ROOT)/@RTEMS_BSP@: $(bsptools_bindir):
$(mkinstalldirs) $@ $(mkinstalldirs) $@
$(PROJECT_ROOT)/@RTEMS_BSP@/runtest: runtest $(bsptools_bindir)/runtest: runtest
$(INSTALL_SCRIPT) $< $@ $(INSTALL_SCRIPT) $< $@
all-local: $(TMPINSTALL_FILES) all-local: $(TMPINSTALL_FILES)

View File

@@ -6,8 +6,11 @@ ACLOCAL_AMFLAGS = -I ../../../../../../aclocal
# wrapup is the one that actually builds and installs the library # wrapup is the one that actually builds and installs the library
# from the individual .rel files built in other directories # from the individual .rel files built in other directories
SHMSUPP_DIR = shmsupp
SUBDIRS = . include start startup gnatsupp amba console clock timer \ 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 include $(top_srcdir)/../../bsp.am

View File

@@ -13,7 +13,7 @@
* $Id$ * $Id$
*/ */
#include <leon.h> #include <bsp.h>
#define amba_insert_device(tab, address) \ #define amba_insert_device(tab, address) \
{ \ { \
@@ -31,6 +31,9 @@ amba_confarea_type amba_conf;
/* Pointers to Interrupt Controller configuration registers */ /* Pointers to Interrupt Controller configuration registers */
volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs; volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs;
int LEON3_Cpu_Index = 0;
static int apb_init = 0;
/* /*
* bsp_leon3_predriver_hook * bsp_leon3_predriver_hook
* *
@@ -41,12 +44,23 @@ volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs;
* amba_ahb_masters, amba_ahb_slaves and amba. * 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) void bsp_leon3_predriver_hook(void)
{ {
unsigned int *cfg_area; /* address to configuration area */ unsigned int *cfg_area; /* address to configuration area */
unsigned int mbar, iobar, conf; unsigned int mbar, iobar, conf;
int i, j; int i, j;
unsigned int tmp;
amba_conf.ahbmst.devnr = 0; amba_conf.ahbslv.devnr = 0; amba_conf.apbslv.devnr = 0; 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); 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); conf = amba_get_confword(amba_conf.ahbslv, i, 0);
mbar = amba_ahb_get_membar(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); amba_conf.apbmst = amba_membar_start(mbar);
cfg_area = (unsigned int *) (amba_conf.apbmst | LEON3_CONF_AREA); 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); amba_insert_device(&amba_conf.apbslv, cfg_area);
cfg_area += LEON3_APB_CONF_WORDS; 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); iobar = amba_apb_get_membar(amba_conf.apbslv, i);
LEON3_IrqCtrl_Regs = (volatile LEON3_IrqCtrl_Regs_Map *) amba_iobar_start(amba_conf.apbmst, iobar); 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; break;
} }
i++; i++;

View File

@@ -30,6 +30,10 @@
* The Real Time Clock Counter Timer uses this trap type. * 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 ) #define CLOCK_VECTOR LEON_TRAP_TYPE( LEON_INTERRUPT_TIMER1 )
/* /*
@@ -145,12 +149,18 @@ void Install_clock(
clkirq = (LEON3_Timer_Regs->status & 0xfc) >> 3; clkirq = (LEON3_Timer_Regs->status & 0xfc) >> 3;
/* MP */
if (Configuration.User_multiprocessing_table != NULL)
{
clkirq += LEON3_Cpu_Index;
}
if ( BSP_Configuration.ticks_per_timeslice ) { if ( BSP_Configuration.ticks_per_timeslice ) {
Old_ticker = (rtems_isr_entry) set_vector( clock_isr, LEON_TRAP_TYPE(clkirq), 1 ); 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 ); atexit( Clock_exit );
} }
@@ -176,7 +186,7 @@ void Clock_exit( void )
if ( BSP_Configuration.ticks_per_timeslice ) { if ( BSP_Configuration.ticks_per_timeslice ) {
LEON_Mask_interrupt(LEON_TRAP_TYPE(clkirq)); 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 */ /* do not restore old vector */
} }

View File

@@ -17,6 +17,7 @@ RTEMS_CANONICALIZE_TOOLS
RTEMS_CHECK_NETWORKING RTEMS_CHECK_NETWORKING
AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes") AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
AM_CONDITIONAL(HAS_MP,test "$HAS_MP" = "yes")
RTEMS_CONFIG_BUILD_SUBDIRS(tools) RTEMS_CONFIG_BUILD_SUBDIRS(tools)
@@ -41,10 +42,12 @@ AC_CONFIG_FILES([Makefile
amba/Makefile amba/Makefile
clock/Makefile clock/Makefile
console/Makefile console/Makefile
leon_greth/Makefile
leon_open_eth/Makefile leon_open_eth/Makefile
leon_smc91111/Makefile leon_smc91111/Makefile
gnatsupp/Makefile gnatsupp/Makefile
include/Makefile include/Makefile
shmsupp/Makefile
start/Makefile start/Makefile
startup/Makefile startup/Makefile
timer/Makefile timer/Makefile

View File

@@ -5,7 +5,7 @@
PGM = $(ARCH)/console.rel 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)) C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
OBJS = $(C_O_FILES) OBJS = $(C_O_FILES)

View File

@@ -85,8 +85,29 @@ int console_write_support (int minor, const char *buf, int len)
* Console Device Driver Entry Points * 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;
}
volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
rtems_device_driver console_initialize( rtems_device_driver console_initialize(
rtems_device_major_number major, rtems_device_major_number major,
@@ -95,52 +116,48 @@ rtems_device_driver console_initialize(
) )
{ {
rtems_status_code status; rtems_status_code status;
unsigned int iobar, conf; int i;
int i, uarts;
char *console_name = "/dev/console_a"; char *console_name = "/dev/console_a";
extern rtems_configuration_table Configuration;
int uart0;
rtems_termios_initialize(); rtems_termios_initialize();
/* Find UARTs */ /* 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 */ /* Register Device Names */
if (uarts) if (uarts && (uart0 < uarts))
{ {
status = rtems_io_register_name( "/dev/console", major, 0 ); status = rtems_io_register_name( "/dev/console", major, 0 );
if (status != RTEMS_SUCCESSFUL) if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred(status); rtems_fatal_error_occurred(status);
for (i = 1; i < uarts; i++) for (i = uart0+1; i < uarts; i++)
{ {
console_name[13]++; console_name[13]++;
status = rtems_io_register_name( console_name, major, i); status = rtems_io_register_name( console_name, major, i);
} }
} }
/* /*
* Initialize Hardware * Initialize Hardware
*/ */
for (i = 0; i < uarts; i++) if ((Configuration.User_multiprocessing_table == NULL) ||
((Configuration.User_multiprocessing_table)->node == 1))
{ {
LEON3_Console_Uart[i]->ctrl |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE; for (i = uart0; i < uarts; i++)
LEON3_Console_Uart[i]->status = 0; {
LEON3_Console_Uart[i]->ctrl |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE;
LEON3_Console_Uart[i]->status = 0;
}
} }
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;

View 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;
}

View File

@@ -35,8 +35,8 @@ void console_outbyte_polled(
{ {
if ((port >= 0) && (port <= CONFIGURE_NUMBER_OF_TERMIOS_PORTS)) if ((port >= 0) && (port <= CONFIGURE_NUMBER_OF_TERMIOS_PORTS))
{ {
while ( (LEON3_Console_Uart[port]->status & LEON_REG_UART_STATUS_THE) == 0 ); while ( (LEON3_Console_Uart[LEON3_Cpu_Index+port]->status & LEON_REG_UART_STATUS_THE) == 0 );
LEON3_Console_Uart[port]->data = (unsigned int) ch; 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 ((port >=0) && (port < CONFIGURE_NUMBER_OF_TERMIOS_PORTS))
{ {
if (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[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 -1;
return (int) LEON3_Console_Uart[port]->data; return (int) LEON3_Console_Uart[LEON3_Cpu_Index+port]->data;
} }
else else
@@ -90,15 +90,15 @@ void DEBUG_puts(
{ {
char *s; char *s;
/* unsigned32 old_level; */ /* unsigned32 old_level; */
/* LEON_Disable_interrupt( LEON_INTERRUPT_UART_1_RX_TX, old_level ); */ /* LEON_Disable_interrupt( LEON_INTERRUPT_UART_1_RX_TX, old_level ); */
sparc_disable_interrupts(); sparc_disable_interrupts();
LEON3_Console_Uart[0]->ctrl = LEON_REG_UART_CTRL_TE; LEON3_Console_Uart[0]->ctrl = LEON_REG_UART_CTRL_TE;
for ( s = string ; *s ; s++ ) for ( s = string ; *s ; s++ )
console_outbyte_polled( 0, *s ); console_outbyte_polled( 0, *s );
console_outbyte_polled( 0, '\r' ); console_outbyte_polled( 0, '\r' );
console_outbyte_polled( 0, '\n' ); console_outbyte_polled( 0, '\n' );
sparc_enable_interrupts(); sparc_enable_interrupts();
/* LEON_Restore_interrupt( LEON_INTERRUPT_UART_1_RX_TX, old_level ); */ /* LEON_Restore_interrupt( LEON_INTERRUPT_UART_1_RX_TX, old_level ); */
} }

View 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);
}

View File

@@ -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): $(PROJECT_INCLUDE):
$(mkinstalldirs) $@ $(mkinstalldirs) $@

View File

@@ -19,8 +19,8 @@
#define LEON3_AHB_CONF_WORDS 8 #define LEON3_AHB_CONF_WORDS 8
#define LEON3_APB_CONF_WORDS 2 #define LEON3_APB_CONF_WORDS 2
#define LEON3_AHB_MASTERS 8 #define LEON3_AHB_MASTERS 64
#define LEON3_AHB_SLAVES 8 #define LEON3_AHB_SLAVES 64
#define LEON3_APB_SLAVES 16 #define LEON3_APB_SLAVES 16
#define LEON3_APBUARTS 8 #define LEON3_APBUARTS 8
@@ -48,6 +48,9 @@
#define GAISLER_PCITRACE 0x15 #define GAISLER_PCITRACE 0x15
#define GAISLER_DMACTRL 0x16 #define GAISLER_DMACTRL 0x16
#define GAISLER_PIOPORT 0x1A #define GAISLER_PIOPORT 0x1A
#define GAISLER_ETHMAC 0x1D
#define GAISLER_SPACEWIRE 0x01f
/* European Space Agency device id's */ /* European Space Agency device id's */
#define ESA_LEON2 0x2 #define ESA_LEON2 0x2

View File

@@ -44,6 +44,11 @@ extern "C" {
#define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 2 #define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 2
#define CONFIGURE_INTERRUPT_STACK_MEMORY (16 * 1024) #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 * Network driver configuration
*/ */
@@ -57,10 +62,22 @@ extern int rtems_smc91111_driver_attach_leon3(
struct rtems_bsdnet_ifconfig *config, struct rtems_bsdnet_ifconfig *config,
int attach int attach
); );
#define RTEMS_BSP_NETWORK_DRIVER_NAME "open_eth1" extern int rtems_leon_greth_driver_attach(
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH_OPENETH rtems_leon_open_eth_driver_attach struct rtems_bsdnet_ifconfig *config,
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH_SMC91111 rtems_smc91111_driver_attach_leon3 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. * Define the time limits for RTEMS Test Suite test durations.

View File

@@ -116,7 +116,7 @@ typedef struct {
volatile unsigned int ipend; volatile unsigned int ipend;
volatile unsigned int iforce; volatile unsigned int iforce;
volatile unsigned int iclear; volatile unsigned int iclear;
volatile unsigned int notused00; volatile unsigned int mpstat;
volatile unsigned int notused01; volatile unsigned int notused01;
volatile unsigned int notused02; volatile unsigned int notused02;
volatile unsigned int notused03; volatile unsigned int notused03;
@@ -128,65 +128,24 @@ typedef struct {
volatile unsigned int notused21; volatile unsigned int notused21;
volatile unsigned int notused22; volatile unsigned int notused22;
volatile unsigned int notused23; volatile unsigned int notused23;
volatile unsigned int mask_p0; volatile unsigned int mask[16];
volatile unsigned int mask_p1; volatile unsigned int force[16];
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;
} LEON3_IrqCtrl_Regs_Map; } LEON3_IrqCtrl_Regs_Map;
/*
typedef struct { typedef struct {
volatile unsigned int value; volatile unsigned int value;
volatile unsigned int reload; volatile unsigned int reload;
volatile unsigned int conf; volatile unsigned int conf;
volatile unsigned int notused; volatile unsigned int notused;
} LEON3_Timer_SubType; } LEON3_Timer_SubType;
*/
typedef struct { typedef struct {
volatile unsigned int scaler_value; /* common timer registers */ volatile unsigned int scaler_value; /* common timer registers */
volatile unsigned int scaler_reload; volatile unsigned int scaler_reload;
volatile unsigned int status; volatile unsigned int status;
volatile unsigned int notused; volatile unsigned int notused;
volatile unsigned int value_t0; /* timer 0 */ LEON3_Timer_SubType timer[8];
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_Regs_Map; } LEON3_Timer_Regs_Map;
typedef struct { 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_Timer_Regs_Map *LEON3_Timer_Regs; /* LEON3 GP Timer */
extern volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS]; 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 */ /* Macros used for manipulating bits in LEON3 GP Timer Control Register */
#define LEON3_GPTIMER_EN 1 #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_LD 4
#define LEON3_GPTIMER_IRQEN 8 #define LEON3_GPTIMER_IRQEN 8
#define LEON3_MP_IRQ 14 /* Irq used by shared memory driver */
#ifndef ASM #ifndef ASM
/* /*
@@ -328,23 +291,24 @@ extern volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
(LEON3_IrqCtrl_Regs.ipend & (1 << (_source))) (LEON3_IrqCtrl_Regs.ipend & (1 << (_source)))
#define LEON_Is_interrupt_masked( _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 ) \ #define LEON_Mask_interrupt( _source ) \
do { \ do { \
unsigned32 _level; \ unsigned32 _level; \
\
_level = sparc_disable_interrupts(); \ _level = sparc_disable_interrupts(); \
LEON3_IrqCtrl_Regs->mask_p0 &= ~(1 << (_source)); \ LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] &= ~(1 << (_source)); \
sparc_enable_interrupts( _level ); \ sparc_enable_interrupts( _level ); \
} while (0) } while (0)
#define LEON_Unmask_interrupt( _source ) \ #define LEON_Unmask_interrupt( _source ) \
do { \ do { \
unsigned32 _level; \ unsigned32 _level; \
\
_level = sparc_disable_interrupts(); \ _level = sparc_disable_interrupts(); \
LEON3_IrqCtrl_Regs->mask_p0 |= (1 << (_source)); \ LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] |= (1 << (_source)); \
sparc_enable_interrupts( _level ); \ sparc_enable_interrupts( _level ); \
} while (0) } while (0)
@@ -352,10 +316,9 @@ extern volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
do { \ do { \
unsigned32 _level; \ unsigned32 _level; \
unsigned32 _mask = 1 << (_source); \ unsigned32 _mask = 1 << (_source); \
\
_level = sparc_disable_interrupts(); \ _level = sparc_disable_interrupts(); \
(_previous) = LEON3_IrqCtrl_Regs->mask_p0; \ (_previous) = LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index]; \
LEON3_IrqCtrl_Regs->mask_p0 = _previous & ~_mask; \ LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] = _previous & ~_mask; \
sparc_enable_interrupts( _level ); \ sparc_enable_interrupts( _level ); \
(_previous) &= _mask; \ (_previous) &= _mask; \
} while (0) } while (0)
@@ -364,13 +327,13 @@ extern volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
do { \ do { \
unsigned32 _level; \ unsigned32 _level; \
unsigned32 _mask = 1 << (_source); \ unsigned32 _mask = 1 << (_source); \
\
_level = sparc_disable_interrupts(); \ _level = sparc_disable_interrupts(); \
LEON3_IrqCtrl_Regs->mask_p0 = \ LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] = \
(LEON3_IrqCtrl_Regs->mask_p0 & ~_mask) | (_previous); \ (LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] & ~_mask) | (_previous); \
sparc_enable_interrupts( _level ); \ sparc_enable_interrupts( _level ); \
} while (0) } while (0)
/* /*
* Each timer control register is organized as follows: * 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_DEFINED_MASK 0x00000003
#define LEON_REG_TIMER_COUNTER_CURRENT_MODE_MASK 0x00000003 #define LEON_REG_TIMER_COUNTER_CURRENT_MODE_MASK 0x00000003
#include "spacewire.h"
#endif /* !ASM */ #endif /* !ASM */
#ifdef __cplusplus #ifdef __cplusplus

View 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

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View 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

View 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;
}

View File

@@ -15,7 +15,7 @@ scmv91111_configuration_t leon_scmv91111_configuration = {
SMC91111_BASE_ADDR, /* base address */ SMC91111_BASE_ADDR, /* base address */
LEON_TRAP_TYPE(SMC91111_BASE_IRQ), /* vector number */ LEON_TRAP_TYPE(SMC91111_BASE_IRQ), /* vector number */
SMC91111_BASE_PIO, /* PIO */ SMC91111_BASE_PIO, /* PIO */
10, /* 10b */ 100, /* 100b */
1, /* fulldx */ 1, /* fulldx */
1 /* autoneg */ 1 /* autoneg */
}; };
@@ -37,7 +37,7 @@ int rtems_smc91111_driver_attach_leon3 (
{ {
unsigned long irq_pio, irq_mctrl, addr_pio = 0; unsigned long irq_pio, irq_mctrl, addr_pio = 0;
unsigned long addr_mctrl = 0, addr_timer = 0; unsigned long addr_mctrl = 0;
i = 0; i = 0;
while (i < amba_conf.apbslv.devnr) while (i < amba_conf.apbslv.devnr)
@@ -56,25 +56,14 @@ int rtems_smc91111_driver_attach_leon3 (
irq_mctrl = amba_irq(conf); irq_mctrl = amba_irq(conf);
iobar = amba_apb_get_membar(amba_conf.apbslv, i); iobar = amba_apb_get_membar(amba_conf.apbslv, i);
addr_mctrl = (unsigned long) amba_iobar_start(amba_conf.apbmst, iobar); 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++; 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) { if (addr_pio && addr_mctrl) {
LEON3_IOPORT_Regs_Map *io = (LEON3_IOPORT_Regs_Map *) addr_pio; LEON3_IOPORT_Regs_Map *io = (LEON3_IOPORT_Regs_Map *) addr_pio;
/*
{ {
char buf[1024]; char buf[1024];
@@ -84,6 +73,7 @@ int rtems_smc91111_driver_attach_leon3 (
(unsigned int)addr_mctrl); (unsigned int)addr_mctrl);
DEBUG_puts(buf); DEBUG_puts(buf);
} }
*/
*((volatile unsigned int *)addr_mctrl) |= 0x10f80000; /*mctrl ctrl 1 */ *((volatile unsigned int *)addr_mctrl) |= 0x10f80000; /*mctrl ctrl 1 */
io->irqmask |= (1 << leon_scmv91111_configuration.pio); io->irqmask |= (1 << leon_scmv91111_configuration.pio);

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View 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

View 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 );
}

View 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;
}

View 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 );
}

View 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);
}

View File

@@ -125,7 +125,7 @@ void bsp_pretasking_hook(void)
bsp_libc_init((void *) heap_start, heap_size, 0); bsp_libc_init((void *) heap_start, heap_size, 0);
#if SIMSPARC_FAST_IDLE #if SIMSPARC_FAST_IDLE
/* /*
* Install the fast idle task switch extension * Install the fast idle task switch extension
@@ -160,7 +160,7 @@ void bsp_pretasking_hook(void)
rtems_debug_enable( RTEMS_DEBUG_ALL_MASK ); rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
#endif #endif
bsp_spurious_initialize(); bsp_spurious_initialize();
} }
void bsp_leon3_predriver_hook(void); void bsp_leon3_predriver_hook(void);

View File

@@ -22,6 +22,13 @@
#include <bsp.h> #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_Find_average_overhead;
rtems_boolean Timer_driver_Is_initialized = FALSE; rtems_boolean Timer_driver_Is_initialized = FALSE;
@@ -36,12 +43,12 @@ void Timer_initialize()
if (LEON3_Timer_Regs) { if (LEON3_Timer_Regs) {
if ( Timer_driver_Is_initialized == FALSE ) { if ( Timer_driver_Is_initialized == FALSE ) {
/* approximately 1 us per countdown */ /* approximately 1 us per countdown */
LEON3_Timer_Regs->reload_t1 = 0xffffff; LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].reload = 0xffffff;
LEON3_Timer_Regs->value_t1 = 0xffffff; LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].value = 0xffffff;
} else { } else {
Timer_driver_Is_initialized = TRUE; 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; rtems_unsigned32 total;
if (LEON3_Timer_Regs) { if (LEON3_Timer_Regs) {
total = LEON3_Timer_Regs->value_t1; total = LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].value;
total = 0xffffff - total; total = 0xffffff - total;
@@ -63,7 +70,7 @@ int Read_timer()
if ( total < LEAST_VALID ) if ( total < LEAST_VALID )
return 0; /* below timer resolution */ return 0; /* below timer resolution */
return total - AVG_OVERHEAD; return total - AVG_OVERHEAD;
} }
return 0; return 0;

View File

@@ -5,7 +5,7 @@
ACLOCAL_AMFLAGS = -I ../../../../../../../aclocal ACLOCAL_AMFLAGS = -I ../../../../../../../aclocal
transform = transform =
bsptools_bindir = ${exec_prefix}/@RTEMS_BSP@/tests bsptools_bindir = $(PROJECT_ROOT)/@RTEMS_BSP@/tests
bsptools_bin_SCRIPTS = runtest bsptools_bin_SCRIPTS = runtest
TMPINSTALL_FILES = $(bsptools_bindir) $(bsptools_bindir)/runtest TMPINSTALL_FILES = $(bsptools_bindir) $(bsptools_bindir)/runtest

View File

@@ -4,16 +4,29 @@
# We only build the networking device driver if HAS_NETWORKING was defined # We only build the networking device driver if HAS_NETWORKING was defined
if HAS_NETWORKING if HAS_NETWORKING
NETWORKING_DRIVER = leon_open_eth leon_smc91111 NETWORKING_DRIVER = leon_open_eth leon_smc91111 leon_greth
endif 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 # pieces to pick up out of libcpu/sparc
CPU_PIECES = cache reg_win syscall CPU_PIECES = cache reg_win syscall
# bummer; have to use $foreach since % pattern subst rules only replace 1x # bummer; have to use $foreach since % pattern subst rules only replace 1x
OBJS = $(foreach piece, $(BSP_PIECES), $(wildcard ../$(piece)/$(ARCH)/*.$(OBJEXT))) \ OBJS = \
$(foreach piece, $(CPU_PIECES), ../../../../libcpu/$(RTEMS_CPU)/$(piece)/$(ARCH)/*.$(OBJEXT)) $(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 LIB = $(ARCH)/libbsp.a
include $(top_srcdir)/../../../../../../automake/compile.am include $(top_srcdir)/../../../../../../automake/compile.am
@@ -29,3 +42,5 @@ $(LIB): $(OBJS)
all-local: $(ARCH) $(LIB) all-local: $(ARCH) $(LIB)
include $(top_srcdir)/../../../../../../automake/local.am include $(top_srcdir)/../../../../../../automake/local.am
../../../shmdr/o-optimize/shmdr.rel: