source: rtems/c/src/lib/libcpu/sparc/include/erc32.h @ 16a9ee1

4.104.114.84.95
Last change on this file since 16a9ee1 was 16a9ee1, checked in by Joel Sherrill <joel.sherrill@…>, on 01/13/99 at 14:13:47

Bug report from Jiri Gaisler <jgais@…>:

I think I have found a bug in src/exec/scor/sparc/cpu/erc32.h in:

#define ERC32_Disable_interrupt( _source, _previous ) \

do { \

unsigned32 _level; \
unsigned32 _mask = 1 << (_source); \
\
sparc_disable_interrupts( _level ); \

(_previous) = ERC32_MEC.Interrupt_Mask; \
ERC32_MEC.Interrupt_Mask = _previous | _mask; \

sparc_enable_interrupts( _level ); \
(_previous) &= ~_mask; \ <- IS THIS CORRECT...?

} while (0)

The previous interrupt mask is returned after first clearing the
bit to be disabled, regardless whether the bit was set before or
not. If the bit was set (interrupt masked), subsequent call to
ERC32_Restore_interrupt() will enable the interrupt even though
it was supposed to be masked. This is indeed what happens in
DEBUG_puts when polled console I/O is used. In my opinion, the
last statement in the macro should be removed - what is your opinion?

I think the "~" shouldn't be there. I recall that the intent of that line
is to only return the state of the interrupts you were concerned with.
Removing the line returns entire state. Given that the value returned
shuold only be used in conjunction with the map, I suppose either removing
the ~ or the entire line is correct? I can go either way. Just let me
know which you think is more correct and the source will change. :)

Hmmm, just removing the '~' should be OK. DEBUG_puts() seems to be the
only user of ERC32_Restore_interrupt() anyway ...

  • Property mode set to 100644
File size: 22.0 KB
Line 
1/*  erc32.h
2 *
3 *  This include file contains information pertaining to the ERC32.
4 *  The ERC32 is a custom SPARC V7 implementation based on the Cypress
5 *  601/602 chipset.  This CPU has a number of on-board peripherals and
6 *  was developed by the European Space Agency to target space applications.
7 *
8 *  NOTE:  Other than where absolutely required, this version currently
9 *         supports only the peripherals and bits used by the basic board
10 *         support package. This includes at least significant pieces of
11 *         the following items:
12 *
13 *           + UART Channels A and B
14 *           + General Purpose Timer
15 *           + Real Time Clock
16 *           + Watchdog Timer (so it can be disabled)
17 *           + Control Register (so powerdown mode can be enabled)
18 *           + Memory Control Register
19 *           + Interrupt Control
20 *
21 *  COPYRIGHT (c) 1989-1998.
22 *  On-Line Applications Research Corporation (OAR).
23 *  Copyright assigned to U.S. Government, 1994.
24 *
25 *  The license and distribution terms for this file may be
26 *  found in the file LICENSE in this distribution or at
27 *  http://www.OARcorp.com/rtems/license.html.
28 *
29 *  Ported to ERC32 implementation of the SPARC by On-Line Applications
30 *  Research Corporation (OAR) under contract to the European Space
31 *  Agency (ESA).
32 *
33 *  ERC32 modifications of respective RTEMS file: COPYRIGHT (c) 1995.
34 *  European Space Agency.
35 *
36 *  $Id$
37 */
38 
39#ifndef _INCLUDE_ERC32_h
40#define _INCLUDE_ERC32_h
41
42#include <rtems/score/sparc.h>
43 
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48/*
49 *  Interrupt Sources
50 *
51 *  The interrupt source numbers directly map to the trap type and to
52 *  the bits used in the Interrupt Clear, Interrupt Force, Interrupt Mask,
53 *  and the Interrupt Pending Registers.
54 */
55
56#define ERC32_INTERRUPT_MASKED_ERRORS             1
57#define ERC32_INTERRUPT_EXTERNAL_1                2
58#define ERC32_INTERRUPT_EXTERNAL_2                3
59#define ERC32_INTERRUPT_UART_A_RX_TX              4
60#define ERC32_INTERRUPT_UART_B_RX_TX              5
61#define ERC32_INTERRUPT_CORRECTABLE_MEMORY_ERROR  6
62#define ERC32_INTERRUPT_UART_ERROR                7
63#define ERC32_INTERRUPT_DMA_ACCESS_ERROR          8
64#define ERC32_INTERRUPT_DMA_TIMEOUT               9
65#define ERC32_INTERRUPT_EXTERNAL_3               10
66#define ERC32_INTERRUPT_EXTERNAL_4               11
67#define ERC32_INTERRUPT_GENERAL_PURPOSE_TIMER    12
68#define ERC32_INTERRUPT_REAL_TIME_CLOCK          13
69#define ERC32_INTERRUPT_EXTERNAL_5               14
70#define ERC32_INTERRUPT_WATCHDOG_TIMEOUT         15
71
72#ifndef ASM
73
74/*
75 *  Trap Types for on-chip peripherals
76 *
77 *  Source: Table 8 - Interrupt Trap Type and Default Priority Assignments
78 *
79 *  NOTE: The priority level for each source corresponds to the least
80 *        significant nibble of the trap type.
81 */
82
83#define ERC32_TRAP_TYPE( _source ) SPARC_ASYNCHRONOUS_TRAP((_source) + 0x10)
84
85#define ERC32_TRAP_SOURCE( _trap ) ((_trap) - 0x10)
86
87#define ERC32_Is_MEC_Trap( _trap ) \
88  ( (_trap) >= ERC32_TRAP_TYPE( ERC32_INTERRUPT_MASKED_ERRORS ) && \
89    (_trap) <= ERC32_TRAP_TYPE( ERC32_INTERRUPT_WATCHDOG_TIMEOUT ) )
90
91/*
92 *  Structure for ERC32 memory mapped registers. 
93 *
94 *  Source: Section 3.25.2 - Register Address Map
95 *
96 *  NOTE:  There is only one of these structures per CPU, its base address
97 *         is 0x01f80000, and the variable MEC is placed there by the
98 *         linkcmds file.
99 */
100
101typedef struct {
102  volatile unsigned32  Control;                              /* offset 0x00 */
103  volatile unsigned32  Software_Reset;                       /* offset 0x04 */
104  volatile unsigned32  Power_Down;                           /* offset 0x08 */
105  volatile unsigned32  Unimplemented_0;                      /* offset 0x0c */
106  volatile unsigned32  Memory_Configuration;                 /* offset 0x10 */
107  volatile unsigned32  IO_Configuration;                     /* offset 0x14 */
108  volatile unsigned32  Wait_State_Configuration;             /* offset 0x18 */
109  volatile unsigned32  Unimplemented_1;                      /* offset 0x1c */
110  volatile unsigned32  Memory_Access_0;                      /* offset 0x20 */
111  volatile unsigned32  Memory_Access_1;                      /* offset 0x24 */
112  volatile unsigned32  Unimplemented_2[ 7 ];                 /* offset 0x28 */
113  volatile unsigned32  Interrupt_Shape;                      /* offset 0x44 */
114  volatile unsigned32  Interrupt_Pending;                    /* offset 0x48 */
115  volatile unsigned32  Interrupt_Mask;                       /* offset 0x4c */
116  volatile unsigned32  Interrupt_Clear;                      /* offset 0x50 */
117  volatile unsigned32  Interrupt_Force;                      /* offset 0x54 */
118  volatile unsigned32  Unimplemented_3[ 2 ];                 /* offset 0x58 */
119                                                             /* offset 0x60 */
120  volatile unsigned32  Watchdog_Program_and_Timeout_Acknowledge;
121  volatile unsigned32  Watchdog_Trap_Door_Set;               /* offset 0x64 */
122  volatile unsigned32  Unimplemented_4[ 6 ];                 /* offset 0x68 */
123  volatile unsigned32  Real_Time_Clock_Counter;              /* offset 0x80 */
124  volatile unsigned32  Real_Time_Clock_Scalar;               /* offset 0x84 */
125  volatile unsigned32  General_Purpose_Timer_Counter;        /* offset 0x88 */
126  volatile unsigned32  General_Purpose_Timer_Scalar;         /* offset 0x8c */
127  volatile unsigned32  Unimplemented_5[ 2 ];                 /* offset 0x90 */
128  volatile unsigned32  Timer_Control;                        /* offset 0x98 */
129  volatile unsigned32  Unimplemented_6;                      /* offset 0x9c */
130  volatile unsigned32  System_Fault_Status;                  /* offset 0xa0 */
131  volatile unsigned32  First_Failing_Address;                /* offset 0xa4 */
132  volatile unsigned32  First_Failing_Data;                   /* offset 0xa8 */
133  volatile unsigned32  First_Failing_Syndrome_and_Check_Bits;/* offset 0xac */
134  volatile unsigned32  Error_and_Reset_Status;               /* offset 0xb0 */
135  volatile unsigned32  Error_Mask;                           /* offset 0xb4 */
136  volatile unsigned32  Unimplemented_7[ 2 ];                 /* offset 0xb8 */
137  volatile unsigned32  Debug_Control;                        /* offset 0xc0 */
138  volatile unsigned32  Breakpoint;                           /* offset 0xc4 */
139  volatile unsigned32  Watchpoint;                           /* offset 0xc8 */
140  volatile unsigned32  Unimplemented_8;                      /* offset 0xcc */
141  volatile unsigned32  Test_Control;                         /* offset 0xd0 */
142  volatile unsigned32  Test_Data;                            /* offset 0xd4 */
143  volatile unsigned32  Unimplemented_9[ 2 ];                 /* offset 0xd8 */
144  volatile unsigned32  UART_Channel_A;                       /* offset 0xe0 */
145  volatile unsigned32  UART_Channel_B;                       /* offset 0xe4 */
146  volatile unsigned32  UART_Status;                          /* offset 0xe8 */
147} ERC32_Register_Map;
148
149#endif
150
151/*
152 *  The following constants are intended to be used ONLY in assembly
153 *  language files.
154 *
155 *  NOTE:  The intended style of usage is to load the address of MEC
156 *         into a register and then use these as displacements from
157 *         that register.
158 */
159
160#ifdef ASM
161
162#define  ERC32_MEC_CONTROL_OFFSET                                  0x00
163#define  ERC32_MEC_SOFTWARE_RESET_OFFSET                           0x04
164#define  ERC32_MEC_POWER_DOWN_OFFSET                               0x08
165#define  ERC32_MEC_UNIMPLEMENTED_0_OFFSET                          0x0C
166#define  ERC32_MEC_MEMORY_CONFIGURATION_OFFSET                     0x10
167#define  ERC32_MEC_IO_CONFIGURATION_OFFSET                         0x14
168#define  ERC32_MEC_WAIT_STATE_CONFIGURATION_OFFSET                 0x18
169#define  ERC32_MEC_UNIMPLEMENTED_1_OFFSET                          0x1C
170#define  ERC32_MEC_MEMORY_ACCESS_0_OFFSET                          0x20
171#define  ERC32_MEC_MEMORY_ACCESS_1_OFFSET                          0x24
172#define  ERC32_MEC_UNIMPLEMENTED_2_OFFSET                          0x28
173#define  ERC32_MEC_INTERRUPT_SHAPE_OFFSET                          0x44
174#define  ERC32_MEC_INTERRUPT_PENDING_OFFSET                        0x48
175#define  ERC32_MEC_INTERRUPT_MASK_OFFSET                           0x4C
176#define  ERC32_MEC_INTERRUPT_CLEAR_OFFSET                          0x50
177#define  ERC32_MEC_INTERRUPT_FORCE_OFFSET                          0x54
178#define  ERC32_MEC_UNIMPLEMENTED_3_OFFSET                          0x58
179#define  ERC32_MEC_WATCHDOG_PROGRAM_AND_TIMEOUT_ACKNOWLEDGE_OFFSET 0x60
180#define  ERC32_MEC_WATCHDOG_TRAP_DOOR_SET_OFFSET                   0x64
181#define  ERC32_MEC_UNIMPLEMENTED_4_OFFSET                          0x6C
182#define  ERC32_MEC_REAL_TIME_CLOCK_COUNTER_OFFSET                  0x80
183#define  ERC32_MEC_REAL_TIME_CLOCK_SCALAR_OFFSET                   0x84
184#define  ERC32_MEC_GENERAL_PURPOSE_TIMER_COUNTER_OFFSET            0x88
185#define  ERC32_MEC_GENERAL_PURPOSE_TIMER_SCALAR_OFFSET             0x8C
186#define  ERC32_MEC_UNIMPLEMENTED_5_OFFSET                          0x90
187#define  ERC32_MEC_TIMER_CONTROL_OFFSET                            0x98
188#define  ERC32_MEC_UNIMPLEMENTED_6_OFFSET                          0x9C
189#define  ERC32_MEC_SYSTEM_FAULT_STATUS_OFFSET                      0xA0
190#define  ERC32_MEC_FIRST_FAILING_ADDRESS_OFFSET                    0xA4
191#define  ERC32_MEC_FIRST_FAILING_DATA_OFFSET                       0xA8
192#define  ERC32_MEC_FIRST_FAILING_SYNDROME_AND_CHECK_BITS_OFFSET    0xAC
193#define  ERC32_MEC_ERROR_AND_RESET_STATUS_OFFSET                   0xB0
194#define  ERC32_MEC_ERROR_MASK_OFFSET                               0xB4
195#define  ERC32_MEC_UNIMPLEMENTED_7_OFFSET                          0xB8
196#define  ERC32_MEC_DEBUG_CONTROL_OFFSET                            0xC0
197#define  ERC32_MEC_BREAKPOINT_OFFSET                               0xC4
198#define  ERC32_MEC_WATCHPOINT_OFFSET                               0xC8
199#define  ERC32_MEC_UNIMPLEMENTED_8_OFFSET                          0xCC
200#define  ERC32_MEC_TEST_CONTROL_OFFSET                             0xD0
201#define  ERC32_MEC_TEST_DATA_OFFSET                                0xD4
202#define  ERC32_MEC_UNIMPLEMENTED_9_OFFSET                          0xD8
203#define  ERC32_MEC_UART_CHANNEL_A_OFFSET                           0xE0
204#define  ERC32_MEC_UART_CHANNEL_B_OFFSET                           0xE4
205#define  ERC32_MEC_UART_STATUS_OFFSET                              0xE8
206
207#endif
208
209/*
210 *  The following defines the bits in the Configuration Register.
211 */
212
213#define ERC32_CONFIGURATION_POWER_DOWN_MASK               0x00000001
214#define ERC32_CONFIGURATION_POWER_DOWN_ALLOWED            0x00000001
215#define ERC32_CONFIGURATION_POWER_DOWN_DISABLED           0x00000000
216
217#define ERC32_CONFIGURATION_SOFTWARE_RESET_MASK           0x00000002
218#define ERC32_CONFIGURATION_SOFTWARE_RESET_ALLOWED        0x00000002
219#define ERC32_CONFIGURATION_SOFTWARE_RESET_DISABLED       0x00000000
220
221#define ERC32_CONFIGURATION_BUS_TIMEOUT_MASK              0x00000004
222#define ERC32_CONFIGURATION_BUS_TIMEOUT_ENABLED           0x00000004
223#define ERC32_CONFIGURATION_BUS_TIMEOUT_DISABLED          0x00000000
224
225#define ERC32_CONFIGURATION_ACCESS_PROTECTION_MASK        0x00000008
226#define ERC32_CONFIGURATION_ACCESS_PROTECTION_ENABLED     0x00000008
227#define ERC32_CONFIGURATION_ACCESS_PROTECTION_DISABLED    0x00000000
228
229
230/*
231 *  The following defines the bits in the Memory Configuration Register.
232 */
233
234#define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_MASK  0x00001C00
235#define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_256K  ( 0 << 10 )
236#define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_512K  ( 1 << 10 )
237#define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_1MB   ( 2 << 10 )
238#define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_2MB   ( 3 << 10 )
239#define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_4MB   ( 4 << 10 )
240#define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_8MB   ( 5 << 10 )
241#define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_16MB  ( 6 << 10 )
242#define ERC32_MEMORY_CONFIGURATION_RAM_SIZE_32MB  ( 7 << 10 )
243
244#define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_MASK  0x001C0000
245#define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_128K    ( 0 << 18 )
246#define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_256K    ( 1 << 18 )
247#define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_512K   ( 2 << 18 )
248#define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_1M   ( 3 << 18 )
249#define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_2M   ( 4 << 18 )
250#define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_4M  ( 5 << 18 )
251#define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_8M  ( 6 << 18 )
252#define ERC32_MEMORY_CONFIGURATION_PROM_SIZE_16M  ( 7 << 18 )
253 
254/*
255 *  The following defines the bits in the Timer Control Register.
256 */
257
258#define ERC32_MEC_TIMER_CONTROL_GCR    0x00000001  /* 1 = reload at 0 */
259                                               /* 0 = stop at 0 */
260#define ERC32_MEC_TIMER_CONTROL_GCL    0x00000002  /* 1 = load and start */
261                                               /* 0 = no function */
262#define ERC32_MEC_TIMER_CONTROL_GSE    0x00000004  /* 1 = enable counting */
263                                               /* 0 = hold scalar and counter */
264#define ERC32_MEC_TIMER_CONTROL_GSL    0x00000008  /* 1 = load scalar and start */
265                                               /* 0 = no function */
266
267#define ERC32_MEC_TIMER_CONTROL_RTCCR  0x00000100  /* 1 = reload at 0 */
268                                               /* 0 = stop at 0 */
269#define ERC32_MEC_TIMER_CONTROL_RTCCL  0x00000200  /* 1 = load and start */
270                                               /* 0 = no function */
271#define ERC32_MEC_TIMER_CONTROL_RTCSE  0x00000400  /* 1 = enable counting */
272                                               /* 0 = hold scalar and counter */
273#define ERC32_MEC_TIMER_CONTROL_RTCSL  0x00000800  /* 1 = load scalar and start */
274                                               /* 0 = no function */
275
276/*
277 *  The following defines the bits in the UART Control Registers.
278 *
279 */
280
281#define ERC32_MEC_UART_CONTROL_RTD  0x000000FF /* RX/TX data */
282 
283/*
284 *  The following defines the bits in the MEC UART Control Registers.
285 */
286
287#define ERC32_MEC_UART_STATUS_DR   0x00000001 /* Data Ready */
288#define ERC32_MEC_UART_STATUS_TSE  0x00000002 /* TX Send Register Empty */
289#define ERC32_MEC_UART_STATUS_THE  0x00000004 /* TX Hold Register Empty */
290#define ERC32_MEC_UART_STATUS_FE   0x00000010 /* RX Framing Error */
291#define ERC32_MEC_UART_STATUS_PE   0x00000020 /* RX Parity Error */
292#define ERC32_MEC_UART_STATUS_OE   0x00000040 /* RX Overrun Error */
293#define ERC32_MEC_UART_STATUS_CU   0x00000080 /* Clear Errors */
294#define ERC32_MEC_UART_STATUS_TXE  0x00000006 /* TX Empty */
295#define ERC32_MEC_UART_STATUS_CLRA 0x00000080 /* Clear UART A */
296#define ERC32_MEC_UART_STATUS_CLRB 0x00800000 /* Clear UART B */
297#define ERC32_MEC_UART_STATUS_ERRA 0x00000070 /* Error in UART A */
298#define ERC32_MEC_UART_STATUS_ERRB 0x00700000 /* Error in UART B */
299
300#define ERC32_MEC_UART_STATUS_DRA   (ERC32_MEC_UART_STATUS_DR  << 0)
301#define ERC32_MEC_UART_STATUS_TSEA  (ERC32_MEC_UART_STATUS_TSE << 0)
302#define ERC32_MEC_UART_STATUS_THEA  (ERC32_MEC_UART_STATUS_THE << 0)
303#define ERC32_MEC_UART_STATUS_FEA   (ERC32_MEC_UART_STATUS_FE  << 0)
304#define ERC32_MEC_UART_STATUS_PEA   (ERC32_MEC_UART_STATUS_PE  << 0)
305#define ERC32_MEC_UART_STATUS_OEA   (ERC32_MEC_UART_STATUS_OE  << 0)
306#define ERC32_MEC_UART_STATUS_CUA   (ERC32_MEC_UART_STATUS_CU  << 0)
307#define ERC32_MEC_UART_STATUS_TXEA  (ERC32_MEC_UART_STATUS_TXE << 0)
308
309#define ERC32_MEC_UART_STATUS_DRB   (ERC32_MEC_UART_STATUS_DR  << 16)
310#define ERC32_MEC_UART_STATUS_TSEB  (ERC32_MEC_UART_STATUS_TSE << 16)
311#define ERC32_MEC_UART_STATUS_THEB  (ERC32_MEC_UART_STATUS_THE << 16)
312#define ERC32_MEC_UART_STATUS_FEB   (ERC32_MEC_UART_STATUS_FE  << 16)
313#define ERC32_MEC_UART_STATUS_PEB   (ERC32_MEC_UART_STATUS_PE  << 16)
314#define ERC32_MEC_UART_STATUS_OEB   (ERC32_MEC_UART_STATUS_OE  << 16)
315#define ERC32_MEC_UART_STATUS_CUB   (ERC32_MEC_UART_STATUS_CU  << 16)
316#define ERC32_MEC_UART_STATUS_TXEB  (ERC32_MEC_UART_STATUS_TXE << 16)
317
318#ifndef ASM
319
320/*
321 *  This is used to manipulate the on-chip registers.
322 *
323 *  The following symbol must be defined in the linkcmds file and point
324 *  to the correct location.
325 */
326
327extern ERC32_Register_Map ERC32_MEC;
328 
329/*
330 *  Macros to manipulate the Interrupt Clear, Interrupt Force, Interrupt Mask,
331 *  and the Interrupt Pending Registers.
332 *
333 *  NOTE: For operations which are not atomic, this code disables interrupts
334 *        to guarantee there are no intervening accesses to the same register.
335 *        The operations which read the register, modify the value and then
336 *        store the result back are vulnerable.
337 */
338
339#define ERC32_Clear_interrupt( _source ) \
340  do { \
341    ERC32_MEC.Interrupt_Clear = (1 << (_source)); \
342  } while (0)
343
344#define ERC32_Force_interrupt( _source ) \
345  do { \
346    unsigned32 _level; \
347    \
348    sparc_disable_interrupts( _level ); \
349    ERC32_MEC.Test_Control = ERC32_MEC.Test_Control | 0x80000; \
350    ERC32_MEC.Interrupt_Force = (1 << (_source)); \
351    sparc_enable_interrupts( _level ); \
352  } while (0)
353 
354#define ERC32_Is_interrupt_pending( _source ) \
355  (ERC32_MEC.Interrupt_Pending & (1 << (_source)))
356 
357#define ERC32_Is_interrupt_masked( _source ) \
358  (ERC32_MEC.Interrupt_Masked & (1 << (_source)))
359 
360#define ERC32_Mask_interrupt( _source ) \
361  do { \
362    unsigned32 _level; \
363    \
364    sparc_disable_interrupts( _level ); \
365      ERC32_MEC.Interrupt_Mask |= (1 << (_source)); \
366    sparc_enable_interrupts( _level ); \
367  } while (0)
368 
369#define ERC32_Unmask_interrupt( _source ) \
370  do { \
371    unsigned32 _level; \
372    \
373    sparc_disable_interrupts( _level ); \
374      ERC32_MEC.Interrupt_Mask &= ~(1 << (_source)); \
375    sparc_enable_interrupts( _level ); \
376  } while (0)
377
378#define ERC32_Disable_interrupt( _source, _previous ) \
379  do { \
380    unsigned32 _level; \
381    unsigned32 _mask = 1 << (_source); \
382    \
383    sparc_disable_interrupts( _level ); \
384      (_previous) = ERC32_MEC.Interrupt_Mask; \
385      ERC32_MEC.Interrupt_Mask = _previous | _mask; \
386    sparc_enable_interrupts( _level ); \
387    (_previous) &= _mask; \
388  } while (0)
389 
390#define ERC32_Restore_interrupt( _source, _previous ) \
391  do { \
392    unsigned32 _level; \
393    unsigned32 _mask = 1 << (_source); \
394    \
395    sparc_disable_interrupts( _level ); \
396      ERC32_MEC.Interrupt_Mask = \
397        (ERC32_MEC.Interrupt_Mask & ~_mask) | (_previous); \
398    sparc_enable_interrupts( _level ); \
399  } while (0)
400
401/*
402 *  The following macros attempt to hide the fact that the General Purpose
403 *  Timer and Real Time Clock Timer share the Timer Control Register.  Because
404 *  the Timer Control Register is write only, we must mirror it in software
405 *  and insure that writes to one timer do not alter the current settings
406 *  and status of the other timer.
407 *
408 *  This code promotes the view that the two timers are completely independent.
409 *  By exclusively using the routines below to access the Timer Control
410 *  Register, the application can view the system as having a General Purpose
411 *  Timer Control Register and a Real Time Clock Timer Control Register
412 *  rather than the single shared value.
413 *
414 *  Each logical timer control register is organized as follows:
415 *
416 *    D0 - Counter Reload
417 *          1 = reload counter at zero and restart
418 *          0 = stop counter at zero
419 *
420 *    D1 - Counter Load
421 *          1 = load counter with preset value and restart
422 *          0 = no function
423 *
424 *    D2 - Enable
425 *          1 = enable counting
426 *          0 = hold scaler and counter
427 *
428 *    D3 - Scaler Load
429 *          1 = load scalar with preset value and restart
430 *          0 = no function
431 *
432 *  To insure the management of the mirror is atomic, we disable interrupts
433 *  around updates.
434 */
435
436#define ERC32_MEC_TIMER_COUNTER_RELOAD_AT_ZERO     0x00000001
437#define ERC32_MEC_TIMER_COUNTER_STOP_AT_ZERO       0x00000000
438
439#define ERC32_MEC_TIMER_COUNTER_LOAD_COUNTER       0x00000002
440
441#define ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING    0x00000004
442#define ERC32_MEC_TIMER_COUNTER_DISABLE_COUNTING   0x00000000
443
444#define ERC32_MEC_TIMER_COUNTER_LOAD_SCALER        0x00000008
445
446#define ERC32_MEC_TIMER_COUNTER_RELOAD_MASK        0x00000001
447#define ERC32_MEC_TIMER_COUNTER_ENABLE_MASK        0x00000004
448
449#define ERC32_MEC_TIMER_COUNTER_DEFINED_MASK       0x0000000F
450#define ERC32_MEC_TIMER_COUNTER_CURRENT_MODE_MASK  0x00000005
451
452extern unsigned32 _ERC32_MEC_Timer_Control_Mirror;
453
454/*
455 *  This macros manipulate the General Purpose Timer portion of the
456 *  Timer Control register and promote the view that there are actually
457 *  two independent Timer Control Registers.
458 */
459
460#define ERC32_MEC_Set_General_Purpose_Timer_Control( _value ) \
461  do { \
462    unsigned32 _level; \
463    unsigned32 _control; \
464    unsigned32 __value; \
465    \
466    __value = ((_value) & 0x0f); \
467    sparc_disable_interrupts( _level ); \
468      _control = _ERC32_MEC_Timer_Control_Mirror; \
469      _control &= ERC32_MEC_TIMER_COUNTER_DEFINED_MASK << 8; \
470      _ERC32_MEC_Timer_Control_Mirror = _control | _value; \
471      _control &= (ERC32_MEC_TIMER_COUNTER_CURRENT_MODE_MASK << 8); \
472      _control |= __value; \
473      /* printf( "GPT 0x%x 0x%x 0x%x\n", _value, __value, _control );  */ \
474      ERC32_MEC.Timer_Control = _control; \
475    sparc_enable_interrupts( _level ); \
476  } while ( 0 )
477
478#define ERC32_MEC_Get_General_Purpose_Timer_Control( _value ) \
479  do { \
480    (_value) = _ERC32_MEC_Timer_Control_Mirror & 0xf; \
481  } while ( 0 )
482
483/*
484 *  This macros manipulate the Real Timer Clock Timer portion of the
485 *  Timer Control register and promote the view that there are actually
486 *  two independent Timer Control Registers.
487 */
488 
489#define ERC32_MEC_Set_Real_Time_Clock_Timer_Control( _value ) \
490  do { \
491    unsigned32 _level; \
492    unsigned32 _control; \
493    unsigned32 __value; \
494    \
495    __value = ((_value) & 0x0f) << 8; \
496    sparc_disable_interrupts( _level ); \
497      _control = _ERC32_MEC_Timer_Control_Mirror; \
498      _control &= ERC32_MEC_TIMER_COUNTER_DEFINED_MASK; \
499      _ERC32_MEC_Timer_Control_Mirror = _control | __value; \
500      _control &= ERC32_MEC_TIMER_COUNTER_CURRENT_MODE_MASK; \
501      _control |= __value; \
502      /* printf( "RTC 0x%x 0x%x 0x%x\n", _value, __value, _control ); */ \
503      ERC32_MEC.Timer_Control = _control; \
504    sparc_enable_interrupts( _level ); \
505  } while ( 0 )
506 
507#define ERC32_MEC_Get_Real_Time_Clock_Timer_Control( _value ) \
508  do { \
509    (_value) = (_ERC32_MEC_Timer_Control_Mirror >> 8) & 0xf; \
510  } while ( 0 )
511
512
513#endif /* !ASM */
514
515#ifdef __cplusplus
516}
517#endif
518 
519#endif /* !_INCLUDE_ERC32_h */
520/* end of include file */
521
Note: See TracBrowser for help on using the repository browser.