update from Andy Bray <andy@i-cubed.co.uk>

This commit is contained in:
Joel Sherrill
1995-12-05 19:23:05 +00:00
parent 289ad864a5
commit e57b0e23d4
7 changed files with 139 additions and 194 deletions

View File

@@ -2,7 +2,7 @@
# $Id$
#
This hierachy contains support routines for the various
This hierarchy contains support routines for the various
PowerPC processors.
Since these routines can differ amongst different members
@@ -10,4 +10,4 @@ of the PowerPC family, an entry per CPU type is provided.
Currently only the PPC403 is supported.
Andrew Bray 18/8/1995
Andrew Bray 4/December/1995

View File

@@ -8,7 +8,7 @@ clock - Uses the 403 PIT (Programmable interval timer) to
generate RTEMS clock ticks.
console - Uses the 403 Internal serial port to do RTEMS
console I/O. Not ALL memebers of the 403 family
console I/O. Not ALL members of the 403 family
have this.
include - Currently empty
@@ -19,4 +19,4 @@ timer - Uses the 403 timebase register for timing
vectors - PowerPC 403 specific vector entry points.
Includes CPU dependant, application independant
handlres: alignment.
handlers: alignment.

View File

@@ -3,7 +3,7 @@
* This routine initializes the interval timer on the
* PowerPC 403 CPU. The tick frequency is specified by the bsp.
*
* Author: Andrew Bray <andy@i-cubed.demon.co.uk>
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
@@ -56,7 +56,7 @@ static INLINE rtems_unsigned32 get_itimer(void)
{
register rtems_unsigned32 rc;
asm volatile ("mftblo %0" : "=r" ((rc)));
asm volatile ("mfspr %0, 0x3dd" : "=r" ((rc))); /* TBLO */
return rc;
}
@@ -69,58 +69,59 @@ rtems_isr
Clock_isr(rtems_vector_number vector)
{
if (!auto_restart)
{
rtems_unsigned32 clicks_til_next_interrupt;
rtems_unsigned32 itimer_value;
/*
* setup for next interrupt; making sure the new value is reasonably
* in the future.... in case we lost out on an interrupt somehow
*/
itimer_value = get_itimer();
tick_time += pit_value;
/*
* how far away is next interrupt *really*
* It may be a long time; this subtraction works even if
* Clock_clicks_interrupt < Clock_clicks_low_order via
* the miracle of unsigned math.
*/
clicks_til_next_interrupt = tick_time - itimer_value;
/*
* If it is too soon then bump it up.
* This should only happen if CPU_HPPA_CLICKS_PER_TICK is too small.
* But setting it low is useful for debug, so...
*/
if (clicks_til_next_interrupt < 400)
{
tick_time = itimer_value + 1000;
clicks_til_next_interrupt = 1000;
/* XXX: count these! this should be rare */
}
/*
* If it is too late, that means we missed the interrupt somehow.
* Rather than wait 35-50s for a wrap, we just fudge it here.
*/
if (clicks_til_next_interrupt > pit_value)
{
tick_time = itimer_value + 1000;
clicks_til_next_interrupt = 1000;
/* XXX: count these! this should never happen :-) */
}
asm volatile ("mtpit %0" :: "r" (clicks_til_next_interrupt));
}
asm volatile ( "mttsr %0" :: "r" (0x08000000));
{
rtems_unsigned32 clicks_til_next_interrupt;
rtems_unsigned32 itimer_value;
/*
* setup for next interrupt; making sure the new value is reasonably
* in the future.... in case we lost out on an interrupt somehow
*/
itimer_value = get_itimer();
tick_time += pit_value;
/*
* how far away is next interrupt *really*
* It may be a long time; this subtraction works even if
* Clock_clicks_interrupt < Clock_clicks_low_order via
* the miracle of unsigned math.
*/
clicks_til_next_interrupt = tick_time - itimer_value;
/*
* If it is too soon then bump it up.
* This should only happen if CPU_HPPA_CLICKS_PER_TICK is too small.
* But setting it low is useful for debug, so...
*/
if (clicks_til_next_interrupt < 400)
{
tick_time = itimer_value + 1000;
clicks_til_next_interrupt = 1000;
/* XXX: count these! this should be rare */
}
/*
* If it is too late, that means we missed the interrupt somehow.
* Rather than wait 35-50s for a wrap, we just fudge it here.
*/
if (clicks_til_next_interrupt > pit_value)
{
tick_time = itimer_value + 1000;
clicks_til_next_interrupt = 1000;
/* XXX: count these! this should never happen :-) */
}
asm volatile ("mtspr 0x3db, %0" :: "r"
(clicks_til_next_interrupt)); /* PIT */
}
asm volatile ( "mtspr 0x3d8, %0" :: "r" (0x08000000)); /* TSR */
Clock_driver_ticks++;
rtems_clock_tick();
}
@@ -128,30 +129,31 @@ void Install_clock(rtems_isr_entry clock_isr)
{
rtems_isr_entry previous_isr;
rtems_unsigned32 pvr, iocr;
Clock_driver_ticks = 0;
asm volatile ("mfiocr %0" : "=r" (iocr));
asm volatile ("mfdcr %0, 0xa0" : "=r" (iocr)); /* IOCR */
iocr &= ~4;
iocr |= 4; /* Select external timer clock */
asm volatile ("mtiocr %0" : "=r" (iocr) : "0" (iocr));
asm volatile ("mfpvr %0" : "=r" ((pvr)));
asm volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); /* IOCR */
asm volatile ("mfspr %0, 0x11f" : "=r" ((pvr))); /* PVR */
if (((pvr & 0xffff0000) >> 16) != 0x0020)
return; /* Not a ppc403 */
return; /* Not a ppc403 */
if ((pvr & 0xff00) == 0x0000) /* 403GA */
auto_restart = (pvr & 0x00f0) > 0x0000 ? 1 : 0;
auto_restart = (pvr & 0x00f0) > 0x0000 ? 1 : 0;
else if ((pvr & 0xff00) == 0x0100) /* 403GB */
auto_restart = 1;
auto_restart = 1;
pit_value = BSP_Configuration.microseconds_per_tick *
Cpu_table.clicks_per_usec;
Cpu_table.clicks_per_usec;
if (BSP_Configuration.ticks_per_timeslice)
{
register rtems_unsigned32 tcr;
register rtems_unsigned32 tcr;
/*
* initialize the interval here
* First tick is set to right amount of time in the future
@@ -159,21 +161,20 @@ void Install_clock(rtems_isr_entry clock_isr)
* in order to provide consistent clicks in the face of
* interrupt overhead
*/
rtems_interrupt_catch(clock_isr, PPC_IRQ_PIT,
&previous_isr);
asm volatile ("mtpit %0" : : "r" (pit_value));
asm volatile ("mftcr %0" : "=r" ((tcr)));
tcr &= ~ 0x04400000;
tcr |= (auto_restart ? 0x04400000 : 0x04000000);
tick_time = get_itimer() + pit_value;
asm volatile ("mttcr %0" : "=r" ((tcr)) : "0" ((tcr)));
rtems_interrupt_catch(clock_isr, PPC_IRQ_PIT, &previous_isr);
asm volatile ("mtspr 0x3db, %0" : : "r" (pit_value)); /* PIT */
asm volatile ("mfspr %0, 0x3da" : "=r" ((tcr))); /* TCR */
tcr &= ~ 0x04400000;
tcr |= (auto_restart ? 0x04400000 : 0x04000000);
tick_time = get_itimer() + pit_value;
asm volatile ("mtspr 0x3da, %0" : "=r" ((tcr)) : "0" ((tcr))); /* TCR */
}
atexit(Clock_exit);
}
@@ -186,8 +187,7 @@ ReInstall_clock(rtems_isr_entry new_clock_isr)
rtems_interrupt_disable(isrlevel);
rtems_interrupt_catch(new_clock_isr, PPC_IRQ_PIT,
&previous_isr);
rtems_interrupt_catch(new_clock_isr, PPC_IRQ_PIT, &previous_isr);
rtems_interrupt_enable(isrlevel);
}
@@ -203,16 +203,17 @@ Clock_exit(void)
{
if ( BSP_Configuration.ticks_per_timeslice )
{
register rtems_unsigned32 tcr;
asm volatile ("mftcr %0" : "=r" ((tcr)));
tcr &= ~ 0x04400000;
asm volatile ("mttcr %0" : "=r" ((tcr)) : "0" ((tcr)));
(void) set_vector(0, PPC_IRQ_PIT, 1);
register rtems_unsigned32 tcr;
asm volatile ("mfspr %0, 0x3da" : "=r" ((tcr))); /* TCR */
tcr &= ~ 0x04400000;
asm volatile ("mtspr 0x3da, %0" : "=r" ((tcr)) : "0" ((tcr))); /* TCR */
(void) set_vector(0, PPC_IRQ_PIT, 1);
}
}
rtems_device_driver Clock_initialize(

View File

@@ -1,7 +1,7 @@
/*
* This file contains the PowerPC 403GA console IO package.
*
* Author: Andrew Bray <andy@i-cubed.demon.co.uk>
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
@@ -145,19 +145,19 @@ rtems_device_driver console_initialize(
register unsigned tmp;
/* Initialise the serial port */
asm volatile ("mfiocr %0" : "=r" (tmp));
asm volatile ("mfdcr %0, 0xa0" : "=r" (tmp)); /* IOCR */
tmp &= ~3;
tmp |= (Cpu_table.serial_external_clock ? 2 : 0) |
(Cpu_table.serial_cts_rts ? 1 : 0);
asm volatile ("mtiocr %0" : "=r" (tmp) : "0" (tmp));
asm volatile ("mtdcr 0xa0, %0" : "=r" (tmp) : "0" (tmp)); /* IOCR */
port->SPLS = (LSRDataReady | LSRFramingError | LSROverrunError |
LSRParityError | LSRBreakInterrupt);
LSRParityError | LSRBreakInterrupt);
tmp = Cpu_table.serial_per_sec / Cpu_table.serial_rate;
tmp = ((tmp + 8) >> 4) - 1;
port->BRDL = tmp & 0x255;
port->BRDH = tmp >> 8;
port->SPCTL = (CRNormal | CRDtr | CRRts | CRWordLength8 | CRParityDisable |
CRStopBitsOne);
CRStopBitsOne);
port->SPRC = (RCREnable | RCRIntDisable | RCRPauseEnable);
port->SPTC = (TCREnable | TCRIntDisable);
port->SPHS = (HSRDsr | HSRCts);
@@ -228,15 +228,15 @@ char inbyte( void )
while (1)
{
if ((status = port->SPLS) & LSRDataReady)
break;
break;
/* Clean any dodgy status */
if ((status & (LSRFramingError | LSROverrunError | LSRParityError |
LSRBreakInterrupt)) != 0)
{
port->SPLS = (LSRFramingError | LSROverrunError | LSRParityError |
LSRBreakInterrupt);
}
{
port->SPLS = (LSRFramingError | LSROverrunError | LSRParityError |
LSRBreakInterrupt);
}
}
return port->SPRB;
@@ -269,19 +269,17 @@ void outbyte(
if (port->SPHS)
port->SPHS = (HSRDsr | HSRCts);
else if (status & LSRTxHoldEmpty)
break;
break;
}
if (Cpu_table.serial_xon_xoff)
while (is_character_ready(&status))
{
if (status == XOFFchar)
do
{
while (!is_character_ready(&status));
}
while (status != XONchar);
}
{
if (status == XOFFchar)
do {
while (!is_character_ready(&status));
} while (status != XONchar);
}
port->SPTB = ch;
}

