patch-2.3.16 linux/arch/i386/mm/init.c
Next file: linux/arch/m68k/amiga/amisound.c
Previous file: linux/arch/i386/mm/bigmem.c
Back to the patch index
Back to the overall index
- Lines: 221
- Date:
Mon Aug 30 10:47:02 1999
- Orig file:
v2.3.15/linux/arch/i386/mm/init.c
- Orig date:
Thu Aug 26 13:05:34 1999
diff -u --recursive --new-file v2.3.15/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c
@@ -2,6 +2,8 @@
* linux/arch/i386/mm/init.c
*
* Copyright (C) 1995 Linus Torvalds
+ *
+ * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
*/
#include <linux/config.h>
@@ -20,6 +22,7 @@
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h>
#endif
+#include <linux/bigmem.h>
#include <asm/processor.h>
#include <asm/system.h>
@@ -27,8 +30,10 @@
#include <asm/pgtable.h>
#include <asm/dma.h>
#include <asm/fixmap.h>
+#include <asm/e820.h>
static unsigned long totalram = 0;
+static unsigned long totalbig = 0;
extern void show_net_buffers(void);
extern unsigned long init_smp_mappings(unsigned long);
@@ -150,6 +155,7 @@
{
int i,free = 0,total = 0,reserved = 0;
int shared = 0, cached = 0;
+ int bigmem = 0;
printk("Mem-info:\n");
show_free_areas();
@@ -157,6 +163,8 @@
i = max_mapnr;
while (i-- > 0) {
total++;
+ if (PageBIGMEM(mem_map+i))
+ bigmem++;
if (PageReserved(mem_map+i))
reserved++;
else if (PageSwapCache(mem_map+i))
@@ -167,6 +175,7 @@
shared += page_count(mem_map+i) - 1;
}
printk("%d pages of RAM\n",total);
+ printk("%d pages of BIGMEM\n",bigmem);
printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared);
printk("%d pages swap cached\n",cached);
@@ -238,7 +247,7 @@
* This routines also unmaps the page at virtual kernel address 0, so
* that we can trap those pesky NULL-reference errors in the kernel.
*/
-__initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_mem))
+unsigned long __init paging_init(unsigned long start_mem, unsigned long end_mem)
{
pgd_t * pg_dir;
pte_t * pg_table;
@@ -315,7 +324,12 @@
#endif
local_flush_tlb();
+#ifndef CONFIG_BIGMEM
return free_area_init(start_mem, end_mem);
+#else
+ kmap_init(); /* run after fixmap_init */
+ return free_area_init(start_mem, bigmem_end + PAGE_OFFSET);
+#endif
}
/*
@@ -324,7 +338,7 @@
* before and after the test are here to work-around some nasty CPU bugs.
*/
-__initfunc(void test_wp_bit(void))
+void __init test_wp_bit(void)
{
unsigned char tmp_reg;
unsigned long old = pg0[0];
@@ -353,7 +367,7 @@
printk(".\n");
}
-__initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
+void __init mem_init(unsigned long start_mem, unsigned long end_mem)
{
unsigned long start_low_mem = PAGE_SIZE;
int codepages = 0;
@@ -361,11 +375,22 @@
int datapages = 0;
int initpages = 0;
unsigned long tmp;
- unsigned long endbase;
+ unsigned long addr;
+ int i, avail;
end_mem &= PAGE_MASK;
+#ifdef CONFIG_BIGMEM
+ bigmem_start = PAGE_ALIGN(bigmem_start);
+ bigmem_end &= PAGE_MASK;
+#endif
high_memory = (void *) end_mem;
+#ifndef CONFIG_BIGMEM
max_mapnr = num_physpages = MAP_NR(end_mem);
+#else
+ max_mapnr = num_physpages = PHYSMAP_NR(bigmem_end);
+ /* cache the bigmem_mapnr */
+ bigmem_mapnr = PHYSMAP_NR(bigmem_start);
+#endif
/* clear the zero-page */
memset(empty_zero_page, 0, PAGE_SIZE);
@@ -385,23 +410,43 @@
#endif
start_mem = PAGE_ALIGN(start_mem);
- /*
- * IBM messed up *AGAIN* in their thinkpad: 0xA0000 -> 0x9F000.
- * They seem to have done something stupid with the floppy
- * controller as well..
- * The amount of available base memory is in WORD 40:13. Except
- * when it isn't.
+ /* walk the whitelist, unreserving good memory
*/
- endbase = PAGE_OFFSET + 0x9f000;
- while (start_low_mem < endbase) {
- clear_bit(PG_reserved, &mem_map[MAP_NR(start_low_mem)].flags);
- start_low_mem += PAGE_SIZE;
- }
+ for (avail = i = 0; i < e820.nr_map; i++) {
+ if (e820.map[i].type != 1) /* not usable memory */
+ continue;
+ printk("memory region: %luk @ %08lx\n",
+ ((long)(e820.map[i].size)) / 1024,
+ (long)(e820.map[i].addr) );
+ for (addr=PAGE_ALIGN(((long)(e820.map[i].addr)))+PAGE_OFFSET,
+ tmp = 0;
+ tmp < (unsigned long)(e820.map[i].size);
+ tmp += PAGE_SIZE,
+ addr += PAGE_SIZE) {
+
+ /* this little bit of grossness is for dealing
+ * with memory borrowing for system bookkeeping
+ * (smp stacks, zero page, kernel code, etc)
+ * without having to go back and edit the e820
+ * map to compensate.
+ *
+ * if we're in low memory (<1024k), we need to
+ * avoid the smp stack and zero page.
+ * if we're in high memory, we need to avoid
+ * the kernel code.
+ * in any case, we don't want to hack mem_map
+ * entries above end_mem.
+ */
+ if ( (addr < start_low_mem)
+ || (addr >= HIGH_MEMORY && addr <= start_mem)
+ || (addr > end_mem) )
+ continue;
- while (start_mem < end_mem) {
- clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
- start_mem += PAGE_SIZE;
+ avail++;
+ clear_bit(PG_reserved, &mem_map[MAP_NR(addr)].flags);
+ }
}
+
for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
if (tmp >= MAX_DMA_ADDRESS)
clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
@@ -424,21 +469,33 @@
set_page_count(mem_map+MAP_NR(tmp), 1);
totalram += PAGE_SIZE;
#ifdef CONFIG_BLK_DEV_INITRD
- if (!initrd_start || (tmp < initrd_start || tmp >=
- initrd_end))
+ if (!initrd_start || (tmp < initrd_start || tmp >= initrd_end))
#endif
free_page(tmp);
}
- printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
+#ifdef CONFIG_BIGMEM
+ for (tmp = bigmem_start; tmp < bigmem_end; tmp += PAGE_SIZE) {
+ clear_bit(PG_reserved, &mem_map[PHYSMAP_NR(tmp)].flags);
+ set_bit(PG_BIGMEM, &mem_map[PHYSMAP_NR(tmp)].flags);
+ atomic_set(&mem_map[PHYSMAP_NR(tmp)].count, 1);
+ free_page(tmp + PAGE_OFFSET);
+ totalbig += PAGE_SIZE;
+ }
+ totalram += totalbig;
+#endif
+ printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %dk bigmem)\n",
(unsigned long) nr_free_pages << (PAGE_SHIFT-10),
max_mapnr << (PAGE_SHIFT-10),
codepages << (PAGE_SHIFT-10),
reservedpages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10),
- initpages << (PAGE_SHIFT-10));
+ initpages << (PAGE_SHIFT-10),
+ (int) (totalbig >> 10)
+ );
if (boot_cpu_data.wp_works_ok < 0)
test_wp_bit();
+
}
void free_initmem(void)
@@ -461,5 +518,7 @@
val->sharedram = 0;
val->freeram = nr_free_pages << PAGE_SHIFT;
val->bufferram = atomic_read(&buffermem);
+ val->totalbig = totalbig;
+ val->freebig = nr_free_bigpages << PAGE_SHIFT;
return;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)