Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:54

0001 /* motorola.h
0002  *
0003  *  This include file describe the data structure and the functions implemented
0004  *  by rtems to identify motorola boards.
0005  *
0006  *  Copyright (C) 1999 valette@crf.canon.fr
0007  *
0008  *  The license and distribution terms for this file may be
0009  *  found in the file LICENSE in this distribution or at
0010  *  http://www.rtems.org/license/LICENSE.
0011  */
0012 
0013 #include <bsp.h>
0014 #include <bsp/motorola.h>
0015 #include <rtems/bspIo.h>
0016 #include <libcpu/io.h>
0017 #include <string.h>
0018 #include <libcpu/cpuIdent.h>
0019 
0020 /*
0021 ** Board-specific table that maps interrupt names to onboard PCI
0022 ** peripherals as well as local PCI busses.  This table is used at
0023 ** bspstart() to configure the interrupt name & pin for all devices that
0024 ** do not have it already specified.  If the device is already
0025 ** configured, we leave it alone but sanity check & print a warning if
0026 ** we don't know about the pin/line the card gives us.
0027 **
0028 ** bus = the bus number of the slot/device in question
0029 **
0030 ** slot :
0031 **
0032 **   If slot != -1, it indicates a device on the given bus in that slot
0033 **   is to use one of the listed interrupt names given an interrupt pin.
0034 **
0035 **   If slot == -1, it means devices on this bus can occupy any slot-
0036 **   and for pci, this means the particular interrupt pin that the
0037 **   device signals is therefore dependent on the particular slot.  To
0038 **   work from the slot to the interrupt pin, the swizzle table is used.
0039 **   Once the bus and interrupt pin is known, the correct interrupt name
0040 **   can be pulled from the table.  The swizzle table relates the
0041 **   interrupt pin from the device to the particular interrupt
0042 **   controller interrupt pin- so it is quite reasonable for a device on
0043 **   bus 1 signalling interrupt pin 1 to show up at the interrupt
0044 **   controller as pin 4- this is why the int pin field varies for
0045 **   bridged pci busses.
0046 **
0047 **
0048 ** opts = bitmap of options that control the configuration of this
0049 ** slot/bus.
0050 **
0051 ** pin_routes[] = array of pin & vectors that may serve this slot;
0052 **
0053 **      pin = the pin # which delivers an interrupt on this route, A=1,
0054 **      B=2, C=3, D=4
0055 **
0056 **      int_name[4] = an array of up to 4 bsp-specific interrupt name
0057 **      that can be used by this route.  Unused entries should be -1.
0058 **      The array is of primary use for slots that can be vectored thru
0059 **      multiple interrupt lines over the interrupt pin supplied by the
0060 **      record.  If more than one entry is present, the most preferable
0061 **      should supplied first.
0062 **
0063 */
0064 
0065 #define NULL_PINMAP     {-1,{-1,-1,-1,-1}}
0066 #define NULL_INTMAP     {-1,-1,-1,{}}
0067 
0068 #ifdef qemu
0069 static struct _int_map qemu_prep_intmap[] = {
0070     { 0, -1, 0, { { 1, { 9, -1, -1, -1}},
0071                   { 2, {11, -1  -1, -1}},
0072                   NULL_PINMAP }},
0073     NULL_INTMAP
0074 };
0075 #endif
0076 
0077 static struct _int_map mcp750_intmap[] = {
0078 
0079    { 0, 16, 0, {{1,  {5, 19,-1,-1}}, /* pmc slot */
0080                 NULL_PINMAP}},
0081 
0082    { 0, 14, 0, {{1,  {10,18,-1,-1}}, /* onboard ethernet */
0083                 NULL_PINMAP}},
0084 
0085    { 1, -1, 0, {{1,  {24,-1,-1,-1}},
0086                 {2,  {25,-1,-1,-1}},
0087                 {3,  {26,-1,-1,-1}},
0088                 {4,  {27,-1,-1,-1}},
0089                 NULL_PINMAP}},
0090 
0091    NULL_INTMAP };
0092 
0093 static struct _int_map mtx603_intmap[] = {
0094 
0095    {0, 14, 0, {{1, {10,16,-1,-1}},  /* onboard ethernet */
0096                NULL_PINMAP}},
0097 
0098    {0, 12, 0, {{1, {14,18,-1,-1}},  /* onboard scsi */
0099                NULL_PINMAP}},
0100 
0101    {0, 16, 0, {{1, {25,-1,-1,-1}},  /* pci/pmc slot 1 */
0102                {2, {26,-1,-1,-1}},
0103                {3, {27,-1,-1,-1}},
0104                {4, {28,-1,-1,-1}},
0105                NULL_PINMAP}},
0106 
0107    {0, 17, 0, {{1, {26,-1,-1,-1}},  /* pci/pmc slot 2 */
0108                {2, {27,-1,-1,-1}},
0109                {3, {28,-1,-1,-1}},
0110                {4, {25,-1,-1,-1}},
0111                NULL_PINMAP}},
0112 
0113    {0, 18, 0, {{1, {27,-1,-1,-1}},  /* pci slot 3 */
0114                {2, {28,-1,-1,-1}},
0115                {3, {25,-1,-1,-1}},
0116                {4, {26,-1,-1,-1}},
0117                NULL_PINMAP}},
0118 
0119    NULL_INTMAP };
0120 
0121 static struct _int_map mvme23xx_intmap[] = {
0122 /* Raven Hostbridge; has int_pin == 0
0123    {0,  0, 0, {{0, {-1,-1,-1,-1}},
0124                NULL_PINMAP}},
0125 */
0126 
0127 /* Winbond PCI/ISA 83c553; has int_pin == 0
0128    {0, 11, 0, {{0, {-1,-1,-1,-1}},
0129                NULL_PINMAP}},
0130 */
0131 
0132 #if 0 /* Leave as ISA interrupts for now */
0133    {0, 13, PCI_FIXUP_OPT_OVERRIDE_NAME,
0134             {{1, {11,21,-1,-1,-1}},  /* Universe  ISA/PCI */
0135             /* strictly speaking, a non-multi function device
0136              * must only use pin A
0137              */
0138              {2, {22,-1,-1,-1,-1}},  /* Universe          */
0139              {3, {23,-1,-1,-1,-1}},  /* Universe          */
0140              {4, {24,-1,-1,-1,-1}},  /* Universe          */
0141              NULL_PINMAP}},
0142 
0143    {0, 14, PCI_FIXUP_OPT_OVERRIDE_NAME,
0144             {{1, {10,18,-1,-1}},  /* DEC Tulip enet (ISA/PCI)  */
0145              NULL_PINMAP}},
0146 #endif
0147 
0148    {0, 16, PCI_FIXUP_OPT_OVERRIDE_NAME,
0149             {{1, {25,-1,-1,-1}},  /* pci/pmc slot 1   */
0150              {2, {26,-1,-1,-1}},
0151              {3, {27,-1,-1,-1}},
0152              {4, {28,-1,-1,-1}},
0153              NULL_PINMAP}},
0154 
0155    {0, 17, PCI_FIXUP_OPT_OVERRIDE_NAME,
0156             {{1, {28,-1,-1,-1}},  /* pci/pmc slot 2   */ /* orig: 0xf */
0157              {2, {25,-1,-1,-1}},
0158              {3, {26,-1,-1,-1}},
0159              {4, {27,-1,-1,-1}},
0160              NULL_PINMAP}},
0161 
0162    NULL_INTMAP };
0163 
0164 static struct _int_map mvme24xx_intmap[] = {
0165 /* Raven Hostbridge; has int_pin == 0
0166    {0,  0, 0, {{0, {-1,-1,-1,-1}},
0167                NULL_PINMAP}},
0168 */
0169 
0170 /* Winbond PCI/ISA 83c553; has int_pin == 0
0171    {0, 11, 0, {{0, {-1,-1,-1,-1}},
0172                NULL_PINMAP}},
0173 */
0174 
0175    {0, 13, PCI_FIXUP_OPT_OVERRIDE_NAME,
0176             {{1, {11,21,-1,-1}},  /* Universe  ISA/PCI */
0177             /* strictly speaking, a non-multi function device
0178              * must only use pin A
0179              */
0180              {2, {22,-1,-1,-1}},  /* Universe          */
0181              {3, {23,-1,-1,-1}},  /* Universe          */
0182              {4, {24,-1,-1,-1}},  /* Universe          */
0183              NULL_PINMAP}},
0184 
0185    {0, 14, PCI_FIXUP_OPT_OVERRIDE_NAME,
0186             {{1, {10,18,-1,-1}},  /* DEC Tulip enet (ISA/PCI)  */
0187              NULL_PINMAP}},
0188    {0, 16, PCI_FIXUP_OPT_OVERRIDE_NAME,
0189         {{1, {25,-1,-1,-1}},  /* pci/pmc slot 1   */
0190              {2, {26,-1,-1,-1}},
0191              {3, {27,-1,-1,-1}},
0192              {4, {28,-1,-1,-1}},
0193              NULL_PINMAP}},
0194 
0195    {0, 17, PCI_FIXUP_OPT_OVERRIDE_NAME,
0196         {{1, {28,-1,-1,-1}},  /* pci/pmc slot 2   */ /* orig: 0xf */
0197              {2, {25,-1,-1,-1}},
0198              {3, {26,-1,-1,-1}},
0199              {4, {27,-1,-1,-1}},
0200              NULL_PINMAP}},
0201    NULL_INTMAP };
0202 
0203 static struct _int_map mvme27xx_intmap[] = {
0204 /* Raven Hostbridge; has int_pin == 0 */
0205    {0,  0, 0, {{0, {-1,-1,-1,-1}},
0206                NULL_PINMAP}},
0207 
0208 
0209 /* Winbond PCI/ISA 83c553; has int_pin == 0 */
0210    {0, 11, 0, {{0, {-1,-1,-1,-1}},
0211                NULL_PINMAP}},
0212 
0213    {0, 13, PCI_FIXUP_OPT_OVERRIDE_NAME,
0214             {{1, {11,21,-1,-1}},  /* Universe  ISA/PCI */
0215             /* strictly speaking, a non-multi function device
0216              * must only use pin A
0217              */
0218              {2, {22,-1,-1,-1}},  /* Universe          */
0219              {3, {23,-1,-1,-1}},  /* Universe          */
0220              {4, {24,-1,-1,-1}},  /* Universe          */
0221              NULL_PINMAP}},
0222 
0223    {0, 14, PCI_FIXUP_OPT_OVERRIDE_NAME,
0224             {{1, {10,18,-1,-1}},  /* DEC Tulip enet (ISA/PCI)  */
0225              NULL_PINMAP}},
0226    {0, 16, PCI_FIXUP_OPT_OVERRIDE_NAME,
0227         {{1, {25,-1,-1,-1}},  /* pci/pmc slot 1   */
0228              {2, {26,-1,-1,-1}},
0229              {3, {27,-1,-1,-1}},
0230              {4, {28,-1,-1,-1}},
0231              NULL_PINMAP}},
0232 
0233    {0, 17, PCI_FIXUP_OPT_OVERRIDE_NAME,
0234         {{1, {28,-1,-1,-1}},  /* pci/pmc slot 2   */ /* orig: 0xf */
0235              {2, {25,-1,-1,-1}},
0236              {3, {26,-1,-1,-1}},
0237              {4, {27,-1,-1,-1}},
0238              NULL_PINMAP}},
0239    NULL_INTMAP };
0240 
0241 static struct _int_map mvme2100_intmap[] = {
0242    {0, 0, 0, {{1, {16,-1,-1,-1}}, /* something shows up in slot 0 and OpenPIC  */
0243                                   /* 0 is unused.  This hushes the init code.  */
0244                NULL_PINMAP}},
0245 
0246    {0, 13, 0, {{1, {23,-1,-1,-1}},  /* Universe Lint[0-3]; not quite legal     */
0247                {2, {24,-1,-1,-1}},  /* since the universe is a single-function */
0248                {3, {25,-1,-1,-1}},  /* device. We leave it for info purposes   */
0249                {4, {26,-1,-1,-1}},
0250                NULL_PINMAP}},
0251 
0252    {0, 14, 0, {{1, {17,-1,-1,-1}},  /* onboard ethernet */
0253                NULL_PINMAP}},
0254 
0255    {0, 16, PCI_FIXUP_OPT_OVERRIDE_NAME,
0256               {{1, {18,-1,-1,-1}},  /* PMC slot; all pins are routed to 18     */
0257                {2, {18,-1,-1,-1}},  /* I give the OVERRIDE option since I had  */
0258                {3, {18,-1,-1,-1}},  /* problems with devices behind a bridge   */
0259                {4, {18,-1,-1,-1}},  /* on a PMC card reading irq line 0...     */
0260                NULL_PINMAP}},
0261 
0262    /* FIXME: I don't know how MIP works or what it is; these probably won't work */
0263 
0264    {0, -1, PCI_FIXUP_OPT_OVERRIDE_NAME,
0265               {{1, {23,-1,-1,-1}},  /* PCI INT[A-D] expansion */
0266                {2, {24,-1,-1,-1}},
0267                {3, {25,-1,-1,-1}},
0268                {4, {26,-1,-1,-1}},
0269                NULL_PINMAP}},
0270 
0271    NULL_INTMAP };
0272 
0273 /*
0274  * This table represents the standard PCI swizzle defined in the
0275  * PCI bus specification.  Table taken from Linux 2.4.18, prep_pci.c,
0276  * the values in this table are interrupt_pin values (1 based).
0277  */
0278 static unsigned char prep_pci_intpins[4][4] =
0279 {
0280     { 1, 2, 3, 4 },  /* Buses 0, 4, 8, ... */
0281     { 2, 3, 4, 1 },  /* Buses 1, 5, 9, ... */
0282     { 3, 4, 1, 2 },  /* Buses 2, 6, 10 ... */
0283     { 4, 1, 2, 3 },  /* Buses 3, 7, 11 ... */
0284 };
0285 
0286 static int prep_pci_swizzle(int slot, int pin)
0287 {
0288    return prep_pci_intpins[ slot % 4 ][ pin-1 ];
0289 }
0290 
0291 typedef struct {
0292   /*
0293    * 0x100 mask assumes for Raven and Hawk boards
0294    * that the level/edge are set.
0295    * 0x200 if this board has a Hawk chip.
0296    */
0297       int       cpu_type;
0298       int       base_type;
0299       ppc_cpu_id_t      proc_type;
0300       const char    *name;
0301 
0302       struct _int_map   *intmap;
0303       int               (*swizzler)(int, int);
0304 } mot_info_t;
0305 
0306 /* NOTE: When adding boards here the 'motorolaBoard' enums MUST be
0307  *       updated accordingly!
0308  */
0309 static const mot_info_t mot_boards[] = {
0310   {0x0E0, 0xF9, PPC_604,     "MVME 2400", mvme24xx_intmap,prep_pci_swizzle},
0311   {0x3E0, 0x00, PPC_750,     "MVME 2400 (PPC 750)", mvme24xx_intmap,prep_pci_swizzle},
0312   {0x010, 0x00, PPC_UNKNOWN, "Genesis", NULL, NULL},
0313   {0x020, 0x00, PPC_UNKNOWN, "Powerstack (Series E)", NULL, NULL},
0314   {0x040, 0x00, PPC_UNKNOWN, "Blackhawk (Powerstack)", NULL, NULL},
0315   {0x050, 0x00, PPC_UNKNOWN, "Omaha (PowerStack II Pro3000)", NULL, NULL},
0316   {0x060, 0x00, PPC_UNKNOWN, "Utah (Powerstack II Pro4000)", NULL, NULL},
0317   {0x0A0, 0x00, PPC_UNKNOWN, "Powerstack (Series EX)", NULL, NULL},
0318 #ifdef qemu
0319   {0x1E0, 0xE0, PPC_UNKNOWN, "QEMU", qemu_prep_intmap, prep_pci_swizzle},
0320 #else
0321   {0x1E0, 0xE0, PPC_UNKNOWN, "Mesquite cPCI (MCP750)", mcp750_intmap, prep_pci_swizzle},
0322 #endif
0323   {0x1E0, 0xE1, PPC_UNKNOWN, "Sitka cPCI (MCPN750)", mcp750_intmap, prep_pci_swizzle},
0324   {0x1E0, 0xE2, PPC_UNKNOWN, "Mesquite cPCI (MCP750) w/ HAC", mcp750_intmap, prep_pci_swizzle},
0325   {0x1E0, 0xF6, PPC_UNKNOWN, "MTX Plus", NULL, NULL},
0326   {0x1E0, 0xF7, PPC_UNKNOWN, "MTX w/o Parallel Port", mtx603_intmap, prep_pci_swizzle},
0327   {0x1E0, 0xF8, PPC_UNKNOWN, "MTX w/ Parallel Port", mtx603_intmap, prep_pci_swizzle},
0328   {0x1E0, 0xF9, PPC_604,     "MVME 2300", mvme23xx_intmap, prep_pci_swizzle},
0329   {0x1E0, 0xFA, PPC_UNKNOWN, "MVME 2300SC/2600", mvme23xx_intmap, prep_pci_swizzle},
0330   {0x1E0, 0xFB, PPC_UNKNOWN, "MVME 2600 with MVME712M", NULL, NULL},
0331   {0x1E0, 0xFC, PPC_750,     "MVME 2600/2700 with MVME761", mvme27xx_intmap, prep_pci_swizzle},
0332   {0x1E0, 0xFD, PPC_UNKNOWN, "MVME 3600 with MVME712M", NULL, NULL},
0333   {0x1E0, 0xFE, PPC_UNKNOWN, "MVME 3600 with MVME761", NULL, NULL},
0334   {0x1E0, 0xFF, PPC_UNKNOWN, "MVME 1600-001 or 1600-011", NULL, NULL},
0335   {0x000, 0x00, PPC_UNKNOWN, ""},   /* end of probeable values for automatic scan */
0336   {0x000, 0x00, PPC_UNKNOWN, "MVME 2100", mvme2100_intmap, prep_pci_swizzle},
0337 };
0338 
0339 prep_t currentPrepType;
0340 motorolaBoard currentBoard;
0341 
0342 prep_t checkPrepBoardType(RESIDUAL *res)
0343 {
0344   prep_t PREP_type;
0345   /* figure out what kind of prep workstation we are */
0346   if ( res->ResidualLength != 0 ) {
0347     if ( !strncmp((char*)res->VitalProductData.PrintableModel,"IBM",3) )
0348       PREP_type = PREP_IBM;
0349     else if (!strncmp((char*)res->VitalProductData.PrintableModel,
0350               "Radstone",8)){
0351       PREP_type = PREP_Radstone;
0352     }
0353     else
0354       PREP_type = PREP_Motorola;
0355   }
0356   else /* assume motorola if no residual (netboot?) */ {
0357     PREP_type = PREP_Motorola;
0358   }
0359   currentPrepType = PREP_type;
0360   return PREP_type;
0361 }
0362 
0363 motorolaBoard getMotorolaBoard(void)
0364 {
0365 /*
0366  *  At least the MVME2100 does not have the CPU Type and Base Type Registers,
0367  *  so it cannot be probed.
0368  *
0369  *  NOTE: Every path must set currentBoard.
0370  */
0371 #if defined(mot_ppc_mvme2100)
0372   currentBoard = (motorolaBoard) MVME_2100;
0373 #else
0374   unsigned char  cpu_type;
0375   unsigned char  base_mod;
0376   ppc_cpu_id_t   proc_type;
0377   int            entry;
0378   int            mot_entry = -1;
0379 
0380   cpu_type  = inb(MOTOROLA_CPUTYPE_REG) & 0xF0;
0381   base_mod  = inb(MOTOROLA_BASETYPE_REG);
0382   proc_type = get_ppc_cpu_type ();
0383 
0384   for (entry = 0; mot_boards[entry].cpu_type != 0; entry++) {
0385     if ((mot_boards[entry].cpu_type & 0xff) != cpu_type)
0386       continue;
0387 
0388     if ((mot_boards[entry].proc_type != PPC_UNKNOWN) &&
0389     (mot_boards[entry].proc_type != proc_type))
0390       /*
0391        * IMD: processor type does not match
0392        * (here we distinguish a MVME2300 and a MVME2400)
0393        */
0394       continue;
0395 
0396     if (mot_boards[entry].base_type != base_mod)
0397       continue;
0398     else {
0399       mot_entry = entry;
0400       break;
0401     }
0402   }
0403   if (mot_entry == -1) {
0404     printk("Unknown motorola board Please update libbsp/powerpc/shared/motorola/motorola.c\n");
0405     printk("cpu_type = %x\n", (unsigned) cpu_type);
0406     printk("base_mod = %x\n", (unsigned) base_mod);
0407     currentBoard = MOTOROLA_UNKNOWN;
0408     return currentBoard;
0409   }
0410   currentBoard = (motorolaBoard) mot_entry;
0411 #endif
0412   return currentBoard;
0413 }
0414 
0415 const char* motorolaBoardToString(motorolaBoard board)
0416 {
0417   if (board == MOTOROLA_UNKNOWN) return "Unknown motorola board";
0418   return (mot_boards[board].name);
0419 }
0420 
0421 const struct _int_map *motorolaIntMap(motorolaBoard board)
0422 {
0423   if (board == MOTOROLA_UNKNOWN) return NULL;
0424   /* printk( "IntMap board %d 0x%08x\n", board, mot_boards[board].intmap ); */
0425   return mot_boards[board].intmap;
0426 }
0427 
0428 const void *motorolaIntSwizzle(motorolaBoard board)
0429 {
0430   if (board == MOTOROLA_UNKNOWN) return NULL;
0431   return (void *)mot_boards[board].swizzler;
0432 }