166d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer/*
266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer *  linux/arch/m68k/mm/init.c
366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer *
466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer *  Copyright (C) 1995  Hamish Macdonald
566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer *
666d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer *  Contains common initialization routines, specific init code moved
766d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer *  to motorola.c and sun3mmu.c
866d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer */
966d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
1066d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <linux/module.h>
1166d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <linux/signal.h>
1266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <linux/sched.h>
1366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <linux/mm.h>
1466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <linux/swap.h>
1566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <linux/kernel.h>
1666d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <linux/string.h>
1766d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <linux/types.h>
1866d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <linux/init.h>
1966d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <linux/bootmem.h>
2066d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <linux/gfp.h>
2166d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
2266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <asm/setup.h>
2366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <asm/uaccess.h>
2466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <asm/page.h>
2566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <asm/pgalloc.h>
26e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer#include <asm/traps.h>
2766d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <asm/machdep.h>
2866d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <asm/io.h>
2966d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#ifdef CONFIG_ATARI
3066d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <asm/atari_stram.h>
3166d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#endif
3266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <asm/sections.h>
3366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#include <asm/tlb.h>
3466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
3566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungererpg_data_t pg_data_map[MAX_NUMNODES];
3666d857b08b8c3ed5c72c361f863cce77d2a978d7Greg UngererEXPORT_SYMBOL(pg_data_map);
3766d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
3866d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungererint m68k_virt_to_node_shift;
3966d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
4066d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#ifndef CONFIG_SINGLE_MEMORY_CHUNK
4166d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungererpg_data_t *pg_data_table[65];
4266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg UngererEXPORT_SYMBOL(pg_data_table);
4366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#endif
4466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
4566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerervoid __init m68k_setup_node(int node)
4666d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer{
4766d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#ifndef CONFIG_SINGLE_MEMORY_CHUNK
4866d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	struct mem_info *info = m68k_memory + node;
4966d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	int i, end;
5066d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
5166d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	i = (unsigned long)phys_to_virt(info->addr) >> __virt_to_node_shift();
5266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	end = (unsigned long)phys_to_virt(info->addr + info->size - 1) >> __virt_to_node_shift();
5366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	for (; i <= end; i++) {
5466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer		if (pg_data_table[i])
5566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer			printk("overlap at %u for chunk %u\n", i, node);
5666d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer		pg_data_table[i] = pg_data_map + node;
5766d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	}
5866d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#endif
5966d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	pg_data_map[node].bdata = bootmem_node_data + node;
6066d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	node_set_online(node);
6166d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer}
6266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
6366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
6466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer/*
6566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer * ZERO_PAGE is a special page that is used for zero-initialized
6666d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer * data and COW.
6766d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer */
6866d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
6966d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerervoid *empty_zero_page;
7066d857b08b8c3ed5c72c361f863cce77d2a978d7Greg UngererEXPORT_SYMBOL(empty_zero_page);
7166d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
7266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungererextern void init_pointer_table(unsigned long ptable);
7366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
7466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer/* References to section boundaries */
7566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
7666d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungererextern pmd_t *zero_pgtable;
7766d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
78e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE)
79e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer#define VECTORS	&vectors[0]
80e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer#else
81e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer#define VECTORS	_ramvec
82e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer#endif
83e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer
84e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerervoid __init print_memmap(void)
85e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer{
86e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer#define UL(x) ((unsigned long) (x))
87e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer#define MLK(b, t) UL(b), UL(t), (UL(t) - UL(b)) >> 10
88e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer#define MLM(b, t) UL(b), UL(t), (UL(t) - UL(b)) >> 20
89e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), 1024)
90e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer
91e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer	pr_notice("Virtual kernel memory layout:\n"
92e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		"    vector  : 0x%08lx - 0x%08lx   (%4ld KiB)\n"
93e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		"    kmap    : 0x%08lx - 0x%08lx   (%4ld MiB)\n"
94e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		"    vmalloc : 0x%08lx - 0x%08lx   (%4ld MiB)\n"
95e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		"    lowmem  : 0x%08lx - 0x%08lx   (%4ld MiB)\n"
96e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		"      .init : 0x%p" " - 0x%p" "   (%4d KiB)\n"
97e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		"      .text : 0x%p" " - 0x%p" "   (%4d KiB)\n"
98e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		"      .data : 0x%p" " - 0x%p" "   (%4d KiB)\n"
99e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		"      .bss  : 0x%p" " - 0x%p" "   (%4d KiB)\n",
100e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		MLK(VECTORS, VECTORS + 256),
101e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		MLM(KMAP_START, KMAP_END),
102e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		MLM(VMALLOC_START, VMALLOC_END),
103e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		MLM(PAGE_OFFSET, (unsigned long)high_memory),
104e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		MLK_ROUNDUP(__init_begin, __init_end),
105e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		MLK_ROUNDUP(_stext, _etext),
106e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		MLK_ROUNDUP(_sdata, _edata),
107e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer		MLK_ROUNDUP(_sbss, _ebss));
108e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer}
109e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer
11066d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerervoid __init mem_init(void)
11166d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer{
11266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	pg_data_t *pgdat;
11366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	int codepages = 0;
11466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	int datapages = 0;
11566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	int initpages = 0;
11666d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	int i;
11766d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
11866d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	/* this will put all memory onto the freelists */
11966d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	totalram_pages = num_physpages = 0;
12066d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	for_each_online_pgdat(pgdat) {
12166d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer		num_physpages += pgdat->node_present_pages;
12266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
12366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer		totalram_pages += free_all_bootmem_node(pgdat);
12466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer		for (i = 0; i < pgdat->node_spanned_pages; i++) {
12566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer			struct page *page = pgdat->node_mem_map + i;
12666d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer			char *addr = page_to_virt(page);
12766d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
12866d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer			if (!PageReserved(page))
12966d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer				continue;
13066d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer			if (addr >= _text &&
13166d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer			    addr < _etext)
13266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer				codepages++;
13366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer			else if (addr >= __init_begin &&
13466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer				 addr < __init_end)
13566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer				initpages++;
13666d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer			else
13766d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer				datapages++;
13866d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer		}
13966d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	}
14066d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
141fbe3364ac4fa82caa585f98e4a525946d2cc21f4Greg Ungerer#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
14266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	/* insert pointer tables allocated so far into the tablelist */
14366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	init_pointer_table((unsigned long)kernel_pg_dir);
14466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	for (i = 0; i < PTRS_PER_PGD; i++) {
14566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer		if (pgd_present(kernel_pg_dir[i]))
14666d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer			init_pointer_table(__pgd_page(kernel_pg_dir[i]));
14766d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	}
14866d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
14966d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	/* insert also pointer table that we used to unmap the zero page */
15066d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	if (zero_pgtable)
15166d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer		init_pointer_table((unsigned long)zero_pgtable);
15266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#endif
15366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
15466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n",
15566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	       nr_free_pages() << (PAGE_SHIFT-10),
15666d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	       totalram_pages << (PAGE_SHIFT-10),
15766d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	       codepages << (PAGE_SHIFT-10),
15866d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	       datapages << (PAGE_SHIFT-10),
15966d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	       initpages << (PAGE_SHIFT-10));
160e87c09a899d38d1b6858e010c22a1200fb77965dGreg Ungerer	print_memmap();
16166d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer}
16266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer
16366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#ifdef CONFIG_BLK_DEV_INITRD
16466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerervoid free_initrd_mem(unsigned long start, unsigned long end)
16566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer{
16666d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	int pages = 0;
16766d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	for (; start < end; start += PAGE_SIZE) {
16866d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer		ClearPageReserved(virt_to_page(start));
16966d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer		init_page_count(virt_to_page(start));
17066d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer		free_page(start);
17166d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer		totalram_pages++;
17266d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer		pages++;
17366d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	}
17466d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer	printk ("Freeing initrd memory: %dk freed\n", pages);
17566d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer}
17666d857b08b8c3ed5c72c361f863cce77d2a978d7Greg Ungerer#endif
177