blob: cc7fe660f33d0c322ffc52dddfe0a4aecdadee4f [file] [log] [blame]
Pekka Enberg540aca02009-03-04 11:46:40 +02001#include <linux/ioport.h>
Pekka Enberge5b2bb52009-03-03 13:15:06 +02002#include <linux/swap.h>
Pekka Enberg540aca02009-03-04 11:46:40 +02003
Pekka Enberge5b2bb52009-03-03 13:15:06 +02004#include <asm/cacheflush.h>
5#include <asm/page.h>
Pekka Enberg540aca02009-03-04 11:46:40 +02006#include <asm/page_types.h>
Pekka Enberge5b2bb52009-03-03 13:15:06 +02007#include <asm/sections.h>
8#include <asm/system.h>
9
Pekka Enberg540aca02009-03-04 11:46:40 +020010/*
11 * devmem_is_allowed() checks to see if /dev/mem access to a certain address
12 * is valid. The argument is a physical page number.
13 *
14 *
15 * On x86, access has to be given to the first megabyte of ram because that area
16 * contains bios code and data regions used by X and dosemu and similar apps.
17 * Access has to be given to non-kernel-ram areas as well, these contain the PCI
18 * mmio resources as well as potential bios/acpi data regions.
19 */
20int devmem_is_allowed(unsigned long pagenr)
21{
22 if (pagenr <= 256)
23 return 1;
24 if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
25 return 0;
26 if (!page_is_ram(pagenr))
27 return 1;
28 return 0;
29}
30
Pekka Enberge5b2bb52009-03-03 13:15:06 +020031void free_init_pages(char *what, unsigned long begin, unsigned long end)
32{
33 unsigned long addr = begin;
34
35 if (addr >= end)
36 return;
37
38 /*
39 * If debugging page accesses then do not free this memory but
40 * mark them not present - any buggy init-section access will
41 * create a kernel page fault:
42 */
43#ifdef CONFIG_DEBUG_PAGEALLOC
44 printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
45 begin, PAGE_ALIGN(end));
46 set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
47#else
48 /*
49 * We just marked the kernel text read only above, now that
50 * we are going to free part of that, we need to make that
51 * writeable first.
52 */
53 set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
54
55 printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
56
57 for (; addr < end; addr += PAGE_SIZE) {
58 ClearPageReserved(virt_to_page(addr));
59 init_page_count(virt_to_page(addr));
60 memset((void *)(addr & ~(PAGE_SIZE-1)),
61 POISON_FREE_INITMEM, PAGE_SIZE);
62 free_page(addr);
63 totalram_pages++;
64 }
65#endif
66}
67
68void free_initmem(void)
69{
70 free_init_pages("unused kernel memory",
71 (unsigned long)(&__init_begin),
72 (unsigned long)(&__init_end));
73}
Pekka Enberg731ddea2009-03-04 11:13:40 +020074
75#ifdef CONFIG_BLK_DEV_INITRD
76void free_initrd_mem(unsigned long start, unsigned long end)
77{
78 free_init_pages("initrd memory", start, end);
79}
80#endif