diff options
Diffstat (limited to 'arch/sparc/include/asm/tsb.h')
-rw-r--r-- | arch/sparc/include/asm/tsb.h | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h index b4c258de4443..e696432b950d 100644 --- a/arch/sparc/include/asm/tsb.h +++ b/arch/sparc/include/asm/tsb.h | |||
@@ -157,17 +157,26 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; | |||
157 | andn REG2, 0x7, REG2; \ | 157 | andn REG2, 0x7, REG2; \ |
158 | add REG1, REG2, REG1; | 158 | add REG1, REG2, REG1; |
159 | 159 | ||
160 | /* This macro exists only to make the PMD translator below easier | 160 | /* These macros exists only to make the PMD translator below |
161 | * to read. It hides the ELF section switch for the sun4v code | 161 | * easier to read. It hides the ELF section switch for the |
162 | * patching. | 162 | * sun4v code patching. |
163 | */ | 163 | */ |
164 | #define OR_PTE_BIT(REG, NAME) \ | 164 | #define OR_PTE_BIT_1INSN(REG, NAME) \ |
165 | 661: or REG, _PAGE_##NAME##_4U, REG; \ | 165 | 661: or REG, _PAGE_##NAME##_4U, REG; \ |
166 | .section .sun4v_1insn_patch, "ax"; \ | 166 | .section .sun4v_1insn_patch, "ax"; \ |
167 | .word 661b; \ | 167 | .word 661b; \ |
168 | or REG, _PAGE_##NAME##_4V, REG; \ | 168 | or REG, _PAGE_##NAME##_4V, REG; \ |
169 | .previous; | 169 | .previous; |
170 | 170 | ||
171 | #define OR_PTE_BIT_2INSN(REG, TMP, NAME) \ | ||
172 | 661: sethi %hi(_PAGE_##NAME##_4U), TMP; \ | ||
173 | or REG, TMP, REG; \ | ||
174 | .section .sun4v_2insn_patch, "ax"; \ | ||
175 | .word 661b; \ | ||
176 | mov -1, TMP; \ | ||
177 | or REG, _PAGE_##NAME##_4V, REG; \ | ||
178 | .previous; | ||
179 | |||
171 | /* Load into REG the PTE value for VALID, CACHE, and SZHUGE. */ | 180 | /* Load into REG the PTE value for VALID, CACHE, and SZHUGE. */ |
172 | #define BUILD_PTE_VALID_SZHUGE_CACHE(REG) \ | 181 | #define BUILD_PTE_VALID_SZHUGE_CACHE(REG) \ |
173 | 661: sethi %uhi(_PAGE_VALID|_PAGE_SZHUGE_4U), REG; \ | 182 | 661: sethi %uhi(_PAGE_VALID|_PAGE_SZHUGE_4U), REG; \ |
@@ -214,12 +223,13 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; | |||
214 | andn REG1, PMD_HUGE_PROTBITS, REG2; \ | 223 | andn REG1, PMD_HUGE_PROTBITS, REG2; \ |
215 | sllx REG2, PMD_PADDR_SHIFT, REG2; \ | 224 | sllx REG2, PMD_PADDR_SHIFT, REG2; \ |
216 | /* REG2 now holds PFN << PAGE_SHIFT */ \ | 225 | /* REG2 now holds PFN << PAGE_SHIFT */ \ |
217 | andcc REG1, PMD_HUGE_EXEC, %g0; \ | 226 | andcc REG1, PMD_HUGE_WRITE, %g0; \ |
218 | bne,a,pt %xcc, 1f; \ | ||
219 | OR_PTE_BIT(REG2, EXEC); \ | ||
220 | 1: andcc REG1, PMD_HUGE_WRITE, %g0; \ | ||
221 | bne,a,pt %xcc, 1f; \ | 227 | bne,a,pt %xcc, 1f; \ |
222 | OR_PTE_BIT(REG2, W); \ | 228 | OR_PTE_BIT_1INSN(REG2, W); \ |
229 | 1: andcc REG1, PMD_HUGE_EXEC, %g0; \ | ||
230 | be,pt %xcc, 1f; \ | ||
231 | nop; \ | ||
232 | OR_PTE_BIT_2INSN(REG2, REG1, EXEC); \ | ||
223 | /* REG1 can now be clobbered, build final PTE */ \ | 233 | /* REG1 can now be clobbered, build final PTE */ \ |
224 | 1: BUILD_PTE_VALID_SZHUGE_CACHE(REG1); \ | 234 | 1: BUILD_PTE_VALID_SZHUGE_CACHE(REG1); \ |
225 | ba,pt %xcc, PTE_LABEL; \ | 235 | ba,pt %xcc, PTE_LABEL; \ |