ARM: mmp: fix potential NULL dereference
[linux/fpc-iii.git] / arch / score / mm / tlb-miss.S
blobf27651914e8dba916c107853f15853552d907249
1 /*
2  * arch/score/mm/tlbex.S
3  *
4  * Score Processor version.
5  *
6  * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7  *  Lennox Wu <lennox.wu@sunplusct.com>
8  *  Chen Liqin <liqin.chen@sunplusct.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, see the file COPYING, or write
22  * to the Free Software Foundation, Inc.,
23  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24  */
26 #include <asm/asmmacro.h>
27 #include <asm/pgtable-bits.h>
28 #include <asm/scoreregs.h>
31 * After this macro runs, the pte faulted on is
32 * in register PTE, a ptr into the table in which
33 * the pte belongs is in PTR.
35         .macro  load_pte, pte, ptr
36         la      \ptr, pgd_current
37         lw      \ptr, [\ptr, 0]
38         mfcr    \pte, cr6
39         srli    \pte, \pte, 22
40         slli    \pte, \pte, 2
41         add     \ptr, \ptr, \pte
42         lw      \ptr, [\ptr, 0]
43         mfcr    \pte, cr6
44         srli    \pte, \pte, 10
45         andi    \pte, 0xffc
46         add     \ptr, \ptr, \pte
47         lw      \pte, [\ptr, 0]
48         .endm
50         .macro  pte_reload, ptr
51         lw      \ptr, [\ptr, 0]
52         mtcr    \ptr, cr12
53         nop
54         nop
55         nop
56         nop
57         nop
58         .endm
60         .macro do_fault, write
61         SAVE_ALL
62         mfcr    r6, cr6
63         mv      r4, r0
64         ldi     r5, \write
65         la      r8, do_page_fault
66         brl     r8
67         j       ret_from_exception
68         .endm
70         .macro  pte_writable, pte, ptr, label
71         andi    \pte, 0x280
72         cmpi.c  \pte, 0x280
73         bne     \label
74         lw      \pte, [\ptr, 0]         /*reload PTE*/
75         .endm
78  * Make PTE writable, update software status bits as well,
79  * then store at PTR.
80  */
81         .macro  pte_makewrite, pte, ptr
82         ori     \pte, 0x426
83         sw      \pte, [\ptr, 0]
84         .endm
86         .text
87 ENTRY(score7_FTLB_refill_Handler)
88         la      r31, pgd_current        /* get pgd pointer */
89         lw      r31, [r31, 0]           /* get the address of PGD */
90         mfcr    r30, cr6
91         srli    r30, r30, 22            /* PGDIR_SHIFT = 22*/
92         slli    r30, r30, 2
93         add     r31, r31, r30
94         lw      r31, [r31, 0]           /* get the address of the start address of PTE table */
96         mfcr    r30, cr9
97         andi    r30, 0xfff              /* equivalent to get PET index and right shift 2 bits */
98         add     r31, r31, r30
99         lw      r30, [r31, 0]           /* load pte entry */
100         mtcr    r30, cr12
101         nop
102         nop
103         nop
104         nop
105         nop
106         mtrtlb
107         nop
108         nop
109         nop
110         nop
111         nop
112         rte                             /* 6 cycles to make sure tlb entry works */
114 ENTRY(score7_KSEG_refill_Handler)
115         la      r31, pgd_current        /* get pgd pointer */
116         lw      r31, [r31, 0]           /* get the address of PGD */
117         mfcr    r30, cr6
118         srli    r30, r30, 22            /* PGDIR_SHIFT = 22 */
119         slli    r30, r30, 2
120         add     r31, r31, r30
121         lw      r31, [r31, 0]           /* get the address of the start address of PTE table */
123         mfcr    r30, cr6                /* get Bad VPN */
124         srli    r30, r30, 10
125         andi    r30, 0xffc              /* PTE VPN mask (bit 11~2) */
127         add     r31, r31, r30
128         lw      r30, [r31, 0]           /* load pte entry */
129         mtcr    r30, cr12
130         nop
131         nop
132         nop
133         nop
134         nop
135         mtrtlb
136         nop
137         nop
138         nop
139         nop
140         nop
141         rte                             /* 6 cycles to make sure tlb entry works */
143 nopage_tlbl:
144         do_fault        0               /* Read */
146 ENTRY(handle_tlb_refill)
147         load_pte        r30, r31
148         pte_writable    r30, r31, handle_tlb_refill_nopage
149         pte_makewrite   r30, r31        /* Access|Modify|Dirty|Valid */
150         pte_reload      r31
151         mtrtlb
152         nop
153         nop
154         nop
155         nop
156         nop
157         rte
158 handle_tlb_refill_nopage:
159         do_fault        0               /* Read */
161 ENTRY(handle_tlb_invaild)
162         load_pte        r30, r31
163         stlb                            /* find faulting entry */
164         pte_writable    r30, r31, handle_tlb_invaild_nopage
165         pte_makewrite   r30, r31        /* Access|Modify|Dirty|Valid */
166         pte_reload      r31
167         mtptlb
168         nop
169         nop
170         nop
171         nop
172         nop
173         rte
174 handle_tlb_invaild_nopage:
175         do_fault        0               /* Read */
177 ENTRY(handle_mod)
178         load_pte        r30, r31
179         stlb                            /* find faulting entry */
180         andi    r30, _PAGE_WRITE        /* Writable? */
181         cmpz.c  r30
182         beq     nowrite_mod
183         lw      r30, [r31, 0]           /* reload into r30 */
185         /* Present and writable bits set, set accessed and dirty bits. */
186         pte_makewrite   r30, r31
188         /* Now reload the entry into the tlb. */
189         pte_reload      r31
190         mtptlb
191         nop
192         nop
193         nop
194         nop
195         nop
196         rte
198 nowrite_mod:
199         do_fault        1       /* Write */