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

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