root/arch/sparc/prom/memory.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. prom_sortmemlist
  2. prom_meminit
  3. prom_meminfo

   1 /* $Id: memory.c,v 1.6 1996/04/08 09:02:27 davem Exp $
   2  * memory.c: Prom routine for acquiring various bits of information
   3  *           about RAM on the machine, both virtual and physical.
   4  *
   5  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
   6  */
   7 
   8 #include <linux/kernel.h>
   9 
  10 #include <asm/openprom.h>
  11 #include <asm/oplib.h>
  12 
  13 /* This routine, for consistency, returns the ram parameters in the
  14  * V0 prom memory descriptor format.  I choose this format because I
  15  * think it was the easiest to work with.  I feel the religious
  16  * arguments now... ;)  Also, I return the linked lists sorted to
  17  * prevent paging_init() upset stomach as I have not yet written
  18  * the pepto-bismol kernel module yet.
  19  */
  20 
  21 struct linux_prom_registers prom_reg_memlist[64];
  22 struct linux_prom_registers prom_reg_tmp[64];
  23 
  24 struct linux_mlist_v0 prom_phys_total[64];
  25 struct linux_mlist_v0 prom_prom_taken[64];
  26 struct linux_mlist_v0 prom_phys_avail[64];
  27 
  28 struct linux_mlist_v0 *prom_ptot_ptr = prom_phys_total;
  29 struct linux_mlist_v0 *prom_ptak_ptr = prom_prom_taken;
  30 struct linux_mlist_v0 *prom_pavl_ptr = prom_phys_avail;
  31 
  32 struct linux_mem_v0 prom_memlist;
  33 
  34 
  35 /* Internal Prom library routine to sort a linux_mlist_v0 memory
  36  * list.  Used below in initialization.
  37  */
  38 void
  39 prom_sortmemlist(struct linux_mlist_v0 *thislist)
     /* [previous][next][first][last][top][bottom][index][help] */
  40 {
  41         int swapi = 0;
  42         int i, mitr, tmpsize;
  43         char *tmpaddr;
  44         char *lowest;
  45 
  46         for(i=0; thislist[i].theres_more != 0; i++) {
  47                 lowest = thislist[i].start_adr;
  48                 for(mitr = i+1; thislist[mitr-1].theres_more != 0; mitr++)
  49                         if(thislist[mitr].start_adr < lowest) {
  50                                 lowest = thislist[mitr].start_adr;
  51                                 swapi = mitr;
  52                         }
  53                 if(lowest == thislist[i].start_adr) continue;
  54                 tmpaddr = thislist[swapi].start_adr;
  55                 tmpsize = thislist[swapi].num_bytes;
  56                 for(mitr = swapi; mitr > i; mitr--) {
  57                         thislist[mitr].start_adr = thislist[mitr-1].start_adr;
  58                         thislist[mitr].num_bytes = thislist[mitr-1].num_bytes;
  59                 }
  60                 thislist[i].start_adr = tmpaddr;
  61                 thislist[i].num_bytes = tmpsize;
  62         }
  63 
  64         return;
  65 }
  66 
  67 /* Initialize the memory lists based upon the prom version. */
  68 void
  69 prom_meminit(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  70 {
  71         int node = 0;
  72         unsigned int iter, num_regs;
  73         struct linux_mlist_v0 *mptr;  /* ptr for traversal */
  74 
  75         switch(prom_vers) {
  76         case PROM_V0:
  77                 /* Nice, kind of easier to do in this case. */
  78                 /* First, the total physical descriptors. */
  79                 for(mptr = (*(romvec->pv_v0mem.v0_totphys)), iter=0;
  80                     mptr; mptr=mptr->theres_more, iter++) {
  81                         prom_phys_total[iter].start_adr = mptr->start_adr;
  82                         prom_phys_total[iter].num_bytes = mptr->num_bytes;
  83                         prom_phys_total[iter].theres_more = &prom_phys_total[iter+1];
  84                 }
  85                 prom_phys_total[iter-1].theres_more = 0x0;
  86                 /* Second, the total prom taken descriptors. */
  87                 for(mptr = (*(romvec->pv_v0mem.v0_prommap)), iter=0;
  88                     mptr; mptr=mptr->theres_more, iter++) {
  89                         prom_prom_taken[iter].start_adr = mptr->start_adr;
  90                         prom_prom_taken[iter].num_bytes = mptr->num_bytes;
  91                         prom_prom_taken[iter].theres_more = &prom_prom_taken[iter+1];
  92                 }
  93                 prom_prom_taken[iter-1].theres_more = 0x0;
  94                 /* Last, the available physical descriptors. */
  95                 for(mptr = (*(romvec->pv_v0mem.v0_available)), iter=0;
  96                     mptr; mptr=mptr->theres_more, iter++) {
  97                         prom_phys_avail[iter].start_adr = mptr->start_adr;
  98                         prom_phys_avail[iter].num_bytes = mptr->num_bytes;
  99                         prom_phys_avail[iter].theres_more = &prom_phys_avail[iter+1];
 100                 }
 101                 prom_phys_avail[iter-1].theres_more = 0x0;
 102                 /* Sort all the lists. */
 103                 prom_sortmemlist(prom_phys_total);
 104                 prom_sortmemlist(prom_prom_taken);
 105                 prom_sortmemlist(prom_phys_avail);
 106                 break;
 107         case PROM_V2:
 108         case PROM_V3:
 109         case PROM_P1275:
 110                 /* Grrr, have to traverse the prom device tree ;( */
 111                 node = prom_getchild(prom_root_node);
 112                 node = prom_searchsiblings(node, "memory");
 113                 num_regs = prom_getproperty(node, "available",
 114                                             (char *) prom_reg_memlist,
 115                                             sizeof(prom_reg_memlist));
 116                 num_regs = (num_regs/sizeof(struct linux_prom_registers));
 117                 for(iter=0; iter<num_regs; iter++) {
 118                         prom_phys_avail[iter].start_adr =
 119                                 prom_reg_memlist[iter].phys_addr;
 120                         prom_phys_avail[iter].num_bytes =
 121                                 (unsigned long) prom_reg_memlist[iter].reg_size;
 122                         prom_phys_avail[iter].theres_more =
 123                                 &prom_phys_avail[iter+1];
 124                 }
 125                 prom_phys_avail[iter-1].theres_more = 0x0;
 126 
 127                 num_regs = prom_getproperty(node, "reg",
 128                                             (char *) prom_reg_memlist,
 129                                             sizeof(prom_reg_memlist));
 130                 num_regs = (num_regs/sizeof(struct linux_prom_registers));
 131                 for(iter=0; iter<num_regs; iter++) {
 132                         prom_phys_total[iter].start_adr =
 133                                 prom_reg_memlist[iter].phys_addr;
 134                         prom_phys_total[iter].num_bytes =
 135                                 (unsigned long) prom_reg_memlist[iter].reg_size;
 136                         prom_phys_total[iter].theres_more =
 137                                 &prom_phys_total[iter+1];
 138                 }
 139                 prom_phys_total[iter-1].theres_more = 0x0;
 140 
 141                 node = prom_getchild(prom_root_node);
 142                 node = prom_searchsiblings(node, "virtual-memory");
 143                 num_regs = prom_getproperty(node, "available",
 144                                             (char *) prom_reg_memlist,
 145                                             sizeof(prom_reg_memlist));
 146                 num_regs = (num_regs/sizeof(struct linux_prom_registers));
 147 
 148                 /* Convert available virtual areas to taken virtual
 149                  * areas.  First sort, then convert.
 150                  */
 151                 for(iter=0; iter<num_regs; iter++) {
 152                         prom_prom_taken[iter].start_adr =
 153                                 prom_reg_memlist[iter].phys_addr;
 154                         prom_prom_taken[iter].num_bytes =
 155                                 (unsigned long) prom_reg_memlist[iter].reg_size;
 156                         prom_prom_taken[iter].theres_more =
 157                                 &prom_phys_total[iter+1];
 158                 }
 159                 prom_prom_taken[iter-1].theres_more = 0x0;
 160 
 161                 prom_sortmemlist(prom_prom_taken);
 162 
 163                 /* Finally, convert. */
 164                 for(iter=0; iter<num_regs; iter++) {
 165                         prom_prom_taken[iter].start_adr =
 166                                 prom_prom_taken[iter].start_adr +
 167                                         prom_prom_taken[iter].num_bytes;
 168                         prom_prom_taken[iter].num_bytes =
 169                                 prom_prom_taken[iter+1].start_adr -
 170                                         prom_prom_taken[iter].start_adr;
 171                 }
 172                 prom_prom_taken[iter-1].num_bytes =
 173                         0xffffffff - (unsigned long) prom_prom_taken[iter-1].start_adr;
 174 
 175                 /* Sort the other two lists. */
 176                 prom_sortmemlist(prom_phys_total);
 177                 prom_sortmemlist(prom_phys_avail);
 178                 break;
 179 
 180         case PROM_AP1000:
 181           /* really simple memory map */
 182           prom_phys_total[0].start_adr = 0x00000000;
 183           prom_phys_total[0].num_bytes = 0x01000000; /* 16MB */
 184           prom_phys_total[0].theres_more = 0x0;
 185           prom_prom_taken[0].start_adr = 0x00000000; 
 186           prom_prom_taken[0].num_bytes = 0x00000000;
 187           prom_prom_taken[0].theres_more = 0x0;
 188           prom_phys_avail[0].start_adr = 0x00000000;
 189           prom_phys_avail[0].num_bytes = 0x01000000; /* 16MB */
 190           prom_phys_avail[0].theres_more = 0x0;
 191           prom_sortmemlist(prom_phys_total);
 192           prom_sortmemlist(prom_prom_taken);
 193           prom_sortmemlist(prom_phys_avail);
 194           printk("Initialised AP1000 memory lists (forced 16MB)\n");
 195           break;
 196         };
 197 
 198         /* Link all the lists into the top-level descriptor. */
 199         prom_memlist.v0_totphys=&prom_ptot_ptr;
 200         prom_memlist.v0_prommap=&prom_ptak_ptr;
 201         prom_memlist.v0_available=&prom_pavl_ptr;
 202 
 203         return;
 204 }
 205 
 206 /* This returns a pointer to our libraries internal v0 format
 207  * memory descriptor.
 208  */
 209 struct linux_mem_v0 *
 210 prom_meminfo(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 211 {
 212         return &prom_memlist;
 213 }

/* [previous][next][first][last][top][bottom][index][help] */