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
aac372de
Commit
aac372de
authored
Oct 12, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
parents
02d31ed2
c9c10830
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
166 additions
and
226 deletions
+166
-226
arch/sparc64/kernel/dtlb_base.S
arch/sparc64/kernel/dtlb_base.S
+5
-9
arch/sparc64/kernel/dtlb_prot.S
arch/sparc64/kernel/dtlb_prot.S
+6
-6
arch/sparc64/kernel/head.S
arch/sparc64/kernel/head.S
+26
-35
arch/sparc64/kernel/itlb_base.S
arch/sparc64/kernel/itlb_base.S
+11
-15
arch/sparc64/kernel/ktlb.S
arch/sparc64/kernel/ktlb.S
+44
-48
arch/sparc64/mm/init.c
arch/sparc64/mm/init.c
+74
-113
No files found.
arch/sparc64/kernel/dtlb_base.S
View file @
aac372de
...
...
@@ -53,19 +53,18 @@
*
be
guaranteed
to
be
0
...
mmu_context
.
h
does
guarantee
this
*
by
only
using
10
bits
in
the
hwcontext
value
.
*/
#define CREATE_VPTE_OFFSET1(r1, r2)
#define CREATE_VPTE_OFFSET1(r1, r2)
nop
#define CREATE_VPTE_OFFSET2(r1, r2) \
srax
r1
,
10
,
r2
#define CREATE_VPTE_NOP nop
#else
#define CREATE_VPTE_OFFSET1(r1, r2) \
srax
r1
,
PAGE_SHIFT
,
r2
#define CREATE_VPTE_OFFSET2(r1, r2) \
sllx
r2
,
3
,
r2
#define CREATE_VPTE_NOP
#endif
/*
DTLB
**
ICACHE
line
1
:
Quick
user
TLB
misses
*/
mov
TLB_SFSR
,
%
g1
ldxa
[%
g1
+
%
g1
]
ASI_DMMU
,
%
g4
!
Get
TAG_ACCESS
andcc
%
g4
,
TAG_CONTEXT_BITS
,
%
g0
!
From
Nucleus
?
from_tl1_trap
:
...
...
@@ -74,18 +73,16 @@ from_tl1_trap:
be
,
pn
%
xcc
,
kvmap
!
Yep
,
special
processing
CREATE_VPTE_OFFSET2
(%
g4
,
%
g6
)
!
Create
VPTE
offset
cmp
%
g5
,
4
!
Last
trap
level
?
be
,
pn
%
xcc
,
longpath
!
Yep
,
cannot
risk
VPTE
miss
nop
!
delay
slot
/*
DTLB
**
ICACHE
line
2
:
User
finish
+
quick
kernel
TLB
misses
*/
be
,
pn
%
xcc
,
longpath
!
Yep
,
cannot
risk
VPTE
miss
nop
!
delay
slot
ldxa
[%
g3
+
%
g6
]
ASI_S
,
%
g5
!
Load
VPTE
1
:
brgez
,
pn
%
g5
,
longpath
!
Invalid
,
branch
out
nop
!
Delay
-
slot
9
:
stxa
%
g5
,
[%
g0
]
ASI_DTLB_DATA_IN
!
Reload
TLB
retry
!
Trap
return
nop
nop
nop
/*
DTLB
**
ICACHE
line
3
:
winfixups
+
real_faults
*/
longpath
:
...
...
@@ -106,8 +103,7 @@ longpath:
nop
nop
nop
CREATE_VPTE_NOP
nop
#undef CREATE_VPTE_OFFSET1
#undef CREATE_VPTE_OFFSET2
#undef CREATE_VPTE_NOP
arch/sparc64/kernel/dtlb_prot.S
View file @
aac372de
...
...
@@ -14,14 +14,14 @@
*/
/*
PROT
**
ICACHE
line
1
:
User
DTLB
protection
trap
*/
stxa
%
g0
,
[%
g1
]
ASI_DMMU
!
Clear
SFSR
FaultValid
bit
membar
#
Sync
!
Synchronize
ASI
stores
rdpr
%
pstate
,
%
g5
!
Move
into
alternate
globals
mov
TLB_SFSR
,
%
g1
stxa
%
g0
,
[%
g1
]
ASI_DMMU
!
Clear
FaultValid
bit
membar
#
Sync
!
Synchronize
stores
rdpr
%
pstate
,
%
g5
!
Move
into
alt
-
globals
wrpr
%
g5
,
PSTATE_AG
|
PSTATE_MG
,
%
pstate
rdpr
%
tl
,
%
g1
!
Need
to
do
a
winfixup
?
rdpr
%
tl
,
%
g1
!
Need
a
winfixup
?
cmp
%
g1
,
1
!
Trap
level
>
1
?
mov
TLB_TAG_ACCESS
,
%
g4
!
Prepare
reload
of
vaddr
nop
mov
TLB_TAG_ACCESS
,
%
g4
!
For
reload
of
vaddr
/*
PROT
**
ICACHE
line
2
:
More
real
fault
processing
*/
bgu
,
pn
%
xcc
,
winfix_trampoline
!
Yes
,
perform
winfixup
...
...
arch/sparc64/kernel/head.S
View file @
aac372de
...
...
@@ -28,19 +28,14 @@
#include <asm/mmu.h>
/*
This
section
from
from
_start
to
sparc64_boot_end
should
fit
into
*
0x0000
.0000.0040.4000
to
0x0000
.0000.0040.8000
and
will
be
sharing
space
*
with
bootup_user_stack
,
which
is
from
0x0000
.0000.0040.4000
to
*
0x0000
.0000.0040.6000
and
empty_bad_page
,
which
is
from
*
0x0000
.0000.0040.6000
to
0x0000
.0000.0040.8000.
*
0x0000000000404000
to
0x0000000000408000
.
*/
.
text
.
globl
start
,
_start
,
stext
,
_stext
_start
:
start
:
_stext
:
stext
:
bootup_user_stack
:
!
0
x0000000000404000
b
sparc64_boot
flushw
/*
Flush
register
file
.
*/
...
...
@@ -392,31 +387,30 @@ tlb_fixup_done:
*
former
does
use
this
code
,
the
latter
does
not
yet
due
*
to
some
complexities
.
That
should
be
fixed
up
at
some
*
point
.
*
*
There
used
to
be
enormous
complexity
wrt
.
transferring
*
over
from
the
firwmare
's trap table to the Linux kernel'
s
.
*
For
example
,
there
was
a
chicken
&
egg
problem
wrt
.
building
*
the
OBP
page
tables
,
yet
needing
to
be
on
the
Linux
kernel
*
trap
table
(
to
translate
PAGE_OFFSET
addresses
)
in
order
to
*
do
that
.
*
*
We
now
handle
OBP
tlb
misses
differently
,
via
linear
lookups
*
into
the
prom_trans
[]
array
.
So
that
specific
problem
no
*
longer
exists
.
Yet
,
unfortunately
there
are
still
some
issues
*
preventing
trampoline
.
S
from
using
this
code
...
ho
hum
.
*/
.
globl
setup_trap_table
setup_trap_table
:
save
%
sp
,
-
192
,
%
sp
/
*
Force
interrupts
to
be
disabled
.
Transferring
over
to
*
the
Linux
trap
table
is
a
very
delicate
operation
.
*
Until
we
are
actually
on
the
Linux
trap
table
,
we
cannot
*
get
the
PAGE_OFFSET
linear
mappings
translated
.
We
need
*
that
mapping
to
be
setup
in
order
to
initialize
the
firmware
*
page
tables
.
*
*
So
there
is
this
window
of
time
,
from
the
return
from
*
prom_set_trap_table
()
until
inherit_prom_mappings_post
()
*
(
in
arch
/
sparc64
/
mm
/
init
.
c
)
completes
,
during
which
no
*
firmware
address
space
accesses
can
be
made
.
*/
/
*
Force
interrupts
to
be
disabled
.
*/
rdpr
%
pstate
,
%
o1
andn
%
o1
,
PSTATE_IE
,
%
o1
wrpr
%
o1
,
0x0
,
%
pstate
wrpr
%
g0
,
15
,
%
pil
/
*
Ok
,
now
make
the
final
valid
firmware
call
to
jump
over
*
to
the
Linux
trap
table
.
*/
/
*
Make
the
firmware
call
to
jump
over
to
the
Linux
trap
table
.
*/
call
prom_set_trap_table
sethi
%
hi
(
sparc64_ttable_tl0
),
%
o0
...
...
@@ -540,15 +534,21 @@ setup_tba: /* i0 = is_starfire */
ret
restore
sparc64_boot_end
:
#include "systbls.S"
#include "ktlb.S"
#include "etrap.S"
#include "rtrap.S"
#include "winfixup.S"
#include "entry.S"
/*
*
The
following
skip
s
make
sure
the
trap
table
in
ttable
.
S
is
aligned
*
The
following
skip
makes
sure
the
trap
table
in
ttable
.
S
is
aligned
*
on
a
32
K
boundary
as
required
by
the
v9
specs
for
TBA
register
.
*/
sparc64_boot_end
:
.
skip
0x2000
+
_start
-
sparc64_boot_end
bootup_user_stack_end
:
.
skip
0x2000
1
:
.
skip
0x4000
+
_start
-
1
b
#ifdef CONFIG_SBUS
/*
This
is
just
a
hack
to
fool
make
depend
config
.
h
discovering
...
...
@@ -560,15 +560,6 @@ bootup_user_stack_end:
!
0
x0000000000408000
#include "ttable.S"
#include "systbls.S"
#include "ktlb.S"
#include "etrap.S"
#include "rtrap.S"
#include "winfixup.S"
#include "entry.S"
/
*
This
is
just
anal
retentiveness
on
my
part
...
*/
.
align
16384
.
data
.
align
8
...
...
arch/sparc64/kernel/itlb_base.S
View file @
aac372de
...
...
@@ -15,14 +15,12 @@
*/
#define CREATE_VPTE_OFFSET1(r1, r2) \
srax
r1
,
10
,
r2
#define CREATE_VPTE_OFFSET2(r1, r2)
#define CREATE_VPTE_NOP nop
#define CREATE_VPTE_OFFSET2(r1, r2) nop
#else /* PAGE_SHIFT */
#define CREATE_VPTE_OFFSET1(r1, r2) \
srax
r1
,
PAGE_SHIFT
,
r2
#define CREATE_VPTE_OFFSET2(r1, r2) \
sllx
r2
,
3
,
r2
#define CREATE_VPTE_NOP
#endif /* PAGE_SHIFT */
...
...
@@ -36,6 +34,7 @@
*/
/*
ITLB
**
ICACHE
line
1
:
Quick
user
TLB
misses
*/
mov
TLB_SFSR
,
%
g1
ldxa
[%
g1
+
%
g1
]
ASI_IMMU
,
%
g4
!
Get
TAG_ACCESS
CREATE_VPTE_OFFSET1
(%
g4
,
%
g6
)
!
Create
VPTE
offset
CREATE_VPTE_OFFSET2
(%
g4
,
%
g6
)
!
Create
VPTE
offset
...
...
@@ -43,41 +42,38 @@
1
:
brgez
,
pn
%
g5
,
3
f
!
Not
valid
,
branch
out
sethi
%
hi
(
_PAGE_EXEC
),
%
g4
!
Delay
-
slot
andcc
%
g5
,
%
g4
,
%
g0
!
Executable
?
/*
ITLB
**
ICACHE
line
2
:
Real
faults
*/
be
,
pn
%
xcc
,
3
f
!
Nope
,
branch
.
nop
!
Delay
-
slot
2
:
stxa
%
g5
,
[%
g0
]
ASI_ITLB_DATA_IN
!
Load
PTE
into
TLB
retry
!
Trap
return
3
:
rdpr
%
pstate
,
%
g4
!
Move
into
alternate
globals
/*
ITLB
**
ICACHE
line
2
:
Real
faults
*/
3
:
rdpr
%
pstate
,
%
g4
!
Move
into
alt
-
globals
wrpr
%
g4
,
PSTATE_AG
|
PSTATE_MG
,
%
pstate
rdpr
%
tpc
,
%
g5
!
And
load
faulting
VA
mov
FAULT_CODE_ITLB
,
%
g4
!
It
was
read
from
ITLB
sparc64_realfault_common
:
!
Called
by
TL0
dtlb_miss
too
/*
ITLB
**
ICACHE
line
3
:
Finish
faults
*/
sparc64_realfault_common
:
!
Called
by
dtlb_miss
stb
%
g4
,
[%
g6
+
TI_FAULT_CODE
]
stx
%
g5
,
[%
g6
+
TI_FAULT_ADDR
]
ba
,
pt
%
xcc
,
etrap
!
Save
state
1
:
rd
%
pc
,
%
g7
!
...
nop
/*
ITLB
**
ICACHE
line
3
:
Finish
faults
+
window
fixups
*/
call
do_sparc64_fault
!
Call
fault
handler
add
%
sp
,
PTREGS_OFF
,
%
o0
!
Compute
pt_regs
arg
ba
,
pt
%
xcc
,
rtrap_clr_l6
!
Restore
cpu
state
nop
/*
ITLB
**
ICACHE
line
4
:
Window
fixups
*/
winfix_trampoline
:
rdpr
%
tpc
,
%
g3
!
Prepare
winfixup
TNPC
or
%
g3
,
0x7c
,
%
g3
!
Compute
offset
to
branch
or
%
g3
,
0x7c
,
%
g3
!
Compute
branch
offset
wrpr
%
g3
,
%
tnpc
!
Write
it
into
TNPC
done
!
Do
it
to
it
/*
ITLB
**
ICACHE
line
4
:
Unused
...
*/
nop
nop
nop
nop
CREATE_VPTE_NOP
#undef CREATE_VPTE_OFFSET1
#undef CREATE_VPTE_OFFSET2
#undef CREATE_VPTE_NOP
arch/sparc64/kernel/ktlb.S
View file @
aac372de
...
...
@@ -58,9 +58,6 @@ vpte_noent:
done
vpte_insn_obp
:
sethi
%
hi
(
prom_pmd_phys
),
%
g5
ldx
[%
g5
+
%
lo
(
prom_pmd_phys
)],
%
g5
/
*
Behave
as
if
we
are
at
TL0
.
*/
wrpr
%
g0
,
1
,
%
tl
rdpr
%
tpc
,
%
g4
/*
Find
original
faulting
iaddr
*/
...
...
@@ -71,58 +68,57 @@ vpte_insn_obp:
mov
TLB_SFSR
,
%
g1
stxa
%
g4
,
[%
g1
+
%
g1
]
ASI_IMMU
/
*
Get
PMD
offset
.
*/
srlx
%
g4
,
23
,
%
g6
and
%
g6
,
0x7ff
,
%
g6
sllx
%
g6
,
2
,
%
g6
/
*
Load
PMD
,
is
it
valid
?
*/
lduwa
[%
g5
+
%
g6
]
ASI_PHYS_USE_EC
,
%
g5
brz
,
pn
%
g5
,
longpath
sllx
%
g5
,
11
,
%
g5
/
*
Get
PTE
offset
.
*/
srlx
%
g4
,
13
,
%
g6
and
%
g6
,
0x3ff
,
%
g6
sllx
%
g6
,
3
,
%
g6
/
*
Load
PTE
.
*/
ldxa
[%
g5
+
%
g6
]
ASI_PHYS_USE_EC
,
%
g5
brgez
,
pn
%
g5
,
longpath
nop
/
*
TLB
load
and
return
from
trap
.
*/
sethi
%
hi
(
prom_trans
),
%
g5
or
%
g5
,
%
lo
(
prom_trans
),
%
g5
1
:
ldx
[%
g5
+
0x00
],
%
g6
!
base
brz
,
a
,
pn
%
g6
,
longpath
!
no
more
entries
,
fail
mov
TLB_SFSR
,
%
g1
!
and
restore
%
g1
ldx
[%
g5
+
0x08
],
%
g1
!
len
add
%
g6
,
%
g1
,
%
g1
!
end
cmp
%
g6
,
%
g4
bgu
,
pt
%
xcc
,
2
f
cmp
%
g4
,
%
g1
bgeu
,
pt
%
xcc
,
2
f
ldx
[%
g5
+
0x10
],
%
g1
!
PTE
/
*
TLB
load
,
restore
%
g1
,
and
return
from
trap
.
*/
sub
%
g4
,
%
g6
,
%
g6
add
%
g1
,
%
g6
,
%
g5
mov
TLB_SFSR
,
%
g1
stxa
%
g5
,
[%
g0
]
ASI_ITLB_DATA_IN
retry
kvmap_do_obp
:
sethi
%
hi
(
prom_pmd_phys
),
%
g5
ldx
[%
g5
+
%
lo
(
prom_pmd_phys
)],
%
g5
/
*
Get
PMD
offset
.
*/
srlx
%
g4
,
23
,
%
g6
and
%
g6
,
0x7ff
,
%
g6
sllx
%
g6
,
2
,
%
g6
/
*
Load
PMD
,
is
it
valid
?
*/
lduwa
[%
g5
+
%
g6
]
ASI_PHYS_USE_EC
,
%
g5
brz
,
pn
%
g5
,
longpath
sllx
%
g5
,
11
,
%
g5
/
*
Get
PTE
offset
.
*/
srlx
%
g4
,
13
,
%
g6
and
%
g6
,
0x3ff
,
%
g6
sllx
%
g6
,
3
,
%
g6
/
*
Load
PTE
.
*/
ldxa
[%
g5
+
%
g6
]
ASI_PHYS_USE_EC
,
%
g5
brgez
,
pn
%
g5
,
longpath
nop
2
:
ba
,
pt
%
xcc
,
1
b
add
%
g5
,
(
3
*
8
),
%
g5
!
next
entry
/
*
TLB
load
and
return
from
trap
.
*/
kvmap_do_obp
:
sethi
%
hi
(
prom_trans
),
%
g5
or
%
g5
,
%
lo
(
prom_trans
),
%
g5
srlx
%
g4
,
13
,
%
g4
sllx
%
g4
,
13
,
%
g4
1
:
ldx
[%
g5
+
0x00
],
%
g6
!
base
brz
,
a
,
pn
%
g6
,
longpath
!
no
more
entries
,
fail
mov
TLB_SFSR
,
%
g1
!
and
restore
%
g1
ldx
[%
g5
+
0x08
],
%
g1
!
len
add
%
g6
,
%
g1
,
%
g1
!
end
cmp
%
g6
,
%
g4
bgu
,
pt
%
xcc
,
2
f
cmp
%
g4
,
%
g1
bgeu
,
pt
%
xcc
,
2
f
ldx
[%
g5
+
0x10
],
%
g1
!
PTE
/
*
TLB
load
,
restore
%
g1
,
and
return
from
trap
.
*/
sub
%
g4
,
%
g6
,
%
g6
add
%
g1
,
%
g6
,
%
g5
mov
TLB_SFSR
,
%
g1
stxa
%
g5
,
[%
g0
]
ASI_DTLB_DATA_IN
retry
2
:
ba
,
pt
%
xcc
,
1
b
add
%
g5
,
(
3
*
8
),
%
g5
!
next
entry
/*
*
On
a
first
level
data
miss
,
check
whether
this
is
to
the
OBP
range
(
note
*
that
such
accesses
can
be
made
by
prom
,
as
well
as
by
kernel
using
...
...
arch/sparc64/mm/init.c
View file @
aac372de
...
...
@@ -105,7 +105,7 @@ static void __init read_obp_memory(const char *property,
regs
[
i
].
phys_addr
=
base
;
regs
[
i
].
reg_size
=
size
;
}
sort
(
regs
,
ents
,
sizeof
(
struct
linux_prom64_registers
),
sort
(
regs
,
ents
,
sizeof
(
struct
linux_prom64_registers
),
cmp_p64
,
NULL
);
}
...
...
@@ -367,8 +367,11 @@ struct linux_prom_translation {
unsigned
long
size
;
unsigned
long
data
;
};
static
struct
linux_prom_translation
prom_trans
[
512
]
__initdata
;
static
unsigned
int
prom_trans_ents
__initdata
;
/* Exported for kernel TLB miss handling in ktlb.S */
struct
linux_prom_translation
prom_trans
[
512
]
__read_mostly
;
unsigned
int
prom_trans_ents
__read_mostly
;
unsigned
int
swapper_pgd_zero
__read_mostly
;
extern
unsigned
long
prom_boot_page
;
extern
void
prom_remap
(
unsigned
long
physpage
,
unsigned
long
virtpage
,
int
mmu_ihandle
);
...
...
@@ -378,122 +381,57 @@ extern void register_prom_callbacks(void);
/* Exported for SMP bootup purposes. */
unsigned
long
kern_locked_tte_data
;
/* Exported for kernel TLB miss handling in ktlb.S */
unsigned
long
prom_pmd_phys
__read_mostly
;
unsigned
int
swapper_pgd_zero
__read_mostly
;
static
pmd_t
*
prompmd
__read_mostly
;
#define BASE_PAGE_SIZE 8192
/*
* Translate PROM's mapping we capture at boot time into physical address.
* The second parameter is only set from prom_callback() invocations.
*/
unsigned
long
prom_virt_to_phys
(
unsigned
long
promva
,
int
*
error
)
{
pmd_t
*
pmdp
=
prompmd
+
((
promva
>>
23
)
&
0x7ff
);
pte_t
*
ptep
;
unsigned
long
base
;
if
(
pmd_none
(
*
pmdp
))
{
if
(
error
)
*
error
=
1
;
return
0
;
}
ptep
=
(
pte_t
*
)
__pmd_page
(
*
pmdp
)
+
((
promva
>>
13
)
&
0x3ff
);
if
(
!
pte_present
(
*
ptep
))
{
if
(
error
)
*
error
=
1
;
return
0
;
}
if
(
error
)
{
*
error
=
0
;
return
pte_val
(
*
ptep
);
}
base
=
pte_val
(
*
ptep
)
&
_PAGE_PADDR
;
return
base
+
(
promva
&
(
BASE_PAGE_SIZE
-
1
));
}
int
i
;
/* The obp translations are saved based on 8k pagesize, since obp can
* use a mixture of pagesizes. Misses to the LOW_OBP_ADDRESS ->
* HI_OBP_ADDRESS range are handled in entry.S and do not use the vpte
* scheme (also, see rant in inherit_locked_prom_mappings()).
*/
static
void
__init
build_obp_range
(
unsigned
long
start
,
unsigned
long
end
,
unsigned
long
data
)
{
unsigned
long
vaddr
;
for
(
i
=
0
;
i
<
prom_trans_ents
;
i
++
)
{
struct
linux_prom_translation
*
p
=
&
prom_trans
[
i
];
for
(
vaddr
=
start
;
vaddr
<
end
;
vaddr
+=
BASE_PAGE_SIZE
)
{
unsigned
long
val
;
pmd_t
*
pmd
;
pte_t
*
pte
;
if
(
promva
>=
p
->
virt
&&
promva
<
(
p
->
virt
+
p
->
size
))
{
unsigned
long
base
=
p
->
data
&
_PAGE_PADDR
;
pmd
=
prompmd
+
((
vaddr
>>
23
)
&
0x7ff
);
if
(
pmd_none
(
*
pmd
))
{
pte
=
__alloc_bootmem
(
BASE_PAGE_SIZE
,
BASE_PAGE_SIZE
,
PAGE_SIZE
);
if
(
!
pte
)
prom_halt
();
memset
(
pte
,
0
,
BASE_PAGE_SIZE
);
pmd_set
(
pmd
,
pte
);
if
(
error
)
*
error
=
0
;
return
base
+
(
promva
&
(
8192
-
1
));
}
pte
=
(
pte_t
*
)
__pmd_page
(
*
pmd
)
+
((
vaddr
>>
13
)
&
0x3ff
);
val
=
data
;
/* Clear diag TTE bits. */
if
(
tlb_type
==
spitfire
)
val
&=
~
0x0003fe0000000000UL
;
set_pte_at
(
&
init_mm
,
vaddr
,
pte
,
__pte
(
val
|
_PAGE_MODIFIED
));
data
+=
BASE_PAGE_SIZE
;
}
if
(
error
)
*
error
=
1
;
return
0UL
;
}
/* The obp translations are saved based on 8k pagesize, since obp can
* use a mixture of pagesizes. Misses to the LOW_OBP_ADDRESS ->
* HI_OBP_ADDRESS range are handled in ktlb.S and do not use the vpte
* scheme (also, see rant in inherit_locked_prom_mappings()).
*/
static
inline
int
in_obp_range
(
unsigned
long
vaddr
)
{
return
(
vaddr
>=
LOW_OBP_ADDRESS
&&
vaddr
<
HI_OBP_ADDRESS
);
}
#define OBP_PMD_SIZE 2048
static
void
__init
build_obp_pgtable
(
void
)
static
int
cmp_ptrans
(
const
void
*
a
,
const
void
*
b
)
{
unsigned
long
i
;
prompmd
=
__alloc_bootmem
(
OBP_PMD_SIZE
,
OBP_PMD_SIZE
,
PAGE_SIZE
);
if
(
!
prompmd
)
prom_halt
();
memset
(
prompmd
,
0
,
OBP_PMD_SIZE
);
prom_pmd_phys
=
__pa
(
prompmd
);
for
(
i
=
0
;
i
<
prom_trans_ents
;
i
++
)
{
unsigned
long
start
,
end
;
if
(
!
in_obp_range
(
prom_trans
[
i
].
virt
))
continue
;
const
struct
linux_prom_translation
*
x
=
a
,
*
y
=
b
;
start
=
prom_trans
[
i
].
virt
;
end
=
start
+
prom_trans
[
i
].
size
;
if
(
end
>
HI_OBP_ADDRESS
)
end
=
HI_OBP_ADDRESS
;
build_obp_range
(
start
,
end
,
prom_trans
[
i
].
data
);
}
if
(
x
->
virt
>
y
->
virt
)
return
1
;
if
(
x
->
virt
<
y
->
virt
)
return
-
1
;
return
0
;
}
/* Read OBP translations property into 'prom_trans[]'.
* Return the number of entries.
*/
/* Read OBP translations property into 'prom_trans[]'. */
static
void
__init
read_obp_translations
(
void
)
{
int
n
,
node
;
int
n
,
node
,
ents
,
first
,
last
,
i
;
node
=
prom_finddevice
(
"/virtual-memory"
);
n
=
prom_getproplen
(
node
,
"translations"
);
...
...
@@ -515,7 +453,41 @@ static void __init read_obp_translations(void)
n
=
n
/
sizeof
(
struct
linux_prom_translation
);
prom_trans_ents
=
n
;
ents
=
n
;
sort
(
prom_trans
,
ents
,
sizeof
(
struct
linux_prom_translation
),
cmp_ptrans
,
NULL
);
/* Now kick out all the non-OBP entries. */
for
(
i
=
0
;
i
<
ents
;
i
++
)
{
if
(
in_obp_range
(
prom_trans
[
i
].
virt
))
break
;
}
first
=
i
;
for
(;
i
<
ents
;
i
++
)
{
if
(
!
in_obp_range
(
prom_trans
[
i
].
virt
))
break
;
}
last
=
i
;
for
(
i
=
0
;
i
<
(
last
-
first
);
i
++
)
{
struct
linux_prom_translation
*
src
=
&
prom_trans
[
i
+
first
];
struct
linux_prom_translation
*
dest
=
&
prom_trans
[
i
];
*
dest
=
*
src
;
}
for
(;
i
<
ents
;
i
++
)
{
struct
linux_prom_translation
*
dest
=
&
prom_trans
[
i
];
dest
->
virt
=
dest
->
size
=
dest
->
data
=
0x0UL
;
}
prom_trans_ents
=
last
-
first
;
if
(
tlb_type
==
spitfire
)
{
/* Clear diag TTE bits. */
for
(
i
=
0
;
i
<
prom_trans_ents
;
i
++
)
prom_trans
[
i
].
data
&=
~
0x0003fe0000000000UL
;
}
}
static
void
__init
remap_kernel
(
void
)
...
...
@@ -553,21 +525,18 @@ static void __init remap_kernel(void)
}
static
void
__init
inherit_prom_mappings
_pre
(
void
)
static
void
__init
inherit_prom_mappings
(
void
)
{
read_obp_translations
();
/* Now fixup OBP's idea about where we really are mapped. */
prom_printf
(
"Remapping the kernel... "
);
remap_kernel
();
prom_printf
(
"done.
\n
"
);
}
static
void
__init
inherit_prom_mappings_post
(
void
)
{
build_obp_pgtable
();
prom_printf
(
"Registering callbacks... "
);
register_prom_callbacks
();
prom_printf
(
"done.
\n
"
);
}
/* The OBP specifications for sun4u mark 0xfffffffc00000000 and
...
...
@@ -1519,7 +1488,7 @@ void __init paging_init(void)
swapper_pgd_zero
=
pgd_val
(
swapper_pg_dir
[
0
]);
inherit_prom_mappings
_pre
();
inherit_prom_mappings
();
/* Ok, we can use our TLB miss and window trap handlers safely.
* We need to do a quick peek here to see if we are on StarFire
...
...
@@ -1530,23 +1499,15 @@ void __init paging_init(void)
extern
void
setup_tba
(
int
);
setup_tba
(
this_is_starfire
);
}
__flush_tlb_all
();
/* Everything from this point forward, until we are done with
* inherit_prom_mappings_post(), must complete successfully
* without calling into the firmware. The firwmare page tables
* have not been built, but we are running on the Linux kernel's
* trap table.
*/
inherit_locked_prom_mappings
(
1
);
__flush_tlb_all
();
/* Setup bootmem... */
pages_avail
=
0
;
last_valid_pfn
=
end_pfn
=
bootmem_init
(
&
pages_avail
);
inherit_prom_mappings_post
();
inherit_locked_prom_mappings
(
1
);
#ifdef CONFIG_DEBUG_PAGEALLOC
kernel_physical_mapping_init
();
#endif
...
...
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