View File

@@ -6,7 +6,7 @@
* NOTE: It is important that the timer start/stop overhead be
* determined when porting or modifying this code.
*
* Author: Andrew Bray <andy@i-cubed.demon.co.uk>
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
@@ -49,7 +49,7 @@ static INLINE rtems_unsigned32 get_itimer(void)
{
rtems_unsigned32 ret;
asm volatile ("mftblo %0" : "=r" ((ret)));
asm volatile ("mfspr %0, 0x3dd" : "=r" ((ret))); /* TBLO */
return ret;
}
@@ -58,10 +58,10 @@ void Timer_initialize()
{
rtems_unsigned32 iocr;
asm volatile ("mfiocr %0" : "=r" (iocr));
asm volatile ("mfdcr %0, 0xa0" : "=r" (iocr)); /* IOCR */
iocr &= ~4;
iocr |= 4; /* Select external timer clock */
asm volatile ("mtiocr %0" : "=r" (iocr) : "0" (iocr));
asm volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); /* IOCR */
Timer_starting = get_itimer();
}

View File

@@ -1,4 +1,4 @@
/* align_h.s 1.0 - 95/09/26
/* align_h.s 1.1 - 95/12/04
*
* This file contains the assembly code for the PowerPC 403
* alignment exception handler for RTEMS.
@@ -25,7 +25,7 @@
*
* Modifications:
*
* Author: Andrew Bray <andy@i-cubed.demon.co.uk>
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
@@ -121,17 +121,17 @@ align_h:
stw r8,Open_lr(r1)
stw r9,Open_cr(r1)
stw r10,Open_ctr(r1)
mfsrr2 r7
mfsrr3 r8
mfsrr0 r9
mfsrr1 r10
mfspr r7, srr2 /* SRR 2 */
mfspr r8, srr3 /* SRR 3 */
mfspr r9, srr0 /* SRR 0 */
mfspr r10, srr1 /* SRR 1 */
stw r7,Open_srr2(r1)
stw r8,Open_srr3(r1)
stw r9,Open_srr0(r1)
stw r10,Open_srr1(r1)
/* Set up common registers */
mfdear r5 /* R5 is data exception address */
mfspr r5, dear /* DEAR: R5 is data exception address */
lwz r9,Open_srr0(r1) /* get faulting instruction */
addi r7,r9,4 /* bump instruction */
stw r7,Open_srr0(r1) /* restore to image */
@@ -425,12 +425,9 @@ align_complete:
mtlr r25
mtctr r26
mtcrf 0xFF, r27
mtsrr2 r28
mtsrr3 r29
mtsrr0 r30
mtsrr1 r31
mttcr r30
mtexier r31
mtspr srr2, r28 /* SRR 2 */
mtspr srr3, r29 /* SRR 3 */
mtspr srr0, r30 /* SRR 0 */
mtspr srr1, r31 /* SRR 1 */
lmw r0,Open_gpr0+ALIGN_REGS(r0)
rfi

