source: rtems/c/src/lib/libbsp/powerpc/shared/motorola/motorola.c @ 98afe31

4.104.114.84.9
Last change on this file since 98afe31 was 98afe31, checked in by Till Straumann <strauman@…>, on Nov 4, 2005 at 3:34:08 AM

2005-11-03 Till Straumann <strauman@…>

  • shared/motorola/motorola.c, shared/pci/detect_raven_bridge.c, shared/pci/pci.c, shared/pci/pci.h, shared/pci/pcifinddevice.c: Several PCI enhancements and fixes: all BSP flavors now use the generic clear_hostbridge_errors() routine (this means that only polling memory probing is possible [see detect_raven_bridge.c for details]). Interrupt fixup routine now supports multi-function devices. Interrupt fixup routine now honours a flag/option so that wrong firmware values can be overridden. Fixed irq routing table for mvme2100 [PMC]. Added irq routing table for mvme2300. Added a BSP_pciScan() routine that executes a user callback on each non-empty slot/fun. Added BSP_pciConfigDump() to display basic config headers.
  • Property mode set to 100644
File size: 10.8 KB
Line 
1/* motorola.h
2 *
3 *  This include file describe the data structure and the functions implemented
4 *  by rtems to identify motorola boards.
5 *
6 *  Copyright (C) 1999 valette@crf.canon.fr
7 *
8 *  The license and distribution terms for this file may be
9 *  found in found in the file LICENSE in this distribution or at
10 *  http://www.rtems.com/license/LICENSE.
11 *
12 *  $Id$
13 */
14
15#include <bsp.h>
16#include <bsp/motorola.h>
17#include <rtems/bspIo.h>
18#include <libcpu/io.h>
19#include <string.h>
20
21/*
22** Board-specific table that maps interrupt names to onboard PCI
23** peripherals as well as local PCI busses.  This table is used at
24** bspstart() to configure the interrupt name & pin for all devices that
25** do not have it already specified.  If the device is already
26** configured, we leave it alone but sanity check & print a warning if
27** we don't know about the pin/line the card gives us.
28**
29** bus = the bus number of the slot/device in question
30**
31** slot :
32**
33**   If slot != -1, it indicates a device on the given bus in that slot
34**   is to use one of the listed interrupt names given an interrupt pin.
35**
36**   If slot == -1, it means devices on this bus can occupy any slot-
37**   and for pci, this means the particular interrupt pin that the
38**   device signals is therefore dependent on the particular slot.  To
39**   work from the slot to the interrupt pin, the swizzle table is used.
40**   Once the bus and interrupt pin is known, the correct interrupt name
41**   can be pulled from the table.  The swizzle table relates the
42**   interrupt pin from the device to the particular interrupt
43**   controller interrupt pin- so it is quite reasonable for a device on
44**   bus 1 signalling interrupt pin 1 to show up at the interrupt
45**   controller as pin 4- this is why the int pin field varies for
46**   bridged pci busses.
47**
48**
49** opts = bitmap of options that control the configuration of this
50** slot/bus.
51**
52** pin_routes[] = array of pin & vectors that may serve this slot;
53**
54**      pin = the pin # which delivers an interrupt on this route, A=1,
55**      B=2, C=3, D=4
56**
57**      int_name[4] = an array of up to 4 bsp-specific interrupt name
58**      that can be used by this route.  Unused entries should be -1.
59**      The array is of primary use for slots that can be vectored thru
60**      multiple interrupt lines over the interrupt pin supplied by the
61**      record.  If more than one entry is present, the most preferable
62**      should supplied first.
63**
64*/
65
66#define NULL_PINMAP     {-1,{-1,-1,-1,-1}}
67#define NULL_INTMAP     {-1,-1,-1,{}}
68
69static struct _int_map mcp750_intmap[] = {
70
71   { 0, 16, 0, {{1,  {5, 19,-1,-1}}, /* pmc slot */
72                NULL_PINMAP}},
73
74   { 0, 14, 0, {{1,  {10,18,-1,-1}}, /* onboard ethernet */
75                NULL_PINMAP}},
76
77   { 1, -1, 0, {{1,  {24,-1,-1,-1}},
78                {2,  {25,-1,-1,-1}},
79                {3,  {26,-1,-1,-1}},
80                {4,  {27,-1,-1,-1}},
81                NULL_PINMAP}},
82
83   NULL_INTMAP };
84
85static struct _int_map mtx603_intmap[] = {
86
87   {0, 14, 0, {{1, {10,16,-1,-1}},  /* onboard ethernet */
88               NULL_PINMAP}},
89
90   {0, 12, 0, {{1, {14,18,-1,-1}},  /* onboard scsi */
91               NULL_PINMAP}},
92
93   {0, 16, 0, {{1, {25,-1,-1,-1}},  /* pci/pmc slot 1 */
94               {2, {26,-1,-1,-1}},
95               {3, {27,-1,-1,-1}},
96               {4, {28,-1,-1,-1}},
97               NULL_PINMAP}},
98
99   {0, 17, 0, {{1, {26,-1,-1,-1}},  /* pci/pmc slot 2 */
100               {2, {27,-1,-1,-1}},
101               {3, {28,-1,-1,-1}},
102               {4, {25,-1,-1,-1}},
103               NULL_PINMAP}},
104
105   {0, 18, 0, {{1, {27,-1,-1,-1}},  /* pci slot 3 */
106               {2, {28,-1,-1,-1}},
107               {3, {25,-1,-1,-1}},
108               {4, {26,-1,-1,-1}},
109               NULL_PINMAP}},
110
111   NULL_INTMAP };
112
113static struct _int_map mvme23xx_intmap[] = {
114/* Raven Hostbridge; has int_pin == 0
115   {0,  0, 0, {{0, {-1,-1,-1,-1}},
116               NULL_PINMAP}},
117*/
118
119/* Winbond PCI/ISA 83c553; has int_pin == 0
120   {0, 11, 0, {{0, {-1,-1,-1,-1}},
121               NULL_PINMAP}},
122*/
123
124#if 0 /* Leave as ISA interrupts for now */
125   {0, 13, PCI_FIXUP_OPT_OVERRIDE_NAME,
126                        {{1, {11,21,-1,-1,-1}},  /* Universe  ISA/PCI */
127                        /* strictly speaking, a non-multi function device
128                         * must only use pin A
129                         */
130                         {2, {22,-1,-1,-1,-1}},  /* Universe          */
131                         {3, {23,-1,-1,-1,-1}},  /* Universe          */
132                         {4, {24,-1,-1,-1,-1}},  /* Universe          */
133             NULL_PINMAP}},
134
135   {0, 14, PCI_FIXUP_OPT_OVERRIDE_NAME,
136                        {{1, {10,18,-1,-1}},  /* DEC Tulip enet (ISA/PCI)  */
137             NULL_PINMAP}},
138#endif
139
140   {0, 16, PCI_FIXUP_OPT_OVERRIDE_NAME,
141                        {{1, {25,-1,-1,-1}},  /* pci/pmc slot 1   */
142             {2, {26,-1,-1,-1}},
143             {3, {27,-1,-1,-1}},
144             {4, {28,-1,-1,-1}},
145             NULL_PINMAP}},
146
147   {0, 17, PCI_FIXUP_OPT_OVERRIDE_NAME,
148                        {{1, {28,-1,-1,-1}},  /* pci/pmc slot 2   */ /* orig: 0xf */
149             {2, {25,-1,-1,-1}},
150             {3, {26,-1,-1,-1}},
151             {4, {27,-1,-1,-1}},
152             NULL_PINMAP}},
153
154   NULL_INTMAP };
155
156static struct _int_map mvme2100_intmap[] = {
157   {0, 0, 0, {{1, {16,-1,-1,-1}}, /* something shows up in slot 0 and OpenPIC  */
158                                  /* 0 is unused.  This hushes the init code.  */
159               NULL_PINMAP}},
160
161   {0, 13, 0, {{1, {23,-1,-1,-1}},  /* Universe Lint[0-3]; not quite legal     */
162               {2, {24,-1,-1,-1}},  /* since the universe is a single-function */
163               {3, {25,-1,-1,-1}},  /* device. We leave it for info purposes   */
164               {4, {26,-1,-1,-1}},
165               NULL_PINMAP}},
166
167   {0, 14, 0, {{1, {17,-1,-1,-1}},  /* onboard ethernet */
168               NULL_PINMAP}},
169
170   {0, 16, PCI_FIXUP_OPT_OVERRIDE_NAME,
171              {{1, {18,-1,-1,-1}},  /* PMC slot; all pins are routed to 18     */
172               {2, {18,-1,-1,-1}},  /* I give the OVERRIDE option since I had  */
173               {3, {18,-1,-1,-1}},  /* problems with devices behind a bridge   */
174               {4, {18,-1,-1,-1}},  /* on a PMC card reading irq line 0...     */
175               NULL_PINMAP}},
176
177   /* FIXME: I don't know how MIP works or what it is; these probably won't work */
178
179   {0, -1, PCI_FIXUP_OPT_OVERRIDE_NAME,
180              {{1, {23,-1,-1,-1}},  /* PCI INT[A-D] expansion */
181               {2, {24,-1,-1,-1}},
182               {3, {25,-1,-1,-1}},
183               {4, {26,-1,-1,-1}},
184               NULL_PINMAP}},
185
186   NULL_INTMAP };
187
188/*
189 * This table represents the standard PCI swizzle defined in the
190 * PCI bus specification.  Table taken from Linux 2.4.18, prep_pci.c,
191 * the values in this table are interrupt_pin values (1 based).
192 */
193static unsigned char prep_pci_intpins[4][4] =
194{
195        { 1, 2, 3, 4 },  /* Buses 0, 4, 8, ... */
196        { 2, 3, 4, 1 },  /* Buses 1, 5, 9, ... */
197        { 3, 4, 1, 2 },  /* Buses 2, 6, 10 ... */
198        { 4, 1, 2, 3 },  /* Buses 3, 7, 11 ... */
199};
200
201static int prep_pci_swizzle(int slot, int pin)
202{
203   return prep_pci_intpins[ slot % 4 ][ pin-1 ];
204}
205
206typedef struct {
207  /*
208   * 0x100 mask assumes for Raven and Hawk boards
209   * that the level/edge are set.
210   * 0x200 if this board has a Hawk chip.
211   */
212      int               cpu_type;
213      int               base_type;
214      const char        *name;
215
216      struct _int_map   *intmap;
217      int               (*swizzler)(int, int);
218} mot_info_t;
219
220static const mot_info_t mot_boards[] = {
221  {0x300, 0x00, "MVME 2400", NULL, NULL},
222  {0x010, 0x00, "Genesis", NULL, NULL},
223  {0x020, 0x00, "Powerstack (Series E)", NULL, NULL},
224  {0x040, 0x00, "Blackhawk (Powerstack)", NULL, NULL},
225  {0x050, 0x00, "Omaha (PowerStack II Pro3000)", NULL, NULL},
226  {0x060, 0x00, "Utah (Powerstack II Pro4000)", NULL, NULL},
227  {0x0A0, 0x00, "Powerstack (Series EX)", NULL, NULL},
228  {0x1E0, 0xE0, "Mesquite cPCI (MCP750)", mcp750_intmap, prep_pci_swizzle},
229  {0x1E0, 0xE1, "Sitka cPCI (MCPN750)", mcp750_intmap, prep_pci_swizzle},
230  {0x1E0, 0xE2, "Mesquite cPCI (MCP750) w/ HAC", mcp750_intmap, prep_pci_swizzle},
231  {0x1E0, 0xF6, "MTX Plus", NULL, NULL},
232  {0x1E0, 0xF7, "MTX w/o Parallel Port", mtx603_intmap, prep_pci_swizzle},
233  {0x1E0, 0xF8, "MTX w/ Parallel Port", mtx603_intmap, prep_pci_swizzle},
234  {0x1E0, 0xF9, "MVME 2300", mvme23xx_intmap, prep_pci_swizzle},
235  {0x1E0, 0xFA, "MVME 2300SC/2600", mvme23xx_intmap, prep_pci_swizzle},
236  {0x1E0, 0xFB, "MVME 2600 with MVME712M", NULL, NULL},
237  {0x1E0, 0xFC, "MVME 2600/2700 with MVME761", NULL, NULL},
238  {0x1E0, 0xFD, "MVME 3600 with MVME712M", NULL, NULL},
239  {0x1E0, 0xFE, "MVME 3600 with MVME761", NULL, NULL},
240  {0x1E0, 0xFF, "MVME 1600-001 or 1600-011", NULL, NULL},
241  {0x000, 0x00, ""},   /* end of probeable values for automatic scan */
242  {0x000, 0x00, "MVME 2100", mvme2100_intmap, prep_pci_swizzle},
243};
244
245prep_t currentPrepType;
246motorolaBoard currentBoard;
247
248prep_t checkPrepBoardType(RESIDUAL *res)
249{
250  prep_t PREP_type;
251  /* figure out what kind of prep workstation we are */
252  if ( res->ResidualLength != 0 ) {
253    if ( !strncmp((char*)res->VitalProductData.PrintableModel,"IBM",3) )
254      PREP_type = PREP_IBM;
255    else if (!strncmp((char*)res->VitalProductData.PrintableModel,
256                      "Radstone",8)){
257      PREP_type = PREP_Radstone;
258    }
259    else
260      PREP_type = PREP_Motorola;
261  }
262  else /* assume motorola if no residual (netboot?) */ {
263    PREP_type = PREP_Motorola;
264  }
265  currentPrepType = PREP_type;
266  return PREP_type;
267}
268
269motorolaBoard getMotorolaBoard()
270{
271/*
272 *  At least the MVME2100 does not have the CPU Type and Base Type Registers,
273 *  so it cannot be probed.
274 *
275 *  NOTE: Every path must set currentBoard.
276 */
277#if defined(mvme2100)
278  currentBoard = (motorolaBoard) MVME_2100;
279#else
280  unsigned char  cpu_type;
281  unsigned char  base_mod;
282  int            entry;
283  int            mot_entry = -1;
284
285  cpu_type = inb(MOTOROLA_CPUTYPE_REG) & 0xF0;
286  base_mod = inb(MOTOROLA_BASETYPE_REG);
287
288  for (entry = 0; mot_boards[entry].cpu_type != 0; entry++) {
289    if ((mot_boards[entry].cpu_type & 0xff) != cpu_type)
290      continue;
291
292    if (mot_boards[entry].base_type == 0) {
293      mot_entry = entry;
294      break;
295    }
296
297    if (mot_boards[entry].base_type != base_mod)
298      continue;
299    else {
300      mot_entry = entry;
301      break;
302    }
303  }
304  if (mot_entry == -1) {
305    printk("Unknown motorola board Please update libbsp/powerpc/shared/motorola/motorola.c\n");
306    printk("cpu_type = %x\n", (unsigned) cpu_type);
307    printk("base_mod = %x\n", (unsigned) base_mod);
308    currentBoard = MOTOROLA_UNKNOWN;
309    return currentBoard;
310  }
311  currentBoard = (motorolaBoard) mot_entry;
312#endif
313  return currentBoard;
314}
315
316const char* motorolaBoardToString(motorolaBoard board)
317{
318  if (board == MOTOROLA_UNKNOWN) return "Unknown motorola board";
319  return (mot_boards[board].name);
320}
321
322const struct _int_map *motorolaIntMap(motorolaBoard board)
323{
324  if (board == MOTOROLA_UNKNOWN) return NULL;
325  /* printk( "IntMap board %d 0x%08x\n", board, mot_boards[board].intmap ); */
326  return mot_boards[board].intmap;
327}
328
329const void *motorolaIntSwizzle(motorolaBoard board)
330{
331  if (board == MOTOROLA_UNKNOWN) return NULL;
332  return (void *)mot_boards[board].swizzler;
333}
Note: See TracBrowser for help on using the repository browser.