1 | /* remap the zero-based PCI IO spaces of both hoses to a single |
---|
2 | * address space |
---|
3 | * |
---|
4 | * This must be called AFTER to BSP_pci_initialize() |
---|
5 | */ |
---|
6 | |
---|
7 | /* |
---|
8 | * Authorship |
---|
9 | * ---------- |
---|
10 | * This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was |
---|
11 | * created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007, |
---|
12 | * Stanford Linear Accelerator Center, Stanford University. |
---|
13 | * |
---|
14 | * Acknowledgement of sponsorship |
---|
15 | * ------------------------------ |
---|
16 | * The 'beatnik' BSP was produced by |
---|
17 | * the Stanford Linear Accelerator Center, Stanford University, |
---|
18 | * under Contract DE-AC03-76SFO0515 with the Department of Energy. |
---|
19 | * |
---|
20 | * Government disclaimer of liability |
---|
21 | * ---------------------------------- |
---|
22 | * Neither the United States nor the United States Department of Energy, |
---|
23 | * nor any of their employees, makes any warranty, express or implied, or |
---|
24 | * assumes any legal liability or responsibility for the accuracy, |
---|
25 | * completeness, or usefulness of any data, apparatus, product, or process |
---|
26 | * disclosed, or represents that its use would not infringe privately owned |
---|
27 | * rights. |
---|
28 | * |
---|
29 | * Stanford disclaimer of liability |
---|
30 | * -------------------------------- |
---|
31 | * Stanford University makes no representations or warranties, express or |
---|
32 | * implied, nor assumes any liability for the use of this software. |
---|
33 | * |
---|
34 | * Stanford disclaimer of copyright |
---|
35 | * -------------------------------- |
---|
36 | * Stanford University, owner of the copyright, hereby disclaims its |
---|
37 | * copyright and all other rights in this software. Hence, anyone may |
---|
38 | * freely use it for any purpose without restriction. |
---|
39 | * |
---|
40 | * Maintenance of notices |
---|
41 | * ---------------------- |
---|
42 | * In the interest of clarity regarding the origin and status of this |
---|
43 | * SLAC software, this and all the preceding Stanford University notices |
---|
44 | * are to remain affixed to any copy or derivative of this software made |
---|
45 | * or distributed by the recipient and are to be affixed to any copy of |
---|
46 | * software made or distributed by the recipient that contains a copy or |
---|
47 | * derivative of this software. |
---|
48 | * |
---|
49 | * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 |
---|
50 | */ |
---|
51 | #include <rtems.h> |
---|
52 | #include <bsp.h> |
---|
53 | #include <libcpu/io.h> |
---|
54 | #include <bsp/pci.h> |
---|
55 | #include <bsp/irq.h> |
---|
56 | #include <rtems/bspIo.h> |
---|
57 | #include <bsp/gtreg.h> |
---|
58 | #include "pci_io_remap.h" |
---|
59 | |
---|
60 | static int |
---|
61 | fixup_irq_line(int bus, int slot, int fun, void *uarg) |
---|
62 | { |
---|
63 | unsigned char line; |
---|
64 | pci_read_config_byte( bus, slot, fun, PCI_INTERRUPT_LINE, &line); |
---|
65 | if ( line < BSP_IRQ_GPP_0 ) { |
---|
66 | pci_write_config_byte( bus, slot, fun, PCI_INTERRUPT_LINE, line + BSP_IRQ_GPP_0 ); |
---|
67 | } |
---|
68 | |
---|
69 | return 0; |
---|
70 | } |
---|
71 | |
---|
72 | void BSP_motload_pci_fixup(void) |
---|
73 | { |
---|
74 | uint32_t b0,b1,r0,r1,lim,dis; |
---|
75 | |
---|
76 | /* MotLoad on the mvme5500 and mvme6100 configures the PCI |
---|
77 | * busses nicely, i.e., the values read from the memory address |
---|
78 | * space BARs by means of PCI config cycles directly reflect the |
---|
79 | * CPU memory map. Thus, the presence of two hoses is already hidden. |
---|
80 | * |
---|
81 | * Unfortunately, all PCI I/O addresses are 'zero-based' i.e., |
---|
82 | * a hose-specific base address would have to be added to |
---|
83 | * the values read from config space. |
---|
84 | * |
---|
85 | * We fix this here so I/O BARs also reflect the CPU memory map. |
---|
86 | * |
---|
87 | * Furthermore, the mvme5500 uses |
---|
88 | * f000.0000 |
---|
89 | * ..f07f.ffff for PCI-0 / hose0 |
---|
90 | * |
---|
91 | * and |
---|
92 | * |
---|
93 | * f080.0000 |
---|
94 | * ..f0ff.0000 for PCI-1 / hose 0 |
---|
95 | * |
---|
96 | * whereas the mvme6100 does it the other way round... |
---|
97 | */ |
---|
98 | |
---|
99 | b0 = in_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI0_IO_Low_Decode) ); |
---|
100 | b1 = in_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI1_IO_Low_Decode) ); |
---|
101 | |
---|
102 | r0 = in_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI0_IO_Remap) ); |
---|
103 | r1 = in_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI1_IO_Remap) ); |
---|
104 | |
---|
105 | switch ( BSP_getDiscoveryVersion(0) ) { |
---|
106 | case MV_64360: |
---|
107 | /* In case of the MV64360 the 'limit' is actually a 'size'! |
---|
108 | * Disable by setting special bits in the 'BAR disable reg'. |
---|
109 | */ |
---|
110 | dis = in_le32( (volatile unsigned*)(BSP_MV64x60_BASE + MV_64360_BASE_ADDR_DISBL) ); |
---|
111 | /* disable PCI0 I/O and PCI1 I/O */ |
---|
112 | out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + MV_64360_BASE_ADDR_DISBL), dis | (1<<9) | (1<<14) ); |
---|
113 | /* remap busses on hose 0; if the remap register was already set, assume |
---|
114 | * that someone else [such as the bootloader] already performed the fixup |
---|
115 | */ |
---|
116 | if ( (b0 & 0xffff) && 0 == (r0 & 0xffff) ) { |
---|
117 | rtems_pci_io_remap( 0, BSP_pci_hose1_bus_base, (b0 & 0xffff)<<16 ); |
---|
118 | out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI0_IO_Remap), (b0 & 0xffff) ); |
---|
119 | } |
---|
120 | |
---|
121 | /* remap busses on hose 1 */ |
---|
122 | if ( (b1 & 0xffff) && 0 == (r1 & 0xffff) ) { |
---|
123 | rtems_pci_io_remap( BSP_pci_hose1_bus_base, pci_bus_count(), (b1 & 0xffff)<<16 ); |
---|
124 | out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI1_IO_Remap), (b1 & 0xffff) ); |
---|
125 | } |
---|
126 | |
---|
127 | /* re-enable */ |
---|
128 | out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + MV_64360_BASE_ADDR_DISBL), dis ); |
---|
129 | break; |
---|
130 | |
---|
131 | case GT_64260_A: |
---|
132 | case GT_64260_B: |
---|
133 | |
---|
134 | if ( (b0 & 0xfff) && 0 == (r0 & 0xfff) ) { /* base are only 12 bits */ |
---|
135 | /* switch window off by setting the limit < base */ |
---|
136 | lim = in_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI0_IO_High_Decode) ); |
---|
137 | out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI0_IO_High_Decode), 0 ); |
---|
138 | /* remap busses on hose 0 */ |
---|
139 | rtems_pci_io_remap( 0, BSP_pci_hose1_bus_base, (b0 & 0xfff)<<20 ); |
---|
140 | |
---|
141 | /* BTW: it seems that writing the base register also copies the |
---|
142 | * value into the 'remap' register automatically (??) |
---|
143 | */ |
---|
144 | out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI0_IO_Remap), (b0 & 0xfff) ); |
---|
145 | |
---|
146 | /* re-enable */ |
---|
147 | out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI0_IO_High_Decode), lim ); |
---|
148 | } |
---|
149 | |
---|
150 | if ( (b1 & 0xfff) && 0 == (r1 & 0xfff) ) { /* base are only 12 bits */ |
---|
151 | /* switch window off by setting the limit < base */ |
---|
152 | lim = in_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI1_IO_High_Decode) ); |
---|
153 | out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI1_IO_High_Decode), 0 ); |
---|
154 | |
---|
155 | /* remap busses on hose 1 */ |
---|
156 | rtems_pci_io_remap( BSP_pci_hose1_bus_base, pci_bus_count(), (b1 & 0xfff)<<20 ); |
---|
157 | |
---|
158 | out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI1_IO_Remap), (b1 & 0xfff) ); |
---|
159 | |
---|
160 | /* re-enable */ |
---|
161 | out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI1_IO_High_Decode), lim ); |
---|
162 | } |
---|
163 | break; |
---|
164 | |
---|
165 | default: |
---|
166 | BSP_panic("Unknown discovery version; switch in file: "__FILE__" not implemented (yet)"); |
---|
167 | break; /* never get here */ |
---|
168 | } |
---|
169 | |
---|
170 | /* Fixup the IRQ lines; the mvme6100 maps them nicely into our scheme, i.e., GPP |
---|
171 | * interrupts start at 64 upwards |
---|
172 | * |
---|
173 | * The mvme5500 is apparently initialized differently :-(. GPP interrupts start at 0 |
---|
174 | * Since all PCI interrupts are wired to GPP we simply check for a value < 64 and |
---|
175 | * reprogram the interrupt line register. |
---|
176 | */ |
---|
177 | BSP_pciScan(0, fixup_irq_line, 0); |
---|
178 | } |
---|
179 | |
---|
180 | |
---|