]> Pileus Git - ~andy/linux/blob - arch/mn10300/mm/tlb-mn10300.S
MN10300: AM34 erratum requires MMUCTR read and write on exception entry
[~andy/linux] / arch / mn10300 / mm / tlb-mn10300.S
1 ###############################################################################
2 #
3 # TLB loading functions
4 #
5 # Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
6 # Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
7 # Modified by David Howells (dhowells@redhat.com)
8 #
9 # This program is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU General Public Licence
11 # as published by the Free Software Foundation; either version
12 # 2 of the Licence, or (at your option) any later version.
13 #
14 ###############################################################################
15 #include <linux/sys.h>
16 #include <linux/linkage.h>
17 #include <asm/smp.h>
18 #include <asm/intctl-regs.h>
19 #include <asm/frame.inc>
20 #include <asm/page.h>
21 #include <asm/pgtable.h>
22
23 ###############################################################################
24 #
25 # Instruction TLB Miss handler entry point
26 #
27 ###############################################################################
28         .type   itlb_miss,@function
29 ENTRY(itlb_miss)
30 #ifdef CONFIG_GDBSTUB
31         movm    [d2,d3,a2],(sp)
32 #else
33         or      EPSW_nAR,epsw           # switch D0-D3 & A0-A3 to the alternate
34                                         # register bank
35         nop
36         nop
37         nop
38 #endif
39
40 #if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)
41         mov     (MMUCTR),d2
42         mov     d2,(MMUCTR)
43 #endif
44
45         and     ~EPSW_NMID,epsw
46         mov     (IPTEU),d3
47         mov     (PTBR),a2
48         mov     d3,d2
49         and     0xffc00000,d2
50         lsr     20,d2
51         mov     (a2,d2),a2              # PTD *ptd = PGD[addr 31..22]
52         btst    _PAGE_VALID,a2
53         beq     itlb_miss_fault         # jump if doesn't point anywhere
54
55         and     ~(PAGE_SIZE-1),a2
56         mov     d3,d2
57         and     0x003ff000,d2
58         lsr     10,d2
59         add     d2,a2
60         mov     (a2),d2                 # get pte from PTD[addr 21..12]
61         btst    _PAGE_VALID,d2
62         beq     itlb_miss_fault         # jump if doesn't point to a page
63                                         # (might be a swap id)
64         bset    _PAGE_ACCESSED,(0,a2)
65         and     ~(xPTEL_UNUSED1|xPTEL_UNUSED2),d2
66 itlb_miss_set:
67         mov     d2,(IPTEL)              # change the TLB
68 #ifdef CONFIG_GDBSTUB
69         movm    (sp),[d2,d3,a2]
70 #endif
71         rti
72
73 itlb_miss_fault:
74         mov     _PAGE_VALID,d2          # force address error handler to be
75                                         # invoked
76         bra     itlb_miss_set
77
78         .size   itlb_miss, . - itlb_miss
79
80 ###############################################################################
81 #
82 # Data TLB Miss handler entry point
83 #
84 ###############################################################################
85         .type   dtlb_miss,@function
86 ENTRY(dtlb_miss)
87 #ifdef CONFIG_GDBSTUB
88         movm    [d2,d3,a2],(sp)
89 #else
90         or      EPSW_nAR,epsw           # switch D0-D3 & A0-A3 to the alternate
91                                         # register bank
92         nop
93         nop
94         nop
95 #endif
96
97 #if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)
98         mov     (MMUCTR),d2
99         mov     d2,(MMUCTR)
100 #endif
101
102         and     ~EPSW_NMID,epsw
103         mov     (DPTEU),d3
104         mov     (PTBR),a2
105         mov     d3,d2
106         and     0xffc00000,d2
107         lsr     20,d2
108         mov     (a2,d2),a2              # PTD *ptd = PGD[addr 31..22]
109         btst    _PAGE_VALID,a2
110         beq     dtlb_miss_fault         # jump if doesn't point anywhere
111
112         and     ~(PAGE_SIZE-1),a2
113         mov     d3,d2
114         and     0x003ff000,d2
115         lsr     10,d2
116         add     d2,a2
117         mov     (a2),d2                 # get pte from PTD[addr 21..12]
118         btst    _PAGE_VALID,d2
119         beq     dtlb_miss_fault         # jump if doesn't point to a page
120                                         # (might be a swap id)
121         bset    _PAGE_ACCESSED,(0,a2)
122         and     ~(xPTEL_UNUSED1|xPTEL_UNUSED2),d2
123 dtlb_miss_set:
124         mov     d2,(DPTEL)              # change the TLB
125 #ifdef CONFIG_GDBSTUB
126         movm    (sp),[d2,d3,a2]
127 #endif
128         rti
129
130 dtlb_miss_fault:
131         mov     _PAGE_VALID,d2          # force address error handler to be
132                                         # invoked
133         bra     dtlb_miss_set
134         .size   dtlb_miss, . - dtlb_miss
135
136 ###############################################################################
137 #
138 # Instruction TLB Address Error handler entry point
139 #
140 ###############################################################################
141         .type   itlb_aerror,@function
142 ENTRY(itlb_aerror)
143         add     -4,sp
144         SAVE_ALL
145
146 #if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)
147         mov     (MMUCTR),d1
148         mov     d1,(MMUCTR)
149 #endif
150
151         and     ~EPSW_NMID,epsw
152         add     -4,sp                           # need to pass three params
153
154         # calculate the fault code
155         movhu   (MMUFCR_IFC),d1
156         or      0x00010000,d1                   # it's an instruction fetch
157
158         # determine the page address
159         mov     (IPTEU),a2
160         mov     a2,d0
161         and     PAGE_MASK,d0
162         mov     d0,(12,sp)
163
164         clr     d0
165         mov     d0,(IPTEL)
166
167         or      EPSW_IE,epsw
168         mov     fp,d0
169         call    do_page_fault[],0               # do_page_fault(regs,code,addr
170
171         jmp     ret_from_exception
172         .size   itlb_aerror, . - itlb_aerror
173
174 ###############################################################################
175 #
176 # Data TLB Address Error handler entry point
177 #
178 ###############################################################################
179         .type   dtlb_aerror,@function
180 ENTRY(dtlb_aerror)
181         add     -4,sp
182         SAVE_ALL
183
184 #if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)
185         mov     (MMUCTR),d1
186         mov     d1,(MMUCTR)
187 #endif
188
189         add     -4,sp                           # need to pass three params
190         and     ~EPSW_NMID,epsw
191
192         # calculate the fault code
193         movhu   (MMUFCR_DFC),d1
194
195         # determine the page address
196         mov     (DPTEU),a2
197         mov     a2,d0
198         and     PAGE_MASK,d0
199         mov     d0,(12,sp)
200
201         clr     d0
202         mov     d0,(DPTEL)
203
204         or      EPSW_IE,epsw
205         mov     fp,d0
206         call    do_page_fault[],0               # do_page_fault(regs,code,addr
207
208         jmp     ret_from_exception
209         .size   dtlb_aerror, . - dtlb_aerror