diff options
Diffstat (limited to 'arch/mn10300/mm')
-rw-r--r-- | arch/mn10300/mm/Kconfig.cache | 46 | ||||
-rw-r--r-- | arch/mn10300/mm/Makefile | 9 | ||||
-rw-r--r-- | arch/mn10300/mm/cache-dbg-flush-by-reg.S | 160 | ||||
-rw-r--r-- | arch/mn10300/mm/cache-dbg-flush-by-tag.S | 114 | ||||
-rw-r--r-- | arch/mn10300/mm/cache-dbg-inv-by-reg.S | 69 | ||||
-rw-r--r-- | arch/mn10300/mm/cache-dbg-inv-by-tag.S | 120 | ||||
-rw-r--r-- | arch/mn10300/mm/cache-dbg-inv.S | 47 | ||||
-rw-r--r-- | arch/mn10300/mm/cache-flush-by-tag.S | 13 | ||||
-rw-r--r-- | arch/mn10300/mm/cache-inv-by-reg.S | 22 | ||||
-rw-r--r-- | arch/mn10300/mm/cache-inv-by-tag.S | 86 | ||||
-rw-r--r-- | arch/mn10300/mm/cache.inc | 133 | ||||
-rw-r--r-- | arch/mn10300/mm/fault.c | 9 |
12 files changed, 723 insertions, 105 deletions
diff --git a/arch/mn10300/mm/Kconfig.cache b/arch/mn10300/mm/Kconfig.cache index c4fd923a55a0..bfbe52691f2c 100644 --- a/arch/mn10300/mm/Kconfig.cache +++ b/arch/mn10300/mm/Kconfig.cache | |||
@@ -99,3 +99,49 @@ config MN10300_CACHE_INV_ICACHE | |||
99 | help | 99 | help |
100 | Set if we need the icache to be invalidated, even if the dcache is in | 100 | Set if we need the icache to be invalidated, even if the dcache is in |
101 | write-through mode and doesn't need flushing. | 101 | write-through mode and doesn't need flushing. |
102 | |||
103 | # | ||
104 | # The kernel debugger gets its own separate cache flushing functions | ||
105 | # | ||
106 | config MN10300_DEBUGGER_CACHE_FLUSH_BY_TAG | ||
107 | def_bool y if KERNEL_DEBUGGER && \ | ||
108 | MN10300_CACHE_WBACK && \ | ||
109 | !MN10300_CACHE_SNOOP && \ | ||
110 | MN10300_CACHE_MANAGE_BY_TAG | ||
111 | help | ||
112 | Set if the debugger needs to flush the dcache and invalidate the | ||
113 | icache using the cache tag registers to make breakpoints work. | ||
114 | |||
115 | config MN10300_DEBUGGER_CACHE_FLUSH_BY_REG | ||
116 | def_bool y if KERNEL_DEBUGGER && \ | ||
117 | MN10300_CACHE_WBACK && \ | ||
118 | !MN10300_CACHE_SNOOP && \ | ||
119 | MN10300_CACHE_MANAGE_BY_REG | ||
120 | help | ||
121 | Set if the debugger needs to flush the dcache and invalidate the | ||
122 | icache using automatic purge registers to make breakpoints work. | ||
123 | |||
124 | config MN10300_DEBUGGER_CACHE_INV_BY_TAG | ||
125 | def_bool y if KERNEL_DEBUGGER && \ | ||
126 | MN10300_CACHE_WTHRU && \ | ||
127 | !MN10300_CACHE_SNOOP && \ | ||
128 | MN10300_CACHE_MANAGE_BY_TAG | ||
129 | help | ||
130 | Set if the debugger needs to invalidate the icache using the cache | ||
131 | tag registers to make breakpoints work. | ||
132 | |||
133 | config MN10300_DEBUGGER_CACHE_INV_BY_REG | ||
134 | def_bool y if KERNEL_DEBUGGER && \ | ||
135 | MN10300_CACHE_WTHRU && \ | ||
136 | !MN10300_CACHE_SNOOP && \ | ||
137 | MN10300_CACHE_MANAGE_BY_REG | ||
138 | help | ||
139 | Set if the debugger needs to invalidate the icache using automatic | ||
140 | purge registers to make breakpoints work. | ||
141 | |||
142 | config MN10300_DEBUGGER_CACHE_NO_FLUSH | ||
143 | def_bool y if KERNEL_DEBUGGER && \ | ||
144 | (MN10300_CACHE_DISABLED || MN10300_CACHE_SNOOP) | ||
145 | help | ||
146 | Set if the debugger does not need to flush the dcache and/or | ||
147 | invalidate the icache to make breakpoints work. | ||
diff --git a/arch/mn10300/mm/Makefile b/arch/mn10300/mm/Makefile index 203fee23f7d7..11f38466ac28 100644 --- a/arch/mn10300/mm/Makefile +++ b/arch/mn10300/mm/Makefile | |||
@@ -13,6 +13,15 @@ cacheflush-$(CONFIG_MN10300_CACHE_INV_BY_REG) += cache-inv-by-reg.o | |||
13 | cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_TAG) += cache-flush-by-tag.o | 13 | cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_TAG) += cache-flush-by-tag.o |
14 | cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_REG) += cache-flush-by-reg.o | 14 | cacheflush-$(CONFIG_MN10300_CACHE_FLUSH_BY_REG) += cache-flush-by-reg.o |
15 | 15 | ||
16 | cacheflush-$(CONFIG_MN10300_DEBUGGER_CACHE_FLUSH_BY_TAG) += \ | ||
17 | cache-dbg-flush-by-tag.o cache-dbg-inv-by-tag.o | ||
18 | cacheflush-$(CONFIG_MN10300_DEBUGGER_CACHE_FLUSH_BY_REG) += \ | ||
19 | cache-dbg-flush-by-reg.o | ||
20 | cacheflush-$(CONFIG_MN10300_DEBUGGER_CACHE_INV_BY_TAG) += \ | ||
21 | cache-dbg-inv-by-tag.o cache-dbg-inv.o | ||
22 | cacheflush-$(CONFIG_MN10300_DEBUGGER_CACHE_INV_BY_REG) += \ | ||
23 | cache-dbg-inv-by-reg.o cache-dbg-inv.o | ||
24 | |||
16 | cacheflush-$(CONFIG_MN10300_CACHE_DISABLED) := cache-disabled.o | 25 | cacheflush-$(CONFIG_MN10300_CACHE_DISABLED) := cache-disabled.o |
17 | 26 | ||
18 | obj-y := \ | 27 | obj-y := \ |
diff --git a/arch/mn10300/mm/cache-dbg-flush-by-reg.S b/arch/mn10300/mm/cache-dbg-flush-by-reg.S new file mode 100644 index 000000000000..665919f2ab62 --- /dev/null +++ b/arch/mn10300/mm/cache-dbg-flush-by-reg.S | |||
@@ -0,0 +1,160 @@ | |||
1 | /* MN10300 CPU cache invalidation routines, using automatic purge registers | ||
2 | * | ||
3 | * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/sys.h> | ||
12 | #include <linux/linkage.h> | ||
13 | #include <asm/smp.h> | ||
14 | #include <asm/page.h> | ||
15 | #include <asm/cache.h> | ||
16 | #include <asm/irqflags.h> | ||
17 | #include <asm/cacheflush.h> | ||
18 | #include "cache.inc" | ||
19 | |||
20 | .am33_2 | ||
21 | |||
22 | ############################################################################### | ||
23 | # | ||
24 | # void debugger_local_cache_flushinv(void) | ||
25 | # Flush the entire data cache back to RAM and invalidate the icache | ||
26 | # | ||
27 | ############################################################################### | ||
28 | ALIGN | ||
29 | .globl debugger_local_cache_flushinv | ||
30 | .type debugger_local_cache_flushinv,@function | ||
31 | debugger_local_cache_flushinv: | ||
32 | # | ||
33 | # firstly flush the dcache | ||
34 | # | ||
35 | movhu (CHCTR),d0 | ||
36 | btst CHCTR_DCEN|CHCTR_ICEN,d0 | ||
37 | beq debugger_local_cache_flushinv_end | ||
38 | |||
39 | mov DCPGCR,a0 | ||
40 | |||
41 | mov epsw,d1 | ||
42 | and ~EPSW_IE,epsw | ||
43 | or EPSW_NMID,epsw | ||
44 | nop | ||
45 | |||
46 | btst CHCTR_DCEN,d0 | ||
47 | beq debugger_local_cache_flushinv_no_dcache | ||
48 | |||
49 | # wait for busy bit of area purge | ||
50 | setlb | ||
51 | mov (a0),d0 | ||
52 | btst DCPGCR_DCPGBSY,d0 | ||
53 | lne | ||
54 | |||
55 | # set mask | ||
56 | clr d0 | ||
57 | mov d0,(DCPGMR) | ||
58 | |||
59 | # area purge | ||
60 | # | ||
61 | # DCPGCR = DCPGCR_DCP | ||
62 | # | ||
63 | mov DCPGCR_DCP,d0 | ||
64 | mov d0,(a0) | ||
65 | |||
66 | # wait for busy bit of area purge | ||
67 | setlb | ||
68 | mov (a0),d0 | ||
69 | btst DCPGCR_DCPGBSY,d0 | ||
70 | lne | ||
71 | |||
72 | debugger_local_cache_flushinv_no_dcache: | ||
73 | # | ||
74 | # secondly, invalidate the icache if it is enabled | ||
75 | # | ||
76 | mov CHCTR,a0 | ||
77 | movhu (a0),d0 | ||
78 | btst CHCTR_ICEN,d0 | ||
79 | beq debugger_local_cache_flushinv_done | ||
80 | |||
81 | invalidate_icache 0 | ||
82 | |||
83 | debugger_local_cache_flushinv_done: | ||
84 | mov d1,epsw | ||
85 | |||
86 | debugger_local_cache_flushinv_end: | ||
87 | ret [],0 | ||
88 | .size debugger_local_cache_flushinv,.-debugger_local_cache_flushinv | ||
89 | |||
90 | ############################################################################### | ||
91 | # | ||
92 | # void debugger_local_cache_flushinv_one(u8 *addr) | ||
93 | # | ||
94 | # Invalidate one particular cacheline if it's in the icache | ||
95 | # | ||
96 | ############################################################################### | ||
97 | ALIGN | ||
98 | .globl debugger_local_cache_flushinv_one | ||
99 | .type debugger_local_cache_flushinv_one,@function | ||
100 | debugger_local_cache_flushinv_one: | ||
101 | movhu (CHCTR),d1 | ||
102 | btst CHCTR_DCEN|CHCTR_ICEN,d1 | ||
103 | beq debugger_local_cache_flushinv_one_end | ||
104 | btst CHCTR_DCEN,d1 | ||
105 | beq debugger_local_cache_flushinv_one_no_dcache | ||
106 | |||
107 | # round cacheline addr down | ||
108 | and L1_CACHE_TAG_MASK,d0 | ||
109 | mov d0,a1 | ||
110 | mov d0,d1 | ||
111 | |||
112 | # determine the dcache purge control reg address | ||
113 | mov DCACHE_PURGE(0,0),a0 | ||
114 | and L1_CACHE_TAG_ENTRY,d0 | ||
115 | add d0,a0 | ||
116 | |||
117 | # retain valid entries in the cache | ||
118 | or L1_CACHE_TAG_VALID,d1 | ||
119 | |||
120 | # conditionally purge this line in all ways | ||
121 | mov d1,(L1_CACHE_WAYDISP*0,a0) | ||
122 | |||
123 | debugger_local_cache_flushinv_no_dcache: | ||
124 | # | ||
125 | # now try to flush the icache | ||
126 | # | ||
127 | mov CHCTR,a0 | ||
128 | movhu (a0),d0 | ||
129 | btst CHCTR_ICEN,d0 | ||
130 | beq mn10300_local_icache_inv_range_reg_end | ||
131 | |||
132 | LOCAL_CLI_SAVE(d1) | ||
133 | |||
134 | mov ICIVCR,a0 | ||
135 | |||
136 | # wait for the invalidator to quiesce | ||
137 | setlb | ||
138 | mov (a0),d0 | ||
139 | btst ICIVCR_ICIVBSY,d0 | ||
140 | lne | ||
141 | |||
142 | # set the mask | ||
143 | mov L1_CACHE_TAG_MASK,d0 | ||
144 | mov d0,(ICIVMR) | ||
145 | |||
146 | # invalidate the cache line at the given address | ||
147 | or ICIVCR_ICI,a1 | ||
148 | mov a1,(a0) | ||
149 | |||
150 | # wait for the invalidator to quiesce again | ||
151 | setlb | ||
152 | mov (a0),d0 | ||
153 | btst ICIVCR_ICIVBSY,d0 | ||
154 | lne | ||
155 | |||
156 | LOCAL_IRQ_RESTORE(d1) | ||
157 | |||
158 | debugger_local_cache_flushinv_one_end: | ||
159 | ret [],0 | ||
160 | .size debugger_local_cache_flushinv_one,.-debugger_local_cache_flushinv_one | ||
diff --git a/arch/mn10300/mm/cache-dbg-flush-by-tag.S b/arch/mn10300/mm/cache-dbg-flush-by-tag.S new file mode 100644 index 000000000000..bf56930e6e70 --- /dev/null +++ b/arch/mn10300/mm/cache-dbg-flush-by-tag.S | |||
@@ -0,0 +1,114 @@ | |||
1 | /* MN10300 CPU cache invalidation routines, using direct tag flushing | ||
2 | * | ||
3 | * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/sys.h> | ||
12 | #include <linux/linkage.h> | ||
13 | #include <asm/smp.h> | ||
14 | #include <asm/page.h> | ||
15 | #include <asm/cache.h> | ||
16 | #include <asm/irqflags.h> | ||
17 | #include <asm/cacheflush.h> | ||
18 | #include "cache.inc" | ||
19 | |||
20 | .am33_2 | ||
21 | |||
22 | ############################################################################### | ||
23 | # | ||
24 | # void debugger_local_cache_flushinv(void) | ||
25 | # | ||
26 | # Flush the entire data cache back to RAM and invalidate the icache | ||
27 | # | ||
28 | ############################################################################### | ||
29 | ALIGN | ||
30 | .globl debugger_local_cache_flushinv | ||
31 | .type debugger_local_cache_flushinv,@function | ||
32 | debugger_local_cache_flushinv: | ||
33 | # | ||
34 | # firstly flush the dcache | ||
35 | # | ||
36 | movhu (CHCTR),d0 | ||
37 | btst CHCTR_DCEN|CHCTR_ICEN,d0 | ||
38 | beq debugger_local_cache_flushinv_end | ||
39 | |||
40 | btst CHCTR_DCEN,d0 | ||
41 | beq debugger_local_cache_flushinv_no_dcache | ||
42 | |||
43 | # read the addresses tagged in the cache's tag RAM and attempt to flush | ||
44 | # those addresses specifically | ||
45 | # - we rely on the hardware to filter out invalid tag entry addresses | ||
46 | mov DCACHE_TAG(0,0),a0 # dcache tag RAM access address | ||
47 | mov DCACHE_PURGE(0,0),a1 # dcache purge request address | ||
48 | mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,e0 # total number of entries | ||
49 | |||
50 | mn10300_local_dcache_flush_loop: | ||
51 | mov (a0),d0 | ||
52 | and L1_CACHE_TAG_MASK,d0 | ||
53 | or L1_CACHE_TAG_VALID,d0 # retain valid entries in the | ||
54 | # cache | ||
55 | mov d0,(a1) # conditional purge | ||
56 | |||
57 | add L1_CACHE_BYTES,a0 | ||
58 | add L1_CACHE_BYTES,a1 | ||
59 | add -1,e0 | ||
60 | bne mn10300_local_dcache_flush_loop | ||
61 | |||
62 | debugger_local_cache_flushinv_no_dcache: | ||
63 | # | ||
64 | # secondly, invalidate the icache if it is enabled | ||
65 | # | ||
66 | mov CHCTR,a0 | ||
67 | movhu (a0),d0 | ||
68 | btst CHCTR_ICEN,d0 | ||
69 | beq debugger_local_cache_flushinv_end | ||
70 | |||
71 | invalidate_icache 1 | ||
72 | |||
73 | debugger_local_cache_flushinv_end: | ||
74 | ret [],0 | ||
75 | .size debugger_local_cache_flushinv,.-debugger_local_cache_flushinv | ||
76 | |||
77 | ############################################################################### | ||
78 | # | ||
79 | # void debugger_local_cache_flushinv_one(u8 *addr) | ||
80 | # | ||
81 | # Invalidate one particular cacheline if it's in the icache | ||
82 | # | ||
83 | ############################################################################### | ||
84 | ALIGN | ||
85 | .globl debugger_local_cache_flushinv_one | ||
86 | .type debugger_local_cache_flushinv_one,@function | ||
87 | debugger_local_cache_flushinv_one: | ||
88 | movhu (CHCTR),d1 | ||
89 | btst CHCTR_DCEN|CHCTR_ICEN,d1 | ||
90 | beq debugger_local_cache_flushinv_one_end | ||
91 | btst CHCTR_DCEN,d1 | ||
92 | beq debugger_local_cache_flushinv_one_icache | ||
93 | |||
94 | # round cacheline addr down | ||
95 | and L1_CACHE_TAG_MASK,d0 | ||
96 | mov d0,a1 | ||
97 | |||
98 | # determine the dcache purge control reg address | ||
99 | mov DCACHE_PURGE(0,0),a0 | ||
100 | and L1_CACHE_TAG_ENTRY,d0 | ||
101 | add d0,a0 | ||
102 | |||
103 | # retain valid entries in the cache | ||
104 | or L1_CACHE_TAG_VALID,a1 | ||
105 | |||
106 | # conditionally purge this line in all ways | ||
107 | mov a1,(L1_CACHE_WAYDISP*0,a0) | ||
108 | |||
109 | # now go and do the icache | ||
110 | bra debugger_local_cache_flushinv_one_icache | ||
111 | |||
112 | debugger_local_cache_flushinv_one_end: | ||
113 | ret [],0 | ||
114 | .size debugger_local_cache_flushinv_one,.-debugger_local_cache_flushinv_one | ||
diff --git a/arch/mn10300/mm/cache-dbg-inv-by-reg.S b/arch/mn10300/mm/cache-dbg-inv-by-reg.S new file mode 100644 index 000000000000..c4e6252941b1 --- /dev/null +++ b/arch/mn10300/mm/cache-dbg-inv-by-reg.S | |||
@@ -0,0 +1,69 @@ | |||
1 | /* MN10300 CPU cache invalidation routines, using automatic purge registers | ||
2 | * | ||
3 | * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/sys.h> | ||
12 | #include <linux/linkage.h> | ||
13 | #include <asm/cache.h> | ||
14 | #include <asm/irqflags.h> | ||
15 | #include <asm/cacheflush.h> | ||
16 | #include "cache.inc" | ||
17 | |||
18 | .am33_2 | ||
19 | |||
20 | .globl debugger_local_cache_flushinv_one | ||
21 | |||
22 | ############################################################################### | ||
23 | # | ||
24 | # void debugger_local_cache_flushinv_one(u8 *addr) | ||
25 | # | ||
26 | # Invalidate one particular cacheline if it's in the icache | ||
27 | # | ||
28 | ############################################################################### | ||
29 | ALIGN | ||
30 | .globl debugger_local_cache_flushinv_one | ||
31 | .type debugger_local_cache_flushinv_one,@function | ||
32 | debugger_local_cache_flushinv_one: | ||
33 | mov d0,a1 | ||
34 | |||
35 | mov CHCTR,a0 | ||
36 | movhu (a0),d0 | ||
37 | btst CHCTR_ICEN,d0 | ||
38 | beq mn10300_local_icache_inv_range_reg_end | ||
39 | |||
40 | LOCAL_CLI_SAVE(d1) | ||
41 | |||
42 | mov ICIVCR,a0 | ||
43 | |||
44 | # wait for the invalidator to quiesce | ||
45 | setlb | ||
46 | mov (a0),d0 | ||
47 | btst ICIVCR_ICIVBSY,d0 | ||
48 | lne | ||
49 | |||
50 | # set the mask | ||
51 | mov ~L1_CACHE_TAG_MASK,d0 | ||
52 | mov d0,(ICIVMR) | ||
53 | |||
54 | # invalidate the cache line at the given address | ||
55 | and ~L1_CACHE_TAG_MASK,a1 | ||
56 | or ICIVCR_ICI,a1 | ||
57 | mov a1,(a0) | ||
58 | |||
59 | # wait for the invalidator to quiesce again | ||
60 | setlb | ||
61 | mov (a0),d0 | ||
62 | btst ICIVCR_ICIVBSY,d0 | ||
63 | lne | ||
64 | |||
65 | LOCAL_IRQ_RESTORE(d1) | ||
66 | |||
67 | mn10300_local_icache_inv_range_reg_end: | ||
68 | ret [],0 | ||
69 | .size debugger_local_cache_flushinv_one,.-debugger_local_cache_flushinv_one | ||
diff --git a/arch/mn10300/mm/cache-dbg-inv-by-tag.S b/arch/mn10300/mm/cache-dbg-inv-by-tag.S new file mode 100644 index 000000000000..d8ec821e5f88 --- /dev/null +++ b/arch/mn10300/mm/cache-dbg-inv-by-tag.S | |||
@@ -0,0 +1,120 @@ | |||
1 | /* MN10300 CPU cache invalidation routines, using direct tag flushing | ||
2 | * | ||
3 | * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/sys.h> | ||
12 | #include <linux/linkage.h> | ||
13 | #include <asm/smp.h> | ||
14 | #include <asm/page.h> | ||
15 | #include <asm/cache.h> | ||
16 | #include <asm/irqflags.h> | ||
17 | #include <asm/cacheflush.h> | ||
18 | #include "cache.inc" | ||
19 | |||
20 | .am33_2 | ||
21 | |||
22 | .globl debugger_local_cache_flushinv_one_icache | ||
23 | |||
24 | ############################################################################### | ||
25 | # | ||
26 | # void debugger_local_cache_flushinv_one(u8 *addr) | ||
27 | # | ||
28 | # Invalidate one particular cacheline if it's in the icache | ||
29 | # | ||
30 | ############################################################################### | ||
31 | ALIGN | ||
32 | .globl debugger_local_cache_flushinv_one_icache | ||
33 | .type debugger_local_cache_flushinv_one_icache,@function | ||
34 | debugger_local_cache_flushinv_one_icache: | ||
35 | movm [d3,a2],(sp) | ||
36 | |||
37 | mov CHCTR,a2 | ||
38 | movhu (a2),d0 | ||
39 | btst CHCTR_ICEN,d0 | ||
40 | beq debugger_local_cache_flushinv_one_icache_end | ||
41 | |||
42 | mov d0,a1 | ||
43 | and L1_CACHE_TAG_MASK,a1 | ||
44 | |||
45 | # read the tags from the tag RAM, and if they indicate a matching valid | ||
46 | # cache line then we invalidate that line | ||
47 | mov ICACHE_TAG(0,0),a0 | ||
48 | mov a1,d0 | ||
49 | and L1_CACHE_TAG_ENTRY,d0 | ||
50 | add d0,a0 # starting icache tag RAM | ||
51 | # access address | ||
52 | |||
53 | and ~(L1_CACHE_DISPARITY-1),a1 # determine comparator base | ||
54 | or L1_CACHE_TAG_VALID,a1 | ||
55 | mov L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_VALID,d1 | ||
56 | |||
57 | LOCAL_CLI_SAVE(d3) | ||
58 | |||
59 | # disable the icache | ||
60 | movhu (a2),d0 | ||
61 | and ~CHCTR_ICEN,d0 | ||
62 | movhu d0,(a2) | ||
63 | |||
64 | # and wait for it to calm down | ||
65 | setlb | ||
66 | movhu (a2),d0 | ||
67 | btst CHCTR_ICBUSY,d0 | ||
68 | lne | ||
69 | |||
70 | # check all the way tags for this cache entry | ||
71 | mov (a0),d0 # read the tag in the way 0 slot | ||
72 | xor a1,d0 | ||
73 | and d1,d0 | ||
74 | beq debugger_local_icache_kill # jump if matched | ||
75 | |||
76 | add L1_CACHE_WAYDISP,a0 | ||
77 | mov (a0),d0 # read the tag in the way 1 slot | ||
78 | xor a1,d0 | ||
79 | and d1,d0 | ||
80 | beq debugger_local_icache_kill # jump if matched | ||
81 | |||
82 | add L1_CACHE_WAYDISP,a0 | ||
83 | mov (a0),d0 # read the tag in the way 2 slot | ||
84 | xor a1,d0 | ||
85 | and d1,d0 | ||
86 | beq debugger_local_icache_kill # jump if matched | ||
87 | |||
88 | add L1_CACHE_WAYDISP,a0 | ||
89 | mov (a0),d0 # read the tag in the way 3 slot | ||
90 | xor a1,d0 | ||
91 | and d1,d0 | ||
92 | bne debugger_local_icache_finish # jump if not matched | ||
93 | |||
94 | debugger_local_icache_kill: | ||
95 | mov d0,(a0) # kill the tag (D0 is 0 at this point) | ||
96 | |||
97 | debugger_local_icache_finish: | ||
98 | # wait for the cache to finish what it's doing | ||
99 | setlb | ||
100 | movhu (a2),d0 | ||
101 | btst CHCTR_ICBUSY,d0 | ||
102 | lne | ||
103 | |||
104 | # and reenable it | ||
105 | or CHCTR_ICEN,d0 | ||
106 | movhu d0,(a2) | ||
107 | movhu (a2),d0 | ||
108 | |||
109 | # re-enable interrupts | ||
110 | LOCAL_IRQ_RESTORE(d3) | ||
111 | |||
112 | debugger_local_cache_flushinv_one_icache_end: | ||
113 | ret [d3,a2],8 | ||
114 | .size debugger_local_cache_flushinv_one_icache,.-debugger_local_cache_flushinv_one_icache | ||
115 | |||
116 | #ifdef CONFIG_MN10300_DEBUGGER_CACHE_INV_BY_TAG | ||
117 | .globl debugger_local_cache_flushinv_one | ||
118 | .type debugger_local_cache_flushinv_one,@function | ||
119 | debugger_local_cache_flushinv_one = debugger_local_cache_flushinv_one_icache | ||
120 | #endif | ||
diff --git a/arch/mn10300/mm/cache-dbg-inv.S b/arch/mn10300/mm/cache-dbg-inv.S new file mode 100644 index 000000000000..eba2d6dca066 --- /dev/null +++ b/arch/mn10300/mm/cache-dbg-inv.S | |||
@@ -0,0 +1,47 @@ | |||
1 | /* MN10300 CPU cache invalidation routines | ||
2 | * | ||
3 | * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/sys.h> | ||
12 | #include <linux/linkage.h> | ||
13 | #include <asm/smp.h> | ||
14 | #include <asm/page.h> | ||
15 | #include <asm/cache.h> | ||
16 | #include <asm/irqflags.h> | ||
17 | #include <asm/cacheflush.h> | ||
18 | #include "cache.inc" | ||
19 | |||
20 | .am33_2 | ||
21 | |||
22 | .globl debugger_local_cache_flushinv | ||
23 | |||
24 | ############################################################################### | ||
25 | # | ||
26 | # void debugger_local_cache_flushinv(void) | ||
27 | # | ||
28 | # Invalidate the entire icache | ||
29 | # | ||
30 | ############################################################################### | ||
31 | ALIGN | ||
32 | .globl debugger_local_cache_flushinv | ||
33 | .type debugger_local_cache_flushinv,@function | ||
34 | debugger_local_cache_flushinv: | ||
35 | # | ||
36 | # we only need to invalidate the icache in this cache mode | ||
37 | # | ||
38 | mov CHCTR,a0 | ||
39 | movhu (a0),d0 | ||
40 | btst CHCTR_ICEN,d0 | ||
41 | beq debugger_local_cache_flushinv_end | ||
42 | |||
43 | invalidate_icache 1 | ||
44 | |||
45 | debugger_local_cache_flushinv_end: | ||
46 | ret [],0 | ||
47 | .size debugger_local_cache_flushinv,.-debugger_local_cache_flushinv | ||
diff --git a/arch/mn10300/mm/cache-flush-by-tag.S b/arch/mn10300/mm/cache-flush-by-tag.S index 5cd6a27dd63e..1ddc06849242 100644 --- a/arch/mn10300/mm/cache-flush-by-tag.S +++ b/arch/mn10300/mm/cache-flush-by-tag.S | |||
@@ -62,7 +62,7 @@ mn10300_local_dcache_flush: | |||
62 | 62 | ||
63 | mn10300_local_dcache_flush_loop: | 63 | mn10300_local_dcache_flush_loop: |
64 | mov (a0),d0 | 64 | mov (a0),d0 |
65 | and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 | 65 | and L1_CACHE_TAG_MASK,d0 |
66 | or L1_CACHE_TAG_VALID,d0 # retain valid entries in the | 66 | or L1_CACHE_TAG_VALID,d0 # retain valid entries in the |
67 | # cache | 67 | # cache |
68 | mov d0,(a1) # conditional purge | 68 | mov d0,(a1) # conditional purge |
@@ -112,11 +112,11 @@ mn10300_local_dcache_flush_range: | |||
112 | 1: | 112 | 1: |
113 | 113 | ||
114 | # round start addr down | 114 | # round start addr down |
115 | and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 | 115 | and L1_CACHE_TAG_MASK,d0 |
116 | mov d0,a1 | 116 | mov d0,a1 |
117 | 117 | ||
118 | add L1_CACHE_BYTES,d1 # round end addr up | 118 | add L1_CACHE_BYTES,d1 # round end addr up |
119 | and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 | 119 | and L1_CACHE_TAG_MASK,d1 |
120 | 120 | ||
121 | # write a request to flush all instances of an address from the cache | 121 | # write a request to flush all instances of an address from the cache |
122 | mov DCACHE_PURGE(0,0),a0 | 122 | mov DCACHE_PURGE(0,0),a0 |
@@ -215,12 +215,11 @@ mn10300_local_dcache_flush_inv_range: | |||
215 | bra mn10300_local_dcache_flush_inv | 215 | bra mn10300_local_dcache_flush_inv |
216 | 1: | 216 | 1: |
217 | 217 | ||
218 | and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start | 218 | and L1_CACHE_TAG_MASK,d0 # round start addr down |
219 | # addr down | ||
220 | mov d0,a1 | 219 | mov d0,a1 |
221 | 220 | ||
222 | add L1_CACHE_BYTES,d1 # round end addr up | 221 | add L1_CACHE_BYTES,d1 # round end addr up |
223 | and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 | 222 | and L1_CACHE_TAG_MASK,d1 |
224 | 223 | ||
225 | # write a request to flush and invalidate all instances of an address | 224 | # write a request to flush and invalidate all instances of an address |
226 | # from the cache | 225 | # from the cache |
diff --git a/arch/mn10300/mm/cache-inv-by-reg.S b/arch/mn10300/mm/cache-inv-by-reg.S index c8950861ed77..a60825b91e77 100644 --- a/arch/mn10300/mm/cache-inv-by-reg.S +++ b/arch/mn10300/mm/cache-inv-by-reg.S | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <asm/cache.h> | 15 | #include <asm/cache.h> |
16 | #include <asm/irqflags.h> | 16 | #include <asm/irqflags.h> |
17 | #include <asm/cacheflush.h> | 17 | #include <asm/cacheflush.h> |
18 | #include "cache.inc" | ||
18 | 19 | ||
19 | #define mn10300_local_dcache_inv_range_intr_interval \ | 20 | #define mn10300_local_dcache_inv_range_intr_interval \ |
20 | +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1) | 21 | +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1) |
@@ -62,10 +63,7 @@ mn10300_local_icache_inv: | |||
62 | btst CHCTR_ICEN,d0 | 63 | btst CHCTR_ICEN,d0 |
63 | beq mn10300_local_icache_inv_end | 64 | beq mn10300_local_icache_inv_end |
64 | 65 | ||
65 | # invalidate | 66 | invalidate_icache 1 |
66 | or CHCTR_ICINV,d0 | ||
67 | movhu d0,(a0) | ||
68 | movhu (a0),d0 | ||
69 | 67 | ||
70 | mn10300_local_icache_inv_end: | 68 | mn10300_local_icache_inv_end: |
71 | ret [],0 | 69 | ret [],0 |
@@ -87,11 +85,8 @@ mn10300_local_dcache_inv: | |||
87 | btst CHCTR_DCEN,d0 | 85 | btst CHCTR_DCEN,d0 |
88 | beq mn10300_local_dcache_inv_end | 86 | beq mn10300_local_dcache_inv_end |
89 | 87 | ||
90 | # invalidate | 88 | invalidate_dcache 1 |
91 | or CHCTR_DCINV,d0 | 89 | |
92 | movhu d0,(a0) | ||
93 | movhu (a0),d0 | ||
94 | |||
95 | mn10300_local_dcache_inv_end: | 90 | mn10300_local_dcache_inv_end: |
96 | ret [],0 | 91 | ret [],0 |
97 | .size mn10300_local_dcache_inv,.-mn10300_local_dcache_inv | 92 | .size mn10300_local_dcache_inv,.-mn10300_local_dcache_inv |
@@ -121,9 +116,9 @@ mn10300_local_dcache_inv_range: | |||
121 | # and if they're not cacheline-aligned, we must flush any bits outside | 116 | # and if they're not cacheline-aligned, we must flush any bits outside |
122 | # the range that share cachelines with stuff inside the range | 117 | # the range that share cachelines with stuff inside the range |
123 | #ifdef CONFIG_MN10300_CACHE_WBACK | 118 | #ifdef CONFIG_MN10300_CACHE_WBACK |
124 | btst ~(L1_CACHE_BYTES-1),d0 | 119 | btst ~L1_CACHE_TAG_MASK,d0 |
125 | bne 1f | 120 | bne 1f |
126 | btst ~(L1_CACHE_BYTES-1),d1 | 121 | btst ~L1_CACHE_TAG_MASK,d1 |
127 | beq 2f | 122 | beq 2f |
128 | 1: | 123 | 1: |
129 | bra mn10300_local_dcache_flush_inv_range | 124 | bra mn10300_local_dcache_flush_inv_range |
@@ -141,12 +136,11 @@ mn10300_local_dcache_inv_range: | |||
141 | # writeback mode, in which case we would be in flush and invalidate by | 136 | # writeback mode, in which case we would be in flush and invalidate by |
142 | # now | 137 | # now |
143 | #ifndef CONFIG_MN10300_CACHE_WBACK | 138 | #ifndef CONFIG_MN10300_CACHE_WBACK |
144 | and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start | 139 | and L1_CACHE_TAG_MASK,d0 # round start addr down |
145 | # addr down | ||
146 | 140 | ||
147 | mov L1_CACHE_BYTES-1,d2 | 141 | mov L1_CACHE_BYTES-1,d2 |
148 | add d2,d1 | 142 | add d2,d1 |
149 | and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 # round end addr up | 143 | and L1_CACHE_TAG_MASK,d1 # round end addr up |
150 | #endif /* !CONFIG_MN10300_CACHE_WBACK */ | 144 | #endif /* !CONFIG_MN10300_CACHE_WBACK */ |
151 | 145 | ||
152 | sub d0,d1,d2 # calculate the total size | 146 | sub d0,d1,d2 # calculate the total size |
diff --git a/arch/mn10300/mm/cache-inv-by-tag.S b/arch/mn10300/mm/cache-inv-by-tag.S index e9713b40c0ff..ccedce9c144d 100644 --- a/arch/mn10300/mm/cache-inv-by-tag.S +++ b/arch/mn10300/mm/cache-inv-by-tag.S | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <asm/cache.h> | 15 | #include <asm/cache.h> |
16 | #include <asm/irqflags.h> | 16 | #include <asm/irqflags.h> |
17 | #include <asm/cacheflush.h> | 17 | #include <asm/cacheflush.h> |
18 | #include "cache.inc" | ||
18 | 19 | ||
19 | #define mn10300_local_dcache_inv_range_intr_interval \ | 20 | #define mn10300_local_dcache_inv_range_intr_interval \ |
20 | +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1) | 21 | +((1 << MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL) - 1) |
@@ -70,43 +71,7 @@ mn10300_local_icache_inv: | |||
70 | btst CHCTR_ICEN,d0 | 71 | btst CHCTR_ICEN,d0 |
71 | beq mn10300_local_icache_inv_end | 72 | beq mn10300_local_icache_inv_end |
72 | 73 | ||
73 | #if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3) | 74 | invalidate_icache 1 |
74 | LOCAL_CLI_SAVE(d1) | ||
75 | |||
76 | # disable the icache | ||
77 | and ~CHCTR_ICEN,d0 | ||
78 | movhu d0,(a0) | ||
79 | |||
80 | # and wait for it to calm down | ||
81 | setlb | ||
82 | movhu (a0),d0 | ||
83 | btst CHCTR_ICBUSY,d0 | ||
84 | lne | ||
85 | |||
86 | # invalidate | ||
87 | or CHCTR_ICINV,d0 | ||
88 | movhu d0,(a0) | ||
89 | |||
90 | # wait for the cache to finish | ||
91 | mov CHCTR,a0 | ||
92 | setlb | ||
93 | movhu (a0),d0 | ||
94 | btst CHCTR_ICBUSY,d0 | ||
95 | lne | ||
96 | |||
97 | # and reenable it | ||
98 | and ~CHCTR_ICINV,d0 | ||
99 | or CHCTR_ICEN,d0 | ||
100 | movhu d0,(a0) | ||
101 | movhu (a0),d0 | ||
102 | |||
103 | LOCAL_IRQ_RESTORE(d1) | ||
104 | #else /* CONFIG_AM33_2 || CONFIG_AM33_3 */ | ||
105 | # invalidate | ||
106 | or CHCTR_ICINV,d0 | ||
107 | movhu d0,(a0) | ||
108 | movhu (a0),d0 | ||
109 | #endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */ | ||
110 | 75 | ||
111 | mn10300_local_icache_inv_end: | 76 | mn10300_local_icache_inv_end: |
112 | ret [],0 | 77 | ret [],0 |
@@ -128,43 +93,7 @@ mn10300_local_dcache_inv: | |||
128 | btst CHCTR_DCEN,d0 | 93 | btst CHCTR_DCEN,d0 |
129 | beq mn10300_local_dcache_inv_end | 94 | beq mn10300_local_dcache_inv_end |
130 | 95 | ||
131 | #if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3) | 96 | invalidate_dcache 1 |
132 | LOCAL_CLI_SAVE(d1) | ||
133 | |||
134 | # disable the dcache | ||
135 | and ~CHCTR_DCEN,d0 | ||
136 | movhu d0,(a0) | ||
137 | |||
138 | # and wait for it to calm down | ||
139 | setlb | ||
140 | movhu (a0),d0 | ||
141 | btst CHCTR_DCBUSY,d0 | ||
142 | lne | ||
143 | |||
144 | # invalidate | ||
145 | or CHCTR_DCINV,d0 | ||
146 | movhu d0,(a0) | ||
147 | |||
148 | # wait for the cache to finish | ||
149 | mov CHCTR,a0 | ||
150 | setlb | ||
151 | movhu (a0),d0 | ||
152 | btst CHCTR_DCBUSY,d0 | ||
153 | lne | ||
154 | |||
155 | # and reenable it | ||
156 | and ~CHCTR_DCINV,d0 | ||
157 | or CHCTR_DCEN,d0 | ||
158 | movhu d0,(a0) | ||
159 | movhu (a0),d0 | ||
160 | |||
161 | LOCAL_IRQ_RESTORE(d1) | ||
162 | #else /* CONFIG_AM33_2 || CONFIG_AM33_3 */ | ||
163 | # invalidate | ||
164 | or CHCTR_DCINV,d0 | ||
165 | movhu d0,(a0) | ||
166 | movhu (a0),d0 | ||
167 | #endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */ | ||
168 | 97 | ||
169 | mn10300_local_dcache_inv_end: | 98 | mn10300_local_dcache_inv_end: |
170 | ret [],0 | 99 | ret [],0 |
@@ -195,9 +124,9 @@ mn10300_local_dcache_inv_range: | |||
195 | # and if they're not cacheline-aligned, we must flush any bits outside | 124 | # and if they're not cacheline-aligned, we must flush any bits outside |
196 | # the range that share cachelines with stuff inside the range | 125 | # the range that share cachelines with stuff inside the range |
197 | #ifdef CONFIG_MN10300_CACHE_WBACK | 126 | #ifdef CONFIG_MN10300_CACHE_WBACK |
198 | btst ~(L1_CACHE_BYTES-1),d0 | 127 | btst ~L1_CACHE_TAG_MASK,d0 |
199 | bne 1f | 128 | bne 1f |
200 | btst ~(L1_CACHE_BYTES-1),d1 | 129 | btst ~L1_CACHE_TAG_MASK,d1 |
201 | beq 2f | 130 | beq 2f |
202 | 1: | 131 | 1: |
203 | bra mn10300_local_dcache_flush_inv_range | 132 | bra mn10300_local_dcache_flush_inv_range |
@@ -212,11 +141,10 @@ mn10300_local_dcache_inv_range: | |||
212 | beq mn10300_local_dcache_inv_range_end | 141 | beq mn10300_local_dcache_inv_range_end |
213 | 142 | ||
214 | #ifndef CONFIG_MN10300_CACHE_WBACK | 143 | #ifndef CONFIG_MN10300_CACHE_WBACK |
215 | and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start | 144 | and L1_CACHE_TAG_MASK,d0 # round start addr down |
216 | # addr down | ||
217 | 145 | ||
218 | add L1_CACHE_BYTES,d1 # round end addr up | 146 | add L1_CACHE_BYTES,d1 # round end addr up |
219 | and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 | 147 | and L1_CACHE_TAG_MASK,d1 |
220 | #endif /* !CONFIG_MN10300_CACHE_WBACK */ | 148 | #endif /* !CONFIG_MN10300_CACHE_WBACK */ |
221 | mov d0,a1 | 149 | mov d0,a1 |
222 | 150 | ||
diff --git a/arch/mn10300/mm/cache.inc b/arch/mn10300/mm/cache.inc new file mode 100644 index 000000000000..394a119b9c73 --- /dev/null +++ b/arch/mn10300/mm/cache.inc | |||
@@ -0,0 +1,133 @@ | |||
1 | /* MN10300 CPU core caching macros -*- asm -*- | ||
2 | * | ||
3 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | |||
13 | ############################################################################### | ||
14 | # | ||
15 | # Invalidate the instruction cache. | ||
16 | # A0: Should hold CHCTR | ||
17 | # D0: Should have been read from CHCTR | ||
18 | # D1: Will be clobbered | ||
19 | # | ||
20 | # On some cores it is necessary to disable the icache whilst we do this. | ||
21 | # | ||
22 | ############################################################################### | ||
23 | .macro invalidate_icache,disable_irq | ||
24 | |||
25 | #if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3) | ||
26 | .if \disable_irq | ||
27 | # don't want an interrupt routine seeing a disabled cache | ||
28 | mov epsw,d1 | ||
29 | and ~EPSW_IE,epsw | ||
30 | or EPSW_NMID,epsw | ||
31 | nop | ||
32 | nop | ||
33 | .endif | ||
34 | |||
35 | # disable the icache | ||
36 | and ~CHCTR_ICEN,d0 | ||
37 | movhu d0,(a0) | ||
38 | |||
39 | # and wait for it to calm down | ||
40 | setlb | ||
41 | movhu (a0),d0 | ||
42 | btst CHCTR_ICBUSY,d0 | ||
43 | lne | ||
44 | |||
45 | # invalidate | ||
46 | or CHCTR_ICINV,d0 | ||
47 | movhu d0,(a0) | ||
48 | |||
49 | # wait for the cache to finish | ||
50 | setlb | ||
51 | movhu (a0),d0 | ||
52 | btst CHCTR_ICBUSY,d0 | ||
53 | lne | ||
54 | |||
55 | # and reenable it | ||
56 | or CHCTR_ICEN,d0 | ||
57 | movhu d0,(a0) | ||
58 | movhu (a0),d0 | ||
59 | |||
60 | .if \disable_irq | ||
61 | LOCAL_IRQ_RESTORE(d1) | ||
62 | .endif | ||
63 | |||
64 | #else /* CONFIG_AM33_2 || CONFIG_AM33_3 */ | ||
65 | |||
66 | # invalidate | ||
67 | or CHCTR_ICINV,d0 | ||
68 | movhu d0,(a0) | ||
69 | movhu (a0),d0 | ||
70 | |||
71 | #endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */ | ||
72 | .endm | ||
73 | |||
74 | ############################################################################### | ||
75 | # | ||
76 | # Invalidate the data cache. | ||
77 | # A0: Should hold CHCTR | ||
78 | # D0: Should have been read from CHCTR | ||
79 | # D1: Will be clobbered | ||
80 | # | ||
81 | # On some cores it is necessary to disable the dcache whilst we do this. | ||
82 | # | ||
83 | ############################################################################### | ||
84 | .macro invalidate_dcache,disable_irq | ||
85 | |||
86 | #if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3) | ||
87 | .if \disable_irq | ||
88 | # don't want an interrupt routine seeing a disabled cache | ||
89 | mov epsw,d1 | ||
90 | and ~EPSW_IE,epsw | ||
91 | or EPSW_NMID,epsw | ||
92 | nop | ||
93 | nop | ||
94 | .endif | ||
95 | |||
96 | # disable the dcache | ||
97 | and ~CHCTR_DCEN,d0 | ||
98 | movhu d0,(a0) | ||
99 | |||
100 | # and wait for it to calm down | ||
101 | setlb | ||
102 | movhu (a0),d0 | ||
103 | btst CHCTR_DCBUSY,d0 | ||
104 | lne | ||
105 | |||
106 | # invalidate | ||
107 | or CHCTR_DCINV,d0 | ||
108 | movhu d0,(a0) | ||
109 | |||
110 | # wait for the cache to finish | ||
111 | setlb | ||
112 | movhu (a0),d0 | ||
113 | btst CHCTR_DCBUSY,d0 | ||
114 | lne | ||
115 | |||
116 | # and reenable it | ||
117 | or CHCTR_DCEN,d0 | ||
118 | movhu d0,(a0) | ||
119 | movhu (a0),d0 | ||
120 | |||
121 | .if \disable_irq | ||
122 | LOCAL_IRQ_RESTORE(d1) | ||
123 | .endif | ||
124 | |||
125 | #else /* CONFIG_AM33_2 || CONFIG_AM33_3 */ | ||
126 | |||
127 | # invalidate | ||
128 | or CHCTR_DCINV,d0 | ||
129 | movhu d0,(a0) | ||
130 | movhu (a0),d0 | ||
131 | |||
132 | #endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */ | ||
133 | .endm | ||
diff --git a/arch/mn10300/mm/fault.c b/arch/mn10300/mm/fault.c index 59c3da49d9d9..0945409a8022 100644 --- a/arch/mn10300/mm/fault.c +++ b/arch/mn10300/mm/fault.c | |||
@@ -28,8 +28,9 @@ | |||
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <asm/pgalloc.h> | 29 | #include <asm/pgalloc.h> |
30 | #include <asm/hardirq.h> | 30 | #include <asm/hardirq.h> |
31 | #include <asm/gdb-stub.h> | ||
32 | #include <asm/cpu-regs.h> | 31 | #include <asm/cpu-regs.h> |
32 | #include <asm/debugger.h> | ||
33 | #include <asm/gdb-stub.h> | ||
33 | 34 | ||
34 | /* | 35 | /* |
35 | * Unlock any spinlocks which will prevent us from getting the | 36 | * Unlock any spinlocks which will prevent us from getting the |
@@ -306,10 +307,8 @@ no_context: | |||
306 | printk(" printing pc:\n"); | 307 | printk(" printing pc:\n"); |
307 | printk(KERN_ALERT "%08lx\n", regs->pc); | 308 | printk(KERN_ALERT "%08lx\n", regs->pc); |
308 | 309 | ||
309 | #ifdef CONFIG_GDBSTUB | 310 | debugger_intercept(fault_code & 0x00010000 ? EXCEP_IAERROR : EXCEP_DAERROR, |
310 | gdbstub_intercept( | 311 | SIGSEGV, SEGV_ACCERR, regs); |
311 | regs, fault_code & 0x00010000 ? EXCEP_IAERROR : EXCEP_DAERROR); | ||
312 | #endif | ||
313 | 312 | ||
314 | page = PTBR; | 313 | page = PTBR; |
315 | page = ((unsigned long *) __va(page))[address >> 22]; | 314 | page = ((unsigned long *) __va(page))[address >> 22]; |