diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-10-13 09:43:54 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-10-13 09:43:54 -0400 |
commit | b160292cc216a50fd0cd386b0bda2cd48352c73b (patch) | |
tree | ef07cf98f91353ee4c9ec1e1ca7a2a5d9d4b538a /arch/mips/mm | |
parent | b37bde147890c8fea8369a5a4e230dabdea4ebfb (diff) | |
parent | bbf25010f1a6b761914430f5fca081ec8c7accd1 (diff) |
Merge Linux 2.6.23
Diffstat (limited to 'arch/mips/mm')
-rw-r--r-- | arch/mips/mm/dma-default.c | 2 | ||||
-rw-r--r-- | arch/mips/mm/init.c | 14 | ||||
-rw-r--r-- | arch/mips/mm/pg-r4k.c | 2 | ||||
-rw-r--r-- | arch/mips/mm/tlbex.c | 30 |
4 files changed, 41 insertions, 7 deletions
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 76903c727647..f60b3dc0fc62 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
@@ -35,7 +35,7 @@ static inline unsigned long dma_addr_to_virt(dma_addr_t dma_addr) | |||
35 | static inline int cpu_is_noncoherent_r10000(struct device *dev) | 35 | static inline int cpu_is_noncoherent_r10000(struct device *dev) |
36 | { | 36 | { |
37 | return !plat_device_is_coherent(dev) && | 37 | return !plat_device_is_coherent(dev) && |
38 | (current_cpu_data.cputype == CPU_R10000 && | 38 | (current_cpu_data.cputype == CPU_R10000 || |
39 | current_cpu_data.cputype == CPU_R12000); | 39 | current_cpu_data.cputype == CPU_R12000); |
40 | } | 40 | } |
41 | 41 | ||
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index b8cb0dde3af0..5240432e6d1d 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com | 8 | * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com |
9 | * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. | 9 | * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. |
10 | */ | 10 | */ |
11 | #include <linux/bug.h> | ||
11 | #include <linux/init.h> | 12 | #include <linux/init.h> |
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
13 | #include <linux/signal.h> | 14 | #include <linux/signal.h> |
@@ -26,6 +27,7 @@ | |||
26 | #include <linux/proc_fs.h> | 27 | #include <linux/proc_fs.h> |
27 | #include <linux/pfn.h> | 28 | #include <linux/pfn.h> |
28 | 29 | ||
30 | #include <asm/asm-offsets.h> | ||
29 | #include <asm/bootinfo.h> | 31 | #include <asm/bootinfo.h> |
30 | #include <asm/cachectl.h> | 32 | #include <asm/cachectl.h> |
31 | #include <asm/cpu.h> | 33 | #include <asm/cpu.h> |
@@ -131,6 +133,8 @@ void *kmap_coherent(struct page *page, unsigned long addr) | |||
131 | pte_t pte; | 133 | pte_t pte; |
132 | int tlbidx; | 134 | int tlbidx; |
133 | 135 | ||
136 | BUG_ON(Page_dcache_dirty(page)); | ||
137 | |||
134 | inc_preempt_count(); | 138 | inc_preempt_count(); |
135 | idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); | 139 | idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); |
136 | #ifdef CONFIG_MIPS_MT_SMTC | 140 | #ifdef CONFIG_MIPS_MT_SMTC |
@@ -207,7 +211,7 @@ void copy_user_highpage(struct page *to, struct page *from, | |||
207 | void *vfrom, *vto; | 211 | void *vfrom, *vto; |
208 | 212 | ||
209 | vto = kmap_atomic(to, KM_USER1); | 213 | vto = kmap_atomic(to, KM_USER1); |
210 | if (cpu_has_dc_aliases) { | 214 | if (cpu_has_dc_aliases && !Page_dcache_dirty(from)) { |
211 | vfrom = kmap_coherent(from, vaddr); | 215 | vfrom = kmap_coherent(from, vaddr); |
212 | copy_page(vto, vfrom); | 216 | copy_page(vto, vfrom); |
213 | kunmap_coherent(); | 217 | kunmap_coherent(); |
@@ -498,7 +502,13 @@ unsigned long pgd_current[NR_CPUS]; | |||
498 | * different layout ... | 502 | * different layout ... |
499 | */ | 503 | */ |
500 | #define __page_aligned(order) __attribute__((__aligned__(PAGE_SIZE<<order))) | 504 | #define __page_aligned(order) __attribute__((__aligned__(PAGE_SIZE<<order))) |
501 | pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned(PGD_ORDER); | 505 | |
506 | /* | ||
507 | * gcc 3.3 and older have trouble determining that PTRS_PER_PGD and PGD_ORDER | ||
508 | * are constants. So we use the variants from asm-offset.h until that gcc | ||
509 | * will officially be retired. | ||
510 | */ | ||
511 | pgd_t swapper_pg_dir[_PTRS_PER_PGD] __page_aligned(_PGD_ORDER); | ||
502 | #ifdef CONFIG_64BIT | 512 | #ifdef CONFIG_64BIT |
503 | #ifdef MODULE_START | 513 | #ifdef MODULE_START |
504 | pgd_t module_pg_dir[PTRS_PER_PGD] __page_aligned(PGD_ORDER); | 514 | pgd_t module_pg_dir[PTRS_PER_PGD] __page_aligned(PGD_ORDER); |
diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c index dc795be62807..e47e9e9486bf 100644 --- a/arch/mips/mm/pg-r4k.c +++ b/arch/mips/mm/pg-r4k.c | |||
@@ -209,7 +209,7 @@ static inline void build_cdex_p(void) | |||
209 | } | 209 | } |
210 | 210 | ||
211 | if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) | 211 | if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) |
212 | build_insn_word(0x3c01a000); /* lui $at, 0xa000 */ | 212 | build_insn_word(0x8c200000); /* lw $zero, ($at) */ |
213 | 213 | ||
214 | mi.c_format.opcode = cache_op; | 214 | mi.c_format.opcode = cache_op; |
215 | mi.c_format.rs = 4; /* $a0 */ | 215 | mi.c_format.rs = 4; /* $a0 */ |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 4ec0964b8394..6c425b052442 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -58,6 +58,21 @@ static __init int __maybe_unused r10000_llsc_war(void) | |||
58 | } | 58 | } |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * Found by experiment: At least some revisions of the 4kc throw under | ||
62 | * some circumstances a machine check exception, triggered by invalid | ||
63 | * values in the index register. Delaying the tlbp instruction until | ||
64 | * after the next branch, plus adding an additional nop in front of | ||
65 | * tlbwi/tlbwr avoids the invalid index register values. Nobody knows | ||
66 | * why; it's not an issue caused by the core RTL. | ||
67 | * | ||
68 | */ | ||
69 | static __init int __attribute__((unused)) m4kc_tlbp_war(void) | ||
70 | { | ||
71 | return (current_cpu_data.processor_id & 0xffff00) == | ||
72 | (PRID_COMP_MIPS | PRID_IMP_4KC); | ||
73 | } | ||
74 | |||
75 | /* | ||
61 | * A little micro-assembler, intended for TLB refill handler | 76 | * A little micro-assembler, intended for TLB refill handler |
62 | * synthesizing. It is intentionally kept simple, does only support | 77 | * synthesizing. It is intentionally kept simple, does only support |
63 | * a subset of instructions, and does not try to hide pipeline effects | 78 | * a subset of instructions, and does not try to hide pipeline effects |
@@ -78,7 +93,7 @@ enum fields | |||
78 | SET = 0x200 | 93 | SET = 0x200 |
79 | }; | 94 | }; |
80 | 95 | ||
81 | #define OP_MASK 0x2f | 96 | #define OP_MASK 0x3f |
82 | #define OP_SH 26 | 97 | #define OP_SH 26 |
83 | #define RS_MASK 0x1f | 98 | #define RS_MASK 0x1f |
84 | #define RS_SH 21 | 99 | #define RS_SH 21 |
@@ -92,7 +107,7 @@ enum fields | |||
92 | #define IMM_SH 0 | 107 | #define IMM_SH 0 |
93 | #define JIMM_MASK 0x3ffffff | 108 | #define JIMM_MASK 0x3ffffff |
94 | #define JIMM_SH 0 | 109 | #define JIMM_SH 0 |
95 | #define FUNC_MASK 0x2f | 110 | #define FUNC_MASK 0x3f |
96 | #define FUNC_SH 0 | 111 | #define FUNC_SH 0 |
97 | #define SET_MASK 0x7 | 112 | #define SET_MASK 0x7 |
98 | #define SET_SH 0 | 113 | #define SET_SH 0 |
@@ -894,6 +909,8 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l, | |||
894 | case CPU_20KC: | 909 | case CPU_20KC: |
895 | case CPU_25KF: | 910 | case CPU_25KF: |
896 | case CPU_LOONGSON2: | 911 | case CPU_LOONGSON2: |
912 | if (m4kc_tlbp_war()) | ||
913 | i_nop(p); | ||
897 | tlbw(p); | 914 | tlbw(p); |
898 | break; | 915 | break; |
899 | 916 | ||
@@ -1705,7 +1722,8 @@ build_r4000_tlbchange_handler_head(u32 **p, struct label **l, | |||
1705 | l_smp_pgtable_change(l, *p); | 1722 | l_smp_pgtable_change(l, *p); |
1706 | # endif | 1723 | # endif |
1707 | iPTE_LW(p, l, pte, ptr); /* get even pte */ | 1724 | iPTE_LW(p, l, pte, ptr); /* get even pte */ |
1708 | build_tlb_probe_entry(p); | 1725 | if (!m4kc_tlbp_war()) |
1726 | build_tlb_probe_entry(p); | ||
1709 | } | 1727 | } |
1710 | 1728 | ||
1711 | static void __init | 1729 | static void __init |
@@ -1747,6 +1765,8 @@ static void __init build_r4000_tlb_load_handler(void) | |||
1747 | 1765 | ||
1748 | build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); | 1766 | build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); |
1749 | build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl); | 1767 | build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl); |
1768 | if (m4kc_tlbp_war()) | ||
1769 | build_tlb_probe_entry(&p); | ||
1750 | build_make_valid(&p, &r, K0, K1); | 1770 | build_make_valid(&p, &r, K0, K1); |
1751 | build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); | 1771 | build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); |
1752 | 1772 | ||
@@ -1781,6 +1801,8 @@ static void __init build_r4000_tlb_store_handler(void) | |||
1781 | 1801 | ||
1782 | build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); | 1802 | build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); |
1783 | build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs); | 1803 | build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs); |
1804 | if (m4kc_tlbp_war()) | ||
1805 | build_tlb_probe_entry(&p); | ||
1784 | build_make_write(&p, &r, K0, K1); | 1806 | build_make_write(&p, &r, K0, K1); |
1785 | build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); | 1807 | build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); |
1786 | 1808 | ||
@@ -1815,6 +1837,8 @@ static void __init build_r4000_tlb_modify_handler(void) | |||
1815 | 1837 | ||
1816 | build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); | 1838 | build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); |
1817 | build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm); | 1839 | build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm); |
1840 | if (m4kc_tlbp_war()) | ||
1841 | build_tlb_probe_entry(&p); | ||
1818 | /* Present and writable bits set, set accessed and dirty bits. */ | 1842 | /* Present and writable bits set, set accessed and dirty bits. */ |
1819 | build_make_write(&p, &r, K0, K1); | 1843 | build_make_write(&p, &r, K0, K1); |
1820 | build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); | 1844 | build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); |