View File

@@ -1,9 +1,9 @@
/* vectors.s 1.0 - 95/08/08
/* vectors.s 1.1 - 95/12/04
*
* This file contains the assembly code for the PowerPC 403
* interrupt veneers for RTEMS.
*
* Author: Andrew Bray <andy@i-cubed.demon.co.uk>
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
@@ -18,7 +18,6 @@
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
* $Id$
*/
/*
@@ -37,6 +36,8 @@
* The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the
* offset from 0x????0000 to the first location in the file. This
* will usually be 0x0000 or 0x0100.
*
* $Id$
*/
#include "asm.h"
@@ -113,9 +114,6 @@ SYM (__vectors):
/* Critical error handling */
.org crit_vector - file_base
mtsprg1 r0
mfsprg2 r0
mtmsr r0
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
@@ -125,7 +123,6 @@ SYM (__vectors):
#else
stwu r1, -(IP_END)(r1)
#endif
mfsprg1 r0
stw r0, IP_0(r1)
li r0, PPC_IRQ_CRIT
@@ -133,9 +130,6 @@ SYM (__vectors):
/* Machine check exception */
.org mach_vector - file_base
mtsprg1 r0
mfsprg2 r0
mtmsr r0
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
@@ -145,7 +139,6 @@ SYM (__vectors):
#else
stwu r1, -(IP_END)(r1)
#endif
mfsprg1 r0
stw r0, IP_0(r1)
li r0, PPC_IRQ_MCHECK
@@ -153,9 +146,6 @@ SYM (__vectors):
/* Protection exception */
.org prot_vector - file_base
mtsprg0 r0
mfsprg2 r0
mtmsr r0
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
@@ -165,7 +155,6 @@ SYM (__vectors):
#else
stwu r1, -(IP_END)(r1)
#endif
mfsprg0 r0
stw r0, IP_0(r1)
li r0, PPC_IRQ_PROTECT
@@ -173,9 +162,6 @@ SYM (__vectors):
/* External interrupt */
.org ext_vector - file_base
mtsprg0 r0
mfsprg2 r0
mtmsr r0
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
@@ -185,7 +171,6 @@ SYM (__vectors):
#else
stwu r1, -(IP_END)(r1)
#endif
mfsprg0 r0
stw r0, IP_0(r1)
li r0, PPC_IRQ_EXTERNAL
@@ -198,9 +183,6 @@ SYM (__vectors):
/* Program exception */
.org prog_vector - file_base
mtsprg0 r0
mfsprg2 r0
mtmsr r0
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
@@ -210,7 +192,6 @@ SYM (__vectors):
#else
stwu r1, -(IP_END)(r1)
#endif
mfsprg0 r0
stw r0, IP_0(r1)
li r0, PPC_IRQ_PROGRAM
@@ -218,9 +199,6 @@ SYM (__vectors):
/* System call */
.org sys_vector - file_base
mtsprg0 r0
mfsprg2 r0
mtmsr r0
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
@@ -230,7 +208,6 @@ SYM (__vectors):
#else
stwu r1, -(IP_END)(r1)
#endif
mfsprg0 r0
stw r0, IP_0(r1)
li r0, PPC_IRQ_SCALL
@@ -238,21 +215,6 @@ SYM (__vectors):
/* PIT interrupt */
.org pit_vector - file_base
b pit
/* FIT interrupt */
.org fit_vector - file_base
b fit
/* Watchdog interrupt */
.org wadt_vector - file_base
b watch
/* PIT interrupt */
pit:
mtsprg0 r0
mfsprg2 r0
mtmsr r0
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
@@ -262,17 +224,13 @@ pit:
#else
stwu r1, -(IP_END)(r1)
#endif
mfsprg0 r0
stw r0, IP_0(r1)
li r0, PPC_IRQ_PIT
b PROC (_ISR_Handler)
/* FIT interrupt */
fit:
mtsprg0 r0
mfsprg2 r0
mtmsr r0
.org fit_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
@@ -282,17 +240,13 @@ fit:
#else
stwu r1, -(IP_END)(r1)
#endif
mfsprg0 r0
stw r0, IP_0(r1)
li r0, PPC_IRQ_FIT
b PROC (_ISR_Handler)
/* Watchdog interrupt */
watch:
mtsprg1 r0
mfsprg2 r0
mtmsr r0
.org wadt_vector - file_base
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
@@ -302,7 +256,6 @@ watch:
#else
stwu r1, -(IP_END)(r1)
#endif
mfsprg1 r0
stw r0, IP_0(r1)
li r0, PPC_IRQ_WATCHDOG
@@ -310,9 +263,6 @@ watch:
/* Debug exception */
debug:
mtsprg1 r0
mfsprg2 r0
mtmsr r0
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#if (PPC_HAS_FPU)
stwu r1, -(20*4 + 18*8 + IP_END)(r1)
@@ -322,7 +272,6 @@ debug:
#else
stwu r1, -(IP_END)(r1)
#endif
mfsprg1 r0
stw r0, IP_0(r1)
li r0, PPC_IRQ_DEBUG