summaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-27 23:45:22 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-27 23:45:22 +0000
commit5b35aa5cd29bb111d847b2a2ed18110acbfb1f44 (patch)
treec7bbaa1137528330d3c74d14056ef7016a52be72 /arch/sh
parent511bcd7c5924ce9e98ad1cb851988f7448dfef0f (diff)
Merge with Linux 2.3.24.
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/kernel/entry.S11
-rw-r--r--arch/sh/kernel/irq_onchip.c8
-rw-r--r--arch/sh/kernel/setup.c157
-rw-r--r--arch/sh/lib/Makefile2
-rw-r--r--arch/sh/lib/memchr.S26
-rw-r--r--arch/sh/mm/init.c163
6 files changed, 237 insertions, 130 deletions
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index bd9c7bb39..ac5a075c0 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -149,7 +149,7 @@ initial_page_write:
/* Unwind the stack and jmp to the debug entry */
debug:
add #4,r15 ! skip syscall number
- ldc.l @r15+,ssr
+ mov.l @r15+,r11 ! SSR
mov.l @r15+,r10 ! original stack
mov.l @r15+,r0
mov.l @r15+,r1
@@ -164,6 +164,7 @@ debug:
or r9,r14
ldc r14,sr ! here, change the register bank
mov r10,k0
+ mov r11,k1
mov.l @r15+,r8
mov.l @r15+,r9
mov.l @r15+,r10
@@ -180,7 +181,7 @@ debug:
!
mov.l 9f,k0
jmp @k0
- nop
+ ldc k1,ssr
.balign 4
8: .long 0x300000f0
9: .long 0xa0000100
@@ -371,7 +372,7 @@ ret_with_reschedule:
!
restore_all:
add #4,r15 ! skip syscall number
- ldc.l @r15+,ssr
+ mov.l @r15+,r11 ! SSR
mov.l @r15+,r10 ! original stack
mov.l @r15+,r0
mov.l @r15+,r1
@@ -386,6 +387,7 @@ restore_all:
or r9,r14
ldc r14,sr ! here, change the register bank
mov r10,k0
+ mov r11,k1
mov.l @r15+,r8
mov.l @r15+,r9
mov.l @r15+,r10
@@ -399,6 +401,7 @@ restore_all:
lds.l @r15+,pr
ldc.l @r15+,spc
mov k0,r15
+ ldc k1,ssr
rte
nop
@@ -515,7 +518,7 @@ none:
.data
ENTRY(exception_handling_table)
- .long none /* XXX: Avoid spurious interrupt */
+ .long error
.long error
.long tlb_miss_load
.long tlb_miss_store
diff --git a/arch/sh/kernel/irq_onchip.c b/arch/sh/kernel/irq_onchip.c
index b4ba54f31..0ed3400ef 100644
--- a/arch/sh/kernel/irq_onchip.c
+++ b/arch/sh/kernel/irq_onchip.c
@@ -89,29 +89,33 @@ static struct hw_interrupt_type onChip_irq_type = {
void disable_onChip_irq(unsigned int irq)
{
+ unsigned long val, flags;
/* Set priority in IPR to 0 */
int offset = ipr_data[irq-TIMER_IRQ].offset;
unsigned long intc_ipr_address = INTC_IPR + (offset/16*INTC_SIZE);
unsigned short mask = 0xffff ^ (0xf << (offset%16));
- unsigned long val;
+ save_and_cli(flags);
val = ctrl_inw(intc_ipr_address);
val &= mask;
ctrl_outw(val, intc_ipr_address);
+ restore_flags(flags);
}
static void enable_onChip_irq(unsigned int irq)
{
+ unsigned long val, flags;
/* Set priority in IPR back to original value */
int offset = ipr_data[irq-TIMER_IRQ].offset;
int priority = ipr_data[irq-TIMER_IRQ].priority;
unsigned long intc_ipr_address = INTC_IPR + (offset/16*INTC_SIZE);
unsigned short value = (priority << (offset%16));
- unsigned long val;
+ save_and_cli(flags);
val = ctrl_inw(intc_ipr_address);
val |= value;
ctrl_outw(val, intc_ipr_address);
+ restore_flags(flags);
}
void make_onChip_irq(unsigned int irq)
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 59c97a66b..deb532300 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -28,14 +28,17 @@
#ifdef CONFIG_BLK_DEV_RAM
#include <linux/blk.h>
#endif
-#include <asm/processor.h>
+#include <linux/bootmem.h>
#include <linux/console.h>
+#include <asm/processor.h>
+#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/smp.h>
+
/*
* Machine setup..
*/
@@ -62,7 +65,6 @@ extern int _text, _etext, _edata, _end;
#define LOADER_TYPE (*(unsigned long *) (PARAM+0x00c))
#define INITRD_START (*(unsigned long *) (PARAM+0x010))
#define INITRD_SIZE (*(unsigned long *) (PARAM+0x014))
-#define MEMORY_END (*(unsigned long *) (PARAM+0x018))
/* ... */
#define COMMAND_LINE ((char *) (PARAM+0x100))
#define COMMAND_LINE_SIZE 256
@@ -105,11 +107,67 @@ static struct resource rom_resources[MAXROMS] = {
{ "Video ROM", 0xc0000, 0xc7fff }
};
-void __init setup_arch(char **cmdline_p,
- unsigned long * memory_start_p,
- unsigned long * memory_end_p)
+static unsigned long memory_start, memory_end;
+
+unsigned long __init memparse(char *ptr, char **retptr)
{
- unsigned long memory_start, memory_end;
+ unsigned long ret;
+
+ ret = simple_strtoul(ptr, retptr, 0);
+
+ if (**retptr == 'K' || **retptr == 'k') {
+ ret <<= 10;
+ (*retptr)++;
+ }
+ else if (**retptr == 'M' || **retptr == 'm') {
+ ret <<= 20;
+ (*retptr)++;
+ }
+ return ret;
+} /* memparse */
+
+static inline void parse_mem_cmdline (char ** cmdline_p)
+{
+ char c = ' ', *to = command_line, *from = COMMAND_LINE;
+ int len = 0;
+
+ /* Save unparsed command line copy for /proc/cmdline */
+ memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
+ saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
+
+ memory_start = (unsigned long)__va(0)+__MEMORY_START;
+ /* Default is 4Mbyte. */
+ memory_end = (unsigned long)__va(0x00400000)+__MEMORY_START;
+
+ for (;;) {
+ /*
+ * "mem=XXX[kKmM]" defines a size of memory.
+ */
+ if (c == ' ' && !memcmp(from, "mem=", 4)) {
+ if (to != command_line)
+ to--;
+ {
+ unsigned long mem_size;
+
+ mem_size = memparse(from+4, &from);
+ memory_end = memory_start + mem_size;
+ }
+ }
+ c = *(from++);
+ if (!c)
+ break;
+ if (COMMAND_LINE_SIZE <= ++len)
+ break;
+ *(to++) = c;
+ }
+ *to = '\0';
+ *cmdline_p = command_line;
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+ unsigned long bootmap_size;
+ unsigned long start_pfn, max_pfn, max_low_pfn;
ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
@@ -118,12 +176,9 @@ void __init setup_arch(char **cmdline_p,
rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
#endif
+
if (!MOUNT_ROOT_RDONLY)
root_mountflags &= ~MS_RDONLY;
-
- memory_start = (unsigned long) &_end;
- memory_end = MEMORY_END;
-
init_mm.start_code = (unsigned long)&_text;
init_mm.end_code = (unsigned long) &_etext;
init_mm.end_data = (unsigned long) &_edata;
@@ -134,21 +189,73 @@ void __init setup_arch(char **cmdline_p,
data_resource.start = virt_to_bus(&_etext);
data_resource.end = virt_to_bus(&_edata)-1;
- /* Save unparsed command line copy for /proc/cmdline */
- memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
- saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
+ parse_mem_cmdline(cmdline_p);
- memcpy(command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
- command_line[COMMAND_LINE_SIZE-1] = '\0';
+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
+#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
- /* Not support "mem=XXX[kKmM]" command line option. */
- *cmdline_p = command_line;
+ /*
+ * partially used pages are not usable - thus
+ * we are rounding upwards:
+ */
+ start_pfn = PFN_UP(__pa(&_end)-__MEMORY_START);
- memory_end &= PAGE_MASK;
- ram_resources[1].end = memory_end-1;
+ /*
+ * Find the highest page frame number we have available
+ */
+ max_pfn = PFN_DOWN(__pa(memory_end)-__MEMORY_START);
- *memory_start_p = memory_start;
- *memory_end_p = memory_end;
+ /*
+ * Determine low and high memory ranges:
+ */
+ max_low_pfn = max_pfn;
+
+ /*
+ * Initialize the boot-time allocator (with low memory only):
+ */
+ bootmap_size = init_bootmem(start_pfn, max_low_pfn);
+
+ /*
+ * FIXME: what about high memory?
+ */
+ ram_resources[1].end = PFN_PHYS(max_low_pfn) + __MEMORY_START;
+
+ /*
+ * Register fully available low RAM pages with the bootmem allocator.
+ */
+ {
+ unsigned long curr_pfn, last_pfn, size;
+
+ /*
+ * We are rounding up the start address of usable memory:
+ */
+ curr_pfn = PFN_UP(0);
+ /*
+ * ... and at the end of the usable range downwards:
+ */
+ last_pfn = PFN_DOWN(memory_end-__MEMORY_START);
+
+ if (last_pfn > max_low_pfn)
+ last_pfn = max_low_pfn;
+
+ size = last_pfn - curr_pfn;
+ free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
+ }
+ /*
+ * Reserve the kernel text and
+ * Reserve the bootmem bitmap itself as well. We do this in two
+ * steps (first step was init_bootmem()) because this catches
+ * the (very unlikely) case of us accidentally initializing the
+ * bootmem allocator with an invalid RAM area.
+ */
+ reserve_bootmem(PAGE_SIZE, PFN_PHYS(start_pfn) + bootmap_size);
+
+ /*
+ * reserve physical page 0 - it's a special BIOS page on many boxes,
+ * enabling clean reboots, SMP operation, laptop functions.
+ */
+ reserve_bootmem(0, PAGE_SIZE);
#ifdef CONFIG_BLK_DEV_INITRD
if (LOADER_TYPE) {
@@ -156,10 +263,12 @@ void __init setup_arch(char **cmdline_p,
initrd_end = initrd_start+INITRD_SIZE;
if (initrd_end > memory_end) {
printk("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
- initrd_end,memory_end);
+ "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+ initrd_end,memory_end);
initrd_start = 0;
- }
+ } else
+ reserve_bootmem(__pa(initrd_start)-__MEMORY_START,
+ INITRD_SIZE);
}
#endif
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index 934c84744..5f7d68755 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -6,7 +6,7 @@
$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o
L_TARGET = lib.a
-L_OBJS = delay.o memcpy.o memset.o memmove.o old-checksum.o \
+L_OBJS = delay.o memcpy.o memset.o memmove.o memchr.o old-checksum.o \
checksum.o
include $(TOPDIR)/Rules.make
diff --git a/arch/sh/lib/memchr.S b/arch/sh/lib/memchr.S
new file mode 100644
index 000000000..d5f9ba2e3
--- /dev/null
+++ b/arch/sh/lib/memchr.S
@@ -0,0 +1,26 @@
+/* $Id: memchr.S,v 1.1 1999/10/17 11:32:38 gniibe Exp $
+ *
+ * "memchr" implementation of SuperH
+ *
+ * Copyright (C) 1999 Niibe Yutaka
+ *
+ */
+
+/*
+ * void *memchr(const void *s, int c, size_t n);
+ */
+
+#include <linux/linkage.h>
+ENTRY(memchr)
+ tst r6,r6
+ bt/s 2f
+ exts.b r5,r5
+1: mov.b @r4,r1
+ cmp/eq r1,r5
+ bt/s 3f
+ dt r6
+ bf/s 1b
+ add #1,r4
+2: mov #0,r4
+3: rts
+ mov r4,r0
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 4c602a385..2dc194a77 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -24,6 +24,7 @@
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h>
#endif
+#include <linux/bootmem.h>
#include <asm/processor.h>
#include <asm/system.h>
@@ -37,21 +38,53 @@
*/
unsigned long mmu_context_cache;
-static unsigned long totalram = 0;
+static unsigned long totalram_pages = 0;
+static unsigned long totalhigh_pages = 0;
extern void show_net_buffers(void);
extern unsigned long init_smp_mappings(unsigned long);
-void __bad_pte_kernel(pmd_t *pmd)
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving an inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+
+unsigned long empty_bad_page[1024];
+pte_t empty_bad_pte_table[PTRS_PER_PTE];
+extern unsigned long empty_zero_page[1024];
+
+static pte_t * get_bad_pte_table(void)
+{
+ pte_t v;
+ int i;
+
+ v = pte_mkdirty(mk_pte_phys(__pa(empty_bad_page), PAGE_SHARED));
+
+ for (i = 0; i < PAGE_SIZE/sizeof(pte_t); i++)
+ empty_bad_pte_table[i] = v;
+
+ return empty_bad_pte_table;
+}
+
+void __handle_bad_pmd(pmd_t *pmd)
{
- printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
- pmd_val(*pmd) = _KERNPG_TABLE + __pa(BAD_PAGETABLE);
+ pmd_ERROR(*pmd);
+ pmd_val(*pmd) = _PAGE_TABLE + __pa(get_bad_pte_table());
}
-void __bad_pte(pmd_t *pmd)
+void __handle_bad_pmd_kernel(pmd_t *pmd)
{
- printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
- pmd_val(*pmd) = _PAGE_TABLE + __pa(BAD_PAGETABLE);
+ pmd_ERROR(*pmd);
+ pmd_val(*pmd) = _KERNPG_TABLE + __pa(get_bad_pte_table());
}
pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
@@ -61,16 +94,16 @@ pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
pte = (pte_t *) __get_free_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (pte) {
- clear_page((unsigned long)pte);
+ clear_page(pte);
pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte);
return pte + offset;
}
- pmd_val(*pmd) = _KERNPG_TABLE + __pa(BAD_PAGETABLE);
+ pmd_val(*pmd) = _KERNPG_TABLE + __pa(get_bad_pte_table());
return NULL;
}
free_page((unsigned long)pte);
if (pmd_bad(*pmd)) {
- __bad_pte_kernel(pmd);
+ __handle_bad_pmd_kernel(pmd);
return NULL;
}
return (pte_t *) pmd_page(*pmd) + offset;
@@ -83,19 +116,19 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
pte = (unsigned long) __get_free_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (pte) {
- clear_page(pte);
+ clear_page((void *)pte);
pmd_val(*pmd) = _PAGE_TABLE + __pa(pte);
- return (pte_t *)(pte + offset);
+ return (pte_t *)pte + offset;
}
- pmd_val(*pmd) = _PAGE_TABLE + __pa(BAD_PAGETABLE);
+ pmd_val(*pmd) = _PAGE_TABLE + __pa(get_bad_pte_table());
return NULL;
}
free_page(pte);
if (pmd_bad(*pmd)) {
- __bad_pte(pmd);
+ __handle_bad_pmd(pmd);
return NULL;
}
- return (pte_t *) (pmd_page(*pmd) + offset);
+ return (pte_t *) pmd_page(*pmd) + offset;
}
int do_check_pgt_cache(int low, int high)
@@ -114,37 +147,6 @@ int do_check_pgt_cache(int low, int high)
return freed;
}
-/*
- * BAD_PAGE is the page that is used for page faults when linux
- * is out-of-memory. Older versions of linux just did a
- * do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving an inode
- * unused etc..
- *
- * BAD_PAGETABLE is the accompanying page-table: it is initialized
- * to point to BAD_PAGE entries.
- *
- * ZERO_PAGE is a special page that is used for zero-initialized
- * data and COW.
- */
-pte_t * __bad_pagetable(void)
-{
- extern unsigned long empty_bad_page_table[PAGE_SIZE];
- unsigned long page = (unsigned long)empty_bad_page_table;
-
- clear_page(page);
- return (pte_t *)empty_bad_page_table;
-}
-
-pte_t __bad_page(void)
-{
- extern char empty_bad_page[PAGE_SIZE];
- unsigned long page = (unsigned long)empty_bad_page;
-
- clear_page(page);
- return pte_mkdirty(mk_pte(page, PAGE_SHARED));
-}
-
void show_mem(void)
{
int i,free = 0,total = 0,reserved = 0;
@@ -170,13 +172,12 @@ void show_mem(void)
printk("%d pages shared\n",shared);
printk("%d pages swap cached\n",cached);
printk("%ld pages in page table cache\n",pgtable_cache_size);
+ show_buffers();
#ifdef CONFIG_NET
show_net_buffers();
#endif
}
-extern unsigned long free_area_init(unsigned long, unsigned long);
-
/* References to section boundaries */
extern char _text, _etext, _edata, __bss_start, _end;
@@ -190,13 +191,10 @@ pgd_t swapper_pg_dir[1024];
* This routines also unmaps the page at virtual kernel address 0, so
* that we can trap those pesky NULL-reference errors in the kernel.
*/
-unsigned long __init
-paging_init(unsigned long start_mem, unsigned long end_mem)
+void __init paging_init(void)
{
pgd_t * pg_dir;
- start_mem = PAGE_ALIGN(start_mem);
-
/* We don't need kernel mapping as hardware support that. */
pg_dir = swapper_pg_dir;
@@ -209,61 +207,25 @@ paging_init(unsigned long start_mem, unsigned long end_mem)
mmu_context_cache = MMU_CONTEXT_FIRST_VERSION;
set_asid(mmu_context_cache & MMU_CONTEXT_ASID_MASK);
- return free_area_init(start_mem, end_mem);
+ free_area_init(max_low_pfn);
}
-unsigned long empty_bad_page[1024];
-unsigned long empty_bad_page_table[1024];
-extern unsigned long empty_zero_page[1024];
-
-void __init mem_init(unsigned long start_mem, unsigned long end_mem)
+void __init mem_init(void)
{
int codepages = 0;
int reservedpages = 0;
int datapages = 0;
int initpages = 0;
- unsigned long tmp;
- end_mem &= PAGE_MASK;
- high_memory = (void *) end_mem;
- max_mapnr = num_physpages = MAP_NR(end_mem);
+ max_mapnr = num_physpages = max_low_pfn;
+ high_memory = (void *) ((unsigned long)__va(max_low_pfn * PAGE_SIZE)+__MEMORY_START);
/* clear the zero-page */
memset(empty_zero_page, 0, PAGE_SIZE);
- /* Mark (clear "reserved" bit) usable pages in the mem_map[] */
- /* Note that all are marked reserved already. */
- tmp = start_mem = PAGE_ALIGN(start_mem);
- while (tmp < end_mem) {
- clear_bit(PG_reserved, &mem_map[MAP_NR(tmp)].flags);
- clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
- tmp += PAGE_SIZE;
- }
+ /* this will put all low memory onto the freelists */
+ totalram_pages += free_all_bootmem();
- for (tmp = PAGE_OFFSET; tmp < end_mem; tmp += PAGE_SIZE) {
- if (PageReserved(mem_map+MAP_NR(tmp))) {
- if (tmp >= (unsigned long) &_text && tmp < (unsigned long) &_edata) {
- if (tmp < (unsigned long) &_etext)
- codepages++;
- else
- datapages++;
- } else if (tmp >= (unsigned long) &__init_begin
- && tmp < (unsigned long) &__init_end)
- initpages++;
- else if (tmp >= (unsigned long) &__bss_start
- && tmp < (unsigned long) start_mem)
- datapages++;
- else
- reservedpages++;
- continue;
- }
- 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))
-#endif
- free_page(tmp);
- }
printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
(unsigned long) nr_free_pages << (PAGE_SHIFT-10),
max_mapnr << (PAGE_SHIFT-10),
@@ -279,19 +241,22 @@ void free_initmem(void)
addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
- mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
+ ClearPageReserved(mem_map + MAP_NR(addr));
set_page_count(mem_map+MAP_NR(addr), 1);
free_page(addr);
- totalram += PAGE_SIZE;
+ totalram_pages++;
}
printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
}
void si_meminfo(struct sysinfo *val)
{
- val->totalram = totalram;
+ val->totalram = totalram_pages;
val->sharedram = 0;
- val->freeram = nr_free_pages << PAGE_SHIFT;
- val->bufferram = atomic_read(&buffermem);
+ val->freeram = nr_free_pages;
+ val->bufferram = atomic_read(&buffermem_pages);
+ val->totalhigh = totalhigh_pages;
+ val->freehigh = nr_free_highpages;
+ val->mem_unit = PAGE_SIZE;
return;
}