diff options
Diffstat (limited to 'c/src/lib/libcpu/powerpc/ppc403/clock/clock.c')
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/clock/clock.c | 189 |
1 files changed, 95 insertions, 94 deletions
diff --git a/c/src/lib/libcpu/powerpc/ppc403/clock/clock.c b/c/src/lib/libcpu/powerpc/ppc403/clock/clock.c index 5ee8e39c05..068cf4f538 100644 --- a/c/src/lib/libcpu/powerpc/ppc403/clock/clock.c +++ b/c/src/lib/libcpu/powerpc/ppc403/clock/clock.c @@ -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( |