Merge branch 'for_rmk' of git://git.mnementh.co.uk/linux-2.6-im
[linux-2.6] / 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         and     ~EPSW_NMID,epsw
31 #ifdef CONFIG_GDBSTUB
32         movm    [d2,d3,a2],(sp)
33 #else
34         or      EPSW_nAR,epsw           # switch D0-D3 & A0-A3 to the alternate
35                                         # register bank
36         nop
37         nop
38         nop
39 #endif
40
41         mov     (IPTEU),d3
42         mov     (PTBR),a2
43         mov     d3,d2
44         and     0xffc00000,d2
45         lsr     20,d2
46         mov     (a2,d2),a2              # PTD *ptd = PGD[addr 31..22]
47         btst    _PAGE_VALID,a2
48         beq     itlb_miss_fault         # jump if doesn't point anywhere
49
50         and     ~(PAGE_SIZE-1),a2
51         mov     d3,d2
52         and     0x003ff000,d2
53         lsr     10,d2
54         add     d2,a2
55         mov     (a2),d2                 # get pte from PTD[addr 21..12]
56         btst    _PAGE_VALID,d2
57         beq     itlb_miss_fault         # jump if doesn't point to a page
58                                         # (might be a swap id)
59         bset    _PAGE_ACCESSED,(0,a2)
60         and     ~(xPTEL_UNUSED1|xPTEL_UNUSED2),d2
61 itlb_miss_set:
62         mov     d2,(IPTEL)              # change the TLB
63 #ifdef CONFIG_GDBSTUB
64         movm    (sp),[d2,d3,a2]
65 #endif
66         rti
67
68 itlb_miss_fault:
69         mov     _PAGE_VALID,d2          # force address error handler to be
70                                         # invoked
71         bra     itlb_miss_set
72
73         .size   itlb_miss, . - itlb_miss
74
75 ###############################################################################
76 #
77 # Data TLB Miss handler entry point
78 #
79 ###############################################################################
80         .type   dtlb_miss,@function
81 ENTRY(dtlb_miss)
82         and     ~EPSW_NMID,epsw
83 #ifdef CONFIG_GDBSTUB
84         movm    [d2,d3,a2],(sp)
85 #else
86         or      EPSW_nAR,epsw           # switch D0-D3 & A0-A3 to the alternate
87                                         # register bank
88         nop
89         nop
90         nop
91 #endif
92
93         mov     (DPTEU),d3
94         mov     (PTBR),a2
95         mov     d3,d2
96         and     0xffc00000,d2
97         lsr     20,d2
98         mov     (a2,d2),a2              # PTD *ptd = PGD[addr 31..22]
99         btst    _PAGE_VALID,a2
100         beq     dtlb_miss_fault         # jump if doesn't point anywhere
101
102         and     ~(PAGE_SIZE-1),a2
103         mov     d3,d2
104         and     0x003ff000,d2
105         lsr     10,d2
106         add     d2,a2
107         mov     (a2),d2                 # get pte from PTD[addr 21..12]
108         btst    _PAGE_VALID,d2
109         beq     dtlb_miss_fault         # jump if doesn't point to a page
110                                         # (might be a swap id)
111         bset    _PAGE_ACCESSED,(0,a2)
112         and     ~(xPTEL_UNUSED1|xPTEL_UNUSED2),d2
113 dtlb_miss_set:
114         mov     d2,(DPTEL)              # change the TLB
115 #ifdef CONFIG_GDBSTUB
116         movm    (sp),[d2,d3,a2]
117 #endif
118         rti
119
120 dtlb_miss_fault:
121         mov     _PAGE_VALID,d2          # force address error handler to be
122                                         # invoked
123         bra     dtlb_miss_set
124         .size   dtlb_miss, . - dtlb_miss
125
126 ###############################################################################
127 #
128 # Instruction TLB Address Error handler entry point
129 #
130 ###############################################################################
131         .type   itlb_aerror,@function
132 ENTRY(itlb_aerror)
133         and     ~EPSW_NMID,epsw
134         add     -4,sp
135         SAVE_ALL
136         add     -4,sp                           # need to pass three params
137
138         # calculate the fault code
139         movhu   (MMUFCR_IFC),d1
140         or      0x00010000,d1                   # it's an instruction fetch
141
142         # determine the page address
143         mov     (IPTEU),a2
144         mov     a2,d0
145         and     PAGE_MASK,d0
146         mov     d0,(12,sp)
147
148         clr     d0
149         mov     d0,(IPTEL)
150
151         and     ~EPSW_NMID,epsw
152         or      EPSW_IE,epsw
153         mov     fp,d0
154         call    do_page_fault[],0               # do_page_fault(regs,code,addr
155
156         jmp     ret_from_exception
157         .size   itlb_aerror, . - itlb_aerror
158
159 ###############################################################################
160 #
161 # Data TLB Address Error handler entry point
162 #
163 ###############################################################################
164         .type   dtlb_aerror,@function
165 ENTRY(dtlb_aerror)
166         and     ~EPSW_NMID,epsw
167         add     -4,sp
168         mov     d1,(sp)
169
170         movhu   (MMUFCR_DFC),d1                 # is it the initial valid write
171                                                 # to this page?
172         and     MMUFCR_xFC_INITWR,d1
173         beq     dtlb_pagefault                  # jump if not
174
175         mov     (DPTEL),d1                      # set the dirty bit
176                                                 # (don't replace with BSET!)
177         or      _PAGE_DIRTY,d1
178         mov     d1,(DPTEL)
179         mov     (sp),d1
180         add     4,sp
181         rti
182
183         ALIGN
184 dtlb_pagefault:
185         mov     (sp),d1
186         SAVE_ALL
187         add     -4,sp                           # need to pass three params
188
189         # calculate the fault code
190         movhu   (MMUFCR_DFC),d1
191
192         # determine the page address
193         mov     (DPTEU),a2
194         mov     a2,d0
195         and     PAGE_MASK,d0
196         mov     d0,(12,sp)
197
198         clr     d0
199         mov     d0,(DPTEL)
200
201         and     ~EPSW_NMID,epsw
202         or      EPSW_IE,epsw
203         mov     fp,d0
204         call    do_page_fault[],0               # do_page_fault(regs,code,addr
205
206         jmp     ret_from_exception
207         .size   dtlb_aerror, . - dtlb_aerror