2006-07-13 Jerry Needell <jerry.needell@unh.edu>

* clock/ckinit.c, include/leon.h, timer/timer.c, amba/amba.c
	fixed up merge from 4.6.6. Correct references to
	LEON3_IrqCtrl_Regs_Map.mask[x] and LEON3_Timer_Regs_Map.timer[x].
This commit is contained in:
Joel Sherrill
2006-07-14 20:11:29 +00:00
parent 8eb78a204e
commit 0b83afe90a
5 changed files with 90 additions and 35 deletions

View File

@@ -1,3 +1,9 @@
2006-07-13 Jerry Needell <jerry.needell@unh.edu>
* clock/ckinit.c, include/leon.h, timer/timer.c, amba/amba.c
fixed up merge from 4.6.6. Correct references to
LEON3_IrqCtrl_Regs_Map.mask[x] and LEON3_Timer_Regs_Map.timer[x].
2006-07-12 Jerry Needell <jerry.needell@unh.edu> 2006-07-12 Jerry Needell <jerry.needell@unh.edu>
* amba/amba.c, clock/ckinit.c, include/amba.h, timer/timer.c: Search * amba/amba.c, clock/ckinit.c, include/amba.h, timer/timer.c: Search

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,13 +30,17 @@
* 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 )
/* /*
* Clock ticks since initialization * Clock ticks since initialization
*/ */
volatile uint32_t Clock_driver_ticks; volatile rtems_unsigned32 Clock_driver_ticks;
volatile LEON3_Timer_Regs_Map *LEON3_Timer_Regs = 0; volatile LEON3_Timer_Regs_Map *LEON3_Timer_Regs = 0;
static int clkirq; static int clkirq;
@@ -47,7 +51,7 @@ static int clkirq;
* the simulator. * the simulator.
*/ */
extern uint32_t CPU_SPARC_CLICKS_PER_TICK; extern rtems_unsigned32 CPU_SPARC_CLICKS_PER_TICK;
rtems_isr_entry Old_ticker; rtems_isr_entry Old_ticker;
@@ -60,7 +64,6 @@ void Clock_exit( void );
rtems_device_major_number rtems_clock_major = ~0; rtems_device_major_number rtems_clock_major = ~0;
rtems_device_minor_number rtems_clock_minor; rtems_device_minor_number rtems_clock_minor;
/* /*
* Clock_isr * Clock_isr
* *
@@ -124,19 +127,40 @@ void Install_clock(
rtems_isr_entry clock_isr rtems_isr_entry clock_isr
) )
{ {
int i;
unsigned int iobar, conf;
Clock_driver_ticks = 0; Clock_driver_ticks = 0;
/* Find GP Timer */
i = 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_GPTIMER))
{
iobar = amba_apb_get_membar(amba_conf.apbslv, i);
LEON3_Timer_Regs = (volatile LEON3_Timer_Regs_Map *) amba_iobar_start(amba_conf.apbmst, iobar);
break;
}
i++;
}
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) Old_ticker = (rtems_isr_entry) set_vector( clock_isr, LEON_TRAP_TYPE(clkirq), 1 );
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_Timer_Regs->timer[LEON3_CLOCK_INDEX].conf = LEON3_GPTIMER_EN | LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN;
LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN;
atexit( Clock_exit ); atexit( Clock_exit );
} }
@@ -162,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 */
} }
@@ -226,7 +250,7 @@ rtems_device_driver Clock_control(
void *pargp void *pargp
) )
{ {
uint32_t isrlevel; rtems_unsigned32 isrlevel;
rtems_libio_ioctl_args_t *args = pargp; rtems_libio_ioctl_args_t *args = pargp;

View File

@@ -293,23 +293,24 @@ extern int LEON3_Cpu_Index;
(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 { \
uint32_t _level; \ uint32_t _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 { \
uint32_t _level; \ uint32_t _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)
@@ -317,10 +318,9 @@ extern int LEON3_Cpu_Index;
do { \ do { \
uint32_t _level; \ uint32_t _level; \
uint32_t _mask = 1 << (_source); \ uint32_t _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)
@@ -329,13 +329,13 @@ extern int LEON3_Cpu_Index;
do { \ do { \
uint32_t _level; \ uint32_t _level; \
uint32_t _mask = 1 << (_source); \ uint32_t _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:
* *
@@ -367,9 +367,6 @@ extern int LEON3_Cpu_Index;
#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
/* XXX really needed but I can't get it to install -- JRS */
/* #include <spacewire.h> */
#endif /* !ASM */ #endif /* !ASM */
#ifdef __cplusplus #ifdef __cplusplus
@@ -377,4 +374,5 @@ extern int LEON3_Cpu_Index;
#endif #endif
#endif /* !_INCLUDE_LEON_h */ #endif /* !_INCLUDE_LEON_h */
/* end of include file */

View File

@@ -22,28 +22,33 @@
#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;
extern volatile LEON3_Timer_Regs_Map *LEON3_Timer_Regs; extern volatile LEON3_Timer_Regs_Map *LEON3_Timer_Regs;
void Timer_initialize() void Timer_initialize()
{ {
/* /*
* Timer runs long and accurate enough not to require an interrupt. * Timer runs long and accurate enough not to require an interrupt.
*/ */
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;
} }
} }
@@ -53,10 +58,10 @@ void Timer_initialize()
int Read_timer() int Read_timer()
{ {
uint32_t 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;