Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
cMIPS
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Harbor Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Strozzi
cMIPS
Commits
0def435e
Commit
0def435e
authored
9 years ago
by
Roberto Hexsel
Browse files
Options
Downloads
Patches
Plain Diff
handler for TLBload e TLBstore
parent
7fb756c2
No related branches found
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
cMIPS/include/handlers.s
+30
-18
30 additions, 18 deletions
cMIPS/include/handlers.s
cMIPS/include/start.s
+17
-8
17 additions, 8 deletions
cMIPS/include/start.s
cMIPS/tests/pt_walk.c
+31
-21
31 additions, 21 deletions
cMIPS/tests/pt_walk.c
with
78 additions
and
47 deletions
cMIPS/include/handlers.s
+
30
−
18
View file @
0def435e
...
...
@@ -199,7 +199,12 @@ disableInterr:
#===============================================================
=
#
handle
TLB
Modified
exception
(
store
to
page
with
bit
dirty
=
0
)
#
handle
TLB
Modified
exception
--
store
to
page
with
bit
dirty
=
0
#
#
(
a
)
fix
TLB
entry
,
by
setting
dirty
=
1
;
#
(
b
)
check
permissions
in
PT
entry
and
(
maybe
)
kill
the
process
#
OR
mark
PT
entry
as
Used
and
Modified
,
then
#
update
TLB
entry
.
#
.
global
_excp_saves
.
global
_excp_0180ret
...
...
@@ -233,7 +238,7 @@ M_even: addi $a2, $a0, 4 # address for even entry
M_test
:
lw
$a1
,
0
(
$a2
)
#
read
PT
[
badVAddr
]
mfc0
$k0
,
c0_badvaddr
#
get
faulting
address
andi
$a0
,
$a1
,
0x000
3
#
check
if
page
is
mapped
andi
$a0
,
$a1
,
0x000
1
#
check
if
page
is
mapped
beq
$a0
,
$zero
,
M_seg_fault
#
no
,
abort
simulation
nop
...
...
@@ -242,11 +247,11 @@ M_test: lw $a1, 0($a2) # read PT[badVAddr]
nop
andi
$a0
,
$a1
,
0x0002
#
check
if
page
is
in
secondary
memory
bne
$a0
,
$zero
,
M_sec_mem
bne
$a0
,
$zero
,
M_sec_mem
#
yes
,
abort
simulation
nop
mfc0
$a0
,
c0_epc
#
check
if
fault
is
on
an
instruction
beq
$a0
,
$k0
,
M_prot_viol
#
k0
is
badVAddr
beq
$a0
,
$k0
,
M_prot_viol
#
k0
is
badVAddr
,
if
so
,
abort
nop
ori
$a1
,
$a1
,
0x0030
#
mark
PT
entry
as
modified
,
used
...
...
@@ -277,7 +282,7 @@ M_prot_viol: # print message and abort simulation
nop
nop
nop
wait
0x4
1
wait
0x4
2
M_sec_mem
:
#
print
message
and
abort
simulation
la
$k1
,
x_IO_BASE_ADDR
...
...
@@ -287,7 +292,7 @@ M_sec_mem: # print message and abort simulation
nop
nop
nop
wait
0x4
1
wait
0x4
3
.
end
handle_Mod
#----------------------------------------------------------------
...
...
@@ -296,7 +301,10 @@ M_sec_mem: # print message and abort simulation
#===============================================================
=
#
handle
TLB
Load
exception
:
double
-
fault
caused
by
a
TLB
miss
#
to
the
Page
Table
--
mapping
pointing
to
PT
is
not
on
TLB
#
so
,
fix
the
TLB
by
storing
mapping
onto
TLB
[
4
]
#
#
(
a
)
fix
the
fault
by
(
re
)
loading
the
mapping
into
TLB
[
4
]
;
#
(
b
)
check
permissions
in
PT
entry
and
(
maybe
)
kill
the
process
.
#
.
global
_excp_saves
.
global
_excp_0180ret
.
global
handle_TLBL
...
...
@@ -305,7 +313,7 @@ M_sec_mem: # print message and abort simulation
.
ent
handle_TLBL
handle_TLBL
:
#
EntryHi
points
to
offending
TLB
entry
tlbp
#
what
is
the
offender
's index
?
tlbp
#
probe
it
to
find
the
offender
's index
lui
$k1
,
%
hi
(
_excp_saves
)
ori
$k1
,
$k1
,
%
lo
(
_excp_saves
)
sw
$a0
,
9
*
4
(
$k1
)
...
...
@@ -315,8 +323,8 @@ handle_TLBL: # EntryHi points to offending TLB entry
mfc0
$a0
,
c0_badvaddr
la
$a1
,
(
_PT
+
(
x_INST_BASE_ADDR
>>
13
)*
16
)
slt
$a2
,
$a0
,
$a1
#
a2
<-
badVAddr
<=
PageTable
bne
$a2
,
$zero
,
L_chks
slt
$a2
,
$a0
,
$a1
#
a2
<-
(
badVAddr
<=
PageTable
)
bne
$a2
,
$zero
,
L_chks
#
fault
is
not
to
PageTable
nop
#
this
is
same
code
as
in
start
.
s
...
...
@@ -344,24 +352,27 @@ L_chks: andi $a0, $a0, 0x1000 # check if even or odd page
mfc0
$a0
,
c0_context
L_odd
:
j
L_test
addi
$a2
,
$a0
,
12
#
address
for
odd
entry
addi
$a2
,
$a0
,
12
#
address
for
odd
intLo1
entry
L_even
:
addi
$a2
,
$a0
,
4
#
address
for
even
entry
L_even
:
addi
$a2
,
$a0
,
4
#
address
for
even
intLo0
entry
L_test
:
lw
$a1
,
0
(
$a2
)
mfc0
$k0
,
c0_badvaddr
#
get
faulting
address
andi
$a0
,
$a1
,
0x000
3
#
check
if
page
is
mapped
beq
$a0
,
$zero
,
M_seg_fault
L_test
:
lw
$a1
,
0
(
$a2
)
#
get
intLo
{
0
,
1
}
mfc0
$k0
,
c0_badvaddr
#
get
faulting
address
for
printing
andi
$a0
,
$a1
,
0x000
1
#
check
if
page
is
mapped
beq
$a0
,
$zero
,
M_seg_fault
#
no
,
abort
simulation
nop
andi
$a0
,
$a1
,
0x0002
#
check
if
page
is
in
secondary
memory
bne
$a0
,
$zero
,
M_sec_mem
bne
$a0
,
$zero
,
M_sec_mem
#
yes
,
abort
simulation
nop
ori
$a1
,
$a1
,
0x0010
#
mark
PT
entry
as
used
sw
$a1
,
0
(
$a2
)
L_ret
:
lw
$a0
,
9
*
4
(
$k1
)
#
nothing
else
to
do
,
return
??
# if this were handler_TLBS, now is the time to also mark the
#
PT
entry
as
Modified
L_ret
:
lw
$a0
,
9
*
4
(
$k1
)
#
nothing
else
to
do
,
return
lw
$a1
,
10
*
4
(
$k1
)
j
_excp_0180ret
lw
$a2
,
11
*
4
(
$k1
)
...
...
@@ -407,6 +418,7 @@ TLB_purge:
move
$v0
,
$zero
#
V_addr
was
purged
from
TLB
tlbwi
#
write
invalid
mappings
to
TLB
ehb
pu_miss
:
jr
$ra
nop
...
...
This diff is collapsed.
Click to expand it.
cMIPS/include/start.s
+
17
−
8
View file @
0def435e
...
...
@@ -100,14 +100,23 @@ _start:
mtc0
$a1
,
c0_entrylo0
#
bottom
page
(
even
)
la
$a0
,
(
(
MIDDLE_RAM
+
1
*
4096
)
>>
12
)<<
6
ori
$a
1
,
$a0
,
0
b00000000000000000000000000000111
#
ccc
=
0
,
d
,
v
,
g1
mtc0
$a
1
,
c0_entrylo1
#
bottom
page
+
1
(
odd
)
ori
$a
2
,
$a0
,
0
b00000000000000000000000000000111
#
ccc
=
0
,
d
,
v
,
g1
mtc0
$a
2
,
c0_entrylo1
#
bottom
page
+
1
(
odd
)
#
and
write
it
to
TLB
[
4
]
li
$k0
,
4
mtc0
$k0
,
c0_index
tlbwi
#
create
a
PT
entry
for
the
Page
Table
itself
#
in
these
simulations
,
only
the
first
page
is
used
la
$a0
,
MIDDLE_RAM
srl
$a0
,
$a0
,
9
#
(
_PT
>>
13
)*
16
la
$v0
,
PTbase
add
$a0
,
$v0
,
$a0
sw
$a1
,
0
(
$a0
)
#
write
to
PT
[
_PTV
]
.
entryLo0
sw
$a2
,
8
(
$a0
)
#
write
to
PT
[
_PTV
]
.
entryLo1
#
pin
down
first
five
TLB
entries
:
ROM
[
0
],
I
/
O
,
RAM
[
0
],
stack
,
PgTbl
li
$k0
,
5
...
...
@@ -233,8 +242,8 @@ excp_tbl: # see Table 8-25, pg 95,96
j
handle_TLBL
#
2
nop
j
h_TLB
S
#
3
nop
j
h
andle
_TLB
L
#
3
==
TLBS
if
miss
on
PT
,
on
the
TLB
,
on
a
store
nop
#
should
mark
page
as
Modified
on
PT
wait
0x04
#
4
AdEL
addr
error
--
abort
simulation
nop
...
...
@@ -449,15 +458,15 @@ PTbase: .word ( (x_INST_BASE_ADDR + 0*4096) >>6) | 0b000011
.
word
0x00000006
#
PT
[
2
]
--
not
mapped
for
simulation
.
word
(
(
x_INST_BASE_ADDR
+
4
*
4096
)
>>
6
)
|
0
b0000
1
1
.
word
(
(
x_INST_BASE_ADDR
+
4
*
4096
)
>>
6
)
|
0
b0000
0
1
.
word
0x00000004
.
word
(
(
x_INST_BASE_ADDR
+
5
*
4096
)
>>
6
)
|
0
b0000
1
1
.
word
(
(
x_INST_BASE_ADDR
+
5
*
4096
)
>>
6
)
|
0
b0000
0
1
.
word
0x00000004
#
PT
[
3
]
--
not
mapped
for
simulation
.
word
(
(
x_INST_BASE_ADDR
+
6
*
4096
)
>>
6
)
|
0
b0000
1
1
.
word
(
(
x_INST_BASE_ADDR
+
6
*
4096
)
>>
6
)
|
0
b0000
0
1
.
word
0x00000004
.
word
(
(
x_INST_BASE_ADDR
+
7
*
4096
)
>>
6
)
|
0
b0000
1
1
.
word
(
(
x_INST_BASE_ADDR
+
7
*
4096
)
>>
6
)
|
0
b0000
0
1
.
word
0x00000004
#
PT
[
4
]
--
not
mapped
for
simulation
...
...
This diff is collapsed.
Click to expand it.
cMIPS/tests/pt_walk.c
+
31
−
21
View file @
0def435e
...
...
@@ -17,9 +17,9 @@
//-----------------------------------------------------------------------
// decide on the tests to run
#define WALK_THE_PT
0
#define WALK_THE_PT
1
#define TLB_MODIFIED 1
#define DOUBLE_FAULT
0
#define DOUBLE_FAULT
1
// these will abort the simulation when the fault is detected/handled
#define PROT_VIOL 0
...
...
@@ -83,8 +83,8 @@ void main(void) {
// let's change a mapping to cause a TLB-Modified exception
//
// in fact, there will be TWO exceptions:
// (1) a TLB-Refill will cop
u
the
write-protected
mapping from the PT
//
and retry the
instruction;
// (1) a TLB-Refill will cop
y
the mapping from the PT
and retry the
// instruction;
// (2) when the sw is retried, it will cause a TLB-Modified
// exception, which checks PT's protection bits, then fixes the
// dirty bit in the TLB, and retries again, succeeding this time.
...
...
@@ -110,9 +110,9 @@ void main(void) {
if
(
*
walker
==
0x99
)
{
// this load is optimized away by gcc
print
(
*
walker
);
print_str
(
"
\t
Mod ok
\n
"
);
print_str
(
"
\t
Mod ok
\n
\n
"
);
}
else
{
print_str
(
"
\t
Mod err
\n
"
);
print_str
(
"
\t
Mod err
\n
\n
"
);
}
#endif
...
...
@@ -121,30 +121,41 @@ void main(void) {
#if DOUBLE_FAULT
//--------------------------------------------------------------------
// let's remove a PT's mapping from the TLB and cause a double-fault:
// let's remove from the TLB the mapping for the PT itself and cause
// a double-fault:
//
// (1) on the 1st reference, TLB-refill does not find a mapping for
// the PT on the TLB; this causes a TLBL (load) exception;
// (2) routine handle_TLBL writes a new mapping on the PT, refills
// the TLB, then retries the reference, which succeeds this time.
// the TLB, then retries the reference;
// (3) the page referenced is not on the TLB, so there is another
// TLB-refill, which loads the mapping, the store is retried
// and succeeds.
//--------------------------------------------------------------------
// remove the TLB entry for datum to be referenced
walker
=
(
int
*
)(
x_DATA_BASE_ADDR
+
PG_NUM
*
4096
+
1024
);
if
(
TLB_purge
((
void
*
)
walker
)
==
0
)
{
print_str
(
"
\t
addr purged from TLB
\n
"
);
}
else
{
print_str
(
"
\t
TLB miss
\n
"
);
}
// this is the base of the page table
walker
=
(
int
*
)(
x_DATA_BASE_ADDR
+
(
x_DATA_MEM_SZ
/
2
));
// remove the TLB entry which points to the PT
if
(
TLB_purge
((
void
*
)
walker
)
==
0
)
{
print_str
(
"
\
n\
t
PT purged from TLB
\n
"
);
print_str
(
"
\t
PT purged from TLB
\n
"
);
}
else
{
print_str
(
"
\
n\
t
wtf?
\n
"
);
print_str
(
"
\t
wtf?
\n
"
);
}
// now reference a mapped page, to cause the double fault
walker
=
(
int
*
)(
x_DATA_BASE_ADDR
+
PG_NUM
*
4096
+
1024
);
*
walker
=
0x88
;
// cause a TLBrefill then a TLBload
*
walker
=
0x77
;
// cause a TLBrefill then a TLBload
if
(
*
walker
==
0x77
)
{
// this load is optimized away by gcc
if
(
*
walker
==
0x88
)
{
// this load is optimized away by gcc
print
(
*
walker
);
print_str
(
"
\t
double ok
\n
"
);
}
else
{
...
...
@@ -176,10 +187,10 @@ void main(void) {
new_value
=
0x00000001
;
// NOT-writable, mapped
PT_update
(
(
int
*
)
walker
,
1
,
new_value
);
*
walker
=
0x
88
;
*
walker
=
0x
77
;
// will never get here -- protection violation on the store
if
(
*
walker
==
0x
88
)
{
// this load is optimized away by gcc
if
(
*
walker
==
0x
77
)
{
// this load is optimized away by gcc
print
(
*
walker
);
print_str
(
"
\t
prot viol not ok
\n
"
);
}
else
{
...
...
@@ -219,10 +230,10 @@ void main(void) {
PT_update
(
(
int
*
)
walker
,
2
,
new_value
);
PT_update
(
(
int
*
)
walker
,
3
,
0
);
// mark as unmapped
*
walker
=
0x
44
;
*
walker
=
0x
66
;
// will never get here -- seg fault on the store
if
(
*
walker
==
0x
44
)
{
// this load is optimized away by gcc
if
(
*
walker
==
0x
66
)
{
// this load is optimized away by gcc
print
(
*
walker
);
print_str
(
"
\t
seg fault not ok
\n
"
);
}
else
{
...
...
@@ -231,10 +242,9 @@ void main(void) {
#endif
to_stdout
(
'\n'
);
}
//----------------------------------------------------------------------
void
print_str
(
char
*
s
)
{
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment