[patch] 2.3.29 alpha updates

Andrea Arcangeli (andrea@suse.de)
Wed, 24 Nov 1999 21:52:40 +0100 (CET)


I cleanedup the mem init stuff and I made the allocation of memory
completly based on the memory layout provided by the bios. So far part of
the dyamic memory allocation worked assuming there was some not well
defined available RAM after the kernel memory. Now on alpha nothing works
by magic anymore.

With this patch the early boot process is pretty verbose to help
debugging, in the future we may shutdown some printk...

Patch against 2.3.29 that works fine here:

diff -urN 2.3.29/arch/alpha/kernel/setup.c alpha/arch/alpha/kernel/setup.c
--- 2.3.29/arch/alpha/kernel/setup.c Wed Nov 24 18:22:03 1999
+++ alpha/arch/alpha/kernel/setup.c Wed Nov 24 21:44:57 1999
@@ -189,29 +189,26 @@
#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
#define PFN_MAX PFN_DOWN(0x80000000)
+#define for_each_mem_cluster(memdesc, cluster, i) \
+ for ((cluster) = (memdesc)->cluster, (i) = 0; \
+ (i) < (memdesc)->numclusters; (i)++, (cluster)++)
static void __init setup_memory(void)
{
struct memclust_struct * cluster;
struct memdesc_struct * memdesc;
- unsigned long start_pfn, bootmap_size;
+ unsigned long start_pfn, bootmap_size, bootmap_pages, bootmap_start;
+ unsigned long start, end;
extern char _end[];
int i;

- /* alloc the bootmem after the kernel */
- start_pfn = PFN_UP(virt_to_phys(_end));
- SRM_printf("_end %p\n", _end);
-
/* find free clusters, and init and free the bootmem accordingly */
memdesc = (struct memdesc_struct *) (hwrpb->mddt_offset + (unsigned long) hwrpb);

- for (cluster = memdesc->cluster, i = memdesc->numclusters;
- i > 0; i--, cluster++)
+ for_each_mem_cluster(memdesc, cluster, i)
{
- unsigned long end;
-
- printk("memcluster %d, usage %02lx, start %8lu, end %8lu\n",
+ printk("memcluster %d, usage %01lx, start %8lu, end %8lu\n",
i, cluster->usage, cluster->start_pfn,
- cluster->numpages);
+ cluster->start_pfn + cluster->numpages);

/* Bit 0 is console/PALcode reserved. Bit 1 is
non-volatile memory -- we might want to mark
@@ -226,38 +223,89 @@
/* Enforce maximum of 2GB even if there is more. Blah. */
if (max_low_pfn > PFN_MAX)
max_low_pfn = PFN_MAX;
- SRM_printf("max_low_pfn %d\n", max_low_pfn);
+ printk("max_low_pfn %ld\n", max_low_pfn);

- /* allocate the bootmem array after the kernel and mark
- the whole MM as reserved */
- bootmap_size = init_bootmem(start_pfn, max_low_pfn);
+ /* find the end of the kernel memory */
+ start_pfn = PFN_UP(virt_to_phys(_end));
+ printk("_end %p, start_pfn %ld\n", _end, start_pfn);

- for (cluster = memdesc->cluster, i = memdesc->numclusters;
- i > 0; i--, cluster++)
- {
- unsigned long end, start;
+ bootmap_start = -1;

- /* Bit 0 is console/PALcode reserved. Bit 1 is
- non-volatile memory -- we might want to mark
- this for later */
+ try_again:
+ if (max_low_pfn <= start_pfn)
+ panic("not enough memory to boot");
+
+ /* we need to know how many physically contigous pages
+ we'll need for the bootmap */
+ bootmap_pages = bootmem_bootmap_pages(max_low_pfn);
+ printk("bootmap size: %ld pages\n", bootmap_pages);
+
+ /* now find a good region where to allocate the bootmap */
+ for_each_mem_cluster(memdesc, cluster, i)
+ {
if (cluster->usage & 3)
continue;

- start = PFN_PHYS(cluster->start_pfn);
- if (start < PFN_PHYS(start_pfn) + bootmap_size)
- start = PFN_PHYS(start_pfn) + bootmap_size;
- if (PFN_DOWN(start) >= PFN_MAX)
+ start = cluster->start_pfn;
+ end = start + cluster->numpages;
+ if (end <= start_pfn)
+ continue;
+ if (start >= max_low_pfn)
+ continue;
+ if (start < start_pfn)
+ start = start_pfn;
+ if (end > max_low_pfn)
+ end = max_low_pfn;
+ if (end - start >= bootmap_pages)
+ {
+ printk("allocating bootmap in area %ld:%ld\n",
+ start, start+bootmap_pages);
+ bootmap_start = start;
+ break;
+ }
+ }
+
+ if (bootmap_start == -1)
+ {
+ max_low_pfn >>= 1;
+ printk("bootmap area not found now trying with %ld pages\n",
+ max_low_pfn);
+ goto try_again;
+ }
+
+ /* allocate the bootmap and mark the whole MM as reserved */
+ bootmap_size = init_bootmem(bootmap_start, max_low_pfn);
+
+ /* mark the free regions */
+ for_each_mem_cluster(memdesc, cluster, i)
+ {
+ if (cluster->usage & 3)
continue;

- end = PFN_PHYS(cluster->start_pfn + cluster->numpages);
- if (PFN_DOWN(end) > PFN_MAX)
- end = PFN_PHYS(PFN_MAX);
+ start = cluster->start_pfn;
+ if (start < start_pfn)
+ start = start_pfn;
+
+ end = cluster->start_pfn + cluster->numpages;
+ if (end > max_low_pfn)
+ end = max_low_pfn;

if (start >= end)
continue;
- free_bootmem(start, end-start);
+
+ start = PFN_PHYS(start);
+ end = PFN_PHYS(end);
+
+ free_bootmem(start, end - start);
+ printk("freeing pages %ld:%ld\n",
+ PFN_UP(start), PFN_DOWN(end));
}

+ /* reserve the bootmap memory */
+ reserve_bootmem(PFN_PHYS(bootmap_start), bootmap_size);
+ printk("reserving bootmap %ld:%ld\n", bootmap_start,
+ bootmap_start + PFN_UP(bootmap_size));
+
#ifdef CONFIG_BLK_DEV_INITRD
initrd_start = INITRD_START;
if (initrd_start) {
@@ -354,10 +402,6 @@
Detect the later by looking for "MILO" in the system serial nr. */
alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;
#endif
-
- SRM_printf("Booting on %s%s%s using machine vector %s\n",
- type_name, (*var_name ? " variation " : ""),
- var_name, alpha_mv.vector_name);

printk("Booting "
#ifdef CONFIG_ALPHA_GENERIC
diff -urN 2.3.29/arch/alpha/mm/init.c alpha/arch/alpha/mm/init.c
--- 2.3.29/arch/alpha/mm/init.c Wed Nov 24 18:22:03 1999
+++ alpha/arch/alpha/mm/init.c Wed Nov 24 18:25:06 1999
@@ -212,7 +212,7 @@
zones_size[ZONE_DMA] = high_pfn;
else
{
- zones_size[0] = dma_pfn;
+ zones_size[ZONE_DMA] = dma_pfn;
zones_size[ZONE_NORMAL] = high_pfn - dma_pfn;
}

@@ -278,7 +278,7 @@
{
max_mapnr = num_physpages = max_low_pfn;
totalram_pages += free_all_bootmem();
- printk("Memory: %luk available\n", totalram_pages >> 10);
+ printk("Memory: %luk available\n", totalram_pages << (PAGE_SHIFT-10));
}

void
diff -urN 2.3.29/include/asm-alpha/page.h alpha/include/asm-alpha/page.h
--- 2.3.29/include/asm-alpha/page.h Wed Nov 24 18:22:06 1999
+++ alpha/include/asm-alpha/page.h Wed Nov 24 18:52:11 1999
@@ -106,16 +106,7 @@

#endif /* STRICT_MM_TYPECHECKS */

-#if 0
#define BUG() __asm__ __volatile__("call_pal 129 # bugchk")
-#else
-/* hack to see the BUG() information in the early boot stage */
-#define BUG() \
-do { \
- SRM_printf("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
- halt(); \
-} while(0)
-#endif
#define PAGE_BUG(page) BUG()

#endif /* !ASSEMBLY */
diff -urN 2.3.29/include/asm-alpha/system.h alpha/include/asm-alpha/system.h
--- 2.3.29/include/asm-alpha/system.h Wed Nov 24 18:22:06 1999
+++ alpha/include/asm-alpha/system.h Wed Nov 24 18:55:45 1999
@@ -363,17 +363,6 @@
((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
#define tas(ptr) (xchg((ptr),1))

-/* Very dirty but nevertheless very fun hack ;). I recall the aboot printf()
- that will in turn use the SRM console to do the debugging of the boot
- process. As there's no runtime symbol table, the address of printf()
- is hardwired and is in function of the bootlx binary you have in /boot...
- 1999 Andrea Arcangeli <andrea@suse.de> */
-#if 0
-#define SRM_printf(args...) ({ int (*__SRM_printf)(const char *fmt, ...) = (int (*)(const char *fmt, ...)) 0x20000aa0; __SRM_printf(args); })
-#else
-#define SRM_printf(args...)
-#endif
-
#endif /* __ASSEMBLY__ */

#endif
diff -urN 2.3.29/include/linux/bootmem.h alpha/include/linux/bootmem.h
--- 2.3.29/include/linux/bootmem.h Wed Nov 24 18:22:06 1999
+++ alpha/include/linux/bootmem.h Wed Nov 24 18:56:02 1999
@@ -12,6 +12,7 @@

extern unsigned long max_low_pfn;

+extern unsigned long __init bootmem_bootmap_pages (unsigned long);
extern unsigned long __init init_bootmem (unsigned long addr, unsigned long memend);
extern void __init reserve_bootmem (unsigned long addr, unsigned long size);
extern void __init free_bootmem (unsigned long addr, unsigned long size);
diff -urN 2.3.29/mm/bootmem.c alpha/mm/bootmem.c
--- 2.3.29/mm/bootmem.c Wed Nov 24 18:22:06 1999
+++ alpha/mm/bootmem.c Wed Nov 24 18:25:06 1999
@@ -28,6 +28,18 @@

static void * bootmem_map = NULL;

+/* return the number of _pages_ that will be allocated for the boot bitmap */
+unsigned long __init bootmem_bootmap_pages (unsigned long pages)
+{
+ unsigned long mapsize;
+
+ mapsize = (pages+7)/8;
+ mapsize = (mapsize + ~PAGE_MASK) & PAGE_MASK;
+ mapsize >>= PAGE_SHIFT;
+
+ return mapsize;
+}
+
/*
* Called once to set up the allocator itself.
*/

Andrea

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/