-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 95862 b: refs/heads/master c: 9f2b2a5 h: refs/heads/master v: v3
- Loading branch information
David S. Miller
committed
May 2, 2008
1 parent
d5d9305
commit d4ff51b
Showing
6 changed files
with
72 additions
and
152 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: ccc34028d46230f715eeda4c8cce27e919934fad | ||
refs/heads/master: 9f2b2a5f68c27c00f1e1f1922de5aa2f24505ed8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,120 +1,100 @@ | ||
/* memory.c: Prom routine for acquiring various bits of information | ||
* about RAM on the machine, both virtual and physical. | ||
* | ||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | ||
* Copyright (C) 1995, 2008 David S. Miller (davem@davemloft.net) | ||
* Copyright (C) 1997 Michael A. Griffith (grif@acm.org) | ||
*/ | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/sort.h> | ||
#include <linux/init.h> | ||
|
||
#include <asm/openprom.h> | ||
#include <asm/sun4prom.h> | ||
#include <asm/oplib.h> | ||
#include <asm/page.h> | ||
|
||
/* This routine, for consistency, returns the ram parameters in the | ||
* V0 prom memory descriptor format. I choose this format because I | ||
* think it was the easiest to work with. I feel the religious | ||
* arguments now... ;) Also, I return the linked lists sorted to | ||
* prevent paging_init() upset stomach as I have not yet written | ||
* the pepto-bismol kernel module yet. | ||
*/ | ||
static int __init prom_meminit_v0(void) | ||
{ | ||
struct linux_mlist_v0 *p; | ||
int index; | ||
|
||
struct linux_prom_registers prom_reg_memlist[64]; | ||
index = 0; | ||
for (p = *(romvec->pv_v0mem.v0_available); p; p = p->theres_more) { | ||
sp_banks[index].base_addr = (unsigned long) p->start_adr; | ||
sp_banks[index].num_bytes = p->num_bytes; | ||
index++; | ||
} | ||
|
||
struct linux_mlist_v0 prom_phys_avail[64]; | ||
return index; | ||
} | ||
|
||
/* Internal Prom library routine to sort a linux_mlist_v0 memory | ||
* list. Used below in initialization. | ||
*/ | ||
static void __init | ||
prom_sortmemlist(struct linux_mlist_v0 *thislist) | ||
static int __init prom_meminit_v2(void) | ||
{ | ||
int swapi = 0; | ||
int i, mitr, tmpsize; | ||
char *tmpaddr; | ||
char *lowest; | ||
|
||
for(i=0; thislist[i].theres_more; i++) { | ||
lowest = thislist[i].start_adr; | ||
for(mitr = i+1; thislist[mitr-1].theres_more; mitr++) | ||
if(thislist[mitr].start_adr < lowest) { | ||
lowest = thislist[mitr].start_adr; | ||
swapi = mitr; | ||
} | ||
if(lowest == thislist[i].start_adr) continue; | ||
tmpaddr = thislist[swapi].start_adr; | ||
tmpsize = thislist[swapi].num_bytes; | ||
for(mitr = swapi; mitr > i; mitr--) { | ||
thislist[mitr].start_adr = thislist[mitr-1].start_adr; | ||
thislist[mitr].num_bytes = thislist[mitr-1].num_bytes; | ||
} | ||
thislist[i].start_adr = tmpaddr; | ||
thislist[i].num_bytes = tmpsize; | ||
struct linux_prom_registers reg[64]; | ||
int node, size, num_ents, i; | ||
|
||
node = prom_searchsiblings(prom_getchild(prom_root_node), "memory"); | ||
size = prom_getproperty(node, "available", (char *) reg, sizeof(reg)); | ||
num_ents = size / sizeof(struct linux_prom_registers); | ||
|
||
for (i = 0; i < num_ents; i++) { | ||
sp_banks[i].base_addr = reg[i].phys_addr; | ||
sp_banks[i].num_bytes = reg[i].reg_size; | ||
} | ||
|
||
return; | ||
return num_ents; | ||
} | ||
|
||
static int __init prom_meminit_sun4(void) | ||
{ | ||
#ifdef CONFIG_SUN4 | ||
sp_banks[0].base_addr = 0; | ||
sp_banks[0].num_bytes = *(sun4_romvec->memoryavail); | ||
#endif | ||
return 1; | ||
} | ||
|
||
static int sp_banks_cmp(const void *a, const void *b) | ||
{ | ||
const struct sparc_phys_banks *x = a, *y = b; | ||
|
||
if (x->base_addr > y->base_addr) | ||
return 1; | ||
if (x->base_addr < y->base_addr) | ||
return -1; | ||
return 0; | ||
} | ||
|
||
/* Initialize the memory lists based upon the prom version. */ | ||
void __init prom_meminit(void) | ||
{ | ||
int node = 0; | ||
unsigned int iter, num_regs; | ||
struct linux_mlist_v0 *mptr; /* ptr for traversal */ | ||
int i, num_ents = 0; | ||
|
||
switch(prom_vers) { | ||
switch (prom_vers) { | ||
case PROM_V0: | ||
/* Nice, kind of easier to do in this case. */ | ||
for(mptr = (*(romvec->pv_v0mem.v0_available)), iter=0; | ||
mptr; mptr=mptr->theres_more, iter++) { | ||
prom_phys_avail[iter].start_adr = mptr->start_adr; | ||
prom_phys_avail[iter].num_bytes = mptr->num_bytes; | ||
prom_phys_avail[iter].theres_more = &prom_phys_avail[iter+1]; | ||
} | ||
prom_phys_avail[iter-1].theres_more = NULL; | ||
prom_sortmemlist(prom_phys_avail); | ||
num_ents = prom_meminit_v0(); | ||
break; | ||
|
||
case PROM_V2: | ||
case PROM_V3: | ||
/* Grrr, have to traverse the prom device tree ;( */ | ||
node = prom_getchild(prom_root_node); | ||
node = prom_searchsiblings(node, "memory"); | ||
num_regs = prom_getproperty(node, "available", | ||
(char *) prom_reg_memlist, | ||
sizeof(prom_reg_memlist)); | ||
num_regs = (num_regs/sizeof(struct linux_prom_registers)); | ||
for(iter=0; iter<num_regs; iter++) { | ||
prom_phys_avail[iter].start_adr = | ||
(char *) prom_reg_memlist[iter].phys_addr; | ||
prom_phys_avail[iter].num_bytes = | ||
(unsigned long) prom_reg_memlist[iter].reg_size; | ||
prom_phys_avail[iter].theres_more = | ||
&prom_phys_avail[iter+1]; | ||
} | ||
prom_phys_avail[iter-1].theres_more = NULL; | ||
prom_sortmemlist(prom_phys_avail); | ||
num_ents = prom_meminit_v2(); | ||
break; | ||
|
||
case PROM_SUN4: | ||
#ifdef CONFIG_SUN4 | ||
/* how simple :) */ | ||
prom_phys_avail[0].start_adr = NULL; | ||
prom_phys_avail[0].num_bytes = *(sun4_romvec->memoryavail); | ||
prom_phys_avail[0].theres_more = NULL; | ||
#endif | ||
num_ents = prom_meminit_sun4(); | ||
break; | ||
|
||
default: | ||
break; | ||
}; | ||
} | ||
} | ||
sort(sp_banks, num_ents, sizeof(struct sparc_phys_banks), | ||
sp_banks_cmp, NULL); | ||
|
||
/* This returns a pointer to our libraries internal v0 format | ||
* available memory list. | ||
*/ | ||
struct linux_mlist_v0 * | ||
prom_meminfo(void) | ||
{ | ||
return prom_phys_avail; | ||
/* Sentinel. */ | ||
sp_banks[num_ents].base_addr = 0xdeadbeef; | ||
sp_banks[num_ents].num_bytes = 0; | ||
|
||
for (i = 0; i < num_ents; i++) | ||
sp_banks[i].num_bytes &= PAGE_MASK; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters