linux/arch/mips/dec/prom/identify.c
<<
>>
Prefs
   1/*
   2 * identify.c: machine identification code.
   3 *
   4 * Copyright (C) 1998 Harald Koerfgen and Paul M. Antoine
   5 * Copyright (C) 2002, 2003, 2004, 2005  Maciej W. Rozycki
   6 */
   7#include <linux/init.h>
   8#include <linux/kernel.h>
   9#include <linux/mc146818rtc.h>
  10#include <linux/module.h>
  11#include <linux/string.h>
  12#include <linux/types.h>
  13
  14#include <asm/bootinfo.h>
  15
  16#include <asm/dec/ioasic.h>
  17#include <asm/dec/ioasic_addrs.h>
  18#include <asm/dec/kn01.h>
  19#include <asm/dec/kn02.h>
  20#include <asm/dec/kn02ba.h>
  21#include <asm/dec/kn02ca.h>
  22#include <asm/dec/kn03.h>
  23#include <asm/dec/kn230.h>
  24#include <asm/dec/prom.h>
  25#include <asm/dec/system.h>
  26
  27#include "dectypes.h"
  28
  29static const char *dec_system_strings[] = {
  30        [MACH_DSUNKNOWN]        "unknown DECstation",
  31        [MACH_DS23100]          "DECstation 2100/3100",
  32        [MACH_DS5100]           "DECsystem 5100",
  33        [MACH_DS5000_200]       "DECstation 5000/200",
  34        [MACH_DS5000_1XX]       "DECstation 5000/1xx",
  35        [MACH_DS5000_XX]        "Personal DECstation 5000/xx",
  36        [MACH_DS5000_2X0]       "DECstation 5000/2x0",
  37        [MACH_DS5400]           "DECsystem 5400",
  38        [MACH_DS5500]           "DECsystem 5500",
  39        [MACH_DS5800]           "DECsystem 5800",
  40        [MACH_DS5900]           "DECsystem 5900",
  41};
  42
  43const char *get_system_type(void)
  44{
  45#define STR_BUF_LEN     64
  46        static char system[STR_BUF_LEN];
  47        static int called = 0;
  48
  49        if (called == 0) {
  50                called = 1;
  51                snprintf(system, STR_BUF_LEN, "Digital %s",
  52                         dec_system_strings[mips_machtype]);
  53        }
  54
  55        return system;
  56}
  57
  58
  59/*
  60 * Setup essential system-specific memory addresses.  We need them
  61 * early.  Semantically the functions belong to prom/init.c, but they
  62 * are compact enough we want them inlined. --macro
  63 */
  64volatile u8 *dec_rtc_base;
  65
  66EXPORT_SYMBOL(dec_rtc_base);
  67
  68static inline void prom_init_kn01(void)
  69{
  70        dec_kn_slot_base = KN01_SLOT_BASE;
  71        dec_kn_slot_size = KN01_SLOT_SIZE;
  72
  73        dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN01_RTC);
  74}
  75
  76static inline void prom_init_kn230(void)
  77{
  78        dec_kn_slot_base = KN01_SLOT_BASE;
  79        dec_kn_slot_size = KN01_SLOT_SIZE;
  80
  81        dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN01_RTC);
  82}
  83
  84static inline void prom_init_kn02(void)
  85{
  86        dec_kn_slot_base = KN02_SLOT_BASE;
  87        dec_kn_slot_size = KN02_SLOT_SIZE;
  88        dec_tc_bus = 1;
  89
  90        dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN02_RTC);
  91}
  92
  93static inline void prom_init_kn02xa(void)
  94{
  95        dec_kn_slot_base = KN02XA_SLOT_BASE;
  96        dec_kn_slot_size = IOASIC_SLOT_SIZE;
  97        dec_tc_bus = 1;
  98
  99        ioasic_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_IOCTL);
 100        dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_TOY);
 101}
 102
 103static inline void prom_init_kn03(void)
 104{
 105        dec_kn_slot_base = KN03_SLOT_BASE;
 106        dec_kn_slot_size = IOASIC_SLOT_SIZE;
 107        dec_tc_bus = 1;
 108
 109        ioasic_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_IOCTL);
 110        dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_TOY);
 111}
 112
 113
 114void __init prom_identify_arch(u32 magic)
 115{
 116        unsigned char dec_cpunum, dec_firmrev, dec_etc, dec_systype;
 117        u32 dec_sysid;
 118
 119        if (!prom_is_rex(magic)) {
 120                dec_sysid = simple_strtoul(prom_getenv("systype"),
 121                                           (char **)0, 0);
 122        } else {
 123                dec_sysid = rex_getsysid();
 124                if (dec_sysid == 0) {
 125                        printk("Zero sysid returned from PROM! "
 126                               "Assuming a PMAX-like machine.\n");
 127                        dec_sysid = 1;
 128                }
 129        }
 130
 131        dec_cpunum = (dec_sysid & 0xff000000) >> 24;
 132        dec_systype = (dec_sysid & 0xff0000) >> 16;
 133        dec_firmrev = (dec_sysid & 0xff00) >> 8;
 134        dec_etc = dec_sysid & 0xff;
 135
 136        /*
 137         * FIXME: This may not be an exhaustive list of DECStations/Servers!
 138         * Put all model-specific initialisation calls here.
 139         */
 140        switch (dec_systype) {
 141        case DS2100_3100:
 142                mips_machtype = MACH_DS23100;
 143                prom_init_kn01();
 144                break;
 145        case DS5100:            /* DS5100 MIPSMATE */
 146                mips_machtype = MACH_DS5100;
 147                prom_init_kn230();
 148                break;
 149        case DS5000_200:        /* DS5000 3max */
 150                mips_machtype = MACH_DS5000_200;
 151                prom_init_kn02();
 152                break;
 153        case DS5000_1XX:        /* DS5000/100 3min */
 154                mips_machtype = MACH_DS5000_1XX;
 155                prom_init_kn02xa();
 156                break;
 157        case DS5000_2X0:        /* DS5000/240 3max+ or DS5900 bigmax */
 158                mips_machtype = MACH_DS5000_2X0;
 159                prom_init_kn03();
 160                if (!(ioasic_read(IO_REG_SIR) & KN03_IO_INR_3MAXP))
 161                        mips_machtype = MACH_DS5900;
 162                break;
 163        case DS5000_XX:         /* Personal DS5000/xx maxine */
 164                mips_machtype = MACH_DS5000_XX;
 165                prom_init_kn02xa();
 166                break;
 167        case DS5800:            /* DS5800 Isis */
 168                mips_machtype = MACH_DS5800;
 169                break;
 170        case DS5400:            /* DS5400 MIPSfair */
 171                mips_machtype = MACH_DS5400;
 172                break;
 173        case DS5500:            /* DS5500 MIPSfair-2 */
 174                mips_machtype = MACH_DS5500;
 175                break;
 176        default:
 177                mips_machtype = MACH_DSUNKNOWN;
 178                break;
 179        }
 180
 181        if (mips_machtype == MACH_DSUNKNOWN)
 182                printk("This is an %s, id is %x\n",
 183                       dec_system_strings[mips_machtype], dec_systype);
 184        else
 185                printk("This is a %s\n", dec_system_strings[mips_machtype]);
 186}
 187