aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-10-13 09:43:54 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2007-10-13 09:43:54 -0400
commitb160292cc216a50fd0cd386b0bda2cd48352c73b (patch)
treeef07cf98f91353ee4c9ec1e1ca7a2a5d9d4b538a /arch/mips/mm
parentb37bde147890c8fea8369a5a4e230dabdea4ebfb (diff)
parentbbf25010f1a6b761914430f5fca081ec8c7accd1 (diff)
Merge Linux 2.6.23
Diffstat (limited to 'arch/mips/mm')
-rw-r--r--arch/mips/mm/dma-default.c2
-rw-r--r--arch/mips/mm/init.c14
-rw-r--r--arch/mips/mm/pg-r4k.c2
-rw-r--r--arch/mips/mm/tlbex.c30
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)
35static inline int cpu_is_noncoherent_r10000(struct device *dev) 35static 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)))
501pgd_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 */
511pgd_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
504pgd_t module_pg_dir[PTRS_PER_PGD] __page_aligned(PGD_ORDER); 514pgd_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 */
69static __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
1711static void __init 1729static 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);