comparison packages/hal/arm/ebsa285/current/include/plf_io.h @ 76:435cced73e2f ecos-v1_3_1-release

eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
author jlarmour
date Tue, 28 Mar 2000 14:10:45 +0000
parents
children 6ed91473a1cd
comparison
equal deleted inserted replaced
75:41bf073c0c32 76:435cced73e2f
1 #ifndef CYGONCE_PLF_IO_H
2 #define CYGONCE_PLF_IO_H
3
4 //=============================================================================
5 //
6 // plf_io.h
7 //
8 // Platform specific IO support
9 //
10 //=============================================================================
11 //####COPYRIGHTBEGIN####
12 //
13 // -------------------------------------------
14 // The contents of this file are subject to the Red Hat eCos Public License
15 // Version 1.1 (the "License"); you may not use this file except in
16 // compliance with the License. You may obtain a copy of the License at
17 // http://www.redhat.com/
18 //
19 // Software distributed under the License is distributed on an "AS IS"
20 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
21 // License for the specific language governing rights and limitations under
22 // the License.
23 //
24 // The Original Code is eCos - Embedded Configurable Operating System,
25 // released September 30, 1998.
26 //
27 // The Initial Developer of the Original Code is Red Hat.
28 // Portions created by Red Hat are
29 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
30 // All Rights Reserved.
31 // -------------------------------------------
32 //
33 //####COPYRIGHTEND####
34 //=============================================================================
35 //#####DESCRIPTIONBEGIN####
36 //
37 // Author(s): hmt, jskov
38 // Contributors: hmt, jskov
39 // Date: 1999-08-09
40 // Purpose: Intel EBSA285 PCI IO support macros
41 // Description:
42 // Usage: #include <cyg/hal/plf_io.h>
43 //
44 // Note: Based on information in
45 // "21285 Core Logic for SA-110 Microprocessor"
46 //####DESCRIPTIONEND####
47 //
48 //=============================================================================
49
50 #include <pkgconf/hal_arm_ebsa285.h>
51
52 #include <cyg/hal/hal_ebsa285.h>
53
54 #include <cyg/hal/hal_io.h> // IO macros
55 #include <cyg/hal/hal_platform_ints.h> // Interrupt vectors
56
57 // The PCI resources required by the EBSA are hardcoded to the lowest
58 // addresses in the PCI address space, thus:
59 // PCI Memory Space
60 #define EBSA_SDRAM_PCI_ADDR 0
61 #define EBSA_SDRAM_PCI_SIZE (CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_SIZE)
62 #define EBSA_CSR_MEM_PCI_ADDR (EBSA_SDRAM_PCI_SIZE)
63 #define EBSA_CSR_MEM_PCI_SIZE 0x80
64 // PCI IO Space
65 #define EBSA_CSR_IO_PCI_ADDR 0
66 #define EBSA_CSR_IO_PCI_SIZE 0x80
67
68 // Initialize the PCI bus.
69 #define HAL_PCI_INIT() \
70 CYG_MACRO_START \
71 cyg_uint32 __tmp, __tmp2; \
72 \
73 /* Disable PCI Outbound interrupts */ \
74 /* (according to 7-14 SA110_OUT_INT_MASK is not accessible */ \
75 /* by SA-100) */ \
76 HAL_WRITE_UINT32(SA110_OUT_INT_STATUS, \
77 SA110_OUT_INT_STATUS_DOORBELL_INT \
78 |SA110_OUT_INT_STATUS_OUTBOUND_INT); \
79 \
80 /* Disable Doorbells */ \
81 HAL_WRITE_UINT32(SA110_DOORBELL_PCI_MASK, 0); \
82 HAL_WRITE_UINT32(SA110_DOORBELL_SA_MASK, 0); \
83 \
84 /* Map high PCI address bits to 0 */ \
85 HAL_WRITE_UINT32(SA110_PCI_ADDR_EXT, 0); \
86 \
87 /* Interrupt ID to 1 */ \
88 HAL_WRITE_UINT16(SA110_PCI_CFG_INT_LINE, 0x0100); \
89 \
90 /* Remove PCI_reset */ \
91 HAL_READ_UINT32(SA110_CONTROL, __tmp); \
92 __tmp |= SA110_CONTROL_RST_I; \
93 HAL_WRITE_UINT32(SA110_CONTROL, __tmp); \
94 \
95 /* Open a window to SDRAM from PCI address space */ \
96 HAL_WRITE_UINT32(SA110_SDRAM_BASE_ADDRESS_MASK, \
97 ((CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_SIZE-1) & 0xfffc0000)); \
98 HAL_WRITE_UINT32(SA110_SDRAM_BASE_ADDRESS_OFFSET, \
99 CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE); \
100 \
101 /* Only init PCI if central function is set and */ \
102 /* standalone bit is cleared */ \
103 HAL_READ_UINT32(SA110_CONTROL, __tmp); \
104 HAL_READ_UINT32(SA110_XBUS_XCS2, __tmp2); \
105 if ((__tmp & SA110_CONTROL_CFN) == SA110_CONTROL_CFN \
106 && (__tmp2 & SA110_XBUS_XCS2_PCI_DISABLE) == 0) { \
107 \
108 /* Don't respond to any commands */ \
109 HAL_WRITE_UINT16(SA110_PCI_CFG_COMMAND, 0); \
110 \
111 /* Set up default addresses for board's resources. */ \
112 HAL_WRITE_UINT32(SA110_PCI_CFG_CSR_MEM_BAR, \
113 EBSA_CSR_MEM_PCI_ADDR); \
114 HAL_WRITE_UINT32(SA110_PCI_CFG_CSR_IO_BAR, EBSA_CSR_IO_PCI_ADDR);\
115 HAL_WRITE_UINT32(SA110_PCI_CFG_SDRAM_BAR, EBSA_SDRAM_PCI_ADDR); \
116 \
117 /* Respond to I/O space & Memory transactions. */ \
118 HAL_WRITE_UINT32(SA110_PCI_CFG_COMMAND, \
119 CYG_PCI_CFG_COMMAND_INVALIDATE \
120 |CYG_PCI_CFG_COMMAND_IO \
121 |CYG_PCI_CFG_COMMAND_MEMORY \
122 |CYG_PCI_CFG_COMMAND_MASTER); \
123 } \
124 /* Signal PCI_init_complete */ \
125 HAL_READ_UINT32(SA110_CONTROL, __tmp); \
126 __tmp |= SA110_CONTROL_INIT_COMPLETE; \
127 HAL_WRITE_UINT32(SA110_CONTROL, __tmp); \
128 \
129 CYG_MACRO_END
130
131
132 // Compute address necessary to access PCI config space for the given
133 // bus and device.
134 #define HAL_PCI_CONFIG_ADDRESS( __bus, __devfn, __offset ) \
135 ({ \
136 cyg_uint32 __addr; \
137 cyg_uint32 __dev = CYG_PCI_DEV_GET_DEV(__devfn); \
138 if (0 == __bus) { \
139 if (0 == __dev) { \
140 /* Access self via CSR base */ \
141 __addr = SA110_CONTROL_STATUS_BASE; \
142 } else { \
143 /* Page 3-17, table 3-5: bits 15-11 generate PCI address */ \
144 __addr = SA110_PCI_CONFIG0_BASE | 0x00c00000 | (__dev << 11);\
145 } \
146 } else { \
147 __addr = SA110_PCI_CONFIG1_BASE | (__bus << 16) | (__dev << 11); \
148 } \
149 __addr |= CYG_PCI_DEV_GET_FN(__devfn) << 8; \
150 __addr |= __offset; \
151 __addr; \
152 })
153
154 // Read a value from the PCI configuration space of the appropriate
155 // size at an address composed from the bus, devfn and offset.
156 #define HAL_PCI_CFG_READ_UINT8( __bus, __devfn, __offset, __val ) \
157 HAL_READ_UINT8(HAL_PCI_CONFIG_ADDRESS(__bus, __devfn, __offset), __val)
158
159 #define HAL_PCI_CFG_READ_UINT16( __bus, __devfn, __offset, __val ) \
160 HAL_READ_UINT16(HAL_PCI_CONFIG_ADDRESS(__bus, __devfn, __offset), __val)
161
162 #define HAL_PCI_CFG_READ_UINT32( __bus, __devfn, __offset, __val ) \
163 HAL_READ_UINT32(HAL_PCI_CONFIG_ADDRESS(__bus, __devfn, __offset), __val)
164
165 // Write a value to the PCI configuration space of the appropriate
166 // size at an address composed from the bus, devfn and offset.
167 #define HAL_PCI_CFG_WRITE_UINT8( __bus, __devfn, __offset, __val ) \
168 HAL_WRITE_UINT8(HAL_PCI_CONFIG_ADDRESS(__bus, __devfn, __offset), __val)
169
170 #define HAL_PCI_CFG_WRITE_UINT16( __bus, __devfn, __offset, __val ) \
171 HAL_WRITE_UINT16(HAL_PCI_CONFIG_ADDRESS(__bus, __devfn, __offset), __val)
172
173 #define HAL_PCI_CFG_WRITE_UINT32( __bus, __devfn, __offset, __val ) \
174 HAL_WRITE_UINT32(HAL_PCI_CONFIG_ADDRESS(__bus, __devfn, __offset), __val)
175
176 //-----------------------------------------------------------------------------
177 // Resources
178
179 // Map PCI device resources starting from these addresses in PCI space.
180 #define HAL_PCI_ALLOC_BASE_MEMORY (EBSA_SDRAM_PCI_SIZE+EBSA_CSR_MEM_PCI_SIZE)
181 #define HAL_PCI_ALLOC_BASE_IO (EBSA_CSR_IO_PCI_SIZE)
182
183 // This is where the PCI spaces are mapped in the CPU's address space.
184 #define HAL_PCI_PHYSICAL_MEMORY_BASE 0x80000000
185 #define HAL_PCI_PHYSICAL_IO_BASE 0x7c000000
186
187 // Translate the PCI interrupt requested by the device (INTA#, INTB#,
188 // INTC# or INTD#) to the associated CPU interrupt (i.e., HAL vector).
189 #define HAL_PCI_TRANSLATE_INTERRUPT( __bus, __devfn, __vec, __valid) \
190 CYG_MACRO_START \
191 cyg_uint8 __req; \
192 HAL_PCI_CFG_READ_UINT8(__bus, __devfn, CYG_PCI_CFG_INT_PIN, __req); \
193 if (0 != __req) { \
194 /* Interrupt assignment as 21285 sees them. (From */ \
195 /* EBSA285 Eval Board Reference Manual, 3.4 Interrupt Assignment) */ \
196 CYG_ADDRWORD __translation[4] = { \
197 CYGNUM_HAL_INTERRUPT_IRQ_IN_1, /* INTC# */ \
198 CYGNUM_HAL_INTERRUPT_IRQ_IN_0, /* INTB# */ \
199 CYGNUM_HAL_INTERRUPT_PCI_IRQ, /* INTA# */ \
200 CYGNUM_HAL_INTERRUPT_IRQ_IN_3}; /* INTD# */ \
201 \
202 /* The PCI lines from the different slots are wired like this */ \
203 /* on the PCI backplane: */ \
204 /* pin6A pin7B pin7A pin8B */ \
205 /* System Slot INTA# INTB# INTC# INTD# */ \
206 /* I/O Slot 1 INTB# INTC# INTD# INTA# */ \
207 /* I/O Slot 2 INTC# INTD# INTA# INTB# */ \
208 /* I/O Slot 3 INTD# INTA# INTB# INTC# */ \
209 /* I/O Slot 4 INTA# INTB# INTC# INTD# */ \
210 /* */ \
211 /* (From PCI Development Backplane, 3.2.2 Interrupts) */ \
212 /* */ \
213 /* Devsel signals are wired to, resulting in device IDs: */ \
214 /* I/O Slot 1 AD19 / dev 8 [(8+1)&3 = 1] */ \
215 /* I/O Slot 2 AD18 / dev 7 [(7+1)&3 = 0] */ \
216 /* I/O Slot 3 AD17 / dev 6 [(6+1)&3 = 3] */ \
217 /* I/O Slot 4 AD16 / dev 5 [(5+1)&3 = 2] */ \
218 /* */ \
219 /* (From PCI Development Backplane, 3.2.1 General) */ \
220 /* */ \
221 /* The observant reader will notice that the array does not */ \
222 /* match the table of how interrupts are wired. The array */ \
223 /* does however match observed behavior of the hardware: */ \
224 /* */ \
225 /* Observed interrupts with an Intel ethernet card */ \
226 /* put in the slots in turn and set to generate interrupts: */ \
227 /* slot 1/intA# (dev 8): caused host INTB# */ \
228 /* slot 2/intA# (dev 7): caused host INTC# */ \
229 /* slot 3/intA# (dev 6): caused host INTD# */ \
230 /* slot 4/intA# (dev 5): caused host INTA# */ \
231 \
232 __vec = __translation[((__req+CYG_PCI_DEV_GET_DEV(__devfn))&3)]; \
233 __valid = true; \
234 } else { \
235 /* Device will not generate interrupt requests. */ \
236 __valid = false; \
237 } \
238 CYG_MACRO_END
239
240 //-----------------------------------------------------------------------------
241 // end of plf_io.h
242 #endif // CYGONCE_PLF_IO_H