patch-2.4.25 linux-2.4.25/arch/sparc64/mm/init.c
Next file: linux-2.4.25/arch/x86_64/config.in
Previous file: linux-2.4.25/arch/sparc64/lib/VIScopy.S
Back to the patch index
Back to the overall index
- Lines: 255
- Date:
2004-02-18 05:36:31.000000000 -0800
- Orig file:
linux-2.4.24/arch/sparc64/mm/init.c
- Orig date:
2003-08-25 04:44:40.000000000 -0700
diff -urN linux-2.4.24/arch/sparc64/mm/init.c linux-2.4.25/arch/sparc64/mm/init.c
@@ -34,6 +34,7 @@
#include <asm/starfire.h>
#include <asm/tlb.h>
#include <asm/spitfire.h>
+#include <asm/sections.h>
mmu_gather_t mmu_gathers[NR_CPUS];
@@ -44,7 +45,16 @@
unsigned long *sparc64_valid_addr_bitmap;
/* Ugly, but necessary... -DaveM */
-unsigned long phys_base;
+unsigned long phys_base, kern_base, kern_size;
+
+/* This is even uglier. We have a problem where the kernel may not be
+ * located at phys_base. However, initial __alloc_bootmem() calls need to
+ * be adjusted to be within the 4-8Megs that the kernel is mapped to, else
+ * those page mappings wont work. Things are ok after inherit_prom_mappings
+ * is called though. Dave says he'll clean this up some other time.
+ * -- BenC
+ */
+static unsigned long bootmap_base;
/* get_new_mmu_context() uses "cache + 1". */
spinlock_t ctx_alloc_lock = SPIN_LOCK_UNLOCKED;
@@ -52,9 +62,6 @@
#define CTX_BMAP_SLOTS (1UL << (CTX_VERSION_SHIFT - 6))
unsigned long mmu_context_bmap[CTX_BMAP_SLOTS];
-/* References to section boundaries */
-extern char __init_begin, __init_end, _start, _end, etext, edata;
-
/* Initial ramdisk setup */
extern unsigned int sparc_ramdisk_image;
extern unsigned int sparc_ramdisk_size;
@@ -344,7 +351,7 @@
n += 5 * sizeof(struct linux_prom_translation);
for (tsz = 1; tsz < n; tsz <<= 1)
/* empty */;
- trans = __alloc_bootmem(tsz, SMP_CACHE_BYTES, 0UL);
+ trans = __alloc_bootmem(tsz, SMP_CACHE_BYTES, bootmap_base);
if (trans == NULL) {
prom_printf("inherit_prom_mappings: Cannot alloc translations.\n");
prom_halt();
@@ -364,7 +371,7 @@
* in inherit_locked_prom_mappings()).
*/
#define OBP_PMD_SIZE 2048
- prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, 0UL);
+ prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, bootmap_base);
if (prompmd == NULL)
early_pgtable_allocfail("pmd");
memset(prompmd, 0, OBP_PMD_SIZE);
@@ -382,7 +389,7 @@
if (pmd_none(*pmdp)) {
ptep = __alloc_bootmem(BASE_PAGE_SIZE,
BASE_PAGE_SIZE,
- 0UL);
+ bootmap_base);
if (ptep == NULL)
early_pgtable_allocfail("pte");
memset(ptep, 0, BASE_PAGE_SIZE);
@@ -1202,6 +1209,10 @@
unsigned long bootmap_pfn, bytes_avail, size;
int i;
+#ifdef CONFIG_DEBUG_BOOTMEM
+ prom_printf("bootmem_init: Scan sp_banks, ");
+#endif
+
bytes_avail = 0UL;
for (i = 0; sp_banks[i].num_bytes != 0; i++) {
end_of_phys_memory = sp_banks[i].base_addr +
@@ -1232,15 +1243,8 @@
* image. The kernel is hard mapped below PAGE_OFFSET in a
* 4MB locked TLB translation.
*/
- start_pfn = PAGE_ALIGN((unsigned long) &_end) -
- ((unsigned long) KERNBASE);
+ start_pfn = PAGE_ALIGN(kern_base + kern_size) >> PAGE_SHIFT;
- /* Adjust up to the physical address where the kernel begins. */
- start_pfn += phys_base;
-
- /* Now shift down to get the real physical page frame number. */
- start_pfn >>= PAGE_SHIFT;
-
bootmap_pfn = start_pfn;
end_pfn = end_of_phys_memory >> PAGE_SHIFT;
@@ -1268,19 +1272,33 @@
/* Initialize the boot-time allocator. */
max_pfn = max_low_pfn = end_pfn;
min_low_pfn = phys_base >> PAGE_SHIFT;
- bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, phys_base>>PAGE_SHIFT, end_pfn);
+
+#ifdef CONFIG_DEBUG_BOOTMEM
+ prom_printf("init_bootmem(min[%lx], bootmap[%lx], max[%lx])\n",
+ min_low_pfn, bootmap_pfn, max_low_pfn);
+#endif
+ bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, min_low_pfn, end_pfn);
+
+ bootmap_base = bootmap_pfn << PAGE_SHIFT;
/* Now register the available physical memory with the
* allocator.
*/
- for (i = 0; sp_banks[i].num_bytes != 0; i++)
- free_bootmem(sp_banks[i].base_addr,
- sp_banks[i].num_bytes);
+ for (i = 0; sp_banks[i].num_bytes != 0; i++) {
+#ifdef CONFIG_DEBUG_BOOTMEM
+ prom_printf("free_bootmem(sp_banks:%d): base[%lx] size[%lx]\n",
+ i, sp_banks[i].base_addr, sp_banks[i].num_bytes);
+#endif
+ free_bootmem(sp_banks[i].base_addr, sp_banks[i].num_bytes);
+ }
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start) {
size = initrd_end - initrd_start;
-
+#ifdef CONFIG_DEBUG_BOOTMEM
+ prom_printf("reserve_bootmem(initrd): base[%lx] size[%lx]\n",
+ initrd_start, size);
+#endif
/* Resert the initrd image area. */
reserve_bootmem(initrd_start, size);
*pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
@@ -1290,15 +1308,21 @@
}
#endif
/* Reserve the kernel text/data/bss. */
- size = (start_pfn << PAGE_SHIFT) - phys_base;
- reserve_bootmem(phys_base, size);
- *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
+#ifdef CONFIG_DEBUG_BOOTMEM
+ prom_printf("reserve_bootmem(kernel): base[%lx] size[%lx]\n", kern_base, kern_size);
+#endif
+ reserve_bootmem(kern_base, kern_size);
+ *pages_avail -= PAGE_ALIGN(kern_size) >> PAGE_SHIFT;
/* Reserve the bootmem map. We do not account for it
* in pages_avail because we will release that memory
* in free_all_bootmem.
*/
size = bootmap_size;
+#ifdef CONFIG_DEBUG_BOOTMEM
+ prom_printf("reserve_bootmem(bootmap): base[%lx] size[%lx]\n",
+ (bootmap_pfn << PAGE_SHIFT), size);
+#endif
reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size);
*pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
@@ -1317,7 +1341,7 @@
extern pmd_t swapper_pmd_dir[1024];
extern unsigned int sparc64_vpte_patchme1[1];
extern unsigned int sparc64_vpte_patchme2[1];
- unsigned long alias_base = phys_base + PAGE_OFFSET;
+ unsigned long alias_base = kern_base + PAGE_OFFSET;
unsigned long second_alias_page = 0;
unsigned long pt, flags, end_pfn, pages_avail;
unsigned long shift = alias_base - ((unsigned long)KERNBASE);
@@ -1337,7 +1361,7 @@
* if this were not true we wouldn't boot up to this point
* anyways.
*/
- pt = phys_base | _PAGE_VALID | _PAGE_SZ4MB;
+ pt = kern_base | _PAGE_VALID | _PAGE_SZ4MB;
pt |= _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W;
__save_and_cli(flags);
if (tlb_type == spitfire) {
@@ -1417,14 +1441,6 @@
pages_avail = 0;
last_valid_pfn = end_pfn = bootmem_init(&pages_avail);
-#ifdef CONFIG_SUN_SERIAL
- /* This does not logically belong here, but we need to
- * call it at the moment we are able to use the bootmem
- * allocator.
- */
- sun_serial_setup();
-#endif
-
/* Inherit non-locked OBP mappings. */
inherit_prom_mappings();
@@ -1439,7 +1455,16 @@
}
inherit_locked_prom_mappings(1);
-
+
+#ifdef CONFIG_SUN_SERIAL
+ /* This does not logically belong here, but we need to call it at
+ * the moment we are able to use the bootmem allocator. This _has_
+ * to be done after the prom_mappings above so since
+ * __alloc_bootmem() doesn't work correctly until then.
+ */
+ sun_serial_setup();
+#endif
+
/* We only created DTLB mapping of this stuff. */
spitfire_flush_dtlb_nucleus_page(alias_base);
if (second_alias_page)
@@ -1609,17 +1634,15 @@
i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6);
i += 1;
sparc64_valid_addr_bitmap = (unsigned long *)
- __alloc_bootmem(i << 3, SMP_CACHE_BYTES, 0UL);
+ __alloc_bootmem(i << 3, SMP_CACHE_BYTES, bootmap_base);
if (sparc64_valid_addr_bitmap == NULL) {
prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n");
prom_halt();
}
memset(sparc64_valid_addr_bitmap, 0, i << 3);
- addr = PAGE_OFFSET + phys_base;
- last = PAGE_ALIGN((unsigned long)&_end) -
- ((unsigned long) KERNBASE);
- last += PAGE_OFFSET + phys_base;
+ addr = PAGE_OFFSET + kern_base;
+ last = PAGE_ALIGN(kern_size) + addr;
while (addr < last) {
set_bit(__pa(addr) >> 22, sparc64_valid_addr_bitmap);
addr += PAGE_SIZE;
@@ -1630,6 +1653,9 @@
max_mapnr = last_valid_pfn - (phys_base >> PAGE_SHIFT);
high_memory = __va(last_valid_pfn << PAGE_SHIFT);
+#ifdef CONFIG_DEBUG_BOOTMEM
+ prom_printf("mem_init: Calling free_all_bootmem().\n");
+#endif
num_physpages = free_all_bootmem() - 1;
/*
@@ -1656,7 +1682,7 @@
/* Put empty_pg_dir on pgd_quicklist */
extern pgd_t empty_pg_dir[1024];
unsigned long addr = (unsigned long)empty_pg_dir;
- unsigned long alias_base = phys_base + PAGE_OFFSET -
+ unsigned long alias_base = kern_base + PAGE_OFFSET -
(long)(KERNBASE);
memset(empty_pg_dir, 0, sizeof(empty_pg_dir));
@@ -1691,7 +1717,7 @@
struct page *p;
page = (addr +
- ((unsigned long) __va(phys_base)) -
+ ((unsigned long) __va(kern_base)) -
((unsigned long) KERNBASE));
p = virt_to_page(page);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)