Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
3d44305a
Commit
3d44305a
authored
Jan 25, 2008
by
Jesper Nilsson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
CRIS v32: Add workaround for MMU hardware bug for ETRAX FS in mm/mmu.S
parent
108ecfbc
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
81 additions
and
12 deletions
+81
-12
arch/cris/arch-v32/mm/mmu.S
arch/cris/arch-v32/mm/mmu.S
+81
-12
No files found.
arch/cris/arch-v32/mm/mmu.S
View file @
3d44305a
; WARNING : The refill handler has been modified, see below !!!
/*
*
Copyright
(
C
)
2003
Axis
Communications
AB
*
...
...
@@ -61,6 +63,14 @@
; Note that the code is optimized to minimize stalls (makes the code harder
; to read).
;
; WARNING !!!
; Modified by Mikael Asker 060725: added a workaround for strange TLB
; behavior. If the same PTE is present in more than one set, the TLB
; doesn't recognize it and we get stuck in a loop of refill exceptions.
; The workaround detects such loops and exits them by flushing
; the TLB contents. The problem and workaround were verified
; in VCS by Mikael Starvik.
;
; Each page is 8 KB. Each PMD holds 8192/4 PTEs (each PTE is 4 bytes) so each
; PMD holds 16 MB of virtual memory.
; Bits 0-12 : Offset within a page
...
...
@@ -68,6 +78,11 @@
; Bits 24-31 : PMD offset within the PGD
.
macro
MMU_REFILL_HANDLER
handler
,
mmu
.
data
1
:
.
dword
0
; refill_count
; == 0 <=> last_refill_cause is invalid
2
:
.
dword
0
; last_refill_cause
.
text
.
globl
\
handler
\
handler
:
subq
4
,
$sp
...
...
@@ -76,42 +91,96 @@
subq
4
,
$sp
move
\
mmu
,
$srs
; Select MMU support register bank
move.d
$acr
,
[
$sp
]
subq
4
,
$sp
move.d
$r0
,
[
$sp
]
subq
12
,
$sp
move.d
1
b
,
$acr
; Point to refill_count
movem
$r2
,
[
$sp
]
test.d
[
$acr
]
; refill_count == 0 ?
beq
5
f
; yes, last_refill_cause is invalid
move.d
$acr
,
$r1
; last_refill_cause is valid, investigate cause
addq
4
,
$r1
; Point to last_refill_cause
move
$s3
,
$r0
; Get rw_mm_cause
move.d
[
$r1
],
$r2
; Get last_refill_cause
cmp.d
$r0
,
$r2
; rw_mm_cause == last_refill_cause ?
beq
6
f
; yes, increment count
moveq
1
,
$r2
; rw_mm_cause != last_refill_cause
move.d
$r2
,
[
$acr
]
; refill_count = 1
move.d
$r0
,
[
$r1
]
; last_refill_cause = rw_mm_cause
3
:
; Probably not in a loop, continue normal processing
#ifdef CONFIG_SMP
move
$s7
,
$acr
; PGD
#else
move.d
per_cpu__current_pgd
,
$acr
; PGD
#endif
; Look up PMD in PGD
move
$s3
,
$r0
; rw_mm_cause
lsrq
24
,
$r0
; Get PMD index into PGD (bit 24-31)
move.d
[
$acr
],
$acr
; PGD for the current process
addi
$r0.
d
,
$acr
,
$acr
move
$s3
,
$r0
; rw_mm_cause
move.d
[
$acr
],
$acr
; Get PMD
beq
1
f
beq
8
f
; Look up PTE in PMD
lsrq
PAGE_SHIFT
,
$r0
and.w
PAGE_MASK
,
$acr
; Remove PMD flags
and.d
0x7ff
,
$r0
; Get PTE index into PMD (bit 13-23)
addi
$r0.
d
,
$acr
,
$acr
move.d
[
$acr
],
$acr
; Get PTE
beq
2
f
move.d
[
$sp
+],
$r0
; Pop r0 in delayslot
beq
9
f
movem
[
$sp
],
$r2
; Restore r0-r2 in delay slot
addq
12
,
$sp
; Store in TLB
move
$acr
,
$s5
; Return
4
:
; Return
move.d
[
$sp
+],
$acr
move
[
$sp
],
$srs
move
[
$sp
],
$srs
addq
4
,
$sp
rete
rfe
1
:
; PMD missing, let the mm subsystem fix it up.
move.d
[
$sp
+],
$r0
; Pop r0
2
:
; PTE missing, let the mm subsystem fix it up.
5
:
; last_refill_cause is invalid
moveq
1
,
$r2
addq
4
,
$r1
; Point to last_refill_cause
move.d
$r2
,
[
$acr
]
; refill_count = 1
move
$s3
,
$r0
; Get rw_mm_cause
ba
3
b
; Continue normal processing
move.d
$r0
,[
$r1
]
; last_refill_cause = rw_mm_cause
6
:
; rw_mm_cause == last_refill_cause
move.d
[
$acr
],
$r2
; Get refill_count
cmpq
4
,
$r2
; refill_count > 4 ?
bhi
7
f
; yes
addq
1
,
$r2
; refill_count++
ba
3
b
; Continue normal processing
move.d
$r2
,
[
$acr
]
7
:
; refill_count > 4, error
move.d
$acr
,
$r0
; Save pointer to refill_count
clear.d
[
$r0
]
; refill_count = 0
;; rewind the short stack
movem
[
$sp
],
$r2
; Restore r0-r2
addq
12
,
$sp
move.d
[
$sp
+],
$acr
move
[
$sp
],
$srs
addq
4
,
$sp
;; Keep it simple (slow), save all the regs.
SAVE_ALL
jsr
__flush_tlb_all
nop
ba
ret_from_intr
; Return
nop
8
:
; PMD missing, let the mm subsystem fix it up.
movem
[
$sp
],
$r2
; Restore r0-r2
9
:
; PTE missing, let the mm subsystem fix it up.
addq
12
,
$sp
move.d
[
$sp
+],
$acr
move
[
$sp
],
$srs
move
[
$sp
],
$srs
addq
4
,
$sp
SAVE_ALL
move
\
mmu
,
$srs
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment