linux/arch/sparc/prom/sun4prom.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 1996 The Australian National University.
   3 * Copyright (C) 1996 Fujitsu Laboratories Limited
   4 * Copyright (C) 1997 Michael A. Griffith (grif@acm.org)
   5 * Copyright (C) 1997 Sun Weenie (ko@ko.reno.nv.us)
   6 * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
   7 * 
   8 * This software may be distributed under the terms of the Gnu
   9 * Public License version 2 or later
  10 *
  11 * fake a really simple Sun prom for the SUN4
  12 */
  13
  14#include <linux/kernel.h>
  15#include <linux/string.h>
  16#include <asm/oplib.h>
  17#include <asm/idprom.h> 
  18#include <asm/machines.h> 
  19#include <asm/sun4prom.h>
  20#include <asm/asi.h>
  21#include <asm/contregs.h>
  22#include <linux/init.h>
  23
  24static struct linux_romvec sun4romvec;
  25static struct idprom sun4_idprom;
  26
  27struct property {
  28        char *name;
  29        char *value;
  30        int length;
  31};
  32
  33struct node {
  34        int level;
  35        struct property *properties;
  36};
  37
  38struct property null_properties = { NULL, NULL, -1 };
  39
  40struct property root_properties[] = {
  41        {"device_type", "cpu", 4},
  42        {"idprom", (char *)&sun4_idprom, sizeof(struct idprom)},
  43        {NULL, NULL, -1}
  44};
  45
  46struct node nodes[] = {
  47        { 0, &null_properties }, 
  48        { 0, root_properties },
  49        { -1,&null_properties }
  50};
  51
  52
  53static int no_nextnode(int node)
  54{
  55        if (nodes[node].level == nodes[node+1].level)
  56                return node+1;
  57        return -1;
  58}
  59
  60static int no_child(int node)
  61{
  62        if (nodes[node].level == nodes[node+1].level-1)
  63                return node+1;
  64        return -1;
  65}
  66
  67static struct property *find_property(int node,char *name)
  68{
  69        struct property *prop = &nodes[node].properties[0];
  70        while (prop && prop->name) {
  71                if (strcmp(prop->name,name) == 0) return prop;
  72                prop++;
  73        }
  74        return NULL;
  75}
  76
  77static int no_proplen(int node,char *name)
  78{
  79        struct property *prop = find_property(node,name);
  80        if (prop) return prop->length;
  81        return -1;
  82}
  83
  84static int no_getprop(int node,char *name,char *value)
  85{
  86        struct property *prop = find_property(node,name);
  87        if (prop) {
  88                memcpy(value,prop->value,prop->length);
  89                return 1;
  90        }
  91        return -1;
  92}
  93
  94static int no_setprop(int node,char *name,char *value,int len)
  95{
  96        return -1;
  97}
  98
  99static char *no_nextprop(int node,char *name)
 100{
 101        struct property *prop = find_property(node,name);
 102        if (prop) return prop[1].name;
 103        return NULL;
 104}
 105
 106static struct linux_nodeops sun4_nodeops = {
 107        no_nextnode,
 108        no_child,
 109        no_proplen,
 110        no_getprop,
 111        no_setprop,
 112        no_nextprop
 113};
 114        
 115static int synch_hook;
 116
 117struct linux_romvec * __init sun4_prom_init(void)
 118{
 119        int i;
 120        unsigned char x;
 121        char *p;
 122                                
 123        p = (char *)&sun4_idprom;
 124        for (i = 0; i < sizeof(sun4_idprom); i++) {
 125                __asm__ __volatile__ ("lduba [%1] %2, %0" : "=r" (x) :
 126                                      "r" (AC_IDPROM + i), "i" (ASI_CONTROL));
 127                *p++ = x;
 128        }
 129
 130        memset(&sun4romvec,0,sizeof(sun4romvec));
 131
 132        sun4_romvec = (linux_sun4_romvec *) SUN4_PROM_VECTOR;
 133
 134        sun4romvec.pv_romvers = 40;
 135        sun4romvec.pv_nodeops = &sun4_nodeops;
 136        sun4romvec.pv_reboot = sun4_romvec->reboot;
 137        sun4romvec.pv_abort = sun4_romvec->abortentry;
 138        sun4romvec.pv_halt = sun4_romvec->exittomon;
 139        sun4romvec.pv_synchook = (void (**)(void))&synch_hook;
 140        sun4romvec.pv_setctxt = sun4_romvec->setcxsegmap;
 141        sun4romvec.pv_v0bootargs = sun4_romvec->bootParam;
 142        sun4romvec.pv_nbgetchar = sun4_romvec->mayget;
 143        sun4romvec.pv_nbputchar = sun4_romvec->mayput;
 144        sun4romvec.pv_stdin = sun4_romvec->insource;
 145        sun4romvec.pv_stdout = sun4_romvec->outsink;
 146        
 147        /*
 148         * We turn on the LEDs to let folks without monitors or
 149         * terminals know we booted.   Nothing too fancy now.  They
 150         * are all on, except for LED 5, which blinks.   When we
 151         * have more time, we can teach the penguin to say "By your
 152         * command" or "Activating turbo boost, Michael". :-)
 153         */
 154        sun4_romvec->setLEDs(NULL);
 155        
 156        printk("PROMLIB: Old Sun4 boot PROM monitor %s, romvec version %d\n",
 157                sun4_romvec->monid,
 158                sun4_romvec->romvecversion);
 159
 160        return &sun4romvec;
 161}
 162
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.