linux/arch/arm/boot/compressed/ofw-shark.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/boot/compressed/ofw-shark.c
   3 *
   4 * by Alexander Schulz
   5 *
   6 * This file is used to get some basic information
   7 * about the memory layout of the shark we are running
   8 * on. Memory is usually divided in blocks a 8 MB.
   9 * And bootargs are copied from OpenFirmware.
  10 */
  11
  12
  13#include <linux/kernel.h>
  14#include <linux/types.h>
  15#include <asm/setup.h>
  16#include <asm/page.h>
  17
  18
  19asmlinkage void
  20create_params (unsigned long *buffer)
  21{
  22        /* Is there a better address? Also change in mach-shark/core.c */
  23        struct tag *tag = (struct tag *) 0x08003000;
  24        int j,i,m,k,nr_banks,size;
  25        unsigned char *c;
  26
  27        k = 0;
  28
  29        /* Head of the taglist */
  30        tag->hdr.tag  = ATAG_CORE;
  31        tag->hdr.size = tag_size(tag_core);
  32        tag->u.core.flags = 1;
  33        tag->u.core.pagesize = PAGE_SIZE;
  34        tag->u.core.rootdev = 0;
  35
  36        /* Build up one tagged block for each memory region */
  37        size=0;
  38        nr_banks=(unsigned int) buffer[0];
  39        for (j=0;j<nr_banks;j++){
  40                /* search the lowest address and put it into the next entry   */
  41                /* not a fast sort algorithm, but there are at most 8 entries */
  42                /* and this is used only once anyway                          */
  43                m=0xffffffff;
  44                for (i=0;i<(unsigned int) buffer[0];i++){
  45                        if (buffer[2*i+1]<m) {
  46                                m=buffer[2*i+1];
  47                                k=i;
  48                        }
  49                }
  50          
  51                tag = tag_next(tag);
  52                tag->hdr.tag = ATAG_MEM;
  53                tag->hdr.size = tag_size(tag_mem32);
  54                tag->u.mem.size = buffer[2*k+2];
  55                tag->u.mem.start = buffer[2*k+1];
  56
  57                size += buffer[2*k+2];
  58
  59                buffer[2*k+1]=0xffffffff;                    /* mark as copied */
  60        }
  61        
  62        /* The command line */
  63        tag = tag_next(tag);
  64        tag->hdr.tag = ATAG_CMDLINE;
  65        
  66        c=(unsigned char *)(&buffer[34]);
  67        j=0;
  68        while (*c) tag->u.cmdline.cmdline[j++]=*c++;
  69
  70        tag->u.cmdline.cmdline[j]=0;
  71        tag->hdr.size = (j + 7 + sizeof(struct tag_header)) >> 2;
  72
  73        /* Hardware revision */
  74        tag = tag_next(tag);
  75        tag->hdr.tag = ATAG_REVISION;
  76        tag->hdr.size = tag_size(tag_revision);
  77        tag->u.revision.rev = ((unsigned char) buffer[33])-'0';
  78
  79        /* End of the taglist */
  80        tag = tag_next(tag);
  81        tag->hdr.tag = 0;
  82        tag->hdr.size = 0;
  83}
  84
  85
  86typedef int (*ofw_handle_t)(void *);
  87
  88/* Everything below is called with a wrong MMU setting.
  89 * This means: no string constants, no initialization of
  90 * arrays, no global variables! This is ugly but I didn't
  91 * want to write this in assembler :-)
  92 */
  93
  94int
  95of_decode_int(const unsigned char *p)
  96{
  97        unsigned int i = *p++ << 8;
  98        i = (i + *p++) << 8;
  99        i = (i + *p++) << 8;
 100        return (i + *p);
 101}
 102  
 103int
 104OF_finddevice(ofw_handle_t openfirmware, char *name)
 105{
 106        unsigned int args[8];
 107        char service[12];
 108
 109        service[0]='f';
 110        service[1]='i';
 111        service[2]='n';
 112        service[3]='d';
 113        service[4]='d';
 114        service[5]='e';
 115        service[6]='v';
 116        service[7]='i';
 117        service[8]='c';
 118        service[9]='e';
 119        service[10]='\0';
 120
 121        args[0]=(unsigned int)service;
 122        args[1]=1;
 123        args[2]=1;
 124        args[3]=(unsigned int)name;
 125
 126        if (openfirmware(args) == -1)
 127                return -1;
 128        return args[4];
 129}
 130
 131int
 132OF_getproplen(ofw_handle_t openfirmware, int handle, char *prop)
 133{
 134        unsigned int args[8];
 135        char service[12];
 136
 137        service[0]='g';
 138        service[1]='e';
 139        service[2]='t';
 140        service[3]='p';
 141        service[4]='r';
 142        service[5]='o';
 143        service[6]='p';
 144        service[7]='l';
 145        service[8]='e';
 146        service[9]='n';
 147        service[10]='\0';
 148
 149        args[0] = (unsigned int)service;
 150        args[1] = 2;
 151        args[2] = 1;
 152        args[3] = (unsigned int)handle;
 153        args[4] = (unsigned int)prop;
 154
 155        if (openfirmware(args) == -1)
 156                return -1;
 157        return args[5];
 158}
 159  
 160int
 161OF_getprop(ofw_handle_t openfirmware, int handle, char *prop, void *buf, unsigned int buflen)
 162{
 163        unsigned int args[8];
 164        char service[8];
 165
 166        service[0]='g';
 167        service[1]='e';
 168        service[2]='t';
 169        service[3]='p';
 170        service[4]='r';
 171        service[5]='o';
 172        service[6]='p';
 173        service[7]='\0';
 174
 175        args[0] = (unsigned int)service;
 176        args[1] = 4;
 177        args[2] = 1;
 178        args[3] = (unsigned int)handle;
 179        args[4] = (unsigned int)prop;
 180        args[5] = (unsigned int)buf;
 181        args[6] = buflen;
 182
 183        if (openfirmware(args) == -1)
 184                return -1;
 185        return args[7];
 186}
 187  
 188asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer)
 189{
 190        int phandle,i,mem_len,buffer[32];
 191        char temp[15];
 192  
 193        temp[0]='/';
 194        temp[1]='m';
 195        temp[2]='e';
 196        temp[3]='m';
 197        temp[4]='o';
 198        temp[5]='r';
 199        temp[6]='y';
 200        temp[7]='\0';
 201
 202        phandle=OF_finddevice(o,temp);
 203
 204        temp[0]='r';
 205        temp[1]='e';
 206        temp[2]='g';
 207        temp[3]='\0';
 208
 209        mem_len = OF_getproplen(o,phandle, temp);
 210        OF_getprop(o,phandle, temp, buffer, mem_len);
 211        *nomr=mem_len >> 3;
 212
 213        for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]);
 214
 215        temp[0]='/';
 216        temp[1]='c';
 217        temp[2]='h';
 218        temp[3]='o';
 219        temp[4]='s';
 220        temp[5]='e';
 221        temp[6]='n';
 222        temp[7]='\0';
 223
 224        phandle=OF_finddevice(o,temp);
 225
 226        temp[0]='b';
 227        temp[1]='o';
 228        temp[2]='o';
 229        temp[3]='t';
 230        temp[4]='a';
 231        temp[5]='r';
 232        temp[6]='g';
 233        temp[7]='s';
 234        temp[8]='\0';
 235
 236        mem_len = OF_getproplen(o,phandle, temp);
 237        OF_getprop(o,phandle, temp, buffer, mem_len);
 238        if (mem_len > 128) mem_len=128;
 239        for (i=0; i<=mem_len/4; i++) pointer[i+33]=buffer[i];
 240        pointer[i+33]=0;
 241
 242        temp[0]='/';
 243        temp[1]='\0';
 244        phandle=OF_finddevice(o,temp);
 245        temp[0]='b';
 246        temp[1]='a';
 247        temp[2]='n';
 248        temp[3]='n';
 249        temp[4]='e';
 250        temp[5]='r';
 251        temp[6]='-';
 252        temp[7]='n';
 253        temp[8]='a';
 254        temp[9]='m';
 255        temp[10]='e';
 256        temp[11]='\0';
 257        mem_len = OF_getproplen(o,phandle, temp);
 258        OF_getprop(o,phandle, temp, buffer, mem_len);
 259        * ((unsigned char *) &pointer[32]) = ((unsigned char *) buffer)[mem_len-2];
 260}
 261