linux/arch/mips/sni/sniprom.c
<<
>>
Prefs
   1/*
   2 * Big Endian PROM code for SNI RM machines
   3 *
   4 * This file is subject to the terms and conditions of the GNU General Public
   5 * License.  See the file "COPYING" in the main directory of this archive
   6 * for more details.
   7 *
   8 * Copyright (C) 2005-2006 Florian Lohoff (flo@rfc822.org)
   9 * Copyright (C) 2005-2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
  10 */
  11
  12#define DEBUG
  13
  14#include <linux/kernel.h>
  15#include <linux/init.h>
  16#include <linux/string.h>
  17#include <linux/console.h>
  18
  19#include <asm/addrspace.h>
  20#include <asm/sni.h>
  21#include <asm/mipsprom.h>
  22#include <asm/mipsregs.h>
  23#include <asm/bootinfo.h>
  24
  25/* special SNI prom calls */
  26/*
  27 * This does not exist in all proms - SINIX compares
  28 * the prom env variable "version" against "2.0008"
  29 * or greater. If lesser it tries to probe interesting
  30 * registers
  31 */
  32#define PROM_GET_MEMCONF        58
  33
  34#define PROM_VEC                (u64 *)CKSEG1ADDR(0x1fc00000)
  35#define PROM_ENTRY(x)           (PROM_VEC + (x))
  36
  37
  38static int *(*__prom_putchar)(int)        = (int *(*)(int))PROM_ENTRY(PROM_PUTCHAR);
  39
  40void prom_putchar(char c)
  41{
  42        __prom_putchar(c);
  43}
  44
  45static char *(*__prom_getenv)(char *)     = (char *(*)(char *))PROM_ENTRY(PROM_GETENV);
  46static void (*__prom_get_memconf)(void *) = (void (*)(void *))PROM_ENTRY(PROM_GET_MEMCONF);
  47
  48char *prom_getenv(char *s)
  49{
  50        return __prom_getenv(s);
  51}
  52
  53void __init prom_free_prom_memory(void)
  54{
  55}
  56
  57/*
  58 * /proc/cpuinfo system type
  59 *
  60 */
  61static const char *systype = "Unknown";
  62const char *get_system_type(void)
  63{
  64        return systype;
  65}
  66
  67#define SNI_IDPROM_BASE                0xbff00000
  68#define SNI_IDPROM_MEMSIZE             (SNI_IDPROM_BASE+0x28)  /* Memsize in 16MB quantities */
  69#define SNI_IDPROM_BRDTYPE             (SNI_IDPROM_BASE+0x29)  /* Board Type */
  70#define SNI_IDPROM_CPUTYPE             (SNI_IDPROM_BASE+0x30)  /* CPU Type */
  71
  72#define SNI_IDPROM_SIZE 0x1000
  73
  74#ifdef DEBUG
  75static void __init sni_idprom_dump(void)
  76{
  77        int     i;
  78
  79        pr_debug("SNI IDProm dump:\n");
  80        for (i = 0; i < 256; i++) {
  81                if (i%16 == 0)
  82                        pr_debug("%04x ", i);
  83
  84                printk("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i));
  85
  86                if (i % 16 == 15)
  87                        printk("\n");
  88        }
  89}
  90#endif
  91
  92static void __init sni_mem_init(void )
  93{
  94        int i, memsize;
  95        struct membank {
  96                u32             size;
  97                u32             base;
  98                u32             size2;
  99                u32             pad1;
 100                u32             pad2;
 101        } memconf[8];
 102
 103        /* MemSIZE from prom in 16MByte chunks */
 104        memsize = *((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
 105
 106        pr_debug("IDProm memsize: %lu MByte\n", memsize);
 107
 108        /* get memory bank layout from prom */
 109        __prom_get_memconf(&memconf);
 110
 111        pr_debug("prom_get_mem_conf memory configuration:\n");
 112        for (i = 0;i < 8 && memconf[i].size; i++) {
 113                if (sni_brd_type == SNI_BRD_PCI_TOWER ||
 114                    sni_brd_type == SNI_BRD_PCI_TOWER_CPLUS) {
 115                        if (memconf[i].base >= 0x20000000 &&
 116                            memconf[i].base <  0x30000000) {
 117                                memconf[i].base -= 0x20000000;
 118                        }
 119        }
 120                pr_debug("Bank%d: %08x @ %08x\n", i,
 121                        memconf[i].size, memconf[i].base);
 122                add_memory_region(memconf[i].base, memconf[i].size, BOOT_MEM_RAM);
 123        }
 124}
 125
 126static void __init sni_console_setup(void)
 127{
 128        char *ctype;
 129        char *cdev;
 130        char *baud;
 131        int port;
 132        static char options[8];
 133
 134        cdev = prom_getenv("console_dev");
 135        if (strncmp (cdev, "tty", 3) == 0) {
 136                ctype = prom_getenv("console");
 137                switch (*ctype) {
 138                default:
 139                case 'l':
 140                        port = 0;
 141                        baud = prom_getenv("lbaud");
 142                        break;
 143                case 'r':
 144                        port = 1;
 145                        baud = prom_getenv("rbaud");
 146                        break;
 147                }
 148                if (baud)
 149                        strcpy(options, baud);
 150                if (strncmp (cdev, "tty552", 6) == 0)
 151                        add_preferred_console("ttyS", port, baud ? options : NULL);
 152                else
 153                        add_preferred_console("ttySC", port, baud ? options : NULL);
 154        }
 155}
 156
 157void __init prom_init(void)
 158{
 159        int argc = fw_arg0;
 160        char **argv = (void *)fw_arg1;
 161        int i;
 162        int cputype;
 163
 164        sni_brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
 165        cputype = *(unsigned char *)SNI_IDPROM_CPUTYPE;
 166        switch (sni_brd_type) {
 167        case SNI_BRD_TOWER_OASIC:
 168                switch (cputype) {
 169                case SNI_CPU_M8030:
 170                        systype = "RM400-330";
 171                        break;
 172                case SNI_CPU_M8031:
 173                        systype = "RM400-430";
 174                        break;
 175                case SNI_CPU_M8037:
 176                        systype = "RM400-530";
 177                        break;
 178                case SNI_CPU_M8034:
 179                        systype = "RM400-730";
 180                        break;
 181                default:
 182                        systype = "RM400-xxx";
 183                        break;
 184                }
 185                break;
 186        case SNI_BRD_MINITOWER:
 187                switch (cputype) {
 188                case SNI_CPU_M8021:
 189                case SNI_CPU_M8043:
 190                        systype = "RM400-120";
 191                        break;
 192                case SNI_CPU_M8040:
 193                        systype = "RM400-220";
 194                        break;
 195                case SNI_CPU_M8053:
 196                        systype = "RM400-225";
 197                        break;
 198                case SNI_CPU_M8050:
 199                        systype = "RM400-420";
 200                        break;
 201                default:
 202                        systype = "RM400-xxx";
 203                        break;
 204                }
 205                break;
 206        case SNI_BRD_PCI_TOWER:
 207                systype = "RM400-Cxx";
 208                break;
 209        case SNI_BRD_RM200:
 210                systype = "RM200-xxx";
 211                break;
 212        case SNI_BRD_PCI_MTOWER:
 213                systype = "RM300-Cxx";
 214                break;
 215        case SNI_BRD_PCI_DESKTOP:
 216                switch (read_c0_prid() & 0xff00) {
 217                case PRID_IMP_R4600:
 218                case PRID_IMP_R4700:
 219                        systype = "RM200-C20";
 220                        break;
 221                case PRID_IMP_R5000:
 222                        systype = "RM200-C40";
 223                        break;
 224                default:
 225                        systype = "RM200-Cxx";
 226                        break;
 227                }
 228                break;
 229        case SNI_BRD_PCI_TOWER_CPLUS:
 230                systype = "RM400-Exx";
 231                break;
 232        case SNI_BRD_PCI_MTOWER_CPLUS:
 233                systype = "RM300-Exx";
 234                break;
 235        }
 236        pr_debug("Found SNI brdtype %02x name %s\n", sni_brd_type, systype);
 237
 238#ifdef DEBUG
 239        sni_idprom_dump();
 240#endif
 241        sni_mem_init();
 242        sni_console_setup();
 243
 244        /* copy prom cmdline parameters to kernel cmdline */
 245        for (i = 1; i < argc; i++) {
 246                strcat(arcs_cmdline, argv[i]);
 247                if (i < (argc - 1))
 248                        strcat(arcs_cmdline, " ");
 249        }
 250}
 251
 252