Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:08

0001 /**
0002  * @file
0003  * @ingroup sparc_erc32
0004  * @brief Contains information pertaining to the ERC32
0005  */
0006 
0007 /*  erc32.h
0008  *
0009  *  This include file contains information pertaining to the ERC32.
0010  *  The ERC32 is a custom SPARC V7 implementation based on the Cypress
0011  *  601/602 chipset.  This CPU has a number of on-board peripherals and
0012  *  was developed by the European Space Agency to target space applications.
0013  *
0014  *  NOTE:  Other than where absolutely required, this version currently
0015  *         supports only the peripherals and bits used by the basic board
0016  *         support package. This includes at least significant pieces of
0017  *         the following items:
0018  *
0019  *           + UART Channels A and B
0020  *           + General Purpose Timer
0021  *           + Real Time Clock
0022  *           + Watchdog Timer (so it can be disabled)
0023  *           + Control Register (so powerdown mode can be enabled)
0024  *           + Memory Control Register
0025  *           + Interrupt Control
0026  *
0027  *  COPYRIGHT (c) 1989-1999.
0028  *  On-Line Applications Research Corporation (OAR).
0029  *
0030  *  The license and distribution terms for this file may be
0031  *  found in the file LICENSE in this distribution or at
0032  *  http://www.rtems.org/license/LICENSE.
0033  *
0034  *  Ported to ERC32 implementation of the SPARC by On-Line Applications
0035  *  Research Corporation (OAR) under contract to the European Space
0036  *  Agency (ESA).
0037  *
0038  *  ERC32 modifications of respective RTEMS file: COPYRIGHT (c) 1995.
0039  *  European Space Agency.
0040  */
0041 
0042 #ifndef _INCLUDE_ERC32_h
0043 #define _INCLUDE_ERC32_h
0044 
0045 #include <rtems/score/sparc.h>
0046 
0047 #ifdef __cplusplus
0048 extern "C" {
0049 #endif
0050 
0051 /*
0052  *  Interrupt Sources
0053  *
0054  *  The interrupt source numbers directly map to the trap type and to
0055  *  the bits used in the Interrupt Clear, Interrupt Force, Interrupt Mask,
0056  *  and the Interrupt Pending Registers.
0057  */
0058 
0059 #define ERC32_INTERRUPT_MASKED_ERRORS             1
0060 #define ERC32_INTERRUPT_EXTERNAL_1                2
0061 #define ERC32_INTERRUPT_EXTERNAL_2                3
0062 #define ERC32_INTERRUPT_UART_A_RX_TX              4
0063 #define ERC32_INTERRUPT_UART_B_RX_TX              5
0064 #define ERC32_INTERRUPT_CORRECTABLE_MEMORY_ERROR  6
0065 #define ERC32_INTERRUPT_UART_ERROR                7
0066 #define ERC32_INTERRUPT_DMA_ACCESS_ERROR          8
0067 #define ERC32_INTERRUPT_DMA_TIMEOUT               9
0068 #define ERC32_INTERRUPT_EXTERNAL_3               10
0069 #define ERC32_INTERRUPT_EXTERNAL_4               11
0070 #define ERC32_INTERRUPT_GENERAL_PURPOSE_TIMER    12
0071 #define ERC32_INTERRUPT_REAL_TIME_CLOCK          13
0072 #define ERC32_INTERRUPT_EXTERNAL_5               14
0073 #define ERC32_INTERRUPT_WATCHDOG_TIMEOUT         15
0074 
0075 #ifndef ASM
0076 
0077 /*
0078  *  Trap Types for on-chip peripherals
0079  *
0080  *  Source: Table 8 - Interrupt Trap Type and Default Priority Assignments
0081  *
0082  *  NOTE: The priority level for each source corresponds to the least
0083  *        significant nibble of the trap type.
0084  */
0085 
0086 #define ERC32_TRAP_TYPE( _source ) SPARC_INTERRUPT_SOURCE_TO_TRAP( _source )
0087 
0088 #define ERC32_TRAP_SOURCE( _trap ) SPARC_INTERRUPT_TRAP_TO_SOURCE( _trap )
0089 
0090 #define ERC32_Is_MEC_Trap( _trap ) SPARC_IS_INTERRUPT_TRAP( _trap )
0091 
0092 /*
0093  *  Structure for ERC32 memory mapped registers.
0094  *
0095  *  Source: Section 3.25.2 - Register Address Map
0096  *
0097  *  NOTE:  There is only one of these structures per CPU, its base address
0098  *         is 0x01f80000, and the variable MEC is placed there by the
0099  *         linkcmds file.
0100  */
0101 
0102 typedef struct {
0103   volatile uint32_t    Control;                              /* offset 0x00 */
0104   volatile uint32_t    Software_Reset;                       /* offset 0x04 */
0105   volatile uint32_t    Power_Down;                           /* offset 0x08 */
0106   volatile uint32_t    Unimplemented_0;                      /* offset 0x0c */
0107   volatile uint32_t    Memory_Configuration;                 /* offset 0x10 */
0108   volatile uint32_t    IO_Configuration;                     /* offset 0x14 */
0109   volatile uint32_t    Wait_State_Configuration;             /* offset 0x18 */
0110   volatile uint32_t    Unimplemented_1;                      /* offset 0x1c */
0111   volatile uint32_t    Memory_Access_0;                      /* offset 0x20 */
0112   volatile uint32_t    Memory_Access_1;                      /* offset 0x24 */
0113   volatile uint32_t    Unimplemented_2[ 7 ];                 /* offset 0x28 */
0114   volatile uint32_t    Interrupt_Shape;                      /* offset 0x44 */
0115   volatile uint32_t    Interrupt_Pending;                    /* offset 0x48 */
0116   volatile uint32_t    Interrupt_Mask;                       /* offset 0x4c */
0117   volatile uint32_t    Interrupt_Clear;                      /* offset 0x50 */
0118   volatile uint32_t    Interrupt_Force;                      /* offset 0x54 */
0119   volatile uint32_t    Unimplemented_3[ 2 ];                 /* offset 0x58 */
0120                                                              /* offset 0x60 */
0121   volatile uint32_t    Watchdog_Program_and_Timeout_Acknowledge;
0122   volatile uint32_t    Watchdog_Trap_Door_Set;               /* offset 0x64 */
0123   volatile uint32_t    Unimplemented_4[ 6 ];                 /* offset 0x68 */
0124   volatile uint32_t    Real_Time_Clock_Counter;              /* offset 0x80 */
0125   volatile uint32_t    Real_Time_Clock_Scalar;               /* offset 0x84 */
0126   volatile uint32_t    General_Purpose_Timer_Counter;        /* offset 0x88 */
0127   volatile uint32_t    General_Purpose_Timer_Scalar;         /* offset 0x8c */
0128   volatile uint32_t    Unimplemented_5[ 2 ];                 /* offset 0x90 */
0129   volatile uint32_t    Timer_Control;                        /* offset 0x98 */
0130   volatile uint32_t    Unimplemented_6;                      /* offset 0x9c */
0131   volatile uint32_t    System_Fault_Status;                  /* offset 0xa0 */
0132   volatile uint32_t    First_Failing_Address;                /* offset 0xa4 */
0133   volatile uint32_t    First_Failing_Data;                   /* offset 0xa8 */
0134   volatile uint32_t    First_Failing_Syndrome_and_Check_Bits;/* offset 0xac */
0135   volatile uint32_t    Error_and_Reset_Status;               /* offset 0xb0 */
0136   volatile uint32_t    Error_Mask;                           /* offset 0xb4 */
0137   volatile uint32_t    Unimplemented_7[ 2 ];                 /* offset 0xb8 */
0138   volatile uint32_t    Debug_Control;                        /* offset 0xc0 */
0139   volatile uint32_t    Breakpoint;                           /* offset 0xc4 */
0140   volatile uint32_t    Watchpoint;                           /* offset 0xc8 */
0141   volatile uint32_t    Unimplemented_8;                      /* offset 0xcc */
0142   volatile uint32_t    Test_Control;                         /* offset 0xd0 */
0143   volatile uint32_t    Test_Data;                            /* offset 0xd4 */
0144   volatile uint32_t    Unimplemented_9[ 2 ];                 /* offset 0xd8 */
0145   volatile uint32_t    UART_Channel_A;                       /* offset 0xe0 */
0146   volatile uint32_t    UART_Channel_B;                       /* offset 0xe4 */
0147   volatile uint32_t    UART_Status;                          /* offset 0xe8 */
0148 } ERC32_Register_Map;
0149 
0150 #endif
0151 
0152 /*
0153  *  The following constants are intended to be used ONLY in assembly
0154  *  language files.
0155  *
0156  *  NOTE:  The intended style of usage is to load the address of MEC
0157  *         into a register and then use these as displacements from
0158  *         that register.
0159  */
0160 
0161 #ifdef ASM
0162 
0163 #define  ERC32_MEC_CONTROL_OFFSET                                  0x00
0164 #define  ERC32_MEC_SOFTWARE_RESET_OFFSET                           0x04
0165 #define  ERC32_MEC_POWER_DOWN_OFFSET                               0x08
0166 #define  ERC32_MEC_UNIMPLEMENTED_0_OFFSET                          0x0C
0167 #define  ERC32_MEC_MEMORY_CONFIGURATION_OFFSET                     0x10
0168 #define  ERC32_MEC_IO_CONFIGURATION_OFFSET                         0x14
0169 #define  ERC32_MEC_WAIT_STATE_CONFIGURATION_OFFSET                 0x18
0170 #define  ERC32_MEC_UNIMPLEMENTED_1_OFFSET                          0x1C
0171 #define  ERC32_MEC_MEMORY_ACCESS_0_OFFSET                          0x20
0172 #define  ERC32_MEC_MEMORY_ACCESS_1_OFFSET                          0x24
0173 #define  ERC32_MEC_UNIMPLEMENTED_2_OFFSET                          0x28
0174 #define  ERC32_MEC_INTERRUPT_SHAPE_OFFSET                          0x44
0175 #define  ERC32_MEC_INTERRUPT_PENDING_OFFSET                        0x48
0176 #define  ERC32_MEC_INTERRUPT_MASK_OFFSET                           0x4C
0177 #define  ERC32_MEC_INTERRUPT_CLEAR_OFFSET                          0x50
0178 #define  ERC32_MEC_INTERRUPT_FORCE_OFFSET                          0x54
0179 #define  ERC32_MEC_UNIMPLEMENTED_3_OFFSET                          0x58
0180 #define  ERC32_MEC_WATCHDOG_PROGRAM_AND_TIMEOUT_ACKNOWLEDGE_OFFSET 0x60
0181 #define  ERC32_MEC_WATCHDOG_TRAP_DOOR_SET_OFFSET                   0x64
0182 #define  ERC32_MEC_UNIMPLEMENTED_4_OFFSET                          0x6C
0183 #define  ERC32_MEC_REAL_TIME_CLOCK_COUNTER_OFFSET                  0x80
0184 #define  ERC32_MEC_REAL_TIME_CLOCK_SCALAR_OFFSET                   0x84
0185 #define  ERC32_MEC_GENERAL_PURPOSE_TIMER_COUNTER_OFFSET            0x88
0186 #define  ERC32_MEC_GENERAL_PURPOSE_TIMER_SCALAR_OFFSET             0x8C
0187 #define  ERC32_MEC_UNIMPLEMENTED_5_OFFSET                          0x90
0188 #define  ERC32_MEC_TIMER_CONTROL_OFFSET                            0x98
0189 #define  ERC32_MEC_UNIMPLEMENTED_6_OFFSET                          0x9C
0190 #define  ERC32_MEC_SYSTEM_FAULT_STATUS_OFFSET                      0xA0
0191 #define  ERC32_MEC_FIRST_FAILING_ADDRESS_OFFSET                    0xA4
0192 #define  ERC32_MEC_FIRST_FAILING_DATA_OFFSET                       0xA8
0193 #define  ERC32_MEC_FIRST_FAILING_SYNDROME_AND_CHECK_BITS_OFFSET    0xAC
0194 #define  ERC32_MEC_ERROR_AND_RESET_STATUS_OFFSET                   0xB0
0195 #define  ERC32_MEC_ERROR_MASK_OFFSET                               0xB4
0196 #define  ERC32_MEC_UNIMPLEMENTED_7_OFFSET                          0xB8
0197 #define  ERC32_MEC_DEBUG_CONTROL_OFFSET                            0xC0
0198 #define  ERC32_MEC_BREAKPOINT_OFFSET                               0xC4
0199 #define  ERC32_MEC_WATCHPOINT_OFFSET                               0xC8
0200 #define  ERC32_MEC_UNIMPLEMENTED_8_OFFSET                          0xCC
0201 #define  ERC32_MEC_TEST_CONTROL_OFFSET                             0xD0
0202 #define  ERC32_MEC_TEST_DATA_OFFSET                                0xD4
0203 #define  ERC32_MEC_UNIMPLEMENTED_9_OFFSET                          0xD8
0204 #define  ERC32_MEC_UART_CHANNEL_A_OFFSET                           0xE0
0205 #define  ERC32_MEC_UART_CHANNEL_B_OFFSET                           0xE4
0206 #define  ERC32_MEC_UART_STATUS_OFFSET                              0xE8
0207 
0208 #endif
0209 
0210 /*
0211  *  The following defines the bits in the Configuration Register.
0212  */
0213 
0214 #define ERC32_CONFIGURATION_POWER_DOWN_MASK               0x00000001
0215 #define ERC32_CONFIGURATION_POWER_DOWN_ALLOWED            0x00000001
0216 #define ERC32_CONFIGURATION_POWER_DOWN_DISABLED           0x00000000
0217 
0218 #define ERC32_CONFIGURATION_SOFTWARE_RESET_MASK           0x00000002
0219 #define ERC32_CONFIGURATION_SOFTWARE_RESET_ALLOWED        0x00000002
0220 #define ERC32_CONFIGURATION_SOFTWARE_RESET_DISABLED       0x00000000
0221 
0222 #define ERC32_CONFIGURATION_BUS_TIMEOUT_MASK              0x00000004
0223 #define ERC32_CONFIGURATION_BUS_TIMEOUT_ENABLED           0x00000004
0224 #define ERC32_CONFIGURATION_BUS_TIMEOUT_DISABLED          0x00000000
0225 
0226 #define ERC32_CONFIGURATION_ACCESS_PROTECTION_MASK        0x00000008
0227 #define ERC32_CONFIGURATION_ACCESS_PROTECTION_ENABLED     0x00000008
0228 #define ERC32_CONFIGURATION_ACCESS_PROTECTION_DISABLED    0x00000000
0229 
0230 /*
0231  *  The following defines the bits in the Memory Configuration Register.
0232  */
0233 
0234 #define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_MASK  0x00001C00
0235 #define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_256K  ( 0 << 10 )
0236 #define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_512K  ( 1 << 10 )
0237 #define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_1MB   ( 2 << 10 )
0238 #define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_2MB   ( 3 << 10 )
0239 #define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_4MB   ( 4 << 10 )
0240 #define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_8MB   ( 5 << 10 )
0241 #define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_16MB  ( 6 << 10 )
0242 #define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_32MB  ( 7 << 10 )
0243 
0244 #define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_MASK  0x001C0000
0245 #define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_128K    ( 0 << 18 )
0246 #define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_256K    ( 1 << 18 )
0247 #define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_512K   ( 2 << 18 )
0248 #define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_1M   ( 3 << 18 )
0249 #define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_2M   ( 4 << 18 )
0250 #define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_4M  ( 5 << 18 )
0251 #define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_8M  ( 6 << 18 )
0252 #define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_16M  ( 7 << 18 )
0253 
0254 /*
0255  *  The following defines the bits in the Timer Control Register.
0256  */
0257 
0258 #define ERC32_MEC_TIMER_CONTROL_GCR   0x00000001 /* 1 = reload at 0 */
0259                                               /* 0 = stop at 0 */
0260 #define ERC32_MEC_TIMER_CONTROL_GCL   0x00000002 /* 1 = load and start */
0261                                               /* 0 = no function */
0262 #define ERC32_MEC_TIMER_CONTROL_GSE   0x00000004 /* 1 = enable counting */
0263                                               /* 0 = hold scalar and counter */
0264 #define ERC32_MEC_TIMER_CONTROL_GSL   0x00000008 /* 1 = load scalar and start*/
0265                                               /* 0 = no function */
0266 
0267 #define ERC32_MEC_TIMER_CONTROL_RTCCR 0x00000100 /* 1 = reload at 0 */
0268                                               /* 0 = stop at 0 */
0269 #define ERC32_MEC_TIMER_CONTROL_RTCCL 0x00000200 /* 1 = load and start */
0270                                               /* 0 = no function */
0271 #define ERC32_MEC_TIMER_CONTROL_RTCSE 0x00000400 /* 1 = enable counting */
0272                                               /* 0 = hold scalar and counter */
0273 #define ERC32_MEC_TIMER_CONTROL_RTCSL 0x00000800 /* 1 = load scalar and start*/
0274                                               /* 0 = no function */
0275 
0276 /*
0277  *  The following defines the bits in the UART Control Registers.
0278  *
0279  */
0280 
0281 #define ERC32_MEC_UART_CONTROL_RTD  0x000000FF /* RX/TX data */
0282 
0283 /*
0284  *  The following defines the bits in the MEC UART Control Registers.
0285  */
0286 
0287 #define ERC32_MEC_UART_STATUS_DR   0x00000001 /* Data Ready */
0288 #define ERC32_MEC_UART_STATUS_TSE  0x00000002 /* TX Send Register Empty */
0289 #define ERC32_MEC_UART_STATUS_THE  0x00000004 /* TX Hold Register Empty */
0290 #define ERC32_MEC_UART_STATUS_FE   0x00000010 /* RX Framing Error */
0291 #define ERC32_MEC_UART_STATUS_PE   0x00000020 /* RX Parity Error */
0292 #define ERC32_MEC_UART_STATUS_OE   0x00000040 /* RX Overrun Error */
0293 #define ERC32_MEC_UART_STATUS_CU   0x00000080 /* Clear Errors */
0294 #define ERC32_MEC_UART_STATUS_TXE  0x00000006 /* TX Empty */
0295 #define ERC32_MEC_UART_STATUS_CLRA 0x00000080 /* Clear UART A */
0296 #define ERC32_MEC_UART_STATUS_CLRB 0x00800000 /* Clear UART B */
0297 #define ERC32_MEC_UART_STATUS_ERRA 0x00000070 /* Error in UART A */
0298 #define ERC32_MEC_UART_STATUS_ERRB 0x00700000 /* Error in UART B */
0299 
0300 #define ERC32_MEC_UART_STATUS_DRA   (ERC32_MEC_UART_STATUS_DR  << 0)
0301 #define ERC32_MEC_UART_STATUS_TSEA  (ERC32_MEC_UART_STATUS_TSE << 0)
0302 #define ERC32_MEC_UART_STATUS_THEA  (ERC32_MEC_UART_STATUS_THE << 0)
0303 #define ERC32_MEC_UART_STATUS_FEA   (ERC32_MEC_UART_STATUS_FE  << 0)
0304 #define ERC32_MEC_UART_STATUS_PEA   (ERC32_MEC_UART_STATUS_PE  << 0)
0305 #define ERC32_MEC_UART_STATUS_OEA   (ERC32_MEC_UART_STATUS_OE  << 0)
0306 #define ERC32_MEC_UART_STATUS_CUA   (ERC32_MEC_UART_STATUS_CU  << 0)
0307 #define ERC32_MEC_UART_STATUS_TXEA  (ERC32_MEC_UART_STATUS_TXE << 0)
0308 
0309 #define ERC32_MEC_UART_STATUS_DRB   (ERC32_MEC_UART_STATUS_DR  << 16)
0310 #define ERC32_MEC_UART_STATUS_TSEB  (ERC32_MEC_UART_STATUS_TSE << 16)
0311 #define ERC32_MEC_UART_STATUS_THEB  (ERC32_MEC_UART_STATUS_THE << 16)
0312 #define ERC32_MEC_UART_STATUS_FEB   (ERC32_MEC_UART_STATUS_FE  << 16)
0313 #define ERC32_MEC_UART_STATUS_PEB   (ERC32_MEC_UART_STATUS_PE  << 16)
0314 #define ERC32_MEC_UART_STATUS_OEB   (ERC32_MEC_UART_STATUS_OE  << 16)
0315 #define ERC32_MEC_UART_STATUS_CUB   (ERC32_MEC_UART_STATUS_CU  << 16)
0316 #define ERC32_MEC_UART_STATUS_TXEB  (ERC32_MEC_UART_STATUS_TXE << 16)
0317 
0318 #ifndef ASM
0319 
0320 /*
0321  *  This is used to manipulate the on-chip registers.
0322  *
0323  *  The following symbol must be defined in the linkcmds file and point
0324  *  to the correct location.
0325  */
0326 
0327 extern ERC32_Register_Map ERC32_MEC;
0328 
0329 /*
0330  *  Macros to manipulate the Interrupt Clear, Interrupt Force, Interrupt Mask,
0331  *  and the Interrupt Pending Registers.
0332  *
0333  *  NOTE: For operations which are not atomic, this code disables interrupts
0334  *        to guarantee there are no intervening accesses to the same register.
0335  *        The operations which read the register, modify the value and then
0336  *        store the result back are vulnerable.
0337  */
0338 
0339 #define ERC32_Clear_interrupt( _source ) \
0340   do { \
0341     ERC32_MEC.Interrupt_Clear = (1 << (_source)); \
0342   } while (0)
0343 
0344 #define ERC32_Force_interrupt( _source ) \
0345   do { \
0346     uint32_t   _level; \
0347     \
0348     _level = sparc_disable_interrupts(); \
0349     ERC32_MEC.Test_Control = ERC32_MEC.Test_Control | 0x80000; \
0350     ERC32_MEC.Interrupt_Force |= (1 << (_source)); \
0351     sparc_enable_interrupts( _level ); \
0352   } while (0)
0353 
0354 #define ERC32_Is_interrupt_pending( _source ) \
0355   (ERC32_MEC.Interrupt_Pending & (1 << (_source)))
0356 
0357 #define ERC32_Is_interrupt_masked( _source ) \
0358   (ERC32_MEC.Interrupt_Mask & (1 << (_source)))
0359 
0360 #define ERC32_Mask_interrupt( _source ) \
0361   do { \
0362     uint32_t   _level; \
0363     \
0364     _level = sparc_disable_interrupts(); \
0365       ERC32_MEC.Interrupt_Mask |= (1 << (_source)); \
0366     sparc_enable_interrupts( _level ); \
0367   } while (0)
0368 
0369 #define ERC32_Unmask_interrupt( _source ) \
0370   do { \
0371     uint32_t   _level; \
0372     \
0373     _level = sparc_disable_interrupts(); \
0374       ERC32_MEC.Interrupt_Mask &= ~(1 << (_source)); \
0375     sparc_enable_interrupts( _level ); \
0376   } while (0)
0377 
0378 #define ERC32_Disable_interrupt( _source, _previous ) \
0379   do { \
0380     uint32_t   _level; \
0381     uint32_t   _mask = 1 << (_source); \
0382     \
0383     _level = sparc_disable_interrupts(); \
0384       (_previous) = ERC32_MEC.Interrupt_Mask; \
0385       ERC32_MEC.Interrupt_Mask = _previous | _mask; \
0386     sparc_enable_interrupts( _level ); \
0387     (_previous) &= _mask; \
0388   } while (0)
0389 
0390 #define ERC32_Restore_interrupt( _source, _previous ) \
0391   do { \
0392     uint32_t   _level; \
0393     uint32_t   _mask = 1 << (_source); \
0394     \
0395     _level = sparc_disable_interrupts(); \
0396       ERC32_MEC.Interrupt_Mask = \
0397         (ERC32_MEC.Interrupt_Mask & ~_mask) | (_previous); \
0398     sparc_enable_interrupts( _level ); \
0399   } while (0)
0400 
0401 /* Make all SPARC BSPs have common macros for interrupt handling on local CPU */
0402 #define BSP_Clear_interrupt(_source) ERC32_Clear_interrupt(_source)
0403 #define BSP_Force_interrupt(_source) ERC32_Force_interrupt(_source)
0404 #define BSP_Clear_forced_interrupt( _source ) \
0405   do { \
0406     uint32_t _level; \
0407     \
0408     _level = sparc_disable_interrupts(); \
0409       ERC32_MEC.Interrupt_Force &= ~(1 << (_source)); \
0410     sparc_enable_interrupts( _level ); \
0411   } while (0)
0412 #define BSP_Is_interrupt_pending(_source) ERC32_Is_interrupt_pending(_source)
0413 #define BSP_Is_interrupt_forced(_source) \
0414   (ERC32_MEC.Interrupt_Force & (1 << (_source)))
0415 #define BSP_Is_interrupt_masked(_source) ERC32_Is_interrupt_masked(_source)
0416 #define BSP_Unmask_interrupt(_source) ERC32_Unmask_interrupt(_source)
0417 #define BSP_Mask_interrupt(_source) ERC32_Mask_interrupt(_source)
0418 #define BSP_Disable_interrupt(_source, _previous) \
0419         ERC32_Disable_interrupt(_source, _prev)
0420 #define BSP_Restore_interrupt(_source, _previous) \
0421         ERC32_Restore_interrupt(_source, _previous)
0422 
0423 /* Make all SPARC BSPs have common macros for interrupt handling on any CPU */
0424 #define BSP_Cpu_Is_interrupt_masked(_source, _cpu) \
0425         BSP_Is_interrupt_masked(_source)
0426 #define BSP_Cpu_Unmask_interrupt(_source, _cpu) \
0427         BSP_Unmask_interrupt(_source)
0428 #define BSP_Cpu_Mask_interrupt(_source, _cpu) \
0429         BSP_Mask_interrupt(_source)
0430 #define BSP_Cpu_Disable_interrupt(_source, _previous, _cpu) \
0431         BSP_Disable_interrupt(_source, _prev)
0432 #define BSP_Cpu_Restore_interrupt(_source, _previous, _cpu) \
0433         BSP_Cpu_Restore_interrupt(_source, _previous)
0434 
0435 /*
0436  *  The following macros attempt to hide the fact that the General Purpose
0437  *  Timer and Real Time Clock Timer share the Timer Control Register.  Because
0438  *  the Timer Control Register is write only, we must mirror it in software
0439  *  and insure that writes to one timer do not alter the current settings
0440  *  and status of the other timer.
0441  *
0442  *  This code promotes the view that the two timers are completely independent.
0443  *  By exclusively using the routines below to access the Timer Control
0444  *  Register, the application can view the system as having a General Purpose
0445  *  Timer Control Register and a Real Time Clock Timer Control Register
0446  *  rather than the single shared value.
0447  *
0448  *  Each logical timer control register is organized as follows:
0449  *
0450  *    D0 - Counter Reload
0451  *          1 = reload counter at zero and restart
0452  *          0 = stop counter at zero
0453  *
0454  *    D1 - Counter Load
0455  *          1 = load counter with preset value and restart
0456  *          0 = no function
0457  *
0458  *    D2 - Enable
0459  *          1 = enable counting
0460  *          0 = hold scaler and counter
0461  *
0462  *    D3 - Scaler Load
0463  *          1 = load scalar with preset value and restart
0464  *          0 = no function
0465  *
0466  *  To insure the management of the mirror is atomic, we disable interrupts
0467  *  around updates.
0468  */
0469 
0470 #define ERC32_MEC_TIMER_COUNTER_RELOAD_AT_ZERO     0x00000001
0471 #define ERC32_MEC_TIMER_COUNTER_STOP_AT_ZERO       0x00000000
0472 
0473 #define ERC32_MEC_TIMER_COUNTER_LOAD_COUNTER       0x00000002
0474 
0475 #define ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING    0x00000004
0476 #define ERC32_MEC_TIMER_COUNTER_DISABLE_COUNTING   0x00000000
0477 
0478 #define ERC32_MEC_TIMER_COUNTER_LOAD_SCALER        0x00000008
0479 
0480 #define ERC32_MEC_TIMER_COUNTER_RELOAD_MASK        0x00000001
0481 #define ERC32_MEC_TIMER_COUNTER_ENABLE_MASK        0x00000004
0482 
0483 #define ERC32_MEC_TIMER_COUNTER_DEFINED_MASK       0x0000000F
0484 #define ERC32_MEC_TIMER_COUNTER_CURRENT_MODE_MASK  0x00000005
0485 
0486 extern uint32_t   _ERC32_MEC_Timer_Control_Mirror;
0487 
0488 /*
0489  *  This macros manipulate the General Purpose Timer portion of the
0490  *  Timer Control register and promote the view that there are actually
0491  *  two independent Timer Control Registers.
0492  */
0493 
0494 #define ERC32_MEC_Set_General_Purpose_Timer_Control( _value ) \
0495   do { \
0496     uint32_t   _level; \
0497     uint32_t   _control; \
0498     uint32_t   __value; \
0499     \
0500     __value = ((_value) & 0x0f); \
0501     _level = sparc_disable_interrupts(); \
0502       _control = _ERC32_MEC_Timer_Control_Mirror; \
0503       _control &= ERC32_MEC_TIMER_COUNTER_DEFINED_MASK << 8; \
0504       _ERC32_MEC_Timer_Control_Mirror = _control | _value; \
0505       _control &= (ERC32_MEC_TIMER_COUNTER_CURRENT_MODE_MASK << 8); \
0506       _control |= __value; \
0507       /* printf( "GPT 0x%x 0x%x 0x%x\n", _value, __value, _control );  */ \
0508       ERC32_MEC.Timer_Control = _control; \
0509     sparc_enable_interrupts( _level ); \
0510   } while ( 0 )
0511 
0512 #define ERC32_MEC_Get_General_Purpose_Timer_Control( _value ) \
0513   do { \
0514     (_value) = _ERC32_MEC_Timer_Control_Mirror & 0xf; \
0515   } while ( 0 )
0516 
0517 /*
0518  *  This macros manipulate the Real Timer Clock Timer portion of the
0519  *  Timer Control register and promote the view that there are actually
0520  *  two independent Timer Control Registers.
0521  */
0522 
0523 #define ERC32_MEC_Set_Real_Time_Clock_Timer_Control( _value ) \
0524   do { \
0525     uint32_t   _level; \
0526     uint32_t   _control; \
0527     uint32_t   __value; \
0528     \
0529     __value = ((_value) & 0x0f) << 8; \
0530     _level = sparc_disable_interrupts(); \
0531       _control = _ERC32_MEC_Timer_Control_Mirror; \
0532       _control &= ERC32_MEC_TIMER_COUNTER_DEFINED_MASK; \
0533       _ERC32_MEC_Timer_Control_Mirror = _control | __value; \
0534       _control &= ERC32_MEC_TIMER_COUNTER_CURRENT_MODE_MASK; \
0535       _control |= __value; \
0536       /* printf( "RTC 0x%x 0x%x 0x%x\n", _value, __value, _control ); */ \
0537       ERC32_MEC.Timer_Control = _control; \
0538     sparc_enable_interrupts( _level ); \
0539   } while ( 0 )
0540 
0541 #define ERC32_MEC_Get_Real_Time_Clock_Timer_Control( _value ) \
0542   do { \
0543     (_value) = (_ERC32_MEC_Timer_Control_Mirror >> 8) & 0xf; \
0544   } while ( 0 )
0545 
0546 #endif /* !ASM */
0547 
0548 #ifdef __cplusplus
0549 }
0550 #endif
0551 
0552 #endif /* !_INCLUDE_ERC32_h */