1 |
27 |
unneback |
#ifndef CYGONCE_HAL_PROC_INTR_H
|
2 |
|
|
#define CYGONCE_HAL_PROC_INTR_H
|
3 |
|
|
|
4 |
|
|
//==========================================================================
|
5 |
|
|
//
|
6 |
|
|
// proc_intr.h
|
7 |
|
|
//
|
8 |
|
|
// mcf5272 Processor variant interrupt and clock support
|
9 |
|
|
//
|
10 |
|
|
//==========================================================================
|
11 |
|
|
//####ECOSGPLCOPYRIGHTBEGIN####
|
12 |
|
|
// -------------------------------------------
|
13 |
|
|
// This file is part of eCos, the Embedded Configurable Operating System.
|
14 |
|
|
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
15 |
|
|
//
|
16 |
|
|
// eCos is free software; you can redistribute it and/or modify it under
|
17 |
|
|
// the terms of the GNU General Public License as published by the Free
|
18 |
|
|
// Software Foundation; either version 2 or (at your option) any later version.
|
19 |
|
|
//
|
20 |
|
|
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
|
21 |
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
22 |
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
23 |
|
|
// for more details.
|
24 |
|
|
//
|
25 |
|
|
// You should have received a copy of the GNU General Public License along
|
26 |
|
|
// with eCos; if not, write to the Free Software Foundation, Inc.,
|
27 |
|
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
28 |
|
|
//
|
29 |
|
|
// As a special exception, if other files instantiate templates or use macros
|
30 |
|
|
// or inline functions from this file, or you compile this file and link it
|
31 |
|
|
// with other works to produce a work based on this file, this file does not
|
32 |
|
|
// by itself cause the resulting work to be covered by the GNU General Public
|
33 |
|
|
// License. However the source code for this file must still be made available
|
34 |
|
|
// in accordance with section (3) of the GNU General Public License.
|
35 |
|
|
//
|
36 |
|
|
// This exception does not invalidate any other reasons why a work based on
|
37 |
|
|
// this file might be covered by the GNU General Public License.
|
38 |
|
|
//
|
39 |
|
|
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
|
40 |
|
|
// at http://sources.redhat.com/ecos/ecos-license/
|
41 |
|
|
// -------------------------------------------
|
42 |
|
|
//####ECOSGPLCOPYRIGHTEND####
|
43 |
|
|
//==========================================================================
|
44 |
|
|
|
45 |
|
|
#include <pkgconf/hal.h>
|
46 |
|
|
#include <cyg/infra/cyg_type.h>
|
47 |
|
|
|
48 |
|
|
// Include any platform specific interrupt definitions.
|
49 |
|
|
#include <cyg/hal/plf_intr.h>
|
50 |
|
|
|
51 |
|
|
// Include for the SIM address (MCF5272_SIM).
|
52 |
|
|
#include <cyg/hal/proc_arch.h>
|
53 |
|
|
|
54 |
|
|
//---------------------------------------------------------------------------
|
55 |
|
|
// Interrupt controller management
|
56 |
|
|
|
57 |
|
|
// This chip has a programmable interrupt vector base which is different
|
58 |
|
|
// from the vector base register (VBR). All interrupts from the interrupt
|
59 |
|
|
// controller are offsets from the programmable interrupt vector register
|
60 |
|
|
// (PIVR).
|
61 |
|
|
|
62 |
|
|
#define HAL_PROG_INT_VEC_BASE 64
|
63 |
|
|
|
64 |
|
|
// Vector numbers defined by the interrupt controller.
|
65 |
|
|
// These are all relative to the interrupt vector base number.
|
66 |
|
|
#define CYGNUM_HAL_VECTOR_USR_SPUR_INT (0 + HAL_PROG_INT_VEC_BASE)
|
67 |
|
|
#define CYGNUM_HAL_VECTOR_EXTINT1 (1 + HAL_PROG_INT_VEC_BASE)
|
68 |
|
|
#define CYGNUM_HAL_VECTOR_EXTINT2 (2 + HAL_PROG_INT_VEC_BASE)
|
69 |
|
|
#define CYGNUM_HAL_VECTOR_EXTINT3 (3 + HAL_PROG_INT_VEC_BASE)
|
70 |
|
|
#define CYGNUM_HAL_VECTOR_EXTINT4 (4 + HAL_PROG_INT_VEC_BASE)
|
71 |
|
|
#define CYGNUM_HAL_VECTOR_TMR1 (5 + HAL_PROG_INT_VEC_BASE)
|
72 |
|
|
#define CYGNUM_HAL_VECTOR_TMR2 (6 + HAL_PROG_INT_VEC_BASE)
|
73 |
|
|
#define CYGNUM_HAL_VECTOR_TMR3 (7 + HAL_PROG_INT_VEC_BASE)
|
74 |
|
|
#define CYGNUM_HAL_VECTOR_TMR4 (8 + HAL_PROG_INT_VEC_BASE)
|
75 |
|
|
#define CYGNUM_HAL_VECTOR_UART1 (9 + HAL_PROG_INT_VEC_BASE)
|
76 |
|
|
#define CYGNUM_HAL_VECTOR_UART2 (10 + HAL_PROG_INT_VEC_BASE)
|
77 |
|
|
#define CYGNUM_HAL_VECTOR_PLIP (11 + HAL_PROG_INT_VEC_BASE)
|
78 |
|
|
#define CYGNUM_HAL_VECTOR_PLIA (12 + HAL_PROG_INT_VEC_BASE)
|
79 |
|
|
#define CYGNUM_HAL_VECTOR_USB0 (13 + HAL_PROG_INT_VEC_BASE)
|
80 |
|
|
#define CYGNUM_HAL_VECTOR_USB1 (14 + HAL_PROG_INT_VEC_BASE)
|
81 |
|
|
#define CYGNUM_HAL_VECTOR_USB2 (15 + HAL_PROG_INT_VEC_BASE)
|
82 |
|
|
#define CYGNUM_HAL_VECTOR_USB3 (16 + HAL_PROG_INT_VEC_BASE)
|
83 |
|
|
#define CYGNUM_HAL_VECTOR_USB4 (17 + HAL_PROG_INT_VEC_BASE)
|
84 |
|
|
#define CYGNUM_HAL_VECTOR_USB5 (18 + HAL_PROG_INT_VEC_BASE)
|
85 |
|
|
#define CYGNUM_HAL_VECTOR_USB6 (19 + HAL_PROG_INT_VEC_BASE)
|
86 |
|
|
#define CYGNUM_HAL_VECTOR_USB7 (20 + HAL_PROG_INT_VEC_BASE)
|
87 |
|
|
#define CYGNUM_HAL_VECTOR_DMA (21 + HAL_PROG_INT_VEC_BASE)
|
88 |
|
|
#define CYGNUM_HAL_VECTOR_ERX (22 + HAL_PROG_INT_VEC_BASE)
|
89 |
|
|
#define CYGNUM_HAL_VECTOR_ETX (23 + HAL_PROG_INT_VEC_BASE)
|
90 |
|
|
#define CYGNUM_HAL_VECTOR_ENTC (24 + HAL_PROG_INT_VEC_BASE)
|
91 |
|
|
#define CYGNUM_HAL_VECTOR_QSPI (25 + HAL_PROG_INT_VEC_BASE)
|
92 |
|
|
#define CYGNUM_HAL_VECTOR_EXTINT5 (26 + HAL_PROG_INT_VEC_BASE)
|
93 |
|
|
#define CYGNUM_HAL_VECTOR_EXTINT6 (27 + HAL_PROG_INT_VEC_BASE)
|
94 |
|
|
#define CYGNUM_HAL_VECTOR_SWTO (28 + HAL_PROG_INT_VEC_BASE)
|
95 |
|
|
#define CYGNUM_HAL_VECTOR_RES1 (29 + HAL_PROG_INT_VEC_BASE)
|
96 |
|
|
#define CYGNUM_HAL_VECTOR_RES2 (30 + HAL_PROG_INT_VEC_BASE)
|
97 |
|
|
#define CYGNUM_HAL_VECTOR_RES3 (31 + HAL_PROG_INT_VEC_BASE)
|
98 |
|
|
|
99 |
|
|
//---------------------------------------------------------------------------
|
100 |
|
|
// Interrupt controller macros.
|
101 |
|
|
|
102 |
|
|
// Declare a mirror copy of the interrupt control registers used to set
|
103 |
|
|
// interrupt priorities. In order to mask and unmask a specific interrupt, we
|
104 |
|
|
// must be able to set its priority to zero and then restore it to ist
|
105 |
|
|
// original priority. We use these locations to determine the level to
|
106 |
|
|
// restore the interrupt to in the unmask macro.
|
107 |
|
|
|
108 |
|
|
externC cyg_uint32 hal_icr_pri_mirror[4];
|
109 |
|
|
|
110 |
|
|
// Block the interrupt associated with the given vector. To do this, we
|
111 |
|
|
// set the interrupt priority level to zero for the specified interrupt. To
|
112 |
|
|
// set the interrupt priority level, we simultaneously write a 1 to the
|
113 |
|
|
// pending interrupt field. The other interrupts are unaffected. Disable all
|
114 |
|
|
// interrupts while we access the hardware registers.
|
115 |
|
|
|
116 |
|
|
#define HAL_INTERRUPT_MASK( _vector_ ) \
|
117 |
|
|
CYG_MACRO_START \
|
118 |
|
|
cyg_uint32 _vec_offset = (_vector_) - HAL_PROG_INT_VEC_BASE - 1; \
|
119 |
|
|
cyg_uint32 _icr = _vec_offset / 8; \
|
120 |
|
|
cyg_uint32 _icr_msk = 0xf0000000 >> ((_vec_offset % 8) * 4); \
|
121 |
|
|
CYG_INTERRUPT_STATE _intr_state; \
|
122 |
|
|
HAL_DISABLE_INTERRUPTS(_intr_state); \
|
123 |
|
|
MCF5272_SIM->intc.icr[_icr] &= _icr_msk ^ 0x77777777; \
|
124 |
|
|
HAL_RESTORE_INTERRUPTS(_intr_state); \
|
125 |
|
|
CYG_MACRO_END
|
126 |
|
|
|
127 |
|
|
// Unblock the interrupt associated with the given vector. Set the
|
128 |
|
|
// interrupt priority using the value from the icr mirror variable. Disable
|
129 |
|
|
// all interrupts while we access the hardware registers.
|
130 |
|
|
|
131 |
|
|
#define HAL_INTERRUPT_UNMASK( _vector_ ) \
|
132 |
|
|
CYG_MACRO_START \
|
133 |
|
|
cyg_uint32 _vec_offset = (_vector_) - HAL_PROG_INT_VEC_BASE - 1; \
|
134 |
|
|
cyg_uint32 _icr = _vec_offset / 8; \
|
135 |
|
|
cyg_uint32 _icr_msk_offset = ((8-1)*4) - (_vec_offset % 8) * 4; \
|
136 |
|
|
cyg_uint32 _icr_msk = 0x0F << (_icr_msk_offset); \
|
137 |
|
|
cyg_uint32 _icr_val; \
|
138 |
|
|
CYG_INTERRUPT_STATE _intr_state; \
|
139 |
|
|
HAL_DISABLE_INTERRUPTS(_intr_state); \
|
140 |
|
|
_icr_val = MCF5272_SIM->intc.icr[_icr] & 0x77777777 & ~_icr_msk; \
|
141 |
|
|
_icr_val |= hal_icr_pri_mirror[_icr] & _icr_msk; \
|
142 |
|
|
_icr_val |= 0x08 << _icr_msk_offset; \
|
143 |
|
|
MCF5272_SIM->intc.icr[_icr] = _icr_val; \
|
144 |
|
|
HAL_RESTORE_INTERRUPTS(_intr_state); \
|
145 |
|
|
CYG_MACRO_END
|
146 |
|
|
|
147 |
|
|
// Acknowledge the interrupt by writing a 1 to the corresponding
|
148 |
|
|
// interrupt pending bit. Write 0 to all other interrupt pending bits. Leave
|
149 |
|
|
// all priority levels unchanged. Disable all interrupts while we access the
|
150 |
|
|
// hardware registers.
|
151 |
|
|
|
152 |
|
|
#define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ ) \
|
153 |
|
|
CYG_MACRO_START \
|
154 |
|
|
cyg_uint32 _vec_offset = (_vector_) - HAL_PROG_INT_VEC_BASE - 1; \
|
155 |
|
|
cyg_uint32 _icr = _vec_offset / 8; \
|
156 |
|
|
cyg_uint32 _icr_msk = 0x80000000 >> ((_vec_offset % 8) * 4); \
|
157 |
|
|
CYG_INTERRUPT_STATE _intr_state; \
|
158 |
|
|
HAL_DISABLE_INTERRUPTS(_intr_state); \
|
159 |
|
|
MCF5272_SIM->intc.icr[_icr] &= _icr_msk | 0x77777777; \
|
160 |
|
|
HAL_RESTORE_INTERRUPTS(_intr_state); \
|
161 |
|
|
CYG_MACRO_END
|
162 |
|
|
|
163 |
|
|
// Set the priority in the interrupt control register and the icr mirror.
|
164 |
|
|
// Do not copy the icr mirror into the icr because some interrupts may be
|
165 |
|
|
// masked. Disable all interrupts while we access the hardware registers.
|
166 |
|
|
|
167 |
|
|
#define HAL_INTERRUPT_SET_LEVEL( _vector_, _prilevel_ ) \
|
168 |
|
|
CYG_MACRO_START \
|
169 |
|
|
cyg_uint32 _vec_offset = (_vector_) - HAL_PROG_INT_VEC_BASE - 1; \
|
170 |
|
|
cyg_uint32 _icr = _vec_offset / 8; \
|
171 |
|
|
cyg_uint32 _icr_msk_offset = ((8-1)*4) - (_vec_offset % 8) * 4; \
|
172 |
|
|
cyg_uint32 _icr_msk = 0x0F << (_icr_msk_offset); \
|
173 |
|
|
cyg_uint32 _icr_val = (0x08 | (_prilevel_ & 0x07)) << _icr_msk_offset; \
|
174 |
|
|
CYG_INTERRUPT_STATE _intr_state; \
|
175 |
|
|
HAL_DISABLE_INTERRUPTS(_intr_state); \
|
176 |
|
|
cyg_uint32 _mir_val = hal_icr_pri_mirror[_icr] & 0x77777777 & ~_icr_msk; \
|
177 |
|
|
hal_icr_pri_mirror[_icr] = _mir_val | _icr_val; \
|
178 |
|
|
_icr_val |= MCF5272_SIM->intc.icr[_icr] & 0x77777777 & ~_icr_msk; \
|
179 |
|
|
MCF5272_SIM->intc.icr[_icr] = _icr_val; \
|
180 |
|
|
HAL_RESTORE_INTERRUPTS(_intr_state); \
|
181 |
|
|
CYG_MACRO_END
|
182 |
|
|
|
183 |
|
|
// Set/clear the interrupt transition register bit. Disable all
|
184 |
|
|
// interrupts while we access the hardware registers.
|
185 |
|
|
|
186 |
|
|
// WARNING: It seems that manual currently has the polarity of this bit
|
187 |
|
|
// wrong.
|
188 |
|
|
|
189 |
|
|
#define HAL_INTERRUPT_CONFIGURE( _vector_, _leveltriggered_, _up_ ) \
|
190 |
|
|
CYG_MACRO_START \
|
191 |
|
|
if (!(_leveltriggered_)) \
|
192 |
|
|
{ \
|
193 |
|
|
cyg_uint32 _vec_offset = (_vector_) - HAL_PROG_INT_VEC_BASE - 1; \
|
194 |
|
|
cyg_uint32 _itr_bit = 0x80000000 >> _vec_offset; \
|
195 |
|
|
CYG_INTERRUPT_STATE _intr_state; \
|
196 |
|
|
HAL_DISABLE_INTERRUPTS(_intr_state); \
|
197 |
|
|
if (_up_) \
|
198 |
|
|
{ \
|
199 |
|
|
MCF5272_SIM->intc.pitr |= _itr_bit; \
|
200 |
|
|
} \
|
201 |
|
|
else \
|
202 |
|
|
{ \
|
203 |
|
|
MCF5272_SIM->intc.pitr &= ~_itr_bit; \
|
204 |
|
|
} \
|
205 |
|
|
HAL_RESTORE_INTERRUPTS(_intr_state); \
|
206 |
|
|
} \
|
207 |
|
|
CYG_MACRO_END
|
208 |
|
|
|
209 |
|
|
//--------------------------------------------------------------------------
|
210 |
|
|
#endif // ifndef CYGONCE_HAL_PROC_INTR_H
|
211 |
|
|
|