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

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