diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-19 06:35:52 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-20 09:57:01 +0200 |
commit | 7632906fc290b652416ab59eb5fb49356c064ed6 (patch) | |
tree | ac036b1f95637e044e10138ceea8d2b56d80ec97 /bsps/mips | |
parent | bsps: Move bspsmpgetcurrentprocessor.c to bsps (diff) | |
download | rtems-7632906fc290b652416ab59eb5fb49356c064ed6.tar.bz2 |
bsps: Move clock drivers to bsps
This patch is a part of the BSP source reorganization.
Update #3285.
Diffstat (limited to 'bsps/mips')
-rw-r--r-- | bsps/mips/csb350/clock/clockdrv.c | 90 | ||||
-rw-r--r-- | bsps/mips/hurricane/clock/ckinit.c | 219 | ||||
-rw-r--r-- | bsps/mips/hurricane/clock/clock.S | 42 | ||||
-rw-r--r-- | bsps/mips/hurricane/clock/clock.h | 21 | ||||
-rw-r--r-- | bsps/mips/jmr3904/clock/clockdrv.c | 50 | ||||
-rw-r--r-- | bsps/mips/rbtx4925/clock/clockdrv.c | 120 | ||||
-rw-r--r-- | bsps/mips/rbtx4938/clock/clockdrv.c | 119 | ||||
-rw-r--r-- | bsps/mips/rbtx4938/clock/yamon_api.h | 631 | ||||
-rw-r--r-- | bsps/mips/shared/clock/clockdrv.c | 49 | ||||
-rw-r--r-- | bsps/mips/shared/clock/mips_timer.S | 43 |
10 files changed, 1384 insertions, 0 deletions
diff --git a/bsps/mips/csb350/clock/clockdrv.c b/bsps/mips/csb350/clock/clockdrv.c new file mode 100644 index 0000000000..e42261e529 --- /dev/null +++ b/bsps/mips/csb350/clock/clockdrv.c @@ -0,0 +1,90 @@ +/** + * @file + * + * Instantiate the clock driver shell. + * + * This uses the TOY (Time of Year) timer to implement the clock. + */ + +/* + * Copyright (c) 2005 by Cogent Computer Systems + * Written by Jay Monkman <jtm@lopingdog.com> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <rtems.h> +#include <bsp.h> +#include <bsp/irq.h> +#include <rtems/bspIo.h> + +uint32_t tick_interval; +uint32_t last_match; + +void au1x00_clock_init(void); + +#define CLOCK_VECTOR AU1X00_IRQ_TOY_MATCH2 + +#define Clock_driver_support_at_tick() \ + do { \ + while (AU1X00_SYS_CNTCTRL(AU1X00_SYS_ADDR) & AU1X00_SYS_CNTCTRL_TM0); \ + last_match = AU1X00_SYS_TOYREAD(AU1X00_SYS_ADDR); \ + AU1X00_SYS_TOYMATCH2(AU1X00_SYS_ADDR) = last_match + tick_interval; \ + au_sync(); \ + } while(0) + +/* Set for rising edge interrupt */ +#define Clock_driver_support_install_isr( _new ) \ + do { \ + rtems_interrupt_handler_install( \ + CLOCK_VECTOR, \ + "clock", \ + 0, \ + _new, \ + NULL \ + ); \ + AU1X00_IC_MASKCLR(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \ + AU1X00_IC_SRCSET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \ + AU1X00_IC_CFG0SET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \ + AU1X00_IC_CFG1CLR(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \ + AU1X00_IC_CFG2CLR(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \ + AU1X00_IC_ASSIGNSET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \ + } while(0) + +void au1x00_clock_init(void) +{ + uint32_t wakemask; + /* Clear the trim register */ + AU1X00_SYS_TOYTRIM(AU1X00_SYS_ADDR) = 0; + + /* Clear the TOY counter */ + while (AU1X00_SYS_CNTCTRL(AU1X00_SYS_ADDR) & AU1X00_SYS_CNTCTRL_TS); + AU1X00_SYS_TOYWRITE(AU1X00_SYS_ADDR) = 0; + while (AU1X00_SYS_CNTCTRL(AU1X00_SYS_ADDR) & AU1X00_SYS_CNTCTRL_TS); + + wakemask = AU1X00_SYS_WAKEMSK(AU1X00_SYS_ADDR); + wakemask |= AU1X00_SYS_WAKEMSK_M20; + AU1X00_SYS_WAKEMSK(AU1X00_SYS_ADDR) = wakemask; + AU1X00_IC_WAKESET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; + + tick_interval = 32768 * rtems_configuration_get_microseconds_per_tick(); + tick_interval = tick_interval / 1000000; + + last_match = AU1X00_SYS_TOYREAD(AU1X00_SYS_ADDR); + AU1X00_SYS_TOYMATCH2(AU1X00_SYS_ADDR) = last_match + (50*tick_interval); + AU1X00_IC_MASKSET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; + while (AU1X00_SYS_CNTCTRL(AU1X00_SYS_ADDR) & AU1X00_SYS_CNTCTRL_TM0); +} + +#define Clock_driver_support_initialize_hardware() \ + do { \ + au1x00_clock_init(); \ + } while(0) + +#define Clock_driver_support_shutdown_hardware() + +#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER + +#include "../../../shared/dev/clock/clockimpl.h" diff --git a/bsps/mips/hurricane/clock/ckinit.c b/bsps/mips/hurricane/clock/ckinit.c new file mode 100644 index 0000000000..c0d2a38269 --- /dev/null +++ b/bsps/mips/hurricane/clock/ckinit.c @@ -0,0 +1,219 @@ +/** + * @file + * + * This file contains the clock driver initialization for the Hurricane BSP. + */ + +/* + * Author: Craig Lebakken <craigl@transition.com> + * + * COPYRIGHT (c) 1996 by Transition Networks Inc. + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Transition Networks not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * Transition Networks makes no representations about the suitability + * of this software for any purpose. + * + * Derived from c/src/lib/libbsp/no_cpu/no_bsp/clock/ckinit.c + * + * COPYRIGHT (c) 1989-2012. + * 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.org/license/LICENSE. + */ + +/* + * Rather than deleting this, it is commented out to (hopefully) help + * the submitter send updates. + * + * static char _sccsid[] = "@(#)ckinit.c 08/20/96 1.3\n"; + */ + + +#include <stdlib.h> + +#include <rtems.h> +#include <bsp.h> +#include <bsp/irq.h> +#include <rtems/clockdrv.h> + +extern uint32_t bsp_clicks_per_microsecond; + +#define EXT_INT1 0x800 /* external interrupt 5 */ + +#include "clock.h" + +rtems_isr USC_isr(void *unused); + +void reset_wdt(void); +void enable_wdi(void); +void init_hbt(void); +void enable_hbi(void); +void disable_hbi(void); + +void Clock_exit(void); +rtems_isr Clock_isr(rtems_vector_number vector); +rtems_isr User_Clock_isr(rtems_vector_number vector); +void Install_clock(rtems_isr_entry clock_isr); + + +/* + * The interrupt vector number associated with the clock tick device + * driver. + */ + +#define CLOCK_VECTOR_MASK EXT_INT1 +#define CLOCK_VECTOR MIPS_INTERRUPT_BASE + 0x3 + +/* + * Clock_driver_ticks is a monotonically increasing counter of the + * number of clock ticks since the driver was initialized. + */ + +volatile uint32_t Clock_driver_ticks; + +/* + * Clock_isrs is the number of clock ISRs until the next invocation of + * the RTEMS clock tick routine. The clock tick device driver + * gets an interrupt once a millisecond and counts down until the + * length of time between the user configured microseconds per tick + * has passed. + */ + +uint32_t Clock_isrs; /* ISRs until next tick */ + +/* + * The previous ISR on this clock tick interrupt vector. + */ + +rtems_isr_entry Old_ticker; + +void Clock_exit( void ); + +static uint32_t mips_timer_rate = 0; + +/* + * Isr Handler + */ + +rtems_isr Clock_isr( + rtems_vector_number vector +) +{ +/* + * bump the number of clock driver ticks since initialization + * + * determine if it is time to announce the passing of tick as configured + * to RTEMS through the rtems_clock_tick directive + * + * perform any timer dependent tasks + */ + + reset_wdt(); /* Reset hardware watchdog timer */ + + Clock_driver_ticks += 1; + + rtems_clock_tick(); +} + +/* User callback shell (set from Clock_Control) */ +static void (*user_callback)(void); + +rtems_isr User_Clock_isr( + rtems_vector_number vector +) +{ + if (user_callback) + user_callback(); +} + +/* + * Install_clock + * + * Install a clock tick handleR and reprograms the chip. This + * is used to initially establish the clock tick. + */ + +void Install_clock( + rtems_isr_entry clock_isr +) +{ + /* + * Initialize the clock tick device driver variables + */ + + Clock_driver_ticks = 0; + Clock_isrs = rtems_configuration_get_milliseconds_per_tick(); + + mips_timer_rate = rtems_configuration_get_microseconds_per_tick() * + bsp_clicks_per_microsecond; + + /* + * Hardware specific initialize goes here + */ + + /* Set up USC heartbeat timer to generate interrupts */ + disable_hbi(); /* Disable heartbeat interrupt in USC */ + + /* Install interrupt handler */ + rtems_interrupt_handler_install( + CLOCK_VECTOR, + "clock", + 0, + USC_isr, + NULL + ); + + init_hbt(); /* Initialize heartbeat timer */ + + reset_wdt(); /* Reset watchdog timer */ + + enable_wdi(); /* Enable watchdog interrupt in USC */ + + enable_hbi(); /* Enable heartbeat interrupt in USC */ + + /* Enable USC interrupt in MIPS processor */ + mips_enable_in_interrupt_mask(CLOCK_VECTOR_MASK); + + /* + * Schedule the clock cleanup routine to execute if the application exits. + */ + + atexit( Clock_exit ); +} + +/* + * Clean up before the application exits + */ + +void Clock_exit( void ) +{ + /* mips: turn off the timer interrupts */ + mips_disable_in_interrupt_mask(~CLOCK_VECTOR_MASK); +} + +/* + * Clock_initialize + * + * Device driver entry point for clock tick driver initialization. + */ + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + Install_clock( Clock_isr ); + + return RTEMS_SUCCESSFUL; +} + diff --git a/bsps/mips/hurricane/clock/clock.S b/bsps/mips/hurricane/clock/clock.S new file mode 100644 index 0000000000..0542de0cdc --- /dev/null +++ b/bsps/mips/hurricane/clock/clock.S @@ -0,0 +1,42 @@ +/* clock.s + * + * This file contains the assembly code for the Hurricane BSP clock driver. + * + * Author: Craig Lebakken <craigl@transition.com> + * + * COPYRIGHT (c) 1996 by Transition Networks Inc. + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Transition Networks not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * Transition Networks makes no representations about the suitability + * of this software for any purpose. + */ + +#include <iregdef.h> +#include <idtcpu.h> +#include <asm.h> + +FRAME(mips_set_timer,sp,0,ra) + .set noreorder + mfc0 t0,C0_COUNT + nop + addu t0,a0,t0 + mtc0 t0,C0_COMPARE + j ra + nop + .set reorder +ENDFRAME(mips_set_timer) + +FRAME(mips_get_timer,sp,0,ra) + .set noreorder + mfc0 v0,C0_COUNT + j ra + nop + .set reorder +ENDFRAME(mips_get_timer) diff --git a/bsps/mips/hurricane/clock/clock.h b/bsps/mips/hurricane/clock/clock.h new file mode 100644 index 0000000000..048074f6f0 --- /dev/null +++ b/bsps/mips/hurricane/clock/clock.h @@ -0,0 +1,21 @@ +/* clock.s + * + * This file contains the assembly code for the Hurricane BSP clock driver. + * + * Author: Craig Lebakken <craigl@transition.com> + * + * COPYRIGHT (c) 1996 by Transition Networks Inc. + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Transition Networks not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * Transition Networks makes no representations about the suitability + * of this software for any purpose. + */ + +extern void mips_set_timer( uint32_t timer_clock_interval ); diff --git a/bsps/mips/jmr3904/clock/clockdrv.c b/bsps/mips/jmr3904/clock/clockdrv.c new file mode 100644 index 0000000000..e0539f1f3f --- /dev/null +++ b/bsps/mips/jmr3904/clock/clockdrv.c @@ -0,0 +1,50 @@ +/** + * @file + * + * Instantiate the clock driver shell. + * + * The TX3904 simulator in gdb counts instructions. + */ + +/* + * COPYRIGHT (c) 1989-2012. + * 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.org/license/LICENSE. + */ + +#include <rtems.h> +#include <bsp/irq.h> +#include <bsp.h> + +#define CLOCK_DRIVER_USE_FAST_IDLE 1 + +#define CLOCK_VECTOR TX3904_IRQ_TMR0 + +/* + * 5000 clicks per tick ISR is HIGHLY arbitrary + */ + +#define CLICKS 5000 + +#define Clock_driver_support_install_isr( _new ) \ + rtems_interrupt_handler_install( CLOCK_VECTOR, "clock", 0, _new, NULL ) + +#define Clock_driver_support_initialize_hardware() \ + do { \ + uint32_t _clicks = CLICKS; \ + TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_CCDR, 0x3 ); \ + TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_CPRA, _clicks ); \ + TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_TISR, 0x00 ); \ + TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_ITMR, 0x8001 ); \ + TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_TCR, 0xC0 ); \ + *((volatile uint32_t*) 0xFFFFC01C) = 0x00000700; \ + } while(0) + +#define Clock_driver_support_shutdown_hardware() + +#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER + +#include "../../../shared/dev/clock/clockimpl.h" diff --git a/bsps/mips/rbtx4925/clock/clockdrv.c b/bsps/mips/rbtx4925/clock/clockdrv.c new file mode 100644 index 0000000000..2a3121a58e --- /dev/null +++ b/bsps/mips/rbtx4925/clock/clockdrv.c @@ -0,0 +1,120 @@ +/** + * @file + * + * Instantiate the clock driver shell. + */ + +/* + * COPYRIGHT (c) 1989-2012. + * 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.org/license/LICENSE. + */ + +#include <rtems.h> +#include <bsp/irq.h> +#include <bsp.h> + +/* #define CLOCK_DRIVER_USE_FAST_IDLE 1 */ + +#define CLOCK_VECTOR TX4925_IRQ_TMR0 + +#define TX4925_TIMER_INTERVAL_MODE 1 +#define TX4925_TIMER_PULSE_MODE 2 +#define TX4925_TIMER_MODE TX4925_TIMER_INTERVAL_MODE + +#if (TX4925_TIMER_MODE == TX4925_TIMER_INTERVAL_MODE) +#define TX4925_TIMER_INTERRUPT_FLAG TIIS +#define Clock_driver_support_initialize_hardware() \ + Initialize_timer0_in_interval_mode() +#elif (TX4925_TIMER_MODE == TX4925_TIMER_PULSE_MODE) +#define TX4925_TIMER_INTERRUPT_FLAG TPIBS +#define Clock_driver_support_initialize_hardware() \ + Initialize_timer0_in_pulse_mode() +#else +#error "Build Error: need to select timer mode" +#endif + + +#define Clock_driver_support_install_isr( _new ) \ + rtems_interrupt_handler_install( CLOCK_VECTOR, "clock", 0, _new, NULL ) + + +#define Clock_driver_support_at_tick() \ + do { \ + uint32_t interrupt_flag; \ + do { \ + int loop_count; \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TISR, 0x0 ); /* Clear timer 0 interrupt */ \ + loop_count = 0; \ + do { /* Wait until interrupt flag is cleared (this prevents re-entering interrupt) */ \ + /* Read back interrupt status register and isolate interval timer flag */ \ + interrupt_flag = TX4925_REG_READ( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TISR ) & TX4925_TIMER_INTERRUPT_FLAG; \ + } while (interrupt_flag && (++loop_count < 10)); /* Loop while timer interrupt bit is set, or loop count is lees than 10 */ \ + } while(interrupt_flag); \ + } while(0) + + +/* Setup timer in interval mode to generate peiodic interrupts */ +#define Initialize_timer0_in_interval_mode() \ + do { \ + uint32_t temp; \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TCR, 0x0 ); /* Disable timer */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CCDR, 0x0 ); /* Set register for divide by 2 clock */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_ITMR, TIMER_CLEAR_ENABLE_MASK ); /* Set interval timer mode register */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CPRA, 0x30d40 ); /* Set tmier period ,10.0 msec (20 MHz timer clock) */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TCR, 0xC0 ); /* Enable timer in interval mode */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_DM0, 0x0 ); /* Set interrupt controller detection mode */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_LVL2, 0x1000000 ); /* Set interrupt controller level */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_MSK, 0x0 ); /* Set interrupt controller mask */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_DEN, 0x1 ); /* Enable interrupts from controller */ \ + temp = TX4925_REG_READ( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_ITMR ); /* Enable interval timer interrupts */ \ + temp |= TIMER_INT_ENABLE_MASK; \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_ITMR, temp ); \ + } while(0) + + +/* This mode is used to generate periodic interrupts and also output a pulse on PIO20 pin */ +#define Initialize_timer0_in_pulse_mode() \ + do { \ + uint32_t temp; \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TCR, 0x0 ); /* Disable timer */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CCDR, 0x0 ); /* Set register for divide by 2 clock */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_PGMR, FFI ); /* Set pulse generator mode register */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CPRA, 0x3e8 ); /* Set pulse high duration ,0.05 msec (20 MHz timer clock) */ \ +/* TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CPRB, 0x1388 ); */ /* Set pulse total period, 0.25 msec (20 MHz timer clock) */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CPRB, 0x30d40 ); /* Set pulse total period, 10 msec (20 MHz timer clock) */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TCR, 0xC1 ); /* Enable timer in pulse generator mode */ \ + \ + /* Enable timer 0 output pulses on PIO20 */ \ + temp = TX4925_REG_READ( TX4925_REG_BASE, TX4925_CFG_PCFG ); \ + temp = (temp & ~ SELCHI) | SELTMR0; /* Enable timer 0 pulses on PIO20 */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_CFG_PCFG, temp ); \ + \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_DM0, 0x0 ); /* Set interrupt controller detection mode */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_LVL2, 0x1000000 ); /* Set interrupt controller level */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_MSK, 0x0 ); /* Set interrupt controller mask */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_DEN, 0x1 ); /* Enable interrupts from controller */ \ + temp = TX4925_REG_READ( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_PGMR ); /* Enable pulse generator interrupt */ \ + temp |= TPIBE; /* Only want interrupts on B compare (where clock count is cleared) */ \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_PGMR, temp ); \ + } while(0) + + +#define Clock_driver_support_shutdown_hardware() \ + do { \ + uint32_t temp; \ + temp = TX4925_REG_READ( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_ITMR ); /* Disable interval timer interrupt */ \ + temp &= ~TIMER_INT_ENABLE_MASK; \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_ITMR, temp ); \ + temp = TX4925_REG_READ( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_PGMR ); /* Disable pulse generator interrupt */ \ + temp &= ~(TPIAE | TPIBE); \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_PGMR, temp ); \ + TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TCR, 0x0 ); /* Disable timer */ \ + } while(0) + +#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER + +#include "../../../shared/dev/clock/clockimpl.h" diff --git a/bsps/mips/rbtx4938/clock/clockdrv.c b/bsps/mips/rbtx4938/clock/clockdrv.c new file mode 100644 index 0000000000..616defc91e --- /dev/null +++ b/bsps/mips/rbtx4938/clock/clockdrv.c @@ -0,0 +1,119 @@ +/** + * @file + * + * Instantiate the clock driver shell. + */ + +/* + * COPYRIGHT (c) 1989-2012. + * 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.org/license/LICENSE. + */ + +#include <rtems.h> +#include <bsp/irq.h> +#include <bsp.h> + +#include <stdio.h> +#include <stdlib.h> + +#include "yamon_api.h" + + +/* #define CLOCK_DRIVER_USE_FAST_IDLE 1 */ + +#define CLOCK_VECTOR TX4938_IRQ_TMR0 + +#define TX4938_TIMER_INTERVAL_MODE 1 + +#define TX4938_TIMER_MODE TX4938_TIMER_INTERVAL_MODE + +#if (TX4938_TIMER_MODE == TX4938_TIMER_INTERVAL_MODE) +#define TX4938_TIMER_INTERRUPT_FLAG TIIS +#define Clock_driver_support_initialize_hardware() \ + Initialize_timer0_in_interval_mode() +#else +#error "Build Error: unsupported timer mode" +#endif + +void new_brk_esr(void); + +t_yamon_retfunc esr_retfunc = 0; +t_yamon_ref original_brk_esr = 0; +t_yamon_ref original_tmr0_isr = 0; + +void new_brk_esr(void) +{ + if (original_tmr0_isr) + { + YAMON_FUNC_DEREGISTER_IC_ISR( original_tmr0_isr ); + original_tmr0_isr = 0; + } + if (esr_retfunc) + esr_retfunc(); +} + + +#define Clock_driver_support_install_isr( _new ) \ + do { \ + rtems_interrupt_handler_install( \ + CLOCK_VECTOR, \ + "clock", \ + 0, \ + _new, \ + NULL \ + ); \ + YAMON_FUNC_REGISTER_IC_ISR(17,(t_yamon_isr)_new,0,&original_tmr0_isr); /* Call Yamon to enable interrupt */ \ + } while(0) + + +#define Clock_driver_support_at_tick() \ + do { \ + uint32_t interrupt_flag; \ + do { \ + int loop_count; \ + TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_TISR, 0x0 ); /* Clear timer 0 interrupt */ \ + loop_count = 0; \ + do { /* Wait until interrupt flag is cleared (this prevents re-entering interrupt) */ \ + /* Read back interrupt status register and isolate interval timer flag */ \ + interrupt_flag = TX4938_REG_READ( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_TISR ) & TX4938_TIMER_INTERRUPT_FLAG; \ + } while (interrupt_flag && (++loop_count < 10)); /* Loop while timer interrupt bit is set, or loop count is lees than 10 */ \ + } while(interrupt_flag); \ + } while(0) + + +/* Setup timer in interval mode to generate peiodic interrupts */ +#define Initialize_timer0_in_interval_mode() \ + do { \ + uint32_t temp; \ + TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_TCR, 0x0 ); /* Disable timer */ \ + TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_CCDR, 0x0 ); /* Set register for divide by 2 clock */ \ + TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_ITMR, TIMER_CLEAR_ENABLE_MASK ); /* Set interval timer mode register */ \ + TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_CPRA, 0x3d090 ); /* Set tmier period ,10.0 msec (25 MHz timer clock) */ \ + TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_TCR, 0xC0 ); /* Enable timer in interval mode */ \ + temp = TX4938_REG_READ( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_ITMR ); /* Enable interval timer interrupts */ \ + temp |= TIMER_INT_ENABLE_MASK; \ + TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_ITMR, temp ); \ + } while(0) + + + +#define Clock_driver_support_shutdown_hardware() \ + do { \ + uint32_t temp; \ + temp = TX4938_REG_READ( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_ITMR ); /* Disable interval timer interrupt */ \ + temp &= ~TIMER_INT_ENABLE_MASK; \ + TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_ITMR, temp ); \ + temp = TX4938_REG_READ( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_PGMR ); /* Disable pulse generator interrupt */ \ + temp &= ~(TPIAE | TPIBE); \ + TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_PGMR, temp ); \ + TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_TCR, 0x0 ); /* Disable timer */ \ + } while(0) + + +#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER + +#include "../../../shared/dev/clock/clockimpl.h" diff --git a/bsps/mips/rbtx4938/clock/yamon_api.h b/bsps/mips/rbtx4938/clock/yamon_api.h new file mode 100644 index 0000000000..529cf16a3f --- /dev/null +++ b/bsps/mips/rbtx4938/clock/yamon_api.h @@ -0,0 +1,631 @@ +/************************************************************************ + * + * yamon_api.h + * + * YAMON interface definitions + * + * ###################################################################### + * + * mips_start_of_legal_notice + * + * Copyright (c) 2003 MIPS Technologies, Inc. All rights reserved. + * + * + * Unpublished rights (if any) reserved under the copyright laws of the + * United States of America and other countries. + * + * This code is proprietary to MIPS Technologies, Inc. ("MIPS + * Technologies"). Any copying, reproducing, modifying or use of this code + * (in whole or in part) that is not expressly permitted in writing by MIPS + * Technologies or an authorized third party is strictly prohibited. At a + * minimum, this code is protected under unfair competition and copyright + * laws. Violations thereof may result in criminal penalties and fines. + * + * MIPS Technologies reserves the right to change this code to improve + * function, design or otherwise. MIPS Technologies does not assume any + * liability arising out of the application or use of this code, or of any + * error or omission in such code. Any warranties, whether express, + * statutory, implied or otherwise, including but not limited to the implied + * warranties of merchantability or fitness for a particular purpose, are + * excluded. Except as expressly provided in any written license agreement + * from MIPS Technologies or an authorized third party, the furnishing of + * this code does not give recipient any license to any intellectual + * property rights, including any patent rights, that cover this code. + * + * This code shall not be exported or transferred for the purpose of + * reexporting in violation of any U.S. or non-U.S. regulation, treaty, + * Executive Order, law, statute, amendment or supplement thereto. + * + * This code constitutes one or more of the following: commercial computer + * software, commercial computer software documentation or other commercial + * items. If the user of this code, or any related documentation of any + * kind, including related technical data or manuals, is an agency, + * department, or other entity of the United States government + * ("Government"), the use, duplication, reproduction, release, + * modification, disclosure, or transfer of this code, or any related + * documentation of any kind, is restricted in accordance with Federal + * Acquisition Regulation 12.212 for civilian agencies and Defense Federal + * Acquisition Regulation Supplement 227.7202 for military agencies. The use + * of this code by the Government is further restricted in accordance with + * the terms of the license agreement(s) and/or applicable contract terms + * and conditions covering this code from MIPS Technologies or an authorized + * third party. + * + * + * mips_end_of_legal_notice + * + * + ************************************************************************/ + +#ifndef YAMON_API_H +#define YAMON_API_H + +/************************************************************************ + * Include files + ************************************************************************/ + + +/************************************************************************ + * Definitions +*************************************************************************/ + +/* Basic types */ + +typedef unsigned int t_yamon_uint32; +typedef unsigned short t_yamon_uint16; +typedef unsigned char t_yamon_uint8; +typedef signed int t_yamon_int32; +typedef signed short t_yamon_int16; +typedef signed char t_yamon_int8; + +typedef unsigned char t_yamon_bool; + +#define YAMON_FALSE 0 +#define YAMON_TRUE (!YAMON_FALSE) + +/* YAMON Environment variable */ +typedef struct +{ + char *name; + char *val; +} +t_yamon_env_var; + +/* Format of application function */ +typedef t_yamon_uint32 +(*t_yamon_appl_main)( + t_yamon_uint32 argc, /* Number of tokens in argv array */ + char **argv, /* Array of tokens (first is "go") */ + t_yamon_env_var *env, /* Array of env. variables */ + t_yamon_uint32 memsize ); /* Size of memory (byte count) */ + + +/* ID of YAMON configuration object */ +typedef t_yamon_uint32 t_yamon_syscon_id; + + +/* Number used by the exception registration functions in order to register + * a default ISR/ESR. + */ +#define YAMON_DEFAULT_HANDLER 0xfffffff0 + +/* Number used by the exception registration functions in order to register + * an EJTAG debug exception ESR. + */ +#define YAMON_DEFAULT_EJTAG_ESR 0xfffffff1 + +/* Registered Interrupt Service Routine (ISR) */ +typedef void (*t_yamon_isr)(void *data); + +/* Registered Exception Service Routine (ESR) */ +typedef void (*t_yamon_esr)(void); + +/* Entry point called by ESRs wishing to pass control back to YAMON */ +typedef void (*t_yamon_retfunc)(void); + +/* Handle used for deregistration of ISR/ESR */ +typedef void *t_yamon_ref; + + +/* YAMONE Vector table address */ +#define YAMON_FUNCTION_BASE 0x9fc00500 + +/* YAMON Vector table offsets */ +#define YAMON_FUNC_PRINT_COUNT_OFS 0x04 +#define YAMON_FUNC_EXIT_OFS 0x20 +#define YAMON_FUNC_FLUSH_CACHE_OFS 0x2C +#define YAMON_FUNC_PRINT_OFS 0x34 +#define YAMON_FUNC_REGISTER_CPU_ISR_OFS 0x38 +#define YAMON_FUNC_DEREGISTER_CPU_ISR_OFS 0x3c +#define YAMON_FUNC_REGISTER_IC_ISR_OFS 0x40 +#define YAMON_FUNC_DEREGISTER_IC_ISR_OFS 0x44 +#define YAMON_FUNC_REGISTER_ESR_OFS 0x48 +#define YAMON_FUNC_DEREGISTER_ESR_OFS 0x4c +#define YAMON_FUNC_GETCHAR_OFS 0x50 +#define YAMON_FUNC_SYSCON_READ_OFS 0x54 + +/* Macro for accessing YAMON function */ +#define YAMON_FUNC(ofs)\ + (*(t_yamon_uint32 *)(YAMON_FUNCTION_BASE + (ofs))) + + +/************************************************************************ + * Public variables + ************************************************************************/ + +/************************************************************************ + * Public functions + ************************************************************************/ + + +/************************************************************************ + * + * t_yamon_exit + * Description : + * ------------- + * + * Exit application and return to YAMON. + * + * Parameters : + * ------------ + * + * 'rc' (OUT) : Return code + * + * Return values : + * --------------- + * + * None (never returns) + * + ************************************************************************/ +typedef void +(*t_yamon_exit)( + t_yamon_uint32 rc ); /* Return code */ + +#define YAMON_FUNC_EXIT( rc )\ + ((t_yamon_exit)( YAMON_FUNC(YAMON_FUNC_EXIT_OFS) ))\ + ( rc ) + + +/************************************************************************ + * + * t_yamon_print + * Description : + * ------------- + * + * Print null-terminated string to tty0. + * + * Parameters : + * ------------ + * + * 'port' (OUT) : Ignored, always prints to tty0. Not included in macro. + * 's' (OUT) : String to print. + * + * Return values : + * --------------- + * + * None + * + ************************************************************************/ +typedef void +(*t_yamon_print)( + t_yamon_uint32 port, /* Output port (not used, always tty0) */ + const char *s ); /* String to output */ + +#define YAMON_FUNC_PRINT( s )\ + ((t_yamon_print)( YAMON_FUNC(YAMON_FUNC_PRINT_OFS) ))\ + ( 0, s ) + + +/************************************************************************ + * + * t_yamon_print_count + * Description : + * ------------- + * + * Print specified number of characters to tty0. + * + * Parameters : + * ------------ + * + * 'port' (OUT) : Ignored, always prints to tty0. Not included in macro. + * 's' (OUT) : Array of characters to print. + * 'count' (OUT) : Number of characters to print. + * + * Return values : + * --------------- + * + * None + * + ************************************************************************/ +typedef void +(*t_yamon_print_count)( + t_yamon_uint32 port, /* Output port (not used, always tty0 */ + char *s, /* String to output */ + t_yamon_uint32 count ); /* Number of characters to output */ + +#define YAMON_FUNC_PRINT_COUNT( s, count )\ + ((t_yamon_print_count)( YAMON_FUNC(YAMON_FUNC_PRINT_COUNT_OFS) ))\ + ( 0, s, count ) + + +/************************************************************************ + * + * t_yamon_getchar + * Description : + * ------------- + * + * Get character from tty0 if character is available. Function + * returns immediately if no character is available. + * + * Parameters : + * ------------ + * + * 'port' (OUT) : Ignored, always uses tty0. Not included in macro. + * 'ch' (OUT) : Character read (if available). + * + * Return values : + * --------------- + * + * YAMON_TRUE if character was available, else YAMON_FALSE. + * + ************************************************************************/ +typedef t_yamon_bool +(*t_yamon_getchar)( + t_yamon_uint32 port, /* Output port (not used, always tty0 */ + char *ch ); /* Character to output */ + +#define YAMON_FUNC_GETCHAR( ch )\ + ((t_yamon_getchar)( YAMON_FUNC(YAMON_FUNC_GETCHAR_OFS) ))\ + ( 0, ch ) + + +/************************************************************************ + * + * t_yamon_syscon_read + * Description : + * ------------- + * + * Read the value of system configuration object given by 'id'. + * + * See syscon_api.h in YAMON source distribution for further details + * on object IDs and error codes. + * + * Parameters : + * ------------ + * + * 'id' (IN) : Object id. + * 'param' (INOUT) : Buffer for object value. + * 'size' (IN) : Size of buffer (must match size of object). + * + * Return values : + * --------------- + * + * 0 : Returned parameter is valid. + * Other values indicate error. + * + ************************************************************************/ +typedef t_yamon_int32 +(*t_yamon_syscon_read)( + t_yamon_syscon_id id, /* Object ID */ + void *param, /* Buffer for object value */ + t_yamon_uint32 size); /* Buffer size (bytes) */ + +#define YAMON_FUNC_SYSCON_READ( id, param, size )\ + ((t_yamon_syscon_read)( YAMON_FUNC(YAMON_FUNC_SYSCON_READ_OFS) ))\ + ( id, param, size ) + + +/************************************************************************ + * + * t_yamon_flush_cache + * Description : + * ------------- + * + * Flush I-or D-cache + * + * Function performs "writeback and invalidate" operations on D-cache + * lines and "invalidate" operations on I-cache lines. + * + * Parameters : + * ------------ + * + * 'type' (IN) : Cache to be flushed. + * + * Return values : + * --------------- + * + * None + * + ************************************************************************/ +typedef void +(*t_yamon_flush_cache)( +#define YAMON_FLUSH_ICACHE 0 +#define YAMON_FLUSH_DCACHE 1 + t_yamon_uint32 type ); /* I- or D-cache indication */ + +#define YAMON_FUNC_FLUSH_CACHE( type )\ + ((t_yamon_flush_cache)( YAMON_FUNC(YAMON_FUNC_FLUSH_CACHE_OFS) ))\ + ( type ) + + +/************************************************************************ + * + * t_yamon_register_esr + * Description : + * ------------- + * + * Registers an exception handler, also known as an "Exception Service + * Routine" (ESR) for the specified exception. + * + * Two special exception IDs are defined : + * YAMON_DEFAULT_HANDLER used for a default ESR. + * YAMON_DEFAULT_EJTAG_ESR used for EJTAG exceptions. + * + * The default ESR is called if no other ESR is registered + * for an exception. If no default ESR is registered, a static + * (i.e. not registered) "super default" function is invoked. + * This function prints out the registers and halts. + * + * Deregistration of an ESR may be be done by calling this function + * with 'esr' set to NULL. + * An ESR can also be deregistered using the 'yamon_deregister_esr' + * function. + * + * An ESR may be registered even if a previously registered + * ESR has not been deregistered. In this case the previously + * registered ESR is lost. + * + * The ESR will get called with registers in the state they were + * when the exception occurred. This includes all CP0 registers and + * CPU registers $0..$31, except for k0,k1 ($26,$27). + * + * In case an ESR does not want to handle the exception, it may + * call the return function passed in the 'retfunc' parameter. + * + * Case 1 : 'retfunc' called by ESR registered for the + * INTERRUPT exception. + * + * We assume an application has registered this ESR and wants + * YAMON to process the (remaining) interrupts. + * + * Case 2 : 'retfunc' called by an ESR registered for a specific + * exception (not INTERRUPT). + * + * Default handling will be done. + * + * Case 3 : 'retfunc' is called by the ESR registered as default ESR. + * + * The exception will be handled as though no ESR is registered + * (i.e. the "super default" function is called). + * + * Parameters : + * ------------ + * + * 'exception' (IN) : Exception code + * or YAMON_DEFAULT_HANDLER for a default ESR + * or YAMON_DEFAULT_EJTAG_ESR for ejtag exceptions. + * 'esr' (IN) : Function pointer for ESR. + * 'ref' (OUT) : Handle used for deregistration of ESR. + * 'retfunc' (OUT) : Pointer to function pointer for the return + * function described above. + * + * Return values : + * --------------- + * + * 0 : Registration went well. + * Other values indicate error. + * + ************************************************************************/ +typedef t_yamon_int32 +(*t_yamon_register_esr)( + t_yamon_uint32 exception, /* Exception identification */ + t_yamon_esr esr, /* ESR to be registered */ + t_yamon_ref *ref, /* Handle for deregistration */ + t_yamon_retfunc *retfunc ); /* Return function */ + +#define YAMON_FUNC_REGISTER_ESR( exc, esr, ref, retfunc )\ + ((t_yamon_register_esr)( YAMON_FUNC(YAMON_FUNC_REGISTER_ESR_OFS) ))\ + ( exc, esr, ref, retfunc ) + + +/************************************************************************ + * + * t_yamon_deregister_esr + * Description : + * ------------- + * + * Deregisters ESR.. + * + * Parameters : + * ------------ + * + * 'ref' (IN) : Handle obtained when calling 'yamon_register_esr'. + * + * Return values : + * --------------- + * + * 0 : Deregistration went well. + * Other values indicate error. + * + ************************************************************************/ +typedef t_yamon_int32 +(*t_yamon_deregister_esr)( + t_yamon_ref ref ); /* Handle for deregistration */ + +#define YAMON_FUNC_DEREGISTER_ESR( ref )\ + ((t_yamon_deregister_esr)( YAMON_FUNC(YAMON_FUNC_DEREGISTER_ESR_OFS) ))\ + ( ref ) + + +/************************************************************************ + * + * t_yamon_register_cpu_isr + * Description : + * ------------- + * + * Registers an Interrupt Service Routine (ISR) for the specified + * CPU interrupt. + * The highest service priority is attached to HW-INT5, which is + * connected to the CPU-built-in CP0-timer. SW_INT0 gets the lowest + * service priority. During registration, the interrupt mask field + * in the CPU CP0-status register is updated to enable interrupts + * from the specified interrupt source. + * + * A special ID is defined : + * YAMON_DEFAULT_HANDLER used for a default ISR. + * + * The default ISR is called if no other ISR is registered + * for a CPU interrupt. + * + * Deregistration of the default ISR may be done by calling + * this function with 'isr' set to NULL. + * Also, a new default ISR may be registered even if a + * previously registered ISR has not been deregistered. + * ISRs for specific CPU interrupts must be deregistered using + * 'yamon_deregister_cpu_isr'. + * + * Parameters : + * ------------ + * + * 'cpu_int' (IN) : CPU interrupt (0..7) + * or YAMON_DEFAULT_HANDLER for a default ISR. + * 'isr' (IN) : Function pointer for ISR. + * 'data' (IN) : Data pointer (may be NULL). Will be passed to + * ISR when called. + * 'ref' (OUT) : Handle used for deregistration of ISR. + * + * Return values : + * --------------- + * + * 0 : Registration went well. + * Other values indicate error. + * + ************************************************************************/ +typedef t_yamon_int32 +(*t_yamon_register_cpu_isr)( + t_yamon_uint32 cpu_int, /* CPU interrupt (0..7) */ + t_yamon_isr isr, /* ISR to be registered */ + void *data, /* Data reference to be registered */ + t_yamon_ref *ref ); /* Handle for deregistration */ + +#define YAMON_FUNC_REGISTER_CPU_ISR( cpu_int, isr, data, ref )\ + ((t_yamon_register_cpu_isr)( YAMON_FUNC(YAMON_FUNC_REGISTER_CPU_ISR_OFS) ))\ + ( cpu_int, isr, data, ref ) + + +/************************************************************************ + * + * t_yamon_deregister_cpu_isr + * Description : + * ------------- + * + * Deregisters ISR for CPU interrupt. + * + * Parameters : + * ------------ + * + * 'ref' (IN) : Handle obtained when calling 'yamon_register_cpu_isr'. + * + * Return values : + * --------------- + * + * 0 : Deregistration went well. + * Other values indicate error + * + ************************************************************************/ +typedef t_yamon_int32 +(*t_yamon_deregister_cpu_isr)( + t_yamon_ref ref ); /* Handle for deregistration */ + +#define YAMON_FUNC_DEREGISTER_CPU_ISR( ref )\ + ((t_yamon_deregister_cpu_isr)( YAMON_FUNC(YAMON_FUNC_DEREGISTER_CPU_ISR_OFS) ))\ + ( ref ) + + +/************************************************************************ + * + * t_yamon_register_ic_isr + * Description : + * ------------- + * + * Registers an Interrupt Service Routine (ISR) for the specified + * source in the interrupt controller. + * + * A special ID is defined : + * YAMON_DEFAULT_HANDLER used for a default ISR. + * + * The default ISR is called if no other ISR is registered + * for an interrupt. + * + * Deregistration of the default ISR may be done by calling + * this function with 'isr' set to NULL. + * Also, a new default ISR may be registered even if a + * previously registered ISR has not been deregistered. + * ISRs for specific interrupts must be deregistered using + * 'yamon_deregister_ic_isr'. + * + * Parameters : + * ------------ + * + * 'ic_line' (IN) : Interrupt source line in Int. Controller + * or YAMON_DEFAULT_HANDLER for a default ISR. + * 'isr', (IN) : Function pointer for user defined ISR. + * 'data' (IN) : Data pointer (may be NULL). Will be passed to + * ISR when called. + * 'ref', (OUT) : Handle used for deregistration of ISR. + * + * Return values : + * --------------- + * + * 0 : Registration went well. + * Other values indicate error. + * + ************************************************************************/ +typedef t_yamon_int32 +(*t_yamon_register_ic_isr)( + t_yamon_uint32 ic_line, /* Interrupt controller line */ + t_yamon_isr isr, /* ISR to be registered */ + void *data, /* Data reference to be registered */ + t_yamon_ref *ref ); /* Handle for deregistration */ + +#define YAMON_FUNC_REGISTER_IC_ISR( ic_line, isr, data, ref )\ + ((t_yamon_register_ic_isr)( YAMON_FUNC(YAMON_FUNC_REGISTER_IC_ISR_OFS) ))\ + ( ic_line, isr, data, ref ) + + +/************************************************************************ + * + * t_yamon_deregister_ic_isr + * Description : + * ------------- + * + * Deregisters ISR for source in interrupt controller. + * + * Parameters : + * ------------ + * + * 'ref' (IN) : Handle obtained when calling 'yamon_register_ic_isr'. + * + * Return values : + * --------------- + * + * 0 : Deregistration went well. + * Other values indicate error + * + ************************************************************************/ +typedef t_yamon_int32 +(*t_yamon_deregister_ic_isr)( + t_yamon_ref ref ); /* Handle for deregistration */ + +#define YAMON_FUNC_DEREGISTER_IC_ISR( ref )\ + ((t_yamon_deregister_ic_isr)( YAMON_FUNC(YAMON_FUNC_DEREGISTER_IC_ISR_OFS) ))\ + ( ref ) + + +#endif /* #ifndef YAMON_API_H */ + + + + + + diff --git a/bsps/mips/shared/clock/clockdrv.c b/bsps/mips/shared/clock/clockdrv.c new file mode 100644 index 0000000000..658666c887 --- /dev/null +++ b/bsps/mips/shared/clock/clockdrv.c @@ -0,0 +1,49 @@ +/* + * COPYRIGHT (c) 1989-2013. + * 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.org/license/LICENSE. + */ + +#include <bsp.h> +#include <bsp/irq.h> +#include <bspopts.h> + +/* XXX convert to macros? Move to score/cpu? */ +void mips_set_timer(uint32_t timer_clock_interval); +uint32_t mips_get_timer(void); + +/* XXX move to BSP.h or irq.h?? */ +#define EXT_INT5 0x8000 /* external interrupt 5 */ +#define CLOCK_VECTOR_MASK EXT_INT5 +#define CLOCK_VECTOR (MIPS_INTERRUPT_BASE+0x7) + +extern uint32_t bsp_clicks_per_microsecond; + +static uint32_t mips_timer_rate = 0; + +/* refresh the internal CPU timer */ +#define Clock_driver_support_at_tick() \ + mips_set_timer( mips_timer_rate ); + +#define Clock_driver_support_install_isr( _new ) \ + rtems_interrupt_handler_install(CLOCK_VECTOR, "PIT clock",0, _new, NULL) + +#define Clock_driver_support_initialize_hardware() \ + do { \ + mips_timer_rate = rtems_configuration_get_microseconds_per_tick() * \ + bsp_clicks_per_microsecond; \ + mips_set_timer( mips_timer_rate ); \ + mips_enable_in_interrupt_mask(CLOCK_VECTOR_MASK); \ + } while(0) + +#define Clock_driver_support_shutdown_hardware() \ + do { \ + mips_disable_in_interrupt_mask(CLOCK_VECTOR_MASK); \ + } while (0) + +#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER + +#include "../../../shared/dev/clock/clockimpl.h" diff --git a/bsps/mips/shared/clock/mips_timer.S b/bsps/mips/shared/clock/mips_timer.S new file mode 100644 index 0000000000..2e9ff1ea26 --- /dev/null +++ b/bsps/mips/shared/clock/mips_timer.S @@ -0,0 +1,43 @@ +/* clock.s + * + * This file contains the assembly code for the IDT 4650 clock driver. + * + * Author: Craig Lebakken <craigl@transition.com> + * + * COPYRIGHT (c) 1996 by Transition Networks Inc. + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Transition Networks not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * Transition Networks makes no representations about the suitability + * of this software for any purpose. + */ +/* @(#)clock.S 08/20/96 1.2 */ + +#include <rtems/mips/iregdef.h> +#include <rtems/mips/idtcpu.h> +#include <rtems/asm.h> + +FRAME(mips_set_timer,sp,0,ra) + .set noreorder + mfc0 t0,C0_COUNT + nop + addu t0,a0,t0 + mtc0 t0,C0_COMPARE + j ra + nop + .set reorder +ENDFRAME(mips_set_timer) + +FRAME(mips_get_timer,sp,0,ra) + .set noreorder + mfc0 v0,C0_COUNT + j ra + nop + .set reorder +ENDFRAME(mips_get_timer) |