aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/ioremap.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-28 11:26:12 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-28 11:26:12 -0400
commit7a9787e1eba95a166265e6a260cf30af04ef0a99 (patch)
treee730a4565e0318140d2fbd2f0415d18a339d7336 /arch/x86/mm/ioremap.c
parent41b9eb264c8407655db57b60b4457fe1b2ec9977 (diff)
parent0173a3265b228da319ceb9c1ec6a5682fd1b2d92 (diff)
Merge commit 'v2.6.28-rc2' into x86/pci-ioapic-boot-irq-quirks
Diffstat (limited to 'arch/x86/mm/ioremap.c')
-rw-r--r--arch/x86/mm/ioremap.c213
1 files changed, 172 insertions, 41 deletions
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 24c1d3c30186..ae71e11eb3e5 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -24,18 +24,47 @@
24 24
25#ifdef CONFIG_X86_64 25#ifdef CONFIG_X86_64
26 26
27static inline int phys_addr_valid(unsigned long addr)
28{
29 return addr < (1UL << boot_cpu_data.x86_phys_bits);
30}
31
27unsigned long __phys_addr(unsigned long x) 32unsigned long __phys_addr(unsigned long x)
28{ 33{
29 if (x >= __START_KERNEL_map) 34 if (x >= __START_KERNEL_map) {
30 return x - __START_KERNEL_map + phys_base; 35 x -= __START_KERNEL_map;
31 return x - PAGE_OFFSET; 36 VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE);
37 x += phys_base;
38 } else {
39 VIRTUAL_BUG_ON(x < PAGE_OFFSET);
40 x -= PAGE_OFFSET;
41 VIRTUAL_BUG_ON(system_state == SYSTEM_BOOTING ? x > MAXMEM :
42 !phys_addr_valid(x));
43 }
44 return x;
32} 45}
33EXPORT_SYMBOL(__phys_addr); 46EXPORT_SYMBOL(__phys_addr);
34 47
35static inline int phys_addr_valid(unsigned long addr) 48bool __virt_addr_valid(unsigned long x)
36{ 49{
37 return addr < (1UL << boot_cpu_data.x86_phys_bits); 50 if (x >= __START_KERNEL_map) {
51 x -= __START_KERNEL_map;
52 if (x >= KERNEL_IMAGE_SIZE)
53 return false;
54 x += phys_base;
55 } else {
56 if (x < PAGE_OFFSET)
57 return false;
58 x -= PAGE_OFFSET;
59 if (system_state == SYSTEM_BOOTING ?
60 x > MAXMEM : !phys_addr_valid(x)) {
61 return false;
62 }
63 }
64
65 return pfn_valid(x >> PAGE_SHIFT);
38} 66}
67EXPORT_SYMBOL(__virt_addr_valid);
39 68
40#else 69#else
41 70
@@ -44,6 +73,28 @@ static inline int phys_addr_valid(unsigned long addr)
44 return 1; 73 return 1;
45} 74}
46 75
76#ifdef CONFIG_DEBUG_VIRTUAL
77unsigned long __phys_addr(unsigned long x)
78{
79 /* VMALLOC_* aren't constants; not available at the boot time */
80 VIRTUAL_BUG_ON(x < PAGE_OFFSET);
81 VIRTUAL_BUG_ON(system_state != SYSTEM_BOOTING &&
82 is_vmalloc_addr((void *) x));
83 return x - PAGE_OFFSET;
84}
85EXPORT_SYMBOL(__phys_addr);
86#endif
87
88bool __virt_addr_valid(unsigned long x)
89{
90 if (x < PAGE_OFFSET)
91 return false;
92 if (system_state != SYSTEM_BOOTING && is_vmalloc_addr((void *) x))
93 return false;
94 return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT);
95}
96EXPORT_SYMBOL(__virt_addr_valid);
97
47#endif 98#endif
48 99
49int page_is_ram(unsigned long pagenr) 100int page_is_ram(unsigned long pagenr)
@@ -83,6 +134,25 @@ int page_is_ram(unsigned long pagenr)
83 return 0; 134 return 0;
84} 135}
85 136
137int pagerange_is_ram(unsigned long start, unsigned long end)
138{
139 int ram_page = 0, not_rampage = 0;
140 unsigned long page_nr;
141
142 for (page_nr = (start >> PAGE_SHIFT); page_nr < (end >> PAGE_SHIFT);
143 ++page_nr) {
144 if (page_is_ram(page_nr))
145 ram_page = 1;
146 else
147 not_rampage = 1;
148
149 if (ram_page == not_rampage)
150 return -1;
151 }
152
153 return ram_page;
154}
155
86/* 156/*
87 * Fix up the linear direct mapping of the kernel to avoid cache attribute 157 * Fix up the linear direct mapping of the kernel to avoid cache attribute
88 * conflicts. 158 * conflicts.
@@ -150,6 +220,12 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
150 return (__force void __iomem *)phys_to_virt(phys_addr); 220 return (__force void __iomem *)phys_to_virt(phys_addr);
151 221
152 /* 222 /*
223 * Check if the request spans more than any BAR in the iomem resource
224 * tree.
225 */
226 WARN_ON(iomem_map_sanity_check(phys_addr, size));
227
228 /*
153 * Don't allow anybody to remap normal RAM that we're using.. 229 * Don't allow anybody to remap normal RAM that we're using..
154 */ 230 */
155 for (pfn = phys_addr >> PAGE_SHIFT; 231 for (pfn = phys_addr >> PAGE_SHIFT;
@@ -170,7 +246,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
170 phys_addr &= PAGE_MASK; 246 phys_addr &= PAGE_MASK;
171 size = PAGE_ALIGN(last_addr+1) - phys_addr; 247 size = PAGE_ALIGN(last_addr+1) - phys_addr;
172 248
173 retval = reserve_memtype(phys_addr, phys_addr + size, 249 retval = reserve_memtype(phys_addr, (u64)phys_addr + size,
174 prot_val, &new_prot_val); 250 prot_val, &new_prot_val);
175 if (retval) { 251 if (retval) {
176 pr_debug("Warning: reserve_memtype returned %d\n", retval); 252 pr_debug("Warning: reserve_memtype returned %d\n", retval);
@@ -204,16 +280,16 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
204 switch (prot_val) { 280 switch (prot_val) {
205 case _PAGE_CACHE_UC: 281 case _PAGE_CACHE_UC:
206 default: 282 default:
207 prot = PAGE_KERNEL_NOCACHE; 283 prot = PAGE_KERNEL_IO_NOCACHE;
208 break; 284 break;
209 case _PAGE_CACHE_UC_MINUS: 285 case _PAGE_CACHE_UC_MINUS:
210 prot = PAGE_KERNEL_UC_MINUS; 286 prot = PAGE_KERNEL_IO_UC_MINUS;
211 break; 287 break;
212 case _PAGE_CACHE_WC: 288 case _PAGE_CACHE_WC:
213 prot = PAGE_KERNEL_WC; 289 prot = PAGE_KERNEL_IO_WC;
214 break; 290 break;
215 case _PAGE_CACHE_WB: 291 case _PAGE_CACHE_WB:
216 prot = PAGE_KERNEL; 292 prot = PAGE_KERNEL_IO;
217 break; 293 break;
218 } 294 }
219 295
@@ -330,6 +406,14 @@ static void __iomem *ioremap_default(resource_size_t phys_addr,
330 return (void __iomem *)ret; 406 return (void __iomem *)ret;
331} 407}
332 408
409void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
410 unsigned long prot_val)
411{
412 return __ioremap_caller(phys_addr, size, (prot_val & _PAGE_CACHE_MASK),
413 __builtin_return_address(0));
414}
415EXPORT_SYMBOL(ioremap_prot);
416
333/** 417/**
334 * iounmap - Free a IO remapping 418 * iounmap - Free a IO remapping
335 * @addr: virtual address from ioremap_* 419 * @addr: virtual address from ioremap_*
@@ -413,7 +497,7 @@ void unxlate_dev_mem_ptr(unsigned long phys, void *addr)
413 return; 497 return;
414} 498}
415 499
416int __initdata early_ioremap_debug; 500static int __initdata early_ioremap_debug;
417 501
418static int __init early_ioremap_debug_setup(char *str) 502static int __init early_ioremap_debug_setup(char *str)
419{ 503{
@@ -522,12 +606,12 @@ static void __init __early_set_fixmap(enum fixed_addresses idx,
522} 606}
523 607
524static inline void __init early_set_fixmap(enum fixed_addresses idx, 608static inline void __init early_set_fixmap(enum fixed_addresses idx,
525 unsigned long phys) 609 unsigned long phys, pgprot_t prot)
526{ 610{
527 if (after_paging_init) 611 if (after_paging_init)
528 set_fixmap(idx, phys); 612 __set_fixmap(idx, phys, prot);
529 else 613 else
530 __early_set_fixmap(idx, phys, PAGE_KERNEL); 614 __early_set_fixmap(idx, phys, prot);
531} 615}
532 616
533static inline void __init early_clear_fixmap(enum fixed_addresses idx) 617static inline void __init early_clear_fixmap(enum fixed_addresses idx)
@@ -538,37 +622,56 @@ static inline void __init early_clear_fixmap(enum fixed_addresses idx)
538 __early_set_fixmap(idx, 0, __pgprot(0)); 622 __early_set_fixmap(idx, 0, __pgprot(0));
539} 623}
540 624
541 625static void *prev_map[FIX_BTMAPS_SLOTS] __initdata;
542int __initdata early_ioremap_nested; 626static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata;
543
544static int __init check_early_ioremap_leak(void) 627static int __init check_early_ioremap_leak(void)
545{ 628{
546 if (!early_ioremap_nested) 629 int count = 0;
547 return 0; 630 int i;
548 631
549 printk(KERN_WARNING 632 for (i = 0; i < FIX_BTMAPS_SLOTS; i++)
633 if (prev_map[i])
634 count++;
635
636 if (!count)
637 return 0;
638 WARN(1, KERN_WARNING
550 "Debug warning: early ioremap leak of %d areas detected.\n", 639 "Debug warning: early ioremap leak of %d areas detected.\n",
551 early_ioremap_nested); 640 count);
552 printk(KERN_WARNING 641 printk(KERN_WARNING
553 "please boot with early_ioremap_debug and report the dmesg.\n"); 642 "please boot with early_ioremap_debug and report the dmesg.\n");
554 WARN_ON(1);
555 643
556 return 1; 644 return 1;
557} 645}
558late_initcall(check_early_ioremap_leak); 646late_initcall(check_early_ioremap_leak);
559 647
560void __init *early_ioremap(unsigned long phys_addr, unsigned long size) 648static void __init *__early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot)
561{ 649{
562 unsigned long offset, last_addr; 650 unsigned long offset, last_addr;
563 unsigned int nrpages, nesting; 651 unsigned int nrpages;
564 enum fixed_addresses idx0, idx; 652 enum fixed_addresses idx0, idx;
653 int i, slot;
565 654
566 WARN_ON(system_state != SYSTEM_BOOTING); 655 WARN_ON(system_state != SYSTEM_BOOTING);
567 656
568 nesting = early_ioremap_nested; 657 slot = -1;
658 for (i = 0; i < FIX_BTMAPS_SLOTS; i++) {
659 if (!prev_map[i]) {
660 slot = i;
661 break;
662 }
663 }
664
665 if (slot < 0) {
666 printk(KERN_INFO "early_iomap(%08lx, %08lx) not found slot\n",
667 phys_addr, size);
668 WARN_ON(1);
669 return NULL;
670 }
671
569 if (early_ioremap_debug) { 672 if (early_ioremap_debug) {
570 printk(KERN_INFO "early_ioremap(%08lx, %08lx) [%d] => ", 673 printk(KERN_INFO "early_ioremap(%08lx, %08lx) [%d] => ",
571 phys_addr, size, nesting); 674 phys_addr, size, slot);
572 dump_stack(); 675 dump_stack();
573 } 676 }
574 677
@@ -579,17 +682,13 @@ void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
579 return NULL; 682 return NULL;
580 } 683 }
581 684
582 if (nesting >= FIX_BTMAPS_NESTING) { 685 prev_size[slot] = size;
583 WARN_ON(1);
584 return NULL;
585 }
586 early_ioremap_nested++;
587 /* 686 /*
588 * Mappings have to be page-aligned 687 * Mappings have to be page-aligned
589 */ 688 */
590 offset = phys_addr & ~PAGE_MASK; 689 offset = phys_addr & ~PAGE_MASK;
591 phys_addr &= PAGE_MASK; 690 phys_addr &= PAGE_MASK;
592 size = PAGE_ALIGN(last_addr) - phys_addr; 691 size = PAGE_ALIGN(last_addr + 1) - phys_addr;
593 692
594 /* 693 /*
595 * Mappings have to fit in the FIX_BTMAP area. 694 * Mappings have to fit in the FIX_BTMAP area.
@@ -603,10 +702,10 @@ void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
603 /* 702 /*
604 * Ok, go for it.. 703 * Ok, go for it..
605 */ 704 */
606 idx0 = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*nesting; 705 idx0 = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot;
607 idx = idx0; 706 idx = idx0;
608 while (nrpages > 0) { 707 while (nrpages > 0) {
609 early_set_fixmap(idx, phys_addr); 708 early_set_fixmap(idx, phys_addr, prot);
610 phys_addr += PAGE_SIZE; 709 phys_addr += PAGE_SIZE;
611 --idx; 710 --idx;
612 --nrpages; 711 --nrpages;
@@ -614,7 +713,20 @@ void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
614 if (early_ioremap_debug) 713 if (early_ioremap_debug)
615 printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0)); 714 printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0));
616 715
617 return (void *) (offset + fix_to_virt(idx0)); 716 prev_map[slot] = (void *) (offset + fix_to_virt(idx0));
717 return prev_map[slot];
718}
719
720/* Remap an IO device */
721void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
722{
723 return __early_ioremap(phys_addr, size, PAGE_KERNEL_IO);
724}
725
726/* Remap memory */
727void __init *early_memremap(unsigned long phys_addr, unsigned long size)
728{
729 return __early_ioremap(phys_addr, size, PAGE_KERNEL);
618} 730}
619 731
620void __init early_iounmap(void *addr, unsigned long size) 732void __init early_iounmap(void *addr, unsigned long size)
@@ -623,15 +735,33 @@ void __init early_iounmap(void *addr, unsigned long size)
623 unsigned long offset; 735 unsigned long offset;
624 unsigned int nrpages; 736 unsigned int nrpages;
625 enum fixed_addresses idx; 737 enum fixed_addresses idx;
626 int nesting; 738 int i, slot;
739
740 slot = -1;
741 for (i = 0; i < FIX_BTMAPS_SLOTS; i++) {
742 if (prev_map[i] == addr) {
743 slot = i;
744 break;
745 }
746 }
627 747
628 nesting = --early_ioremap_nested; 748 if (slot < 0) {
629 if (WARN_ON(nesting < 0)) 749 printk(KERN_INFO "early_iounmap(%p, %08lx) not found slot\n",
750 addr, size);
751 WARN_ON(1);
630 return; 752 return;
753 }
754
755 if (prev_size[slot] != size) {
756 printk(KERN_INFO "early_iounmap(%p, %08lx) [%d] size not consistent %08lx\n",
757 addr, size, slot, prev_size[slot]);
758 WARN_ON(1);
759 return;
760 }
631 761
632 if (early_ioremap_debug) { 762 if (early_ioremap_debug) {
633 printk(KERN_INFO "early_iounmap(%p, %08lx) [%d]\n", addr, 763 printk(KERN_INFO "early_iounmap(%p, %08lx) [%d]\n", addr,
634 size, nesting); 764 size, slot);
635 dump_stack(); 765 dump_stack();
636 } 766 }
637 767
@@ -643,12 +773,13 @@ void __init early_iounmap(void *addr, unsigned long size)
643 offset = virt_addr & ~PAGE_MASK; 773 offset = virt_addr & ~PAGE_MASK;
644 nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT; 774 nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT;
645 775
646 idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*nesting; 776 idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot;
647 while (nrpages > 0) { 777 while (nrpages > 0) {
648 early_clear_fixmap(idx); 778 early_clear_fixmap(idx);
649 --idx; 779 --idx;
650 --nrpages; 780 --nrpages;
651 } 781 }
782 prev_map[slot] = 0;
652} 783}
653 784
654void __this_fixmap_does_not_exist(void) 785void __this_fixmap_does_not_exist(void)