summaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-04-05 04:55:58 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-04-05 04:55:58 +0000
commit74a9f2e1b4d3ab45a9f72cb5b556c9f521524ab3 (patch)
tree7c4cdb103ab1b388c9852a88bd6fb1e73eba0b5c /arch/sparc/mm
parentee6374c8b0d333c08061c6a97bc77090d7461225 (diff)
Merge with Linux 2.4.3.
Note that mingetty does no longer work with serial console, you have to switch to another getty like getty_ps. This commit also includes a fix for a setitimer bug which did prevent getty_ps from working on older kernels.
Diffstat (limited to 'arch/sparc/mm')
-rw-r--r--arch/sparc/mm/fault.c20
-rw-r--r--arch/sparc/mm/init.c230
-rw-r--r--arch/sparc/mm/srmmu.c40
-rw-r--r--arch/sparc/mm/sun4c.c32
4 files changed, 166 insertions, 156 deletions
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index 1521d3246..764bca89b 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.118 2000/12/29 07:52:41 anton Exp $
+/* $Id: fault.c,v 1.119 2001/03/24 09:36:10 davem Exp $
* fault.c: Page fault handlers for the Sparc.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -224,7 +224,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
if (in_interrupt() || !mm)
goto no_context;
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
/*
* The kernel referencing a bad kernel pointer can lock up
@@ -274,7 +274,7 @@ good_area:
default:
goto out_of_memory;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return;
/*
@@ -282,7 +282,7 @@ good_area:
* Fix it, but check if it's kernel or user first..
*/
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
bad_area_nosemaphore:
/* User mode accesses just cause a SIGSEGV */
@@ -338,14 +338,14 @@ no_context:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", tsk->comm);
if (from_user)
do_exit(SIGKILL);
goto no_context;
do_sigbus:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRERR;
@@ -479,7 +479,7 @@ inline void force_user_fault(unsigned long address, int write)
printk("wf<pid=%d,wr=%d,addr=%08lx>\n",
tsk->pid, write, address);
#endif
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if(!vma)
goto bad_area;
@@ -500,10 +500,10 @@ good_area:
}
if (!handle_mm_fault(mm, vma, address, write))
goto do_sigbus;
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return;
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
#if 0
printk("Window whee %s [%d]: segfaults at %08lx\n",
tsk->comm, tsk->pid, address);
@@ -518,7 +518,7 @@ bad_area:
return;
do_sigbus:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRERR;
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
index d27495bd6..89807b38a 100644
--- a/arch/sparc/mm/init.c
+++ b/arch/sparc/mm/init.c
@@ -1,10 +1,10 @@
-/* $Id: init.c,v 1.96 2000/11/30 08:51:50 anton Exp $
+/* $Id: init.c,v 1.97 2001/02/26 02:57:34 anton Exp $
* linux/arch/sparc/mm/init.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1995 Eddie C. Dost (ecd@skynet.be)
* Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
+ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au)
*/
#include <linux/config.h>
@@ -53,7 +53,7 @@ extern unsigned int sparc_ramdisk_size;
unsigned long highstart_pfn, highend_pfn;
unsigned long totalram_pages;
-static unsigned long totalhigh_pages;
+unsigned long totalhigh_pages;
/*
* BAD_PAGE is the page that is used for page faults when linux
@@ -134,42 +134,79 @@ void __init sparc_context_init(int numctx)
#define DEBUG_BOOTMEM
extern unsigned long cmdline_memory_size;
-extern unsigned long last_valid_pfn;
+unsigned long last_valid_pfn;
+
+unsigned long calc_highpages(void)
+{
+ int i;
+ int nr = 0;
+
+ for (i = 0; sp_banks[i].num_bytes != 0; i++) {
+ unsigned long start_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
+ unsigned long end_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT;
+
+ if (end_pfn <= max_low_pfn)
+ continue;
+
+ if (start_pfn < max_low_pfn)
+ start_pfn = max_low_pfn;
+
+ nr += end_pfn - start_pfn;
+ }
+
+ return nr;
+}
+
+unsigned long calc_max_low_pfn(void)
+{
+ int i;
+ unsigned long tmp = (SRMMU_MAXMEM >> PAGE_SHIFT);
+ unsigned long curr_pfn, last_pfn;
+
+ last_pfn = (sp_banks[0].base_addr + sp_banks[0].num_bytes) >> PAGE_SHIFT;
+ for (i = 1; sp_banks[i].num_bytes != 0; i++) {
+ curr_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
-void __init bootmem_init(void)
+ if (curr_pfn >= tmp) {
+ if (last_pfn < tmp)
+ tmp = last_pfn;
+ break;
+ }
+
+ last_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT;
+ }
+
+ return tmp;
+}
+
+unsigned long __init bootmem_init(unsigned long *pages_avail)
{
unsigned long bootmap_size, start_pfn, max_pfn;
unsigned long end_of_phys_memory = 0UL;
- unsigned long bootmap_pfn;
+ unsigned long bootmap_pfn, bytes_avail, size;
int i;
- /* XXX It is a bit ambiguous here, whether we should
- * XXX treat the user specified mem=xxx as total wanted
- * XXX physical memory, or as a limit to the upper
- * XXX physical address we allow. For now it is the
- * XXX latter. -DaveM
- */
#ifdef 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 +
sp_banks[i].num_bytes;
+ bytes_avail += sp_banks[i].num_bytes;
if (cmdline_memory_size) {
- if (end_of_phys_memory > cmdline_memory_size) {
- if (cmdline_memory_size < sp_banks[i].base_addr) {
- end_of_phys_memory =
- sp_banks[i-1].base_addr +
- sp_banks[i-1].num_bytes;
+ if (bytes_avail > cmdline_memory_size) {
+ unsigned long slack = bytes_avail - cmdline_memory_size;
+
+ bytes_avail -= slack;
+ end_of_phys_memory -= slack;
+
+ sp_banks[i].num_bytes -= slack;
+ if (sp_banks[i].num_bytes == 0) {
sp_banks[i].base_addr = 0xdeadbeef;
- sp_banks[i].num_bytes = 0;
} else {
- sp_banks[i].num_bytes -=
- (end_of_phys_memory -
- cmdline_memory_size);
- end_of_phys_memory = cmdline_memory_size;
- sp_banks[++i].base_addr = 0xdeadbeef;
- sp_banks[i].num_bytes = 0;
+ sp_banks[i+1].num_bytes = 0;
+ sp_banks[i+1].base_addr = 0xdeadbeef;
}
break;
}
@@ -195,9 +232,9 @@ void __init bootmem_init(void)
highstart_pfn = highend_pfn = max_pfn;
if (max_low_pfn > (SRMMU_MAXMEM >> PAGE_SHIFT)) {
- highstart_pfn = max_low_pfn = (SRMMU_MAXMEM >> PAGE_SHIFT);
- printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
- (highend_pfn - highstart_pfn) >> (20-PAGE_SHIFT));
+ highstart_pfn = (SRMMU_MAXMEM >> PAGE_SHIFT);
+ max_low_pfn = calc_max_low_pfn();
+ printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", calc_highpages());
}
#ifdef CONFIG_BLK_DEV_INITRD
@@ -225,13 +262,14 @@ void __init bootmem_init(void)
prom_printf("init_bootmem(spfn[%lx],bpfn[%lx],mlpfn[%lx])\n",
start_pfn, bootmap_pfn, max_low_pfn);
#endif
- bootmap_size = init_bootmem(bootmap_pfn, max_low_pfn);
+ bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, phys_base>>PAGE_SHIFT, max_low_pfn);
/* Now register the available physical memory with the
* allocator.
*/
+ *pages_avail = 0;
for (i = 0; sp_banks[i].num_bytes != 0; i++) {
- unsigned long curr_pfn, last_pfn, size;
+ unsigned long curr_pfn, last_pfn;
curr_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
if (curr_pfn >= max_low_pfn)
@@ -249,7 +287,7 @@ void __init bootmem_init(void)
continue;
size = (last_pfn - curr_pfn) << PAGE_SHIFT;
-
+ *pages_avail += last_pfn - curr_pfn;
#ifdef DEBUG_BOOTMEM
prom_printf("free_bootmem: base[%lx] size[%lx]\n",
sp_banks[i].base_addr,
@@ -259,29 +297,42 @@ void __init bootmem_init(void)
size);
}
- /* Reserve the kernel text/data/bss, the bootmem bitmap and initrd. */
-#ifdef DEBUG_BOOTMEM
#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start)
+ if (initrd_start) {
+ size = initrd_end - initrd_start;
+#ifdef DEBUG_BOOTMEM
prom_printf("reserve_bootmem: base[%lx] size[%lx]\n",
- initrd_start, initrd_end - initrd_start);
+ initrd_start, size);
#endif
- prom_printf("reserve_bootmem: base[%lx] size[%lx]\n",
- phys_base, (start_pfn << PAGE_SHIFT) - phys_base);
- prom_printf("reserve_bootmem: base[%lx] size[%lx]\n",
- (bootmap_pfn << PAGE_SHIFT), bootmap_size);
-#endif
-#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start) {
- reserve_bootmem(initrd_start, initrd_end - initrd_start);
+ /* Reserve the initrd image area. */
+ reserve_bootmem(initrd_start, size);
+ *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
+
initrd_start += PAGE_OFFSET;
initrd_end += PAGE_OFFSET;
}
#endif
- reserve_bootmem(phys_base, (start_pfn << PAGE_SHIFT) - phys_base);
- reserve_bootmem((bootmap_pfn << PAGE_SHIFT), bootmap_size);
+ /* Reserve the kernel text/data/bss. */
+ size = (start_pfn << PAGE_SHIFT) - phys_base;
+#ifdef DEBUG_BOOTMEM
+ prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", phys_base, size);
+#endif
+ reserve_bootmem(phys_base, size);
+ *pages_avail -= PAGE_ALIGN(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 DEBUG_BOOTMEM
+ prom_printf("reserve_bootmem: 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;
- last_valid_pfn = max_pfn;
+ return max_pfn;
}
/*
@@ -293,8 +344,6 @@ extern void sun4c_paging_init(void);
extern void srmmu_paging_init(void);
extern void device_scan(void);
-unsigned long last_valid_pfn;
-
void __init paging_init(void)
{
switch(sparc_cpu_model) {
@@ -359,71 +408,6 @@ static void __init taint_real_pages(void)
}
}
-void __init free_mem_map_range(struct page *first, struct page *last)
-{
- first = (struct page *) PAGE_ALIGN((unsigned long)first);
- last = (struct page *) ((unsigned long)last & PAGE_MASK);
-#ifdef DEBUG_BOOTMEM
- prom_printf("[%p,%p] ", first, last);
-#endif
- while (first < last) {
- ClearPageReserved(virt_to_page(first));
- set_page_count(virt_to_page(first), 1);
- free_page((unsigned long)first);
- totalram_pages++;
- num_physpages++;
-
- first = (struct page *)((unsigned long)first + PAGE_SIZE);
- }
-}
-
-/* Walk through holes in sp_banks regions, if the mem_map array
- * areas representing those holes consume a page or more, free
- * up such pages. This helps a lot on machines where physical
- * ram is configured such that it begins at some hugh value.
- *
- * The sp_banks array is sorted by base address.
- */
-void __init free_unused_mem_map(void)
-{
- int i;
-
-#ifdef DEBUG_BOOTMEM
- prom_printf("free_unused_mem_map: ");
-#endif
- for (i = 0; sp_banks[i].num_bytes; i++) {
- if (i == 0) {
- struct page *first, *last;
-
- first = mem_map;
- last = &mem_map[sp_banks[i].base_addr >> PAGE_SHIFT];
- free_mem_map_range(first, last);
- } else {
- struct page *first, *last;
- unsigned long prev_end;
-
- prev_end = sp_banks[i-1].base_addr +
- sp_banks[i-1].num_bytes;
- prev_end = PAGE_ALIGN(prev_end);
- first = &mem_map[prev_end >> PAGE_SHIFT];
- last = &mem_map[sp_banks[i].base_addr >> PAGE_SHIFT];
-
- free_mem_map_range(first, last);
-
- if (!sp_banks[i+1].num_bytes) {
- prev_end = sp_banks[i].base_addr +
- sp_banks[i].num_bytes;
- first = &mem_map[prev_end >> PAGE_SHIFT];
- last = &mem_map[last_valid_pfn];
- free_mem_map_range(first, last);
- }
- }
- }
-#ifdef DEBUG_BOOTMEM
- prom_printf("\n");
-#endif
-}
-
void map_high_region(unsigned long start_pfn, unsigned long end_pfn)
{
unsigned long tmp;
@@ -458,9 +442,8 @@ void __init mem_init(void)
/* Saves us work later. */
memset((void *)&empty_zero_page, 0, PAGE_SIZE);
- i = last_valid_pfn >> (8 + 5);
+ i = last_valid_pfn >> ((20 - PAGE_SHIFT) + 5);
i += 1;
-
sparc_valid_addr_bitmap = (unsigned long *)
__alloc_bootmem(i << 2, SMP_CACHE_BYTES, 0UL);
@@ -472,7 +455,7 @@ void __init mem_init(void)
taint_real_pages();
- max_mapnr = last_valid_pfn;
+ max_mapnr = last_valid_pfn - (phys_base >> PAGE_SHIFT);
high_memory = __va(max_low_pfn << PAGE_SHIFT);
#ifdef DEBUG_BOOTMEM
@@ -480,10 +463,6 @@ void __init mem_init(void)
#endif
num_physpages = totalram_pages = free_all_bootmem();
-#if 0
- free_unused_mem_map();
-#endif
-
for (i = 0; sp_banks[i].num_bytes != 0; i++) {
unsigned long start_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
unsigned long end_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT;
@@ -513,19 +492,6 @@ void __init mem_init(void)
initpages << (PAGE_SHIFT-10),
totalhigh_pages << (PAGE_SHIFT-10),
(unsigned long)PAGE_OFFSET, (last_valid_pfn << PAGE_SHIFT));
-
- /* NOTE NOTE NOTE NOTE
- * Please keep track of things and make sure this
- * always matches the code in mm/page_alloc.c -DaveM
- */
- i = nr_free_pages() >> 7;
- if (i < 48)
- i = 48;
- if (i > 256)
- i = 256;
- freepages.min = i;
- freepages.low = i << 1;
- freepages.high = freepages.low + i;
}
void free_initmem (void)
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index a5b2b117b..e2b6116ff 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -1,4 +1,4 @@
-/* $Id: srmmu.c,v 1.226 2001/02/13 01:16:44 davem Exp $
+/* $Id: srmmu.c,v 1.228 2001/03/16 06:56:20 davem Exp $
* srmmu.c: SRMMU specific routines for memory management.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1124,6 +1124,15 @@ static unsigned long __init map_spbank(unsigned long vbase, int sp_entry)
unsigned long pstart = (sp_banks[sp_entry].base_addr & SRMMU_PGDIR_MASK);
unsigned long vstart = (vbase & SRMMU_PGDIR_MASK);
unsigned long vend = SRMMU_PGDIR_ALIGN(vbase + sp_banks[sp_entry].num_bytes);
+ /* Map "low" memory only */
+ const unsigned long min_vaddr = PAGE_OFFSET;
+ const unsigned long max_vaddr = PAGE_OFFSET + SRMMU_MAXMEM;
+
+ if (vstart < min_vaddr || vstart >= max_vaddr)
+ return vstart;
+
+ if (vend > max_vaddr || vend < min_vaddr)
+ vend = max_vaddr;
while(vstart < vend) {
do_large_mapping(vstart, pstart);
@@ -1159,10 +1168,11 @@ static inline void map_kernel(void)
extern void sparc_context_init(int);
extern int linux_num_cpus;
+extern unsigned long totalhigh_pages;
void (*poke_srmmu)(void) __initdata = NULL;
-extern void bootmem_init(void);
+extern unsigned long bootmem_init(unsigned long *pages_avail);
extern void sun_serial_setup(void);
void __init srmmu_paging_init(void)
@@ -1172,6 +1182,7 @@ void __init srmmu_paging_init(void)
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte;
+ unsigned long pages_avail;
sparc_iomap.start = SUN4M_IOBASE_VADDR; /* 16MB of IOSPACE on all sun4m's. */
@@ -1196,7 +1207,8 @@ void __init srmmu_paging_init(void)
prom_halt();
}
- bootmem_init();
+ pages_avail = 0;
+ last_valid_pfn = bootmem_init(&pages_avail);
srmmu_nocache_init();
srmmu_inherit_prom_mappings(0xfe400000,(LINUX_OPPROM_ENDVM-PAGE_SIZE));
@@ -1245,11 +1257,25 @@ void __init srmmu_paging_init(void)
kmap_init();
{
- unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0};
+ unsigned long zones_size[MAX_NR_ZONES];
+ unsigned long zholes_size[MAX_NR_ZONES];
+ unsigned long npages;
+ int znum;
+
+ for (znum = 0; znum < MAX_NR_ZONES; znum++)
+ zones_size[znum] = zholes_size[znum] = 0;
+
+ npages = max_low_pfn - (phys_base >> PAGE_SHIFT);
+
+ zones_size[ZONE_DMA] = npages;
+ zholes_size[ZONE_DMA] = npages - pages_avail;
+
+ npages = highend_pfn - max_low_pfn;
+ zones_size[ZONE_HIGHMEM] = npages;
+ zholes_size[ZONE_HIGHMEM] = npages - calc_highpages();
- zones_size[ZONE_DMA] = max_low_pfn;
- zones_size[ZONE_HIGHMEM] = highend_pfn - max_low_pfn;
- free_area_init(zones_size);
+ free_area_init_node(0, NULL, NULL, zones_size,
+ phys_base, zholes_size);
}
}
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index ef5157b05..91a1d571e 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -1,4 +1,4 @@
-/* $Id: sun4c.c,v 1.202 2000/12/01 03:17:31 anton Exp $
+/* $Id: sun4c.c,v 1.205 2001/03/16 06:57:41 davem Exp $
* sun4c.c: Doing in software what should be done in hardware.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -15,6 +15,7 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/bootmem.h>
+#include <linux/highmem.h>
#include <asm/scatterlist.h>
#include <asm/page.h>
@@ -31,6 +32,7 @@
#include <asm/openprom.h>
#include <asm/mmu_context.h>
#include <asm/sun4paddr.h>
+#include <asm/highmem.h>
/* Because of our dynamic kernel TLB miss strategy, and how
* our DVMA mapping allocation works, you _MUST_:
@@ -2432,7 +2434,7 @@ void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, p
extern void sparc_context_init(int);
extern unsigned long end;
-extern void bootmem_init(void);
+extern unsigned long bootmem_init(unsigned long *pages_avail);
extern unsigned long last_valid_pfn;
extern void sun_serial_setup(void);
@@ -2441,13 +2443,14 @@ void __init sun4c_paging_init(void)
int i, cnt;
unsigned long kernel_end, vaddr;
extern struct resource sparc_iomap;
- unsigned long end_pfn;
+ unsigned long end_pfn, pages_avail;
kernel_end = (unsigned long) &end;
kernel_end += (SUN4C_REAL_PGDIR_SIZE * 4);
kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end);
- bootmem_init();
+ pages_avail = 0;
+ last_valid_pfn = bootmem_init(&pages_avail);
end_pfn = last_valid_pfn;
/* This does not logically belong here, but we need to
@@ -2488,10 +2491,25 @@ void __init sun4c_paging_init(void)
sparc_context_init(num_contexts);
{
- unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0};
+ unsigned long zones_size[MAX_NR_ZONES];
+ unsigned long zholes_size[MAX_NR_ZONES];
+ unsigned long npages;
+ int znum;
- zones_size[ZONE_DMA] = end_pfn;
- free_area_init(zones_size);
+ for (znum = 0; znum < MAX_NR_ZONES; znum++)
+ zones_size[znum] = zholes_size[znum] = 0;
+
+ npages = max_low_pfn - (phys_base >> PAGE_SHIFT);
+
+ zones_size[ZONE_DMA] = npages;
+ zholes_size[ZONE_DMA] = npages - pages_avail;
+
+ npages = highend_pfn - max_low_pfn;
+ zones_size[ZONE_HIGHMEM] = npages;
+ zholes_size[ZONE_HIGHMEM] = npages - calc_highpages();
+
+ free_area_init_node(0, NULL, NULL, zones_size,
+ phys_base, zholes_size);
}
cnt = 0;