patch-2.1.124 linux/arch/ppc/mm/init.c
Next file: linux/arch/ppc/pmac_defconfig
Previous file: linux/arch/ppc/lib/string.S
Back to the patch index
Back to the overall index
- Lines: 255
- Date:
Wed Sep 30 10:14:17 1998
- Orig file:
v2.1.123/linux/arch/ppc/mm/init.c
- Orig date:
Wed Sep 9 14:51:06 1998
diff -u --recursive --new-file v2.1.123/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
@@ -1,5 +1,5 @@
/*
- * $Id: init.c,v 1.115 1998/08/04 20:48:38 davem Exp $
+ * $Id: init.c,v 1.123 1998/09/19 19:03:55 geert Exp $
*
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
@@ -33,6 +33,7 @@
#include <linux/stddef.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
+#include <linux/delay.h>
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h> /* for initrd_* */
#endif
@@ -46,6 +47,8 @@
#include <asm/uaccess.h>
#include <asm/8xx_immap.h>
#include <asm/mbx.h>
+#include <asm/smp.h>
+#include <asm/bootx.h>
/* APUS includes */
#include <asm/setup.h>
#include <asm/amigahw.h>
@@ -69,6 +72,7 @@
unsigned long avail_start;
struct pgtable_cache_struct quicklists;
struct mem_info memory[NUM_MEMINFO];
+extern boot_infos_t *boot_infos;
void MMU_init(void);
static void *MMU_get_page(void);
@@ -229,7 +233,7 @@
{
printk("%-8.8s %3d %3d %8ld %8ld %8ld %c%08lx %08lx ",
p->comm,p->pid,
- p->mm->count,p->mm->context,
+ atomic_read(&p->mm->count),p->mm->context,
p->mm->context<<4, p->tss.last_syscall,
user_mode(p->tss.regs) ? 'u' : 'k', p->tss.regs->nip,
(ulong)p);
@@ -805,11 +809,6 @@
for (bl = 128<<10; bl < 256<<20; bl <<= 1) {
if (bl * 2 > tot)
break;
- /* On some APUS systems, memory grows downwards, i.e.,
- 24MB will be 8MB aligned. Handle that properly by
- mapping first 8MB, then 16MB. */
- if (((bl * 2) - 1) & mem_base)
- break;
}
setbat(2, KERNELBASE, mem_base, bl, RAM_PAGE);
@@ -884,7 +883,6 @@
unsigned long a;
unsigned long num_freed_pages = 0, num_prep_pages = 0,
num_pmac_pages = 0, num_openfirmware_pages = 0;
-
#define FREESEC(START,END,CNT) do { \
a = (unsigned long)(&START); \
for (; a < (unsigned long)(&END); a += PAGE_SIZE) { \
@@ -933,6 +931,11 @@
*/
__initfunc(void MMU_init(void))
{
+
+#ifdef __SMP__
+ if ( first_cpu_booted ) return;
+#endif /* __SMP__ */
+
#ifndef CONFIG_8xx
if (have_of)
end_of_DRAM = pmac_find_end_of_memory();
@@ -967,7 +970,7 @@
break;
case _MACH_apus:
/* Map PPC exception vectors. */
- setbat(0, 0xfff00000, 0xfff00000, 0x00010000, RAM_PAGE);
+ setbat(0, 0xfff00000, 0xfff00000, 0x00020000, RAM_PAGE);
/* Map chip and ZorroII memory */
setbat(1, zTwoBase, 0x00000000, 0x01000000, IO_PAGE);
/* Note: a temporary hack in arch/ppc/amiga/setup.c
@@ -997,17 +1000,16 @@
/*
* Find some memory for setup_arch to return.
- * We use the last chunk of available memory as the area
+ * We use the largest chunk of available memory as the area
* that setup_arch returns, making sure that there are at
* least 32 pages unused before this for MMU_get_page to use.
*/
__initfunc(unsigned long find_available_memory(void))
{
- int i;
+ int i, rn;
unsigned long a, free;
unsigned long start, end;
- free = 0;
if (_machine == _MACH_mbx) {
/* Return the first, not the last region, because we
* may not yet have properly initialized the additonal
@@ -1018,12 +1020,17 @@
return avail_start;
}
- for (i = 0; i < phys_avail.n_regions - 1; ++i) {
+ rn = 0;
+ for (i = 1; i < phys_avail.n_regions; ++i)
+ if (phys_avail.regions[i].size > phys_avail.regions[rn].size)
+ rn = i;
+ free = 0;
+ for (i = 0; i < rn; ++i) {
start = phys_avail.regions[i].address;
end = start + phys_avail.regions[i].size;
free += (end & PAGE_MASK) - PAGE_ALIGN(start);
}
- a = PAGE_ALIGN(phys_avail.regions[i].address);
+ a = PAGE_ALIGN(phys_avail.regions[rn].address);
if (free < 32 * PAGE_SIZE)
a += 32 * PAGE_SIZE - free;
avail_start = (unsigned long) __va(a);
@@ -1082,6 +1089,15 @@
}
phys_avail.n_regions = 0;
+#ifdef CONFIG_BLK_DEV_INITRD
+ /* if we are booted from BootX with an initial ramdisk,
+ make sure the ramdisk pages aren't reserved. */
+ if (initrd_start) {
+ for (a = initrd_start; a < initrd_end; a += PAGE_SIZE)
+ clear_bit(PG_reserved, &mem_map[MAP_NR(a)].flags);
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+
/* free the prom's memory - no-op on prep */
for (i = 0; i < prom_mem.n_regions; ++i) {
a = (unsigned long) __va(prom_mem.regions[i].address);
@@ -1216,8 +1232,13 @@
phys_mem.n_regions = 1;
}
- /* record which bits the prom is using */
- get_mem_prop("available", &phys_avail);
+ if (boot_infos == 0) {
+ /* record which bits the prom is using */
+ get_mem_prop("available", &phys_avail);
+ } else {
+ /* booted from BootX - it's all available (after klimit) */
+ phys_avail = phys_mem;
+ }
prom_mem = phys_mem;
for (i = 0; i < phys_avail.n_regions; ++i)
remove_mem_piece(&prom_mem, phys_avail.regions[i].address,
@@ -1274,36 +1295,69 @@
#define HARDWARE_MAPPED_SIZE (512*1024)
__initfunc(unsigned long *apus_find_end_of_memory(void))
{
- unsigned long kstart, ksize;
+ int shadow = 0;
- /* Add the chunk that ADOS does not see. This may also
- * include a ROM mapping which we reclaim. The top 512KB is
- * removed again below.
- * Do it by aligning the size to the nearest 2MB limit upwards.
- */
- memory[0].size = ((memory[0].size+0x001fffff) & 0xffe00000);
+ /* The memory size reported by ADOS excludes the 512KB
+ reserved for PPC exception registers and possibly 512KB
+ containing a shadow of the ADOS ROM. */
+ {
+ unsigned long size = memory[0].size;
- append_mem_piece(&phys_mem, memory[0].addr, memory[0].size);
+ /* If 2MB aligned, size was probably user
+ specified. We can't tell anything about shadowing
+ in this case so skip shadow assignment. */
+ if (0 != (size & 0x1fffff)){
+ /* Align to 512KB to ensure correct handling
+ of both memfile and system specified
+ sizes. */
+ size = ((size+0x0007ffff) & 0xfff80000);
+ /* If memory is 1MB aligned, assume
+ shadowing. */
+ shadow = !(size & 0x80000);
+ }
- phys_avail = phys_mem;
- kstart = __pa(_stext);
- ksize = PAGE_ALIGN(klimit - _stext);
- remove_mem_piece(&phys_avail, kstart, ksize, 1);
+ /* Add the chunk that ADOS does not see. by aligning
+ the size to the nearest 2MB limit upwards. */
+ memory[0].size = ((size+0x001fffff) & 0xffe00000);
+ }
- /* Remove the upper HARDWARE_MAPPED_SIZE bytes where the address
- * range 0xfff00000-0xfffx0000 is mapped to.
- * We do it this way to ensure that the memory registered in the
- * system has a power-of-two size.
- */
- remove_mem_piece(&phys_avail,
- (memory[0].addr + memory[0].size
- - HARDWARE_MAPPED_SIZE),
- HARDWARE_MAPPED_SIZE, 1);
+ /* Now register the memory block. */
+ {
+ unsigned long kstart, ksize;
+
+ append_mem_piece(&phys_mem, memory[0].addr, memory[0].size);
+ phys_avail = phys_mem;
+ kstart = __pa(_stext);
+ ksize = PAGE_ALIGN(klimit - _stext);
+ remove_mem_piece(&phys_avail, kstart, ksize, 0);
+ }
+
+ /* Remove the memory chunks that are controlled by special
+ Phase5 hardware. */
+ {
+ unsigned long top = memory[0].addr + memory[0].size;
+
+ /* Remove the upper 512KB if it contains a shadow of
+ the ADOS ROM. FIXME: It might be possible to
+ disable this shadow HW. Check the booter
+ (ppc_boot.c) */
+ if (shadow)
+ {
+ top -= HARDWARE_MAPPED_SIZE;
+ remove_mem_piece(&phys_avail, top,
+ HARDWARE_MAPPED_SIZE, 0);
+ }
+
+ /* Remove the upper 512KB where the PPC exception
+ vectors are mapped. */
+ top -= HARDWARE_MAPPED_SIZE;
+ remove_mem_piece(&phys_avail, top,
+ HARDWARE_MAPPED_SIZE, 0);
+ }
/* FIXME:APUS: Only handles one block of memory! Problem is
- * that the VTOP/PTOV code in head.S would be a mess if it had
- * to handle more than one block.
- */
+ that the VTOP/PTOV code in head.S would be a mess if it had
+ to handle more than one block. */
return __va(memory[0].addr + memory[0].size);
}
@@ -1393,6 +1447,5 @@
}
else
Hash_end = 0;
-
}
#endif /* ndef CONFIG_8xx */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov