X-Git-Url: http://ftp.safe.ca/?p=safe%2Fjmp%2Flinux-2.6;a=blobdiff_plain;f=arch%2Fparisc%2Fmm%2Finit.c;h=f4f4d700833affc00d9953871b441eae12227831;hp=25ad28d63e88398c057ddf259f262f49ea09a01f;hb=5a0e3ad6af8660be21ca98a971cd00f331318c05;hpb=89fa30242facca249aead2aac03c4c69764f911c diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 25ad28d..f4f4d70 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -6,7 +6,7 @@ * changed by Philipp Rumpf * Copyright 1999 Philipp Rumpf (prumpf@tux.org) * Copyright 2004 Randolph Chung (tausq@debian.org) - * Copyright 2006 Helge Deller (deller@gmx.de) + * Copyright 2006-2007 Helge Deller (deller@gmx.de) * */ @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include /* for hppa_dma_ops and pcxl_dma_ops */ @@ -24,6 +25,7 @@ #include /* for release_pages and page_cache_release */ #include +#include #include #include #include @@ -31,14 +33,10 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); -extern char _text; /* start of kernel code, defined by linker */ extern int data_start; -extern char _end; /* end of BSS, defined by linker */ -extern char __init_begin, __init_end; #ifdef CONFIG_DISCONTIGMEM struct node_map_data node_data[MAX_NUMNODES] __read_mostly; -bootmem_data_t bmem_data[MAX_NUMNODES] __read_mostly; unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly; #endif @@ -68,11 +66,11 @@ static struct resource sysram_resources[MAX_PHYSMEM_RANGES] __read_mostly; physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly; int npmem_ranges __read_mostly; -#ifdef __LP64__ +#ifdef CONFIG_64BIT #define MAX_MEM (~0UL) -#else /* !__LP64__ */ +#else /* !CONFIG_64BIT */ #define MAX_MEM (3584U*1024U*1024U) -#endif /* !__LP64__ */ +#endif /* !CONFIG_64BIT */ static unsigned long mem_limit __read_mostly = MAX_MEM; @@ -80,12 +78,11 @@ static void __init mem_limit_func(void) { char *cp, *end; unsigned long limit; - extern char saved_command_line[]; /* We need this before __setup() functions are called */ limit = MAX_MEM; - for (cp = saved_command_line; *cp; ) { + for (cp = boot_command_line; *cp; ) { if (memcmp(cp, "mem=", 4) == 0) { cp += 4; limit = memparse(cp, &end); @@ -265,7 +262,7 @@ static void __init setup_bootmem(void) #ifdef CONFIG_DISCONTIGMEM for (i = 0; i < MAX_PHYSMEM_RANGES; i++) { memset(NODE_DATA(i), 0, sizeof(pg_data_t)); - NODE_DATA(i)->bdata = &bmem_data[i]; + NODE_DATA(i)->bdata = &bootmem_node_data[i]; } memset(pfnnid_map, 0xff, sizeof(pfnnid_map)); @@ -308,21 +305,21 @@ static void __init setup_bootmem(void) */ max_low_pfn = max_pfn; - if ((bootmap_pfn - bootmap_start_pfn) != bootmap_pages) { - printk(KERN_WARNING "WARNING! bootmap sizing is messed up!\n"); - BUG(); - } + /* bootmap sizing messed up? */ + BUG_ON((bootmap_pfn - bootmap_start_pfn) != bootmap_pages); /* reserve PAGE0 pdc memory, kernel text/data/bss & bootmap */ #define PDC_CONSOLE_IO_IODC_SIZE 32768 reserve_bootmem_node(NODE_DATA(0), 0UL, - (unsigned long)(PAGE0->mem_free + PDC_CONSOLE_IO_IODC_SIZE)); - reserve_bootmem_node(NODE_DATA(0),__pa((unsigned long)&_text), - (unsigned long)(&_end - &_text)); + (unsigned long)(PAGE0->mem_free + + PDC_CONSOLE_IO_IODC_SIZE), BOOTMEM_DEFAULT); + reserve_bootmem_node(NODE_DATA(0), __pa((unsigned long)_text), + (unsigned long)(_end - _text), BOOTMEM_DEFAULT); reserve_bootmem_node(NODE_DATA(0), (bootmap_start_pfn << PAGE_SHIFT), - ((bootmap_pfn - bootmap_start_pfn) << PAGE_SHIFT)); + ((bootmap_pfn - bootmap_start_pfn) << PAGE_SHIFT), + BOOTMEM_DEFAULT); #ifndef CONFIG_DISCONTIGMEM @@ -331,7 +328,8 @@ static void __init setup_bootmem(void) for (i = 0; i < npmem_holes; i++) { reserve_bootmem_node(NODE_DATA(0), (pmem_holes[i].start_pfn << PAGE_SHIFT), - (pmem_holes[i].pages << PAGE_SHIFT)); + (pmem_holes[i].pages << PAGE_SHIFT), + BOOTMEM_DEFAULT); } #endif @@ -349,14 +347,15 @@ static void __init setup_bootmem(void) initrd_below_start_ok = 1; printk(KERN_INFO "initrd: reserving %08lx-%08lx (mem_max %08lx)\n", __pa(initrd_start), __pa(initrd_start) + initrd_reserve, mem_max); - reserve_bootmem_node(NODE_DATA(0),__pa(initrd_start), initrd_reserve); + reserve_bootmem_node(NODE_DATA(0), __pa(initrd_start), + initrd_reserve, BOOTMEM_DEFAULT); } } #endif data_resource.start = virt_to_phys(&data_start); - data_resource.end = virt_to_phys(&_end)-1; - code_resource.start = virt_to_phys(&_text); + data_resource.end = virt_to_phys(_end) - 1; + code_resource.start = virt_to_phys(_text); code_resource.end = virt_to_phys(&data_start)-1; /* We don't know which region the kernel will be in, so try @@ -372,34 +371,22 @@ static void __init setup_bootmem(void) void free_initmem(void) { - unsigned long addr, init_begin, init_end; - - printk(KERN_INFO "Freeing unused kernel memory: "); + unsigned long addr; + unsigned long init_begin = (unsigned long)__init_begin; + unsigned long init_end = (unsigned long)__init_end; #ifdef CONFIG_DEBUG_KERNEL /* Attempt to catch anyone trying to execute code here * by filling the page with BRK insns. - * - * If we disable interrupts for all CPUs, then IPI stops working. - * Kinda breaks the global cache flushing. */ - local_irq_disable(); - - memset(&__init_begin, 0x00, - (unsigned long)&__init_end - (unsigned long)&__init_begin); - - flush_data_cache(); - asm volatile("sync" : : ); - flush_icache_range((unsigned long)&__init_begin, (unsigned long)&__init_end); - asm volatile("sync" : : ); - - local_irq_enable(); + memset((void *)init_begin, 0x00, init_end - init_begin); + flush_icache_range(init_begin, init_end); #endif /* align __init_begin and __init_end to page size, ignoring linker script where we might have tried to save RAM */ - init_begin = PAGE_ALIGN((unsigned long)(&__init_begin)); - init_end = PAGE_ALIGN((unsigned long)(&__init_end)); + init_begin = PAGE_ALIGN(init_begin); + init_end = PAGE_ALIGN(init_end); for (addr = init_begin; addr < init_end; addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); @@ -411,7 +398,8 @@ void free_initmem(void) /* set up a new led state on systems shipped LED State panel */ pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE); - printk("%luk freed\n", (init_end - init_begin) >> 10); + printk(KERN_INFO "Freeing unused kernel memory: %luk freed\n", + (init_end - init_begin) >> 10); } @@ -447,8 +435,8 @@ void mark_rodata_ro(void) #define SET_MAP_OFFSET(x) ((void *)(((unsigned long)(x) + VM_MAP_OFFSET) \ & ~(VM_MAP_OFFSET-1))) -void *vmalloc_start __read_mostly; -EXPORT_SYMBOL(vmalloc_start); +void *parisc_vmalloc_start __read_mostly; +EXPORT_SYMBOL(parisc_vmalloc_start); #ifdef CONFIG_PA11 unsigned long pcxl_dma_start __read_mostly; @@ -456,6 +444,15 @@ unsigned long pcxl_dma_start __read_mostly; void __init mem_init(void) { + int codesize, reservedpages, datasize, initsize; + + /* Do sanity checks on page table constants */ + BUILD_BUG_ON(PTE_ENTRY_SIZE != sizeof(pte_t)); + BUILD_BUG_ON(PMD_ENTRY_SIZE != sizeof(pmd_t)); + BUILD_BUG_ON(PGD_ENTRY_SIZE != sizeof(pgd_t)); + BUILD_BUG_ON(PAGE_SHIFT + BITS_PER_PTE + BITS_PER_PMD + BITS_PER_PGD + > BITS_PER_LONG); + high_memory = __va((max_pfn << PAGE_SHIFT)); #ifndef CONFIG_DISCONTIGMEM @@ -470,23 +467,82 @@ void __init mem_init(void) } #endif - printk(KERN_INFO "Memory: %luk available\n", num_physpages << (PAGE_SHIFT-10)); + codesize = (unsigned long)_etext - (unsigned long)_text; + datasize = (unsigned long)_edata - (unsigned long)_etext; + initsize = (unsigned long)__init_end - (unsigned long)__init_begin; + + reservedpages = 0; +{ + unsigned long pfn; +#ifdef CONFIG_DISCONTIGMEM + int i; + + for (i = 0; i < npmem_ranges; i++) { + for (pfn = node_start_pfn(i); pfn < node_end_pfn(i); pfn++) { + if (PageReserved(pfn_to_page(pfn))) + reservedpages++; + } + } +#else /* !CONFIG_DISCONTIGMEM */ + for (pfn = 0; pfn < max_pfn; pfn++) { + /* + * Only count reserved RAM pages + */ + if (PageReserved(pfn_to_page(pfn))) + reservedpages++; + } +#endif +} #ifdef CONFIG_PA11 if (hppa_dma_ops == &pcxl_dma_ops) { pcxl_dma_start = (unsigned long)SET_MAP_OFFSET(MAP_START); - vmalloc_start = SET_MAP_OFFSET(pcxl_dma_start + PCXL_DMA_MAP_SIZE); + parisc_vmalloc_start = SET_MAP_OFFSET(pcxl_dma_start + + PCXL_DMA_MAP_SIZE); } else { pcxl_dma_start = 0; - vmalloc_start = SET_MAP_OFFSET(MAP_START); + parisc_vmalloc_start = SET_MAP_OFFSET(MAP_START); } #else - vmalloc_start = SET_MAP_OFFSET(MAP_START); + parisc_vmalloc_start = SET_MAP_OFFSET(MAP_START); #endif + printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n", + nr_free_pages() << (PAGE_SHIFT-10), + num_physpages << (PAGE_SHIFT-10), + codesize >> 10, + reservedpages << (PAGE_SHIFT-10), + datasize >> 10, + initsize >> 10 + ); + +#ifdef CONFIG_DEBUG_KERNEL /* double-sanity-check paranoia */ + printk("virtual kernel memory layout:\n" + " vmalloc : 0x%p - 0x%p (%4ld MB)\n" + " memory : 0x%p - 0x%p (%4ld MB)\n" + " .init : 0x%p - 0x%p (%4ld kB)\n" + " .data : 0x%p - 0x%p (%4ld kB)\n" + " .text : 0x%p - 0x%p (%4ld kB)\n", + + (void*)VMALLOC_START, (void*)VMALLOC_END, + (VMALLOC_END - VMALLOC_START) >> 20, + + __va(0), high_memory, + ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20, + + __init_begin, __init_end, + ((unsigned long)__init_end - (unsigned long)__init_begin) >> 10, + + _etext, _edata, + ((unsigned long)_edata - (unsigned long)_etext) >> 10, + + _text, _etext, + ((unsigned long)_etext - (unsigned long)_text) >> 10); +#endif } unsigned long *empty_zero_page __read_mostly; +EXPORT_SYMBOL(empty_zero_page); void show_mem(void) { @@ -495,8 +551,6 @@ void show_mem(void) printk(KERN_INFO "Mem-info:\n"); show_free_areas(); - printk(KERN_INFO "Free swap: %6ldkB\n", - nr_swap_pages<<(PAGE_SHIFT-10)); #ifndef CONFIG_DISCONTIGMEM i = max_mapnr; while (i-- > 0) { @@ -543,15 +597,18 @@ void show_mem(void) #ifdef CONFIG_DISCONTIGMEM { struct zonelist *zl; - int i, j, k; + int i, j; for (i = 0; i < npmem_ranges; i++) { + zl = node_zonelist(i, 0); for (j = 0; j < MAX_NR_ZONES; j++) { - zl = NODE_DATA(i)->node_zonelists + j; + struct zoneref *z; + struct zone *zone; printk("Zone list for zone %d on node %d: ", j, i); - for (k = 0; zl->zones[k] != NULL; k++) - printk("[%d/%s] ", zone_to_nid(zl->zones[k]), zl->zones[k]->name); + for_each_zone_zonelist(zone, z, zl, j) + printk("[%d/%s] ", zone_to_nid(zone), + zone->name); printk("\n"); } } @@ -578,7 +635,7 @@ static void __init map_pages(unsigned long start_vaddr, unsigned long start_padd extern const unsigned long fault_vector_20; extern void * const linux_gateway_page; - ro_start = __pa((unsigned long)&_text); + ro_start = __pa((unsigned long)_text); ro_end = __pa((unsigned long)&data_start); fv_addr = __pa((unsigned long)&fault_vector_20) & PAGE_MASK; gw_addr = __pa((unsigned long)&linux_gateway_page) & PAGE_MASK; @@ -811,9 +868,7 @@ void __init paging_init(void) for (i = 0; i < npmem_ranges; i++) { unsigned long zones_size[MAX_NR_ZONES] = { 0, }; - /* We have an IOMMU, so all memory can go into a single - ZONE_DMA zone. */ - zones_size[ZONE_DMA] = pmem_ranges[i].pages; + zones_size[ZONE_NORMAL] = pmem_ranges[i].pages; #ifdef CONFIG_DISCONTIGMEM /* Need to initialize the pfnnid_map before we can initialize @@ -828,7 +883,7 @@ void __init paging_init(void) } #endif - free_area_init_node(i, NODE_DATA(i), zones_size, + free_area_init_node(i, zones_size, pmem_ranges[i].start_pfn, NULL); } } @@ -836,7 +891,7 @@ void __init paging_init(void) #ifdef CONFIG_PA20 /* - * Currently, all PA20 chips have 18 bit protection id's, which is the + * Currently, all PA20 chips have 18 bit protection IDs, which is the * limiting factor (space ids are 32 bits). */ @@ -845,10 +900,10 @@ void __init paging_init(void) #else /* - * Currently we have a one-to-one relationship between space id's and - * protection id's. Older parisc chips (PCXS, PCXT, PCXL, PCXL2) only - * support 15 bit protection id's, so that is the limiting factor. - * PCXT' has 18 bit protection id's, but only 16 bit spaceids, so it's + * Currently we have a one-to-one relationship between space IDs and + * protection IDs. Older parisc chips (PCXS, PCXT, PCXL, PCXL2) only + * support 15 bit protection IDs, so that is the limiting factor. + * PCXT' has 18 bit protection IDs, but only 16 bit spaceids, so it's * probably not worth the effort for a special case here. */ @@ -993,7 +1048,7 @@ void flush_tlb_all(void) do_recycle++; } spin_unlock(&sid_lock); - on_each_cpu(flush_tlb_all_local, NULL, 1, 1); + on_each_cpu(flush_tlb_all_local, NULL, 1); if (do_recycle) { spin_lock(&sid_lock); recycle_sids(recycle_ndirty,recycle_dirty_array);