1 //==========================================================================
5 // Miscellaneous functions specific to the processor variant
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // Copyright (C) 2006 eCosCentric Ltd.
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
36 // -------------------------------------------
37 //####ECOSGPLCOPYRIGHTEND####
38 //==========================================================================
39 //#####DESCRIPTIONBEGIN####
41 // Author(s): Enrico Piria
44 // Purpose: Miscellaneous functions specific to the MCF5272 processor.
46 //####DESCRIPTIONEND####
47 //========================================================================
49 #include <pkgconf/hal.h>
51 #include <cyg/infra/cyg_type.h>
53 #include <cyg/hal/hal_intr.h>
54 #include <cyg/hal/hal_arch.h>
55 #include <cyg/hal/hal_io.h>
57 #include CYGHWR_MEMORY_LAYOUT_H
59 // -------------------------------------------------------------------------
62 // For the MCF5272, we can point the VBR directly to the VSR table.
63 // However, the table must be on a 1 MB boundary. Locate the VSR table where
64 // the linker tells us to.
66 volatile CYG_ADDRESS cyg_hal_vsr_table[CYGNUM_HAL_VSR_COUNT]
67 __attribute__ ((section (".ramvec")));
69 // -------------------------------------------------------------------------
70 // Function prototypes
72 static void hal_update_interrupt_controller(int vector);
74 // -------------------------------------------------------------------------
75 // Interrupt controller management
77 // With the MCF5272 interrupt controller, it is not possible to mask an
78 // interrupt while retaining its associated priority. Moreover, if we enabled
79 // the use of interrupts with different priorities, we don't have a means to
80 // retrieve the priority of the current interrupt, after having raised the
81 // IPL to the maximum, in the first instruction of the HAL ISR handler.
82 // So, we use an auxiliary table (cyg_hal_ILVL_table) that records all the
83 // priorities set for the various interrupts.
84 // The purpose of the cyg_hal_IMASK_table table is to record wether an
85 // interrupt is currently masked (0) or not (1).
87 volatile cyg_uint8 cyg_hal_ILVL_table[CYGNUM_HAL_ISR_COUNT];
88 volatile cyg_uint8 cyg_hal_IMASK_table[CYGNUM_HAL_ISR_COUNT];
91 // Update priority table and interrupt controller
92 void hal_interrupt_set_level(int vector, int level)
96 CYG_ASSERT((0 <= (level) && 7 >= (level)), "Illegal level");
97 CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector)
98 && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector");
100 HAL_TRANSLATE_VECTOR(vector, index);
101 cyg_hal_ILVL_table[index] = (cyg_uint8) level;
103 hal_update_interrupt_controller(vector);
106 // Update mask table and interrupt controller
107 void hal_interrupt_mask(int vector)
111 CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector)
112 && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector");
114 HAL_TRANSLATE_VECTOR(vector, index);
115 cyg_hal_IMASK_table[index] = 0;
117 hal_update_interrupt_controller(vector);
120 // Update mask table and interrupt controller
121 void hal_interrupt_unmask(int vector)
125 CYG_ASSERT((CYGNUM_HAL_ISR_MIN <= (vector)
126 && CYGNUM_HAL_ISR_MAX >= (vector)), "Illegal vector");
128 HAL_TRANSLATE_VECTOR(vector, index);
129 cyg_hal_IMASK_table[index] = 1;
131 hal_update_interrupt_controller(vector);
135 // Set the priority in the interrupt control register.
136 // Disable all interrupts while we access the hardware registers.
137 static void hal_update_interrupt_controller(int vector)
141 cyg_uint32 vec_offset;
142 cyg_uint32 icr, icr_msk_offset, icr_msk, icr_val, icr_oldval;
143 CYG_INTERRUPT_STATE intr_state;
145 HAL_TRANSLATE_VECTOR(vector, index);
146 level = cyg_hal_IMASK_table[index] ? cyg_hal_ILVL_table[index] : 0;
148 vec_offset = (vector) - HAL_PROG_INT_VEC_BASE - 1;
149 icr = vec_offset / 8;
150 icr_msk_offset = ((8-1)*4) - (vec_offset % 8) * 4;
151 icr_msk = 0x0F << (icr_msk_offset);
152 icr_val = (0x08 | (level & 0x07)) << icr_msk_offset;
154 HAL_DISABLE_INTERRUPTS(intr_state);
155 HAL_READ_UINT32(&MCF5272_DEVS->intc.icr[icr], icr_oldval);
156 icr_val |= icr_oldval & 0x77777777 & ~icr_msk;
157 HAL_WRITE_UINT32(&MCF5272_DEVS->intc.icr[icr], icr_val);
158 HAL_RESTORE_INTERRUPTS(intr_state);
160 // -------------------------------------------------------------------------