summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorThomas Bogendoerfer <tsbogend@alpha.franken.de>1999-02-25 21:04:13 +0000
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>1999-02-25 21:04:13 +0000
commit233c7e2546665dca13e97be2b394dba348314d92 (patch)
tree2e002b7201ba7ef9603e9b41a5c06c5550d27191 /arch
parent4a39bb3720ed828a870000425bf9075c60b543c6 (diff)
added memory handling for ARC firmware
added freeing of prom memory
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/arc/identify.c14
-rw-r--r--arch/mips/arc/memory.c102
2 files changed, 91 insertions, 25 deletions
diff --git a/arch/mips/arc/identify.c b/arch/mips/arc/identify.c
index b8292f073..4e3a3653f 100644
--- a/arch/mips/arc/identify.c
+++ b/arch/mips/arc/identify.c
@@ -7,7 +7,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
- * $Id$
+ * $Id: identify.c,v 1.1 1998/10/18 13:32:09 tsbogend Exp $
*/
#include <linux/init.h>
#include <linux/kernel.h>
@@ -22,15 +22,18 @@ struct smatch {
char *name;
int group;
int type;
+ int flags;
};
static struct smatch mach_table[] = {
- { "SGI-IP22", MACH_GROUP_SGI, MACH_SGI_INDY },
- { "Microsoft-Jazz", MACH_GROUP_JAZZ, MACH_MIPS_MAGNUM_4000 },
- { "PICA-61", MACH_GROUP_JAZZ, MACH_ACER_PICA_61 },
- { "RM200PCI", MACH_GROUP_SNI_RM, MACH_SNI_RM200_PCI }
+ { "SGI-IP22", MACH_GROUP_SGI, MACH_SGI_INDY, PROM_FLAG_ARCS },
+ { "Microsoft-Jazz", MACH_GROUP_JAZZ, MACH_MIPS_MAGNUM_4000, 0 },
+ { "PICA-61", MACH_GROUP_JAZZ, MACH_ACER_PICA_61, 0 },
+ { "RM200PCI", MACH_GROUP_SNI_RM, MACH_SNI_RM200_PCI, 0 }
};
+int prom_flags;
+
static struct smatch * __init string_to_mach(char *s)
{
int i;
@@ -60,5 +63,6 @@ void __init prom_identify_arch(void)
mips_machgroup = mach->group;
mips_machtype = mach->type;
+ prom_flags = mach->flags;
}
diff --git a/arch/mips/arc/memory.c b/arch/mips/arc/memory.c
index 655446a01..5c72f55bd 100644
--- a/arch/mips/arc/memory.c
+++ b/arch/mips/arc/memory.c
@@ -4,7 +4,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
- * $Id: memory.c,v 1.2 1998/04/05 11:24:02 ralf Exp $
+ * $Id: memory.c,v 1.1 1998/10/18 13:32:09 tsbogend Exp $
*/
#include <linux/init.h>
#include <linux/kernel.h>
@@ -27,8 +27,7 @@ __initfunc(struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr))
}
#ifdef DEBUG /* convenient for debugging */
-#ifdef CONFIG_SGI
-static char *mtypes[8] = {
+static char *arcs_mtypes[8] = {
"Exception Block",
"ARCS Romvec Page",
"Free/Contig RAM",
@@ -38,8 +37,8 @@ static char *mtypes[8] = {
"ARCS Temp Storage Area",
"ARCS Permanent Storage Area"
};
-#else
-static char *mtypes[8] = {
+
+static char *arc_mtypes[8] = {
"Exception Block",
"SystemParameterBlock",
"FreeMemory",
@@ -48,7 +47,8 @@ static char *mtypes[8] = {
"FirmwareTemporary",
"FirmwarePermanent",
"FreeContigiuous"
-#endif
+};
+#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] : arc_mtypes[a.arc]
#endif
static struct prom_pmemblock prom_pblocks[PROM_MAX_PMEMBLOCKS];
@@ -58,6 +58,35 @@ __initfunc(struct prom_pmemblock *prom_getpblock_array(void))
return &prom_pblocks[0];
}
+#define MEMTYPE_DONTUSE 0
+#define MEMTYPE_PROM 1
+#define MEMTYPE_FREE 2
+
+static int __init prom_memtype_classify (union linux_memtypes type)
+{
+ if (prom_flags & PROM_FLAG_ARCS) {
+ switch (type.arcs) {
+ case arcs_free:
+ case arcs_fcontig:
+ return MEMTYPE_FREE;
+ default:
+ return MEMTYPE_DONTUSE;
+ }
+ } else {
+ switch (type.arc) {
+ case arc_free:
+ case arc_fcontig:
+ return MEMTYPE_FREE;
+ case arc_rvpage:
+ case arc_atmp:
+ case arc_aperm:
+ return MEMTYPE_PROM;
+ default:
+ return MEMTYPE_DONTUSE;
+ }
+ }
+}
+
__initfunc(static void prom_setup_memupper(void))
{
struct prom_pmemblock *p, *highest;
@@ -86,7 +115,7 @@ __initfunc(void prom_meminit(void))
prom_printf("ARCS MEMORY DESCRIPTOR dump:\n");
while(p) {
prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
- i, p, p->base, p->pages, mtypes[p->type]);
+ i, p, p->base, p->pages, mtypes(p->type));
p = prom_getmdesc(p);
i++;
}
@@ -95,19 +124,31 @@ __initfunc(void prom_meminit(void))
totram = 0;
i = 0;
while(p) {
- if(p->type == free || p->type == fcontig) {
- prom_pblocks[i].base =
- ((p->base<<PAGE_SHIFT) + 0x80000000);
- prom_pblocks[i].size = p->pages << PAGE_SHIFT;
- totram += prom_pblocks[i].size;
+ prom_pblocks[i].type = prom_memtype_classify (p->type);
+ prom_pblocks[i].base = ((p->base<<PAGE_SHIFT) + 0x80000000);
+ prom_pblocks[i].size = p->pages << PAGE_SHIFT;
+ switch (prom_pblocks[i].type) {
+ case MEMTYPE_FREE:
+ totram += prom_pblocks[i].size;
#ifdef DEBUG
- prom_printf("free_chunk[%d]: base=%08lx size=%d\n",
- i, prom_pblocks[i].base,
- prom_pblocks[i].size);
+ prom_printf("free_chunk[%d]: base=%08lx size=%d\n",
+ i, prom_pblocks[i].base,
+ prom_pblocks[i].size);
#endif
- i++;
- }
- p = prom_getmdesc(p);
+ i++;
+ break;
+ case MEMTYPE_PROM:
+#ifdef DEBUG
+ prom_printf("prom_chunk[%d]: base=%08lx size=%d\n",
+ i, prom_pblocks[i].base,
+ prom_pblocks[i].size);
+#endif
+ i++;
+ break;
+ default:
+ break;
+ }
+ p = prom_getmdesc(p);
}
prom_pblocks[i].base = 0xdeadbeef;
prom_pblocks[i].size = 0; /* indicates last elem. of array */
@@ -129,16 +170,37 @@ __initfunc(void prom_fixup_mem_map(unsigned long start, unsigned long end))
for(i = 0; p[i].size; i++)
;
nents = i;
+restart:
while(start < end) {
for(i = 0; i < nents; i++) {
- if((start >= (p[i].base)) &&
+ if((p[i].type == MEMTYPE_FREE) &&
+ (start >= (p[i].base)) &&
(start < (p[i].base + p[i].size))) {
start = p[i].base + p[i].size;
start &= PAGE_MASK;
- continue;
+ goto restart;
}
}
set_bit(PG_reserved, &mem_map[MAP_NR(start)].flags);
start += PAGE_SIZE;
}
}
+
+void prom_free_prom_memory (void)
+{
+ struct prom_pmemblock *p;
+ unsigned long addr;
+ unsigned long num_pages = 0;
+
+ for(p = prom_getpblock_array(); p->size != 0; p++) {
+ if (p->type == MEMTYPE_PROM) {
+ for (addr = p->base; addr < p->base + p->size; addr += PAGE_SIZE) {
+ mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
+ atomic_set(&mem_map[MAP_NR(addr)].count, 1);
+ free_page(addr);
+ num_pages++;
+ }
+ }
+ }
+ printk ("Freeing prom memory: %dk freed\n",num_pages << (PAGE_SHIFT - 10));
+}