Commit 01858d1b authored by Chris Zankel's avatar Chris Zankel

[XTENSA] Add support for executable/non-executable feature in the mmu

Newer processor versions starting with Xtensa6/LX2 support an 'executable'
bit for memory pages. This bit replaces the 'valid' bit, so it must be
always set to one for older processor versions. To mark a page invalid, we now
set the cache-attributes to b11, which is backward compatible.
Signed-off-by: default avatarChris Zankel <chris@zankel.net>
parent 26465f2f
...@@ -1572,10 +1572,12 @@ ENTRY(fast_second_level_miss) ...@@ -1572,10 +1572,12 @@ ENTRY(fast_second_level_miss)
l32i a0, a1, TASK_MM # tsk->mm l32i a0, a1, TASK_MM # tsk->mm
beqz a0, 9f beqz a0, 9f
8: rsr a1, EXCVADDR # fault address
_PGD_OFFSET(a0, a1, a1) /* We deliberately destroy a3 that holds the exception table. */
8: rsr a3, EXCVADDR # fault address
_PGD_OFFSET(a0, a3, a1)
l32i a0, a0, 0 # read pmdval l32i a0, a0, 0 # read pmdval
//beqi a0, _PAGE_USER, 2f
beqz a0, 2f beqz a0, 2f
/* Read ptevaddr and convert to top of page-table page. /* Read ptevaddr and convert to top of page-table page.
...@@ -1596,20 +1598,34 @@ ENTRY(fast_second_level_miss) ...@@ -1596,20 +1598,34 @@ ENTRY(fast_second_level_miss)
extui a1, a0, 0, PAGE_SHIFT # ... & PAGE_MASK extui a1, a0, 0, PAGE_SHIFT # ... & PAGE_MASK
xor a0, a0, a1 xor a0, a0, a1
movi a1, _PAGE_DIRECTORY
movi a1, PAGE_DIRECTORY
or a0, a0, a1 # ... | PAGE_DIRECTORY or a0, a0, a1 # ... | PAGE_DIRECTORY
/*
* We utilize all three wired-ways (7-9( to hold pmd translations.
* Memory regions are mapped to the DTLBs according to bits 28 and 29.
* This allows to map the three most common regions to three different
* DTLBs:
* 0,1 -> way 7 program (0040.0000) and virtual (c000.0000)
* 2 -> way 8 shared libaries (2000.0000)
* 3 -> way 0 stack (3000.0000)
*/
extui a3, a3, 28, 2 # addr. bit 28 and 29 0,1,2,3
rsr a1, PTEVADDR rsr a1, PTEVADDR
addx2 a3, a3, a3 # -> 0,3,6,9
srli a1, a1, PAGE_SHIFT srli a1, a1, PAGE_SHIFT
extui a3, a3, 2, 2 # -> 0,0,1,2
slli a1, a1, PAGE_SHIFT # ptevaddr & PAGE_MASK slli a1, a1, PAGE_SHIFT # ptevaddr & PAGE_MASK
addi a1, a1, DTLB_WAY_PGD # ... + way_number addi a3, a3, DTLB_WAY_PGD
add a1, a1, a3 # ... + way_number
wdtlb a0, a1 3: wdtlb a0, a1
dsync dsync
/* Exit critical section. */ /* Exit critical section. */
4: movi a3, exc_table # restore a3
movi a0, 0 movi a0, 0
s32i a0, a3, EXC_TABLE_FIXUP s32i a0, a3, EXC_TABLE_FIXUP
...@@ -1638,6 +1654,7 @@ ENTRY(fast_second_level_miss) ...@@ -1638,6 +1654,7 @@ ENTRY(fast_second_level_miss)
2: /* Invalid PGD, default exception handling */ 2: /* Invalid PGD, default exception handling */
movi a3, exc_table
rsr a1, DEPC rsr a1, DEPC
xsr a3, EXCSAVE_1 xsr a3, EXCSAVE_1
s32i a1, a2, PT_AREG2 s32i a1, a2, PT_AREG2
...@@ -1682,15 +1699,15 @@ ENTRY(fast_store_prohibited) ...@@ -1682,15 +1699,15 @@ ENTRY(fast_store_prohibited)
8: rsr a1, EXCVADDR # fault address 8: rsr a1, EXCVADDR # fault address
_PGD_OFFSET(a0, a1, a4) _PGD_OFFSET(a0, a1, a4)
l32i a0, a0, 0 l32i a0, a0, 0
//beqi a0, _PAGE_USER, 2f # FIXME use _PAGE_INVALID
beqz a0, 2f beqz a0, 2f
/* Note that we assume _PAGE_WRITABLE_BIT is only set if pte is valid.*/
_PTE_OFFSET(a0, a1, a4) _PTE_OFFSET(a0, a1, a4)
l32i a4, a0, 0 # read pteval l32i a4, a0, 0 # read pteval
movi a1, _PAGE_VALID | _PAGE_RW bbci.l a4, _PAGE_WRITABLE_BIT, 2f
bnall a4, a1, 2f
movi a1, _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_WRENABLE movi a1, _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_HW_WRITE
or a4, a4, a1 or a4, a4, a1
rsr a1, EXCVADDR rsr a1, EXCVADDR
s32i a4, a0, 0 s32i a4, a0, 0
...@@ -1700,10 +1717,7 @@ ENTRY(fast_store_prohibited) ...@@ -1700,10 +1717,7 @@ ENTRY(fast_store_prohibited)
dhwb a0, 0 dhwb a0, 0
#endif #endif
pdtlb a0, a1 pdtlb a0, a1
beqz a0, 1f
idtlb a0 // FIXME do we need this?
wdtlb a4, a0 wdtlb a4, a0
1:
/* Exit critical section. */ /* Exit critical section. */
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment