2007-11-30 Till Straumann <strauman@slac.stanford.edu>

* mpc6xx/clock/c_clock.c, mpc6xx/clock/c_clock.h:
	added support for bookE/ppc405 style CPUs where the
	decrementer works slightly differently.
This commit is contained in:
Till Straumann
2007-12-01 00:22:30 +00:00
parent d18d7fe0dd
commit 3fa48eef10
3 changed files with 103 additions and 4 deletions

View File

@@ -1,3 +1,12 @@
2007-11-30 Till Straumann <strauman@slac.stanford.edu>
* mpc6xx/clock/c_clock.c, mpc6xx/clock/c_clock.h:
added support for bookE/ppc405 style CPUs where the
decrementer works slightly differently.
2007-11-30 Till Straumann <strauman@slac.stanford.edu>
* mpc6xx/mmu/bat.c, mpc6xx/mmu/pte121.c
2007-11-29 Till Straumann <strauman@slac.stanford.edu>
* mpc6xx/exceptions/raw_exception.c,

View File

@@ -25,8 +25,15 @@
#include <stdlib.h> /* for atexit() */
#include <assert.h>
#include <libcpu/c_clock.h>
#include <libcpu/cpuIdent.h>
#include <libcpu/spr.h>
#include <rtems/bspIo.h> /* for printk() */
SPR_RW(BOOKE_TCR)
SPR_RW(BOOKE_TSR)
SPR_RW(BOOKE_DECAR)
SPR_RW(DEC)
extern int BSP_connect_clock_handler (void);
/*
@@ -50,14 +57,39 @@ rtems_device_minor_number rtems_clock_minor;
void clockOff(void* unused)
{
rtems_interrupt_level l;
if ( ppc_cpu_is_bookE() ) {
rtems_interrupt_disable(l);
_write_BOOKE_TCR(_read_BOOKE_TCR() & ~BOOKE_TCR_DIE);
rtems_interrupt_enable(l);
} else {
/*
* Nothing to do as we cannot disable all interrupts and
* the decrementer interrupt enable is MSR_EE
*/
}
}
void clockOn(void* unused)
{
rtems_interrupt_level l;
PPC_Set_decrementer( Clock_Decrementer_value );
if ( ppc_cpu_is_bookE() ) {
_write_BOOKE_DECAR( Clock_Decrementer_value );
rtems_interrupt_disable(l);
/* clear pending/stale irq */
_write_BOOKE_TSR( BOOKE_TSR_DIS );
/* enable */
_write_BOOKE_TCR( _read_BOOKE_TCR() | BOOKE_TCR_DIE );
rtems_interrupt_enable(l);
}
}
static void clockHandler(void)
@@ -101,13 +133,51 @@ int decr;
} while ( decr < 0 );
}
/*
* Clock_isr_bookE
*
* This is the clock tick interrupt handler
* for bookE CPUs. For efficiency reasons we
* provide a separate handler rather than
* checking the CPU type each time.
*
* Input parameters:
* vector - vector number
*
* Output parameters: NONE
*
* Return values: NONE
*
*/
void clockIsrBookE(void *unused)
{
/* Note: TSR bit has already been cleared in the exception handler */
/*
* The driver has seen another tick.
*/
Clock_driver_ticks += 1;
/*
* Real Time Clock counter/timer is set to automatically reload.
*/
clock_handler();
}
int clockIsOn(void* unused)
{
uint32_t msr_value;
uint32_t msr_value;
_CPU_MSR_GET( msr_value );
if (msr_value & MSR_EE) return 1;
return 0;
_CPU_MSR_GET( msr_value );
if ( ppc_cpu_is_bookE() && ! (_read_BOOKE_TCR() & BOOKE_TCR_DIE) )
msr_value = 0;
if (msr_value & MSR_EE) return 1;
return 0;
}
@@ -167,6 +237,8 @@ rtems_device_driver Clock_initialize(
void *pargp
)
{
rtems_interrupt_level l,tcr;
Clock_Decrementer_value = (BSP_bus_frequency/BSP_time_base_divisor)*
(rtems_configuration_get_microseconds_per_tick()/1000);
@@ -175,6 +247,22 @@ rtems_device_driver Clock_initialize(
*/
PPC_Set_decrementer( (unsigned)-1 );
/* On a bookE CPU the decrementer works differently. It doesn't
* count past zero but we can enable auto-reload :-)
*/
if ( ppc_cpu_is_bookE() ) {
rtems_interrupt_disable(l);
tcr = _read_BOOKE_TCR();
tcr |= BOOKE_TCR_ARE;
tcr &= ~BOOKE_TCR_DIE;
_write_BOOKE_TCR(tcr);
rtems_interrupt_enable(l);
}
/*
* Set the nanoseconds since last tick handler
*/

View File

@@ -32,6 +32,8 @@
extern void clockOff (void* unused);
extern void clockOn (void* unused);
extern void clockIsr (void* unused);
/* bookE decrementer is slightly different */
extern void clockIsrBookE (void *unused);
extern int clockIsOn (void* unused);
/*