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
nexedi
linux
Commits
95001ee9
Commit
95001ee9
authored
Sep 27, 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
63906e41
0dc46106
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
908 additions
and
1192 deletions
+908
-1192
arch/sparc64/Kconfig.debug
arch/sparc64/Kconfig.debug
+8
-0
arch/sparc64/kernel/devices.c
arch/sparc64/kernel/devices.c
+22
-0
arch/sparc64/kernel/dtlb_backend.S
arch/sparc64/kernel/dtlb_backend.S
+1
-12
arch/sparc64/kernel/dtlb_base.S
arch/sparc64/kernel/dtlb_base.S
+4
-4
arch/sparc64/kernel/entry.S
arch/sparc64/kernel/entry.S
+18
-162
arch/sparc64/kernel/head.S
arch/sparc64/kernel/head.S
+160
-396
arch/sparc64/kernel/ktlb.S
arch/sparc64/kernel/ktlb.S
+198
-0
arch/sparc64/kernel/pci_schizo.c
arch/sparc64/kernel/pci_schizo.c
+1
-1
arch/sparc64/kernel/setup.c
arch/sparc64/kernel/setup.c
+9
-22
arch/sparc64/kernel/smp.c
arch/sparc64/kernel/smp.c
+21
-0
arch/sparc64/kernel/trampoline.S
arch/sparc64/kernel/trampoline.S
+8
-8
arch/sparc64/kernel/traps.c
arch/sparc64/kernel/traps.c
+27
-13
arch/sparc64/kernel/vmlinux.lds.S
arch/sparc64/kernel/vmlinux.lds.S
+1
-2
arch/sparc64/mm/init.c
arch/sparc64/mm/init.c
+308
-356
arch/sparc64/mm/ultra.S
arch/sparc64/mm/ultra.S
+22
-74
arch/sparc64/prom/Makefile
arch/sparc64/prom/Makefile
+1
-1
arch/sparc64/prom/console.c
arch/sparc64/prom/console.c
+1
-1
arch/sparc64/prom/devops.c
arch/sparc64/prom/devops.c
+1
-1
arch/sparc64/prom/init.c
arch/sparc64/prom/init.c
+1
-1
arch/sparc64/prom/map.S
arch/sparc64/prom/map.S
+0
-72
arch/sparc64/prom/misc.c
arch/sparc64/prom/misc.c
+16
-18
arch/sparc64/prom/p1275.c
arch/sparc64/prom/p1275.c
+1
-1
arch/sparc64/prom/printf.c
arch/sparc64/prom/printf.c
+1
-1
arch/sparc64/prom/tree.c
arch/sparc64/prom/tree.c
+26
-24
include/asm-sparc64/cacheflush.h
include/asm-sparc64/cacheflush.h
+5
-0
include/asm-sparc64/cpudata.h
include/asm-sparc64/cpudata.h
+10
-0
include/asm-sparc64/oplib.h
include/asm-sparc64/oplib.h
+33
-19
include/asm-sparc64/pgtable.h
include/asm-sparc64/pgtable.h
+4
-3
No files found.
arch/sparc64/Kconfig.debug
View file @
95001ee9
...
...
@@ -33,6 +33,14 @@ config DEBUG_BOOTMEM
depends on DEBUG_KERNEL
bool "Debug BOOTMEM initialization"
config DEBUG_PAGEALLOC
bool "Page alloc debugging"
depends on DEBUG_KERNEL && !SOFTWARE_SUSPEND
help
Unmap pages from the kernel linear mapping after free_pages().
This results in a large slowdown, but helps to find certain types
of memory corruptions.
config MCOUNT
bool
depends on STACK_DEBUG
...
...
arch/sparc64/kernel/devices.c
View file @
95001ee9
...
...
@@ -135,6 +135,28 @@ void __init device_scan(void)
cpu_data
(
0
).
clock_tick
=
prom_getintdefault
(
cpu_node
,
"clock-frequency"
,
0
);
cpu_data
(
0
).
dcache_size
=
prom_getintdefault
(
cpu_node
,
"dcache-size"
,
16
*
1024
);
cpu_data
(
0
).
dcache_line_size
=
prom_getintdefault
(
cpu_node
,
"dcache-line-size"
,
32
);
cpu_data
(
0
).
icache_size
=
prom_getintdefault
(
cpu_node
,
"icache-size"
,
16
*
1024
);
cpu_data
(
0
).
icache_line_size
=
prom_getintdefault
(
cpu_node
,
"icache-line-size"
,
32
);
cpu_data
(
0
).
ecache_size
=
prom_getintdefault
(
cpu_node
,
"ecache-size"
,
4
*
1024
*
1024
);
cpu_data
(
0
).
ecache_line_size
=
prom_getintdefault
(
cpu_node
,
"ecache-line-size"
,
64
);
printk
(
"CPU[0]: Caches "
"D[sz(%d):line_sz(%d)] "
"I[sz(%d):line_sz(%d)] "
"E[sz(%d):line_sz(%d)]
\n
"
,
cpu_data
(
0
).
dcache_size
,
cpu_data
(
0
).
dcache_line_size
,
cpu_data
(
0
).
icache_size
,
cpu_data
(
0
).
icache_line_size
,
cpu_data
(
0
).
ecache_size
,
cpu_data
(
0
).
ecache_line_size
);
}
#endif
...
...
arch/sparc64/kernel/dtlb_backend.S
View file @
95001ee9
...
...
@@ -9,17 +9,7 @@
#include <asm/pgtable.h>
#include <asm/mmu.h>
#if PAGE_SHIFT == 13
#define SZ_BITS _PAGE_SZ8K
#elif PAGE_SHIFT == 16
#define SZ_BITS _PAGE_SZ64K
#elif PAGE_SHIFT == 19
#define SZ_BITS _PAGE_SZ512K
#elif PAGE_SHIFT == 22
#define SZ_BITS _PAGE_SZ4MB
#endif
#define VALID_SZ_BITS (_PAGE_VALID | SZ_BITS)
#define VALID_SZ_BITS (_PAGE_VALID | _PAGE_SZBITS)
#define VPTE_BITS (_PAGE_CP | _PAGE_CV | _PAGE_P )
#define VPTE_SHIFT (PAGE_SHIFT - 3)
...
...
@@ -163,7 +153,6 @@ sparc64_vpte_continue:
stxa
%
g4
,
[%
g1
+
%
g1
]
ASI_DMMU
!
Restore
previous
TAG_ACCESS
retry
!
Load
PTE
once
again
#undef SZ_BITS
#undef VALID_SZ_BITS
#undef VPTE_SHIFT
#undef VPTE_BITS
...
...
arch/sparc64/kernel/dtlb_base.S
View file @
95001ee9
...
...
@@ -71,7 +71,7 @@
from_tl1_trap
:
rdpr
%
tl
,
%
g5
!
For
TL
==
3
test
CREATE_VPTE_OFFSET1
(%
g4
,
%
g6
)
!
Create
VPTE
offset
be
,
pn
%
xcc
,
3
f
!
Yep
,
special
processing
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
...
...
@@ -83,9 +83,9 @@ from_tl1_trap:
nop
!
Delay
-
slot
9
:
stxa
%
g5
,
[%
g0
]
ASI_DTLB_DATA_IN
!
Reload
TLB
retry
!
Trap
return
3
:
brlz
,
pt
%
g4
,
9
b
!
Kernel
virtual
map
?
xor
%
g2
,
%
g4
,
%
g5
!
Finish
bit
twiddles
ba
,
a
,
pt
%
xcc
,
kvmap
!
Yep
,
go
check
for
obp
/
vmalloc
nop
nop
nop
/*
DTLB
**
ICACHE
line
3
:
winfixups
+
real_faults
*/
longpath
:
...
...
arch/sparc64/kernel/entry.S
View file @
95001ee9
...
...
@@ -30,159 +30,6 @@
.
text
.
align
32
.
globl
sparc64_vpte_patchme1
.
globl
sparc64_vpte_patchme2
/*
*
On
a
second
level
vpte
miss
,
check
whether
the
original
fault
is
to
the
OBP
*
range
(
note
that
this
is
only
possible
for
instruction
miss
,
data
misses
to
*
obp
range
do
not
use
vpte
)
.
If
so
,
go
back
directly
to
the
faulting
address
.
*
This
is
because
we
want
to
read
the
tpc
,
otherwise
we
have
no
way
of
knowing
*
the
8
k
aligned
faulting
address
if
we
are
using
>
8
k
kernel
pagesize
.
This
*
also
ensures
no
vpte
range
addresses
are
dropped
into
tlb
while
obp
is
*
executing
(
see
inherit_locked_prom_mappings
()
rant
)
.
*/
sparc64_vpte_nucleus
:
/
*
Note
that
kvmap
below
has
verified
that
the
address
is
*
in
the
range
MODULES_VADDR
-->
VMALLOC_END
already
.
So
*
here
we
need
only
check
if
it
is
an
OBP
address
or
not
.
*/
sethi
%
hi
(
LOW_OBP_ADDRESS
),
%
g5
cmp
%
g4
,
%
g5
blu
,
pn
%
xcc
,
sparc64_vpte_patchme1
mov
0x1
,
%
g5
sllx
%
g5
,
32
,
%
g5
cmp
%
g4
,
%
g5
blu
,
pn
%
xcc
,
obp_iaddr_patch
nop
/
*
These
two
instructions
are
patched
by
paginig_init
()
.
*/
sparc64_vpte_patchme1
:
sethi
%
hi
(
0
),
%
g5
sparc64_vpte_patchme2
:
or
%
g5
,
%
lo
(
0
),
%
g5
/
*
With
kernel
PGD
in
%
g5
,
branch
back
into
dtlb_backend
.
*/
ba
,
pt
%
xcc
,
sparc64_kpte_continue
andn
%
g1
,
0x3
,
%
g1
/*
Finish
PMD
offset
adjustment
.
*/
vpte_noent
:
/
*
Restore
previous
TAG_ACCESS
,
%
g5
is
zero
,
and
we
will
*
skip
over
the
trap
instruction
so
that
the
top
level
*
TLB
miss
handler
will
thing
this
%
g5
value
is
just
an
*
invalid
PTE
,
thus
branching
to
full
fault
processing
.
*/
mov
TLB_SFSR
,
%
g1
stxa
%
g4
,
[%
g1
+
%
g1
]
ASI_DMMU
done
.
globl
obp_iaddr_patch
obp_iaddr_patch
:
/
*
These
two
instructions
patched
by
inherit_prom_mappings
()
.
*/
sethi
%
hi
(
0
),
%
g5
or
%
g5
,
%
lo
(
0
),
%
g5
/
*
Behave
as
if
we
are
at
TL0
.
*/
wrpr
%
g0
,
1
,
%
tl
rdpr
%
tpc
,
%
g4
/*
Find
original
faulting
iaddr
*/
srlx
%
g4
,
13
,
%
g4
/*
Throw
out
context
bits
*/
sllx
%
g4
,
13
,
%
g4
/*
g4
has
vpn
+
ctx0
now
*/
/
*
Restore
previous
TAG_ACCESS
.
*/
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
.
*/
stxa
%
g5
,
[%
g0
]
ASI_ITLB_DATA_IN
retry
.
globl
obp_daddr_patch
obp_daddr_patch
:
/
*
These
two
instructions
patched
by
inherit_prom_mappings
()
.
*/
sethi
%
hi
(
0
),
%
g5
or
%
g5
,
%
lo
(
0
),
%
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
/
*
TLB
load
and
return
from
trap
.
*/
stxa
%
g5
,
[%
g0
]
ASI_DTLB_DATA_IN
retry
/*
*
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
*
prom_getproperty
on
"address"
),
and
if
so
,
do
not
use
vpte
access
...
*
rather
,
use
information
saved
during
inherit_prom_mappings
()
using
8
k
*
pagesize
.
*/
.
align
32
kvmap
:
sethi
%
hi
(
MODULES_VADDR
),
%
g5
cmp
%
g4
,
%
g5
blu
,
pn
%
xcc
,
longpath
mov
(
VMALLOC_END
>>
24
),
%
g5
sllx
%
g5
,
24
,
%
g5
cmp
%
g4
,
%
g5
bgeu
,
pn
%
xcc
,
longpath
nop
kvmap_check_obp
:
sethi
%
hi
(
LOW_OBP_ADDRESS
),
%
g5
cmp
%
g4
,
%
g5
blu
,
pn
%
xcc
,
kvmap_vmalloc_addr
mov
0x1
,
%
g5
sllx
%
g5
,
32
,
%
g5
cmp
%
g4
,
%
g5
blu
,
pn
%
xcc
,
obp_daddr_patch
nop
kvmap_vmalloc_addr
:
/
*
If
we
get
here
,
a
vmalloc
addr
was
accessed
,
load
kernel
VPTE
.
*/
ldxa
[%
g3
+
%
g6
]
ASI_N
,
%
g5
brgez
,
pn
%
g5
,
longpath
nop
/
*
PTE
is
valid
,
load
into
TLB
and
return
from
trap
.
*/
stxa
%
g5
,
[%
g0
]
ASI_DTLB_DATA_IN
!
Reload
TLB
retry
/
*
This
is
trivial
with
the
new
code
...
*/
.
globl
do_fpdis
do_fpdis
:
...
...
@@ -525,14 +372,13 @@ cheetah_plus_patch_fpdis:
*
*
DATA
0
:
[
low
32
-
bits
]
Address
of
function
to
call
,
jmp
to
this
*
[
high
32
-
bits
]
MMU
Context
Argument
0
,
place
in
%
g5
*
DATA
1
:
Address
Argument
1
,
place
in
%
g
6
*
DATA
1
:
Address
Argument
1
,
place
in
%
g
1
*
DATA
2
:
Address
Argument
2
,
place
in
%
g7
*
*
With
this
method
we
can
do
most
of
the
cross
-
call
tlb
/
cache
*
flushing
very
quickly
.
*
*
Current
CPU
's IRQ worklist table is locked into %g1,
*
don
't touch.
*
Current
CPU
's IRQ worklist table is locked into %g6, don'
t
touch
.
*/
.
text
.
align
32
...
...
@@ -1006,13 +852,14 @@ cheetah_plus_dcpe_trap_vector:
nop
do_cheetah_plus_data_parity
:
ba
,
pt
%
xcc
,
etrap
rdpr
%
pil
,
%
g2
wrpr
%
g0
,
15
,
%
pil
ba
,
pt
%
xcc
,
etrap_irq
rd
%
pc
,
%
g7
mov
0x0
,
%
o0
call
cheetah_plus_parity_error
add
%
sp
,
PTREGS_OFF
,
%
o1
ba
,
pt
%
xcc
,
rtrap
clr
%
l6
ba
,
a
,
pt
%
xcc
,
rtrap_irq
cheetah_plus_dcpe_trap_vector_tl1
:
membar
#
Sync
...
...
@@ -1036,13 +883,14 @@ cheetah_plus_icpe_trap_vector:
nop
do_cheetah_plus_insn_parity
:
ba
,
pt
%
xcc
,
etrap
rdpr
%
pil
,
%
g2
wrpr
%
g0
,
15
,
%
pil
ba
,
pt
%
xcc
,
etrap_irq
rd
%
pc
,
%
g7
mov
0x1
,
%
o0
call
cheetah_plus_parity_error
add
%
sp
,
PTREGS_OFF
,
%
o1
ba
,
pt
%
xcc
,
rtrap
clr
%
l6
ba
,
a
,
pt
%
xcc
,
rtrap_irq
cheetah_plus_icpe_trap_vector_tl1
:
membar
#
Sync
...
...
@@ -1075,6 +923,10 @@ do_dcpe_tl1:
nop
wrpr
%
g1
,
%
tl
!
Restore
original
trap
level
do_dcpe_tl1_nonfatal
:
/
*
Ok
we
may
use
interrupt
globals
safely
.
*/
sethi
%
hi
(
dcache_parity_tl1_occurred
),
%
g2
lduw
[%
g2
+
%
lo
(
dcache_parity_tl1_occurred
)],
%
g1
add
%
g1
,
1
,
%
g1
stw
%
g1
,
[%
g2
+
%
lo
(
dcache_parity_tl1_occurred
)]
/
*
Reset
D
-
cache
parity
*/
sethi
%
hi
(
1
<<
16
),
%
g1
!
D
-
cache
size
mov
(
1
<<
5
),
%
g2
!
D
-
cache
line
size
...
...
@@ -1121,6 +973,10 @@ do_icpe_tl1:
nop
wrpr
%
g1
,
%
tl
!
Restore
original
trap
level
do_icpe_tl1_nonfatal
:
/
*
Ok
we
may
use
interrupt
globals
safely
.
*/
sethi
%
hi
(
icache_parity_tl1_occurred
),
%
g2
lduw
[%
g2
+
%
lo
(
icache_parity_tl1_occurred
)],
%
g1
add
%
g1
,
1
,
%
g1
stw
%
g1
,
[%
g2
+
%
lo
(
icache_parity_tl1_occurred
)]
/
*
Flush
I
-
cache
*/
sethi
%
hi
(
1
<<
15
),
%
g1
!
I
-
cache
size
mov
(
1
<<
5
),
%
g2
!
I
-
cache
line
size
...
...
arch/sparc64/kernel/head.S
View file @
95001ee9
...
...
@@ -80,15 +80,165 @@ sparc_ramdisk_image64:
.
xword
0
.
word
_end
/
*
We
must
be
careful
,
32
-
bit
OpenBOOT
will
get
confused
if
it
*
tries
to
save
away
a
register
window
to
a
64
-
bit
kernel
*
stack
address
.
Flush
all
windows
,
disable
interrupts
,
*
remap
if
necessary
,
jump
onto
kernel
trap
table
,
then
kernel
*
stack
,
or
else
we
die
.
/
*
PROM
cif
handler
code
address
is
in
%
o4
.
*/
sparc64_boot
:
1
:
rd
%
pc
,
%
g7
set
1
b
,
%
g1
cmp
%
g1
,
%
g7
be
,
pn
%
xcc
,
sparc64_boot_after_remap
mov
%
o4
,
%
l7
/
*
We
need
to
remap
the
kernel
.
Use
position
independant
*
code
to
remap
us
to
KERNBASE
.
*
*
PROM
entry
point
is
on
%
o4
*
SILO
can
invoke
us
with
32
-
bit
address
masking
enabled
,
*
so
make
sure
that
's clear.
*/
sparc64_boot
:
rdpr
%
pstate
,
%
g1
andn
%
g1
,
PSTATE_AM
,
%
g1
wrpr
%
g1
,
0x0
,
%
pstate
ba
,
a
,
pt
%
xcc
,
1
f
.
globl
prom_finddev_name
,
prom_chosen_path
.
globl
prom_getprop_name
,
prom_mmu_name
.
globl
prom_callmethod_name
,
prom_translate_name
.
globl
prom_map_name
,
prom_unmap_name
,
prom_mmu_ihandle_cache
.
globl
prom_boot_mapped_pc
,
prom_boot_mapping_mode
.
globl
prom_boot_mapping_phys_high
,
prom_boot_mapping_phys_low
prom_finddev_name
:
.
asciz
"finddevice"
prom_chosen_path
:
.
asciz
"/chosen"
prom_getprop_name
:
.
asciz
"getprop"
prom_mmu_name
:
.
asciz
"mmu"
prom_callmethod_name
:
.
asciz
"call-method"
prom_translate_name
:
.
asciz
"translate"
prom_map_name
:
.
asciz
"map"
prom_unmap_name
:
.
asciz
"unmap"
.
align
4
prom_mmu_ihandle_cache
:
.
word
0
prom_boot_mapped_pc
:
.
word
0
prom_boot_mapping_mode
:
.
word
0
.
align
8
prom_boot_mapping_phys_high
:
.
xword
0
prom_boot_mapping_phys_low
:
.
xword
0
1
:
rd
%
pc
,
%
l0
mov
(
1
b
-
prom_finddev_name
),
%
l1
mov
(
1
b
-
prom_chosen_path
),
%
l2
mov
(
1
b
-
prom_boot_mapped_pc
),
%
l3
sub
%
l0
,
%
l1
,
%
l1
sub
%
l0
,
%
l2
,
%
l2
sub
%
l0
,
%
l3
,
%
l3
stw
%
l0
,
[%
l3
]
sub
%
sp
,
(
192
+
128
),
%
sp
/
*
chosen_node
=
prom_finddevice
(
"/chosen"
)
*/
stx
%
l1
,
[%
sp
+
2047
+
128
+
0x00
]
!
service
,
"finddevice"
mov
1
,
%
l3
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x08
]
!
num_args
,
1
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x10
]
!
num_rets
,
1
stx
%
l2
,
[%
sp
+
2047
+
128
+
0x18
]
!
arg1
,
"/chosen"
stx
%
g0
,
[%
sp
+
2047
+
128
+
0x20
]
!
ret1
call
%
l7
add
%
sp
,
(
2047
+
128
),
%
o0
!
argument
array
ldx
[%
sp
+
2047
+
128
+
0x20
],
%
l4
!
chosen
device
node
mov
(
1
b
-
prom_getprop_name
),
%
l1
mov
(
1
b
-
prom_mmu_name
),
%
l2
mov
(
1
b
-
prom_mmu_ihandle_cache
),
%
l5
sub
%
l0
,
%
l1
,
%
l1
sub
%
l0
,
%
l2
,
%
l2
sub
%
l0
,
%
l5
,
%
l5
/
*
prom_mmu_ihandle_cache
=
prom_getint
(
chosen_node
,
"mmu"
)
*/
stx
%
l1
,
[%
sp
+
2047
+
128
+
0x00
]
!
service
,
"getprop"
mov
4
,
%
l3
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x08
]
!
num_args
,
4
mov
1
,
%
l3
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x10
]
!
num_rets
,
1
stx
%
l4
,
[%
sp
+
2047
+
128
+
0x18
]
!
arg1
,
chosen_node
stx
%
l2
,
[%
sp
+
2047
+
128
+
0x20
]
!
arg2
,
"mmu"
stx
%
l5
,
[%
sp
+
2047
+
128
+
0x28
]
!
arg3
,
&
prom_mmu_ihandle_cache
mov
4
,
%
l3
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x30
]
!
arg4
,
sizeof
(
arg3
)
stx
%
g0
,
[%
sp
+
2047
+
128
+
0x38
]
!
ret1
call
%
l7
add
%
sp
,
(
2047
+
128
),
%
o0
!
argument
array
mov
(
1
b
-
prom_callmethod_name
),
%
l1
mov
(
1
b
-
prom_translate_name
),
%
l2
sub
%
l0
,
%
l1
,
%
l1
sub
%
l0
,
%
l2
,
%
l2
lduw
[%
l5
],
%
l5
!
prom_mmu_ihandle_cache
stx
%
l1
,
[%
sp
+
2047
+
128
+
0x00
]
!
service
,
"call-method"
mov
3
,
%
l3
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x08
]
!
num_args
,
3
mov
5
,
%
l3
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x10
]
!
num_rets
,
5
stx
%
l2
,
[%
sp
+
2047
+
128
+
0x18
]
!
arg1
:
"translate"
stx
%
l5
,
[%
sp
+
2047
+
128
+
0x20
]
!
arg2
:
prom_mmu_ihandle_cache
srlx
%
l0
,
22
,
%
l3
sllx
%
l3
,
22
,
%
l3
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x28
]
!
arg3
:
vaddr
,
our
PC
stx
%
g0
,
[%
sp
+
2047
+
128
+
0x30
]
!
res1
stx
%
g0
,
[%
sp
+
2047
+
128
+
0x38
]
!
res2
stx
%
g0
,
[%
sp
+
2047
+
128
+
0x40
]
!
res3
stx
%
g0
,
[%
sp
+
2047
+
128
+
0x48
]
!
res4
stx
%
g0
,
[%
sp
+
2047
+
128
+
0x50
]
!
res5
call
%
l7
add
%
sp
,
(
2047
+
128
),
%
o0
!
argument
array
ldx
[%
sp
+
2047
+
128
+
0x40
],
%
l1
!
translation
mode
mov
(
1
b
-
prom_boot_mapping_mode
),
%
l4
sub
%
l0
,
%
l4
,
%
l4
stw
%
l1
,
[%
l4
]
mov
(
1
b
-
prom_boot_mapping_phys_high
),
%
l4
sub
%
l0
,
%
l4
,
%
l4
ldx
[%
sp
+
2047
+
128
+
0x48
],
%
l2
!
physaddr
high
stx
%
l2
,
[%
l4
+
0x0
]
ldx
[%
sp
+
2047
+
128
+
0x50
],
%
l3
!
physaddr
low
stx
%
l3
,
[%
l4
+
0x8
]
/
*
Leave
service
as
-
is
,
"call-method"
*/
mov
7
,
%
l3
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x08
]
!
num_args
,
7
mov
1
,
%
l3
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x10
]
!
num_rets
,
1
mov
(
1
b
-
prom_map_name
),
%
l3
sub
%
l0
,
%
l3
,
%
l3
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x18
]
!
arg1
:
"map"
/
*
Leave
arg2
as
-
is
,
prom_mmu_ihandle_cache
*/
mov
-
1
,
%
l3
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x28
]
!
arg3
:
mode
(-
1
default
)
sethi
%
hi
(
8
*
1024
*
1024
),
%
l3
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x30
]
!
arg4
:
size
(
8
MB
)
sethi
%
hi
(
KERNBASE
),
%
l3
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x38
]
!
arg5
:
vaddr
(
KERNBASE
)
stx
%
g0
,
[%
sp
+
2047
+
128
+
0x40
]
!
arg6
:
empty
mov
(
1
b
-
prom_boot_mapping_phys_low
),
%
l3
sub
%
l0
,
%
l3
,
%
l3
ldx
[%
l3
],
%
l3
stx
%
l3
,
[%
sp
+
2047
+
128
+
0x48
]
!
arg7
:
phys
addr
call
%
l7
add
%
sp
,
(
2047
+
128
),
%
o0
!
argument
array
add
%
sp
,
(
192
+
128
),
%
sp
sparc64_boot_after_remap
:
BRANCH_IF_CHEETAH_BASE
(
g1
,
g7
,
cheetah_boot
)
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON
(
g1
,
g7
,
cheetah_plus_boot
)
ba
,
pt
%
xcc
,
spitfire_boot
...
...
@@ -125,185 +275,7 @@ cheetah_generic_boot:
stxa
%
g0
,
[%
g3
]
ASI_IMMU
membar
#
Sync
wrpr
%
g0
,
(
PSTATE_PRIV|PSTATE_PEF|PSTATE_IE
),
%
pstate
wr
%
g0
,
0
,
%
fprs
/
*
Just
like
for
Spitfire
,
we
probe
itlb
-
2
for
a
mapping
which
*
matches
our
current
%
pc
.
We
take
the
physical
address
in
*
that
mapping
and
use
it
to
make
our
own
.
*/
/
*
%
g5
holds
the
tlb
data
*/
sethi
%
uhi
(
_PAGE_VALID
|
_PAGE_SZ4MB
),
%
g5
sllx
%
g5
,
32
,
%
g5
or
%
g5
,
(
_PAGE_CP
| _PAGE_CV |
_PAGE_P
| _PAGE_L |
_PAGE_W
|
_PAGE_G
),
%
g5
/
*
Put
PADDR
tlb
data
mask
into
%
g3
.
*/
sethi
%
uhi
(
_PAGE_PADDR
),
%
g3
or
%
g3
,
%
ulo
(
_PAGE_PADDR
),
%
g3
sllx
%
g3
,
32
,
%
g3
sethi
%
hi
(
_PAGE_PADDR
),
%
g7
or
%
g7
,
%
lo
(
_PAGE_PADDR
),
%
g7
or
%
g3
,
%
g7
,
%
g3
set
2
<<
16
,
%
l0
/*
TLB
entry
walker
.
*/
set
0x1fff
,
%
l2
/*
Page
mask
.
*/
rd
%
pc
,
%
l3
andn
%
l3
,
%
l2
,
%
g2
/*
vaddr
comparator
*/
1
:
ldxa
[%
l0
]
ASI_ITLB_TAG_READ
,
%
g1
membar
#
Sync
andn
%
g1
,
%
l2
,
%
g1
cmp
%
g1
,
%
g2
be
,
pn
%
xcc
,
cheetah_got_tlbentry
nop
and
%
l0
,
(
127
<<
3
),
%
g1
cmp
%
g1
,
(
127
<<
3
)
blu
,
pt
%
xcc
,
1
b
add
%
l0
,
(
1
<<
3
),
%
l0
/
*
Search
the
small
TLB
.
OBP
never
maps
us
like
that
but
*
newer
SILO
can
.
*/
clr
%
l0
1
:
ldxa
[%
l0
]
ASI_ITLB_TAG_READ
,
%
g1
membar
#
Sync
andn
%
g1
,
%
l2
,
%
g1
cmp
%
g1
,
%
g2
be
,
pn
%
xcc
,
cheetah_got_tlbentry
nop
cmp
%
l0
,
(
15
<<
3
)
blu
,
pt
%
xcc
,
1
b
add
%
l0
,
(
1
<<
3
),
%
l0
/
*
BUG
()
if
we
get
here
...
*/
ta
0x5
cheetah_got_tlbentry
:
ldxa
[%
l0
]
ASI_ITLB_DATA_ACCESS
,
%
g0
ldxa
[%
l0
]
ASI_ITLB_DATA_ACCESS
,
%
g1
membar
#
Sync
and
%
g1
,
%
g3
,
%
g1
set
0x5fff
,
%
l0
andn
%
g1
,
%
l0
,
%
g1
or
%
g5
,
%
g1
,
%
g5
/
*
Clear
out
any
KERNBASE
area
entries
.
*/
set
2
<<
16
,
%
l0
sethi
%
hi
(
KERNBASE
),
%
g3
sethi
%
hi
(
KERNBASE
<<
1
),
%
g7
mov
TLB_TAG_ACCESS
,
%
l7
/
*
First
,
check
ITLB
*/
1
:
ldxa
[%
l0
]
ASI_ITLB_TAG_READ
,
%
g1
membar
#
Sync
andn
%
g1
,
%
l2
,
%
g1
cmp
%
g1
,
%
g3
blu
,
pn
%
xcc
,
2
f
cmp
%
g1
,
%
g7
bgeu
,
pn
%
xcc
,
2
f
nop
stxa
%
g0
,
[%
l7
]
ASI_IMMU
membar
#
Sync
stxa
%
g0
,
[%
l0
]
ASI_ITLB_DATA_ACCESS
membar
#
Sync
2
:
and
%
l0
,
(
127
<<
3
),
%
g1
cmp
%
g1
,
(
127
<<
3
)
blu
,
pt
%
xcc
,
1
b
add
%
l0
,
(
1
<<
3
),
%
l0
/
*
Next
,
check
DTLB
*/
set
2
<<
16
,
%
l0
1
:
ldxa
[%
l0
]
ASI_DTLB_TAG_READ
,
%
g1
membar
#
Sync
andn
%
g1
,
%
l2
,
%
g1
cmp
%
g1
,
%
g3
blu
,
pn
%
xcc
,
2
f
cmp
%
g1
,
%
g7
bgeu
,
pn
%
xcc
,
2
f
nop
stxa
%
g0
,
[%
l7
]
ASI_DMMU
membar
#
Sync
stxa
%
g0
,
[%
l0
]
ASI_DTLB_DATA_ACCESS
membar
#
Sync
2
:
and
%
l0
,
(
511
<<
3
),
%
g1
cmp
%
g1
,
(
511
<<
3
)
blu
,
pt
%
xcc
,
1
b
add
%
l0
,
(
1
<<
3
),
%
l0
/
*
On
Cheetah
+,
have
to
check
second
DTLB
.
*/
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON
(
g1
,
l0
,2
f
)
ba
,
pt
%
xcc
,
9
f
nop
2
:
set
3
<<
16
,
%
l0
1
:
ldxa
[%
l0
]
ASI_DTLB_TAG_READ
,
%
g1
membar
#
Sync
andn
%
g1
,
%
l2
,
%
g1
cmp
%
g1
,
%
g3
blu
,
pn
%
xcc
,
2
f
cmp
%
g1
,
%
g7
bgeu
,
pn
%
xcc
,
2
f
nop
stxa
%
g0
,
[%
l7
]
ASI_DMMU
membar
#
Sync
stxa
%
g0
,
[%
l0
]
ASI_DTLB_DATA_ACCESS
membar
#
Sync
2
:
and
%
l0
,
(
511
<<
3
),
%
g1
cmp
%
g1
,
(
511
<<
3
)
blu
,
pt
%
xcc
,
1
b
add
%
l0
,
(
1
<<
3
),
%
l0
9
:
/
*
Now
lock
the
TTE
we
created
into
ITLB
-
0
and
DTLB
-
0
,
*
entry
15
(
and
maybe
14
too
)
.
*/
sethi
%
hi
(
KERNBASE
),
%
g3
set
(
0
<<
16
)
|
(
15
<<
3
),
%
g7
stxa
%
g3
,
[%
l7
]
ASI_DMMU
membar
#
Sync
stxa
%
g5
,
[%
g7
]
ASI_DTLB_DATA_ACCESS
membar
#
Sync
stxa
%
g3
,
[%
l7
]
ASI_IMMU
membar
#
Sync
stxa
%
g5
,
[%
g7
]
ASI_ITLB_DATA_ACCESS
membar
#
Sync
flush
%
g3
membar
#
Sync
sethi
%
hi
(
_end
),
%
g3
/*
Check
for
bigkernel
case
*/
or
%
g3
,
%
lo
(
_end
),
%
g3
srl
%
g3
,
23
,
%
g3
/*
Check
if
_end
>
8
M
*/
brz
,
pt
%
g3
,
1
f
sethi
%
hi
(
KERNBASE
),
%
g3
/*
Restore
for
fixup
code
below
*/
sethi
%
hi
(
0x400000
),
%
g3
or
%
g3
,
%
lo
(
0x400000
),
%
g3
add
%
g5
,
%
g3
,
%
g5
/*
New
tte
data
*/
andn
%
g5
,
(
_PAGE_G
),
%
g5
sethi
%
hi
(
KERNBASE
+
0x400000
),
%
g3
or
%
g3
,
%
lo
(
KERNBASE
+
0x400000
),
%
g3
set
(
0
<<
16
)
|
(
14
<<
3
),
%
g7
stxa
%
g3
,
[%
l7
]
ASI_DMMU
membar
#
Sync
stxa
%
g5
,
[%
g7
]
ASI_DTLB_DATA_ACCESS
membar
#
Sync
stxa
%
g3
,
[%
l7
]
ASI_IMMU
membar
#
Sync
stxa
%
g5
,
[%
g7
]
ASI_ITLB_DATA_ACCESS
membar
#
Sync
flush
%
g3
membar
#
Sync
sethi
%
hi
(
KERNBASE
),
%
g3
/*
Restore
for
fixup
code
below
*/
ba
,
pt
%
xcc
,
1
f
nop
1
:
set
sun4u_init
,
%
g2
jmpl
%
g2
+
%
g0
,
%
g0
nop
ba
,
a
,
pt
%
xcc
,
jump_to_sun4u_init
spitfire_boot
:
/
*
Typically
PROM
has
already
enabled
both
MMU
's and both on-chip
...
...
@@ -313,6 +285,7 @@ spitfire_boot:
stxa
%
g1
,
[%
g0
]
ASI_LSU_CONTROL
membar
#
Sync
jump_to_sun4u_init
:
/
*
*
Make
sure
we
are
in
privileged
mode
,
have
address
masking
,
*
using
the
ordinary
globals
and
have
enabled
floating
...
...
@@ -324,151 +297,6 @@ spitfire_boot:
wrpr
%
g0
,
(
PSTATE_PRIV|PSTATE_PEF|PSTATE_IE
),
%
pstate
wr
%
g0
,
0
,
%
fprs
spitfire_create_mappings
:
/
*
%
g5
holds
the
tlb
data
*/
sethi
%
uhi
(
_PAGE_VALID
|
_PAGE_SZ4MB
),
%
g5
sllx
%
g5
,
32
,
%
g5
or
%
g5
,
(
_PAGE_CP
| _PAGE_CV |
_PAGE_P
| _PAGE_L |
_PAGE_W
|
_PAGE_G
),
%
g5
/
*
Base
of
physical
memory
cannot
reliably
be
assumed
to
be
*
at
0x0
!
Figure
out
where
it
happens
to
be
.
-
DaveM
*/
/
*
Put
PADDR
tlb
data
mask
into
%
g3
.
*/
sethi
%
uhi
(
_PAGE_PADDR_SF
),
%
g3
or
%
g3
,
%
ulo
(
_PAGE_PADDR_SF
),
%
g3
sllx
%
g3
,
32
,
%
g3
sethi
%
hi
(
_PAGE_PADDR_SF
),
%
g7
or
%
g7
,
%
lo
(
_PAGE_PADDR_SF
),
%
g7
or
%
g3
,
%
g7
,
%
g3
/
*
Walk
through
entire
ITLB
,
looking
for
entry
which
maps
*
our
%
pc
currently
,
stick
PADDR
from
there
into
%
g5
tlb
data
.
*/
clr
%
l0
/*
TLB
entry
walker
.
*/
set
0x1fff
,
%
l2
/*
Page
mask
.
*/
rd
%
pc
,
%
l3
andn
%
l3
,
%
l2
,
%
g2
/*
vaddr
comparator
*/
1
:
/
*
Yes
,
the
nops
seem
to
be
necessary
for
now
,
don
't ask me why. -DaveM */
ldxa
[%
l0
]
ASI_ITLB_TAG_READ
,
%
g1
nop
nop
nop
andn
%
g1
,
%
l2
,
%
g1
/*
Get
vaddr
*/
cmp
%
g1
,
%
g2
be
,
a
,
pn
%
xcc
,
spitfire_got_tlbentry
ldxa
[%
l0
]
ASI_ITLB_DATA_ACCESS
,
%
g1
cmp
%
l0
,
(
63
<<
3
)
blu
,
pt
%
xcc
,
1
b
add
%
l0
,
(
1
<<
3
),
%
l0
/
*
BUG
()
if
we
get
here
...
*/
ta
0x5
spitfire_got_tlbentry
:
/
*
Nops
here
again
,
perhaps
Cheetah
/
Blackbird
are
better
behaved
...
*/
nop
nop
nop
and
%
g1
,
%
g3
,
%
g1
/*
Mask
to
just
get
paddr
bits
.
*/
set
0x5fff
,
%
l3
/*
Mask
offset
to
get
phys
base
.
*/
andn
%
g1
,
%
l3
,
%
g1
/
*
NOTE
:
We
hold
on
to
%
g1
paddr
base
as
we
need
it
below
to
lock
*
NOTE
:
the
PROM
cif
code
into
the
TLB
.
*/
or
%
g5
,
%
g1
,
%
g5
/*
Or
it
into
TAG
being
built
.
*/
clr
%
l0
/*
TLB
entry
walker
.
*/
sethi
%
hi
(
KERNBASE
),
%
g3
/*
4
M
lower
limit
*/
sethi
%
hi
(
KERNBASE
<<
1
),
%
g7
/*
8
M
upper
limit
*/
mov
TLB_TAG_ACCESS
,
%
l7
1
:
/
*
Yes
,
the
nops
seem
to
be
necessary
for
now
,
don
't ask me why. -DaveM */
ldxa
[%
l0
]
ASI_ITLB_TAG_READ
,
%
g1
nop
nop
nop
andn
%
g1
,
%
l2
,
%
g1
/*
Get
vaddr
*/
cmp
%
g1
,
%
g3
blu
,
pn
%
xcc
,
2
f
cmp
%
g1
,
%
g7
bgeu
,
pn
%
xcc
,
2
f
nop
stxa
%
g0
,
[%
l7
]
ASI_IMMU
stxa
%
g0
,
[%
l0
]
ASI_ITLB_DATA_ACCESS
membar
#
Sync
2
:
cmp
%
l0
,
(
63
<<
3
)
blu
,
pt
%
xcc
,
1
b
add
%
l0
,
(
1
<<
3
),
%
l0
nop
; nop; nop
clr
%
l0
/*
TLB
entry
walker
.
*/
1
:
/
*
Yes
,
the
nops
seem
to
be
necessary
for
now
,
don
't ask me why. -DaveM */
ldxa
[%
l0
]
ASI_DTLB_TAG_READ
,
%
g1
nop
nop
nop
andn
%
g1
,
%
l2
,
%
g1
/*
Get
vaddr
*/
cmp
%
g1
,
%
g3
blu
,
pn
%
xcc
,
2
f
cmp
%
g1
,
%
g7
bgeu
,
pn
%
xcc
,
2
f
nop
stxa
%
g0
,
[%
l7
]
ASI_DMMU
stxa
%
g0
,
[%
l0
]
ASI_DTLB_DATA_ACCESS
membar
#
Sync
2
:
cmp
%
l0
,
(
63
<<
3
)
blu
,
pt
%
xcc
,
1
b
add
%
l0
,
(
1
<<
3
),
%
l0
nop
; nop; nop
/
*
PROM
never
puts
any
TLB
entries
into
the
MMU
with
the
lock
bit
*
set
.
So
we
gladly
use
tlb
entry
63
for
KERNBASE
.
And
maybe
62
too
.
*/
sethi
%
hi
(
KERNBASE
),
%
g3
mov
(
63
<<
3
),
%
g7
stxa
%
g3
,
[%
l7
]
ASI_DMMU
/*
KERNBASE
into
TLB
TAG
*/
stxa
%
g5
,
[%
g7
]
ASI_DTLB_DATA_ACCESS
/*
TTE
into
TLB
DATA
*/
membar
#
Sync
stxa
%
g3
,
[%
l7
]
ASI_IMMU
/*
KERNBASE
into
TLB
TAG
*/
stxa
%
g5
,
[%
g7
]
ASI_ITLB_DATA_ACCESS
/*
TTE
into
TLB
DATA
*/
membar
#
Sync
flush
%
g3
membar
#
Sync
sethi
%
hi
(
_end
),
%
g3
/*
Check
for
bigkernel
case
*/
or
%
g3
,
%
lo
(
_end
),
%
g3
srl
%
g3
,
23
,
%
g3
/*
Check
if
_end
>
8
M
*/
brz
,
pt
%
g3
,
2
f
sethi
%
hi
(
KERNBASE
),
%
g3
/*
Restore
for
fixup
code
below
*/
sethi
%
hi
(
0x400000
),
%
g3
or
%
g3
,
%
lo
(
0x400000
),
%
g3
add
%
g5
,
%
g3
,
%
g5
/*
New
tte
data
*/
andn
%
g5
,
(
_PAGE_G
),
%
g5
sethi
%
hi
(
KERNBASE
+
0x400000
),
%
g3
or
%
g3
,
%
lo
(
KERNBASE
+
0x400000
),
%
g3
mov
(
62
<<
3
),
%
g7
stxa
%
g3
,
[%
l7
]
ASI_DMMU
stxa
%
g5
,
[%
g7
]
ASI_DTLB_DATA_ACCESS
membar
#
Sync
stxa
%
g3
,
[%
l7
]
ASI_IMMU
stxa
%
g5
,
[%
g7
]
ASI_ITLB_DATA_ACCESS
membar
#
Sync
flush
%
g3
membar
#
Sync
sethi
%
hi
(
KERNBASE
),
%
g3
/*
Restore
for
fixup
code
below
*/
2
:
ba
,
pt
%
xcc
,
1
f
nop
1
:
set
sun4u_init
,
%
g2
jmpl
%
g2
+
%
g0
,
%
g0
nop
...
...
@@ -483,38 +311,12 @@ sun4u_init:
stxa
%
g0
,
[%
g7
]
ASI_DMMU
membar
#
Sync
/
*
We
are
now
safely
(
we
hope
)
in
Nucleus
context
(
0
),
rewrite
*
the
KERNBASE
TTE
's so they no longer have the global bit set.
*
Don
't forget to setup TAG_ACCESS first 8-)
*/
mov
TLB_TAG_ACCESS
,
%
g2
stxa
%
g3
,
[%
g2
]
ASI_IMMU
stxa
%
g3
,
[%
g2
]
ASI_DMMU
membar
#
Sync
BRANCH_IF_ANY_CHEETAH
(
g1
,
g7
,
cheetah_tlb_fixup
)
ba
,
pt
%
xcc
,
spitfire_tlb_fixup
nop
cheetah_tlb_fixup
:
set
(
0
<<
16
)
|
(
15
<<
3
),
%
g7
ldxa
[%
g7
]
ASI_ITLB_DATA_ACCESS
,
%
g0
ldxa
[%
g7
]
ASI_ITLB_DATA_ACCESS
,
%
g1
andn
%
g1
,
(
_PAGE_G
),
%
g1
stxa
%
g1
,
[%
g7
]
ASI_ITLB_DATA_ACCESS
membar
#
Sync
ldxa
[%
g7
]
ASI_DTLB_DATA_ACCESS
,
%
g0
ldxa
[%
g7
]
ASI_DTLB_DATA_ACCESS
,
%
g1
andn
%
g1
,
(
_PAGE_G
),
%
g1
stxa
%
g1
,
[%
g7
]
ASI_DTLB_DATA_ACCESS
membar
#
Sync
/
*
Kill
instruction
prefetch
queues
.
*/
flush
%
g3
membar
#
Sync
mov
2
,
%
g2
/*
Set
TLB
type
to
cheetah
+
.
*/
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON
(
g1
,
g7
,1
f
)
...
...
@@ -551,21 +353,6 @@ cheetah_tlb_fixup:
nop
spitfire_tlb_fixup
:
mov
(
63
<<
3
),
%
g7
ldxa
[%
g7
]
ASI_ITLB_DATA_ACCESS
,
%
g1
andn
%
g1
,
(
_PAGE_G
),
%
g1
stxa
%
g1
,
[%
g7
]
ASI_ITLB_DATA_ACCESS
membar
#
Sync
ldxa
[%
g7
]
ASI_DTLB_DATA_ACCESS
,
%
g1
andn
%
g1
,
(
_PAGE_G
),
%
g1
stxa
%
g1
,
[%
g7
]
ASI_DTLB_DATA_ACCESS
membar
#
Sync
/
*
Kill
instruction
prefetch
queues
.
*/
flush
%
g3
membar
#
Sync
/
*
Set
TLB
type
to
spitfire
.
*/
mov
0
,
%
g2
sethi
%
hi
(
tlb_type
),
%
g1
...
...
@@ -578,24 +365,6 @@ tlb_fixup_done:
mov
%
sp
,
%
l6
mov
%
o4
,
%
l7
#if 0 /* We don't do it like this anymore, but for historical hack value
*
I
leave
this
snippet
here
to
show
how
crazy
we
can
be
sometimes
.
8
-)
*/
/
*
Setup
"Linux Current Register"
,
thanks
Sun
8
-)
*/
wr
%
g0
,
0x1
,
%
pcr
/
*
Blackbird
errata
workaround
.
See
commentary
in
*
smp
.
c
:
smp_percpu_timer_interrupt
()
for
more
*
information
.
*/
ba
,
pt
%
xcc
,
99
f
nop
.
align
64
99
:
wr
%
g6
,
%
g0
,
%
pic
rd
%
pic
,
%
g0
#endif
wr
%
g0
,
ASI_P
,
%
asi
mov
1
,
%
g1
sllx
%
g1
,
THREAD_SHIFT
,
%
g1
...
...
@@ -756,12 +525,7 @@ bootup_user_stack_end:
#include "ttable.S"
#include "systbls.S"
.
align
1024
.
globl
swapper_pg_dir
swapper_pg_dir
:
.
word
0
#include "ktlb.S"
#include "etrap.S"
#include "rtrap.S"
#include "winfixup.S"
...
...
arch/sparc64/kernel/ktlb.S
0 → 100644
View file @
95001ee9
/*
arch
/
sparc64
/
kernel
/
ktlb.S
:
Kernel
mapping
TLB
miss
handling
.
*
*
Copyright
(
C
)
1995
,
1997
,
2005
David
S
.
Miller
<
davem
@
davemloft
.
net
>
*
Copyright
(
C
)
1996
Eddie
C
.
Dost
(
ecd
@
brainaid
.
de
)
*
Copyright
(
C
)
1996
Miguel
de
Icaza
(
miguel
@
nuclecu
.
unam
.
mx
)
*
Copyright
(
C
)
1996
,
98
,
99
Jakub
Jelinek
(
jj
@
sunsite
.
mff
.
cuni
.
cz
)
*/
#include <linux/config.h>
#include <asm/head.h>
#include <asm/asi.h>
#include <asm/page.h>
#include <asm/pgtable.h>
.
text
.
align
32
/*
*
On
a
second
level
vpte
miss
,
check
whether
the
original
fault
is
to
the
OBP
*
range
(
note
that
this
is
only
possible
for
instruction
miss
,
data
misses
to
*
obp
range
do
not
use
vpte
)
.
If
so
,
go
back
directly
to
the
faulting
address
.
*
This
is
because
we
want
to
read
the
tpc
,
otherwise
we
have
no
way
of
knowing
*
the
8
k
aligned
faulting
address
if
we
are
using
>
8
k
kernel
pagesize
.
This
*
also
ensures
no
vpte
range
addresses
are
dropped
into
tlb
while
obp
is
*
executing
(
see
inherit_locked_prom_mappings
()
rant
)
.
*/
sparc64_vpte_nucleus
:
/
*
Note
that
kvmap
below
has
verified
that
the
address
is
*
in
the
range
MODULES_VADDR
-->
VMALLOC_END
already
.
So
*
here
we
need
only
check
if
it
is
an
OBP
address
or
not
.
*/
sethi
%
hi
(
LOW_OBP_ADDRESS
),
%
g5
cmp
%
g4
,
%
g5
blu
,
pn
%
xcc
,
kern_vpte
mov
0x1
,
%
g5
sllx
%
g5
,
32
,
%
g5
cmp
%
g4
,
%
g5
blu
,
pn
%
xcc
,
vpte_insn_obp
nop
/
*
These
two
instructions
are
patched
by
paginig_init
()
.
*/
kern_vpte
:
sethi
%
hi
(
swapper_pgd_zero
),
%
g5
lduw
[%
g5
+
%
lo
(
swapper_pgd_zero
)],
%
g5
/
*
With
kernel
PGD
in
%
g5
,
branch
back
into
dtlb_backend
.
*/
ba
,
pt
%
xcc
,
sparc64_kpte_continue
andn
%
g1
,
0x3
,
%
g1
/*
Finish
PMD
offset
adjustment
.
*/
vpte_noent
:
/
*
Restore
previous
TAG_ACCESS
,
%
g5
is
zero
,
and
we
will
*
skip
over
the
trap
instruction
so
that
the
top
level
*
TLB
miss
handler
will
thing
this
%
g5
value
is
just
an
*
invalid
PTE
,
thus
branching
to
full
fault
processing
.
*/
mov
TLB_SFSR
,
%
g1
stxa
%
g4
,
[%
g1
+
%
g1
]
ASI_DMMU
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
*/
srlx
%
g4
,
13
,
%
g4
/*
Throw
out
context
bits
*/
sllx
%
g4
,
13
,
%
g4
/*
g4
has
vpn
+
ctx0
now
*/
/
*
Restore
previous
TAG_ACCESS
.
*/
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
.
*/
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
/
*
TLB
load
and
return
from
trap
.
*/
stxa
%
g5
,
[%
g0
]
ASI_DTLB_DATA_IN
retry
/*
*
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
*
prom_getproperty
on
"address"
),
and
if
so
,
do
not
use
vpte
access
...
*
rather
,
use
information
saved
during
inherit_prom_mappings
()
using
8
k
*
pagesize
.
*/
.
align
32
kvmap
:
brgez
,
pn
%
g4
,
kvmap_nonlinear
nop
#ifdef CONFIG_DEBUG_PAGEALLOC
.
globl
kvmap_linear_patch
kvmap_linear_patch
:
#endif
ba
,
pt
%
xcc
,
kvmap_load
xor
%
g2
,
%
g4
,
%
g5
#ifdef CONFIG_DEBUG_PAGEALLOC
sethi
%
hi
(
swapper_pg_dir
),
%
g5
or
%
g5
,
%
lo
(
swapper_pg_dir
),
%
g5
sllx
%
g4
,
64
-
(
PGDIR_SHIFT
+
PGDIR_BITS
),
%
g6
srlx
%
g6
,
64
-
PAGE_SHIFT
,
%
g6
andn
%
g6
,
0x3
,
%
g6
lduw
[%
g5
+
%
g6
],
%
g5
brz
,
pn
%
g5
,
longpath
sllx
%
g4
,
64
-
(
PMD_SHIFT
+
PMD_BITS
),
%
g6
srlx
%
g6
,
64
-
PAGE_SHIFT
,
%
g6
sllx
%
g5
,
11
,
%
g5
andn
%
g6
,
0x3
,
%
g6
lduwa
[%
g5
+
%
g6
]
ASI_PHYS_USE_EC
,
%
g5
brz
,
pn
%
g5
,
longpath
sllx
%
g4
,
64
-
PMD_SHIFT
,
%
g6
srlx
%
g6
,
64
-
PAGE_SHIFT
,
%
g6
sllx
%
g5
,
11
,
%
g5
andn
%
g6
,
0x7
,
%
g6
ldxa
[%
g5
+
%
g6
]
ASI_PHYS_USE_EC
,
%
g5
brz
,
pn
%
g5
,
longpath
nop
ba
,
a
,
pt
%
xcc
,
kvmap_load
#endif
kvmap_nonlinear
:
sethi
%
hi
(
MODULES_VADDR
),
%
g5
cmp
%
g4
,
%
g5
blu
,
pn
%
xcc
,
longpath
mov
(
VMALLOC_END
>>
24
),
%
g5
sllx
%
g5
,
24
,
%
g5
cmp
%
g4
,
%
g5
bgeu
,
pn
%
xcc
,
longpath
nop
kvmap_check_obp
:
sethi
%
hi
(
LOW_OBP_ADDRESS
),
%
g5
cmp
%
g4
,
%
g5
blu
,
pn
%
xcc
,
kvmap_vmalloc_addr
mov
0x1
,
%
g5
sllx
%
g5
,
32
,
%
g5
cmp
%
g4
,
%
g5
blu
,
pn
%
xcc
,
kvmap_do_obp
nop
kvmap_vmalloc_addr
:
/
*
If
we
get
here
,
a
vmalloc
addr
was
accessed
,
load
kernel
VPTE
.
*/
ldxa
[%
g3
+
%
g6
]
ASI_N
,
%
g5
brgez
,
pn
%
g5
,
longpath
nop
kvmap_load
:
/
*
PTE
is
valid
,
load
into
TLB
and
return
from
trap
.
*/
stxa
%
g5
,
[%
g0
]
ASI_DTLB_DATA_IN
!
Reload
TLB
retry
arch/sparc64/kernel/pci_schizo.c
View file @
95001ee9
...
...
@@ -330,7 +330,7 @@ static int schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
static
void
tomatillo_wsync_handler
(
struct
ino_bucket
*
bucket
,
void
*
_arg1
,
void
*
_arg2
)
{
unsigned
long
sync_reg
=
(
unsigned
long
)
_arg2
;
u64
mask
=
1
<<
(
__irq_ino
(
__irq
(
bucket
))
&
IMAP_INO
);
u64
mask
=
1
UL
<<
(
__irq_ino
(
__irq
(
bucket
))
&
IMAP_INO
);
u64
val
;
int
limit
;
...
...
arch/sparc64/kernel/setup.c
View file @
95001ee9
...
...
@@ -496,7 +496,6 @@ extern void paging_init(void);
void
__init
setup_arch
(
char
**
cmdline_p
)
{
unsigned
long
highest_paddr
;
int
i
;
/* Initialize PROM console and command line. */
...
...
@@ -519,11 +518,7 @@ void __init setup_arch(char **cmdline_p)
idprom_init
();
(
void
)
prom_probe_memory
();
/* In paging_init() we tip off this value to see if we need
* to change init_mm.pgd to point to the real alias mapping.
*/
phys_base
=
0xffffffffffffffffUL
;
highest_paddr
=
0UL
;
for
(
i
=
0
;
sp_banks
[
i
].
num_bytes
!=
0
;
i
++
)
{
unsigned
long
top
;
...
...
@@ -531,25 +526,10 @@ void __init setup_arch(char **cmdline_p)
phys_base
=
sp_banks
[
i
].
base_addr
;
top
=
sp_banks
[
i
].
base_addr
+
sp_banks
[
i
].
num_bytes
;
if
(
highest_paddr
<
top
)
highest_paddr
=
top
;
}
pfn_base
=
phys_base
>>
PAGE_SHIFT
;
switch
(
tlb_type
)
{
default:
case
spitfire
:
kern_base
=
spitfire_get_itlb_data
(
sparc64_highest_locked_tlbent
());
kern_base
&=
_PAGE_PADDR_SF
;
break
;
case
cheetah
:
case
cheetah_plus
:
kern_base
=
cheetah_get_litlb_data
(
sparc64_highest_locked_tlbent
());
kern_base
&=
_PAGE_PADDR
;
break
;
};
kern_base
=
(
prom_boot_mapping_phys_low
>>
22UL
)
<<
22UL
;
kern_size
=
(
unsigned
long
)
&
_end
-
(
unsigned
long
)
KERNBASE
;
if
(
!
root_flags
)
...
...
@@ -625,6 +605,9 @@ extern void smp_info(struct seq_file *);
extern
void
smp_bogo
(
struct
seq_file
*
);
extern
void
mmu_info
(
struct
seq_file
*
);
unsigned
int
dcache_parity_tl1_occurred
;
unsigned
int
icache_parity_tl1_occurred
;
static
int
show_cpuinfo
(
struct
seq_file
*
m
,
void
*
__unused
)
{
seq_printf
(
m
,
...
...
@@ -635,6 +618,8 @@ static int show_cpuinfo(struct seq_file *m, void *__unused)
"type
\t\t
: sun4u
\n
"
"ncpus probed
\t
: %ld
\n
"
"ncpus active
\t
: %ld
\n
"
"D$ parity tl1
\t
: %u
\n
"
"I$ parity tl1
\t
: %u
\n
"
#ifndef CONFIG_SMP
"Cpu0Bogo
\t
: %lu.%02lu
\n
"
"Cpu0ClkTck
\t
: %016lx
\n
"
...
...
@@ -647,7 +632,9 @@ static int show_cpuinfo(struct seq_file *m, void *__unused)
(
prom_prev
>>
8
)
&
0xff
,
prom_prev
&
0xff
,
(
long
)
num_possible_cpus
(),
(
long
)
num_online_cpus
()
(
long
)
num_online_cpus
(),
dcache_parity_tl1_occurred
,
icache_parity_tl1_occurred
#ifndef CONFIG_SMP
,
cpu_data
(
0
).
udelay_val
/
(
500000
/
HZ
),
(
cpu_data
(
0
).
udelay_val
/
(
5000
/
HZ
))
%
100
,
...
...
arch/sparc64/kernel/smp.c
View file @
95001ee9
...
...
@@ -93,6 +93,27 @@ void __init smp_store_cpu_info(int id)
cpu_data
(
id
).
pte_cache
[
1
]
=
NULL
;
cpu_data
(
id
).
pgd_cache
=
NULL
;
cpu_data
(
id
).
idle_volume
=
1
;
cpu_data
(
id
).
dcache_size
=
prom_getintdefault
(
cpu_node
,
"dcache-size"
,
16
*
1024
);
cpu_data
(
id
).
dcache_line_size
=
prom_getintdefault
(
cpu_node
,
"dcache-line-size"
,
32
);
cpu_data
(
id
).
icache_size
=
prom_getintdefault
(
cpu_node
,
"icache-size"
,
16
*
1024
);
cpu_data
(
id
).
icache_line_size
=
prom_getintdefault
(
cpu_node
,
"icache-line-size"
,
32
);
cpu_data
(
id
).
ecache_size
=
prom_getintdefault
(
cpu_node
,
"ecache-size"
,
4
*
1024
*
1024
);
cpu_data
(
id
).
ecache_line_size
=
prom_getintdefault
(
cpu_node
,
"ecache-line-size"
,
64
);
printk
(
"CPU[%d]: Caches "
"D[sz(%d):line_sz(%d)] "
"I[sz(%d):line_sz(%d)] "
"E[sz(%d):line_sz(%d)]
\n
"
,
id
,
cpu_data
(
id
).
dcache_size
,
cpu_data
(
id
).
dcache_line_size
,
cpu_data
(
id
).
icache_size
,
cpu_data
(
id
).
icache_line_size
,
cpu_data
(
id
).
ecache_size
,
cpu_data
(
id
).
ecache_line_size
);
}
static
void
smp_setup_percpu_timer
(
void
);
...
...
arch/sparc64/kernel/trampoline.S
View file @
95001ee9
...
...
@@ -119,8 +119,8 @@ startup_continue:
sethi
%
hi
(
itlb_load
),
%
g2
or
%
g2
,
%
lo
(
itlb_load
),
%
g2
stx
%
g2
,
[%
sp
+
2047
+
128
+
0x18
]
sethi
%
hi
(
mmu_ihandle_cache
),
%
g2
lduw
[%
g2
+
%
lo
(
mmu_ihandle_cache
)],
%
g2
sethi
%
hi
(
prom_
mmu_ihandle_cache
),
%
g2
lduw
[%
g2
+
%
lo
(
prom_
mmu_ihandle_cache
)],
%
g2
stx
%
g2
,
[%
sp
+
2047
+
128
+
0x20
]
sethi
%
hi
(
KERNBASE
),
%
g2
stx
%
g2
,
[%
sp
+
2047
+
128
+
0x28
]
...
...
@@ -156,8 +156,8 @@ startup_continue:
sethi
%
hi
(
itlb_load
),
%
g2
or
%
g2
,
%
lo
(
itlb_load
),
%
g2
stx
%
g2
,
[%
sp
+
2047
+
128
+
0x18
]
sethi
%
hi
(
mmu_ihandle_cache
),
%
g2
lduw
[%
g2
+
%
lo
(
mmu_ihandle_cache
)],
%
g2
sethi
%
hi
(
prom_
mmu_ihandle_cache
),
%
g2
lduw
[%
g2
+
%
lo
(
prom_
mmu_ihandle_cache
)],
%
g2
stx
%
g2
,
[%
sp
+
2047
+
128
+
0x20
]
sethi
%
hi
(
KERNBASE
+
0x400000
),
%
g2
stx
%
g2
,
[%
sp
+
2047
+
128
+
0x28
]
...
...
@@ -190,8 +190,8 @@ do_dtlb:
sethi
%
hi
(
dtlb_load
),
%
g2
or
%
g2
,
%
lo
(
dtlb_load
),
%
g2
stx
%
g2
,
[%
sp
+
2047
+
128
+
0x18
]
sethi
%
hi
(
mmu_ihandle_cache
),
%
g2
lduw
[%
g2
+
%
lo
(
mmu_ihandle_cache
)],
%
g2
sethi
%
hi
(
prom_
mmu_ihandle_cache
),
%
g2
lduw
[%
g2
+
%
lo
(
prom_
mmu_ihandle_cache
)],
%
g2
stx
%
g2
,
[%
sp
+
2047
+
128
+
0x20
]
sethi
%
hi
(
KERNBASE
),
%
g2
stx
%
g2
,
[%
sp
+
2047
+
128
+
0x28
]
...
...
@@ -228,8 +228,8 @@ do_dtlb:
sethi
%
hi
(
dtlb_load
),
%
g2
or
%
g2
,
%
lo
(
dtlb_load
),
%
g2
stx
%
g2
,
[%
sp
+
2047
+
128
+
0x18
]
sethi
%
hi
(
mmu_ihandle_cache
),
%
g2
lduw
[%
g2
+
%
lo
(
mmu_ihandle_cache
)],
%
g2
sethi
%
hi
(
prom_
mmu_ihandle_cache
),
%
g2
lduw
[%
g2
+
%
lo
(
prom_
mmu_ihandle_cache
)],
%
g2
stx
%
g2
,
[%
sp
+
2047
+
128
+
0x20
]
sethi
%
hi
(
KERNBASE
+
0x400000
),
%
g2
stx
%
g2
,
[%
sp
+
2047
+
128
+
0x28
]
...
...
arch/sparc64/kernel/traps.c
View file @
95001ee9
...
...
@@ -869,14 +869,19 @@ static void cheetah_flush_ecache_line(unsigned long physaddr)
*/
static
void
__cheetah_flush_icache
(
void
)
{
unsigned
long
i
;
unsigned
int
icache_size
,
icache_line_size
;
unsigned
long
addr
;
icache_size
=
local_cpu_data
().
icache_size
;
icache_line_size
=
local_cpu_data
().
icache_line_size
;
/* Clear the valid bits in all the tags. */
for
(
i
=
0
;
i
<
(
1
<<
15
);
i
+=
(
1
<<
5
)
)
{
for
(
addr
=
0
;
addr
<
icache_size
;
addr
+=
icache_line_size
)
{
__asm__
__volatile__
(
"stxa %%g0, [%0] %1
\n\t
"
"membar #Sync"
:
/* no outputs */
:
"r"
(
i
|
(
2
<<
3
)),
"i"
(
ASI_IC_TAG
));
:
"r"
(
addr
|
(
2
<<
3
)),
"i"
(
ASI_IC_TAG
));
}
}
...
...
@@ -904,13 +909,17 @@ static void cheetah_flush_icache(void)
static
void
cheetah_flush_dcache
(
void
)
{
unsigned
long
i
;
unsigned
int
dcache_size
,
dcache_line_size
;
unsigned
long
addr
;
dcache_size
=
local_cpu_data
().
dcache_size
;
dcache_line_size
=
local_cpu_data
().
dcache_line_size
;
for
(
i
=
0
;
i
<
(
1
<<
16
);
i
+=
(
1
<<
5
)
)
{
for
(
addr
=
0
;
addr
<
dcache_size
;
addr
+=
dcache_line_size
)
{
__asm__
__volatile__
(
"stxa %%g0, [%0] %1
\n\t
"
"membar #Sync"
:
/* no outputs */
:
"r"
(
i
),
"i"
(
ASI_DCACHE_TAG
));
:
"r"
(
addr
),
"i"
(
ASI_DCACHE_TAG
));
}
}
...
...
@@ -921,24 +930,29 @@ static void cheetah_flush_dcache(void)
*/
static
void
cheetah_plus_zap_dcache_parity
(
void
)
{
unsigned
long
i
;
unsigned
int
dcache_size
,
dcache_line_size
;
unsigned
long
addr
;
dcache_size
=
local_cpu_data
().
dcache_size
;
dcache_line_size
=
local_cpu_data
().
dcache_line_size
;
for
(
i
=
0
;
i
<
(
1
<<
16
);
i
+=
(
1
<<
5
)
)
{
unsigned
long
tag
=
(
i
>>
14
);
unsigned
long
j
;
for
(
addr
=
0
;
addr
<
dcache_size
;
addr
+=
dcache_line_size
)
{
unsigned
long
tag
=
(
addr
>>
14
);
unsigned
long
line
;
__asm__
__volatile__
(
"membar #Sync
\n\t
"
"stxa %0, [%1] %2
\n\t
"
"membar #Sync"
:
/* no outputs */
:
"r"
(
tag
),
"r"
(
i
),
:
"r"
(
tag
),
"r"
(
addr
),
"i"
(
ASI_DCACHE_UTAG
));
for
(
j
=
i
;
j
<
i
+
(
1
<<
5
);
j
+=
(
1
<<
3
)
)
for
(
line
=
addr
;
line
<
addr
+
dcache_line_size
;
line
+=
8
)
__asm__
__volatile__
(
"membar #Sync
\n\t
"
"stxa %%g0, [%0] %1
\n\t
"
"membar #Sync"
:
/* no outputs */
:
"r"
(
j
),
"i"
(
ASI_DCACHE_DATA
));
:
"r"
(
line
),
"i"
(
ASI_DCACHE_DATA
));
}
}
...
...
arch/sparc64/kernel/vmlinux.lds.S
View file @
95001ee9
...
...
@@ -9,8 +9,7 @@ ENTRY(_start)
jiffies
=
jiffies_64
;
SECTIONS
{
swapper_pmd_dir
=
0x0000000000402000
;
empty_pg_dir
=
0x0000000000403000
;
swapper_low_pmd_dir
=
0x0000000000402000
;
.
=
0x4000
;
.
text
0x0000000000404000
:
{
...
...
arch/sparc64/mm/init.c
View file @
95001ee9
...
...
@@ -20,6 +20,7 @@
#include <linux/fs.h>
#include <linux/seq_file.h>
#include <linux/kprobes.h>
#include <linux/cache.h>
#include <asm/head.h>
#include <asm/system.h>
...
...
@@ -42,22 +43,13 @@ extern void device_scan(void);
struct
sparc_phys_banks
sp_banks
[
SPARC_PHYS_BANKS
];
unsigned
long
*
sparc64_valid_addr_bitmap
;
unsigned
long
*
sparc64_valid_addr_bitmap
__read_mostly
;
/* Ugly, but necessary... -DaveM */
unsigned
long
phys_base
;
unsigned
long
kern_base
;
unsigned
long
kern_size
;
unsigned
long
pfn_base
;
/* This is even uglier. We have a problem where the kernel may not be
* located at phys_base. However, initial __alloc_bootmem() calls need to
* be adjusted to be within the 4-8Megs that the kernel is mapped to, else
* those page mappings wont work. Things are ok after inherit_prom_mappings
* is called though. Dave says he'll clean this up some other time.
* -- BenC
*/
static
unsigned
long
bootmap_base
;
unsigned
long
phys_base
__read_mostly
;
unsigned
long
kern_base
__read_mostly
;
unsigned
long
kern_size
__read_mostly
;
unsigned
long
pfn_base
__read_mostly
;
/* get_new_mmu_context() uses "cache + 1". */
DEFINE_SPINLOCK
(
ctx_alloc_lock
);
...
...
@@ -73,7 +65,7 @@ extern unsigned long sparc_ramdisk_image64;
extern
unsigned
int
sparc_ramdisk_image
;
extern
unsigned
int
sparc_ramdisk_size
;
struct
page
*
mem_map_zero
;
struct
page
*
mem_map_zero
__read_mostly
;
int
bigkernel
=
0
;
...
...
@@ -179,8 +171,6 @@ static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long c
:
"g1"
,
"g7"
);
}
extern
void
__update_mmu_cache
(
unsigned
long
mmu_context_hw
,
unsigned
long
address
,
pte_t
pte
,
int
code
);
void
update_mmu_cache
(
struct
vm_area_struct
*
vma
,
unsigned
long
address
,
pte_t
pte
)
{
struct
page
*
page
;
...
...
@@ -207,10 +197,6 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p
put_cpu
();
}
if
(
get_thread_fault_code
())
__update_mmu_cache
(
CTX_NRBITS
(
vma
->
vm_mm
->
context
),
address
,
pte
,
get_thread_fault_code
());
}
void
flush_dcache_page
(
struct
page
*
page
)
...
...
@@ -309,6 +295,7 @@ struct linux_prom_translation {
unsigned
long
size
;
unsigned
long
data
;
};
static
struct
linux_prom_translation
prom_trans
[
512
]
__initdata
;
extern
unsigned
long
prom_boot_page
;
extern
void
prom_remap
(
unsigned
long
physpage
,
unsigned
long
virtpage
,
int
mmu_ihandle
);
...
...
@@ -318,14 +305,63 @@ extern void register_prom_callbacks(void);
/* Exported for SMP bootup purposes. */
unsigned
long
kern_locked_tte_data
;
void
__init
early_pgtable_allocfail
(
char
*
type
)
/* Exported for kernel TLB miss handling in ktlb.S */
unsigned
long
prom_pmd_phys
__read_mostly
;
unsigned
int
swapper_pgd_zero
__read_mostly
;
/* Allocate power-of-2 aligned chunks from the end of the
* kernel image. Return physical address.
*/
static
inline
unsigned
long
early_alloc_phys
(
unsigned
long
size
)
{
unsigned
long
base
;
BUILD_BUG_ON
(
size
&
(
size
-
1
));
kern_size
=
(
kern_size
+
(
size
-
1
))
&
~
(
size
-
1
);
base
=
kern_base
+
kern_size
;
kern_size
+=
size
;
return
base
;
}
static
inline
unsigned
long
load_phys32
(
unsigned
long
pa
)
{
unsigned
long
val
;
__asm__
__volatile__
(
"lduwa [%1] %2, %0"
:
"=&r"
(
val
)
:
"r"
(
pa
),
"i"
(
ASI_PHYS_USE_EC
));
return
val
;
}
static
inline
unsigned
long
load_phys64
(
unsigned
long
pa
)
{
unsigned
long
val
;
__asm__
__volatile__
(
"ldxa [%1] %2, %0"
:
"=&r"
(
val
)
:
"r"
(
pa
),
"i"
(
ASI_PHYS_USE_EC
));
return
val
;
}
static
inline
void
store_phys32
(
unsigned
long
pa
,
unsigned
long
val
)
{
__asm__
__volatile__
(
"stwa %0, [%1] %2"
:
/* no outputs */
:
"r"
(
val
),
"r"
(
pa
),
"i"
(
ASI_PHYS_USE_EC
));
}
static
inline
void
store_phys64
(
unsigned
long
pa
,
unsigned
long
val
)
{
prom_printf
(
"inherit_prom_mappings: Cannot alloc kernel %s.
\n
"
,
type
);
prom_halt
();
__asm__
__volatile__
(
"stxa %0, [%1] %2"
:
/* no outputs */
:
"r"
(
val
),
"r"
(
pa
),
"i"
(
ASI_PHYS_USE_EC
));
}
#define BASE_PAGE_SIZE 8192
static
pmd_t
*
prompmd
;
/*
* Translate PROM's mapping we capture at boot time into physical address.
...
...
@@ -333,278 +369,172 @@ static pmd_t *prompmd;
*/
unsigned
long
prom_virt_to_phys
(
unsigned
long
promva
,
int
*
error
)
{
pmd_t
*
pmdp
=
prompmd
+
((
promva
>>
23
)
&
0x7ff
);
pte_t
*
ptep
;
unsigned
long
pmd_phys
=
(
prom_pmd_phys
+
((
promva
>>
23
)
&
0x7ff
)
*
sizeof
(
pmd_t
));
unsigned
long
pte_phys
;
pmd_t
pmd_ent
;
pte_t
pte_ent
;
unsigned
long
base
;
if
(
pmd_none
(
*
pmdp
))
{
pmd_val
(
pmd_ent
)
=
load_phys32
(
pmd_phys
);
if
(
pmd_none
(
pmd_ent
))
{
if
(
error
)
*
error
=
1
;
return
(
0
)
;
return
0
;
}
ptep
=
(
pte_t
*
)
__pmd_page
(
*
pmdp
)
+
((
promva
>>
13
)
&
0x3ff
);
if
(
!
pte_present
(
*
ptep
))
{
pte_phys
=
(
unsigned
long
)
pmd_val
(
pmd_ent
)
<<
11UL
;
pte_phys
+=
((
promva
>>
13
)
&
0x3ff
)
*
sizeof
(
pte_t
);
pte_val
(
pte_ent
)
=
load_phys64
(
pte_phys
);
if
(
!
pte_present
(
pte_ent
))
{
if
(
error
)
*
error
=
1
;
return
(
0
)
;
return
0
;
}
if
(
error
)
{
*
error
=
0
;
return
(
pte_val
(
*
ptep
)
);
return
pte_val
(
pte_ent
);
}
base
=
pte_val
(
*
ptep
)
&
_PAGE_PADDR
;
return
(
base
+
(
promva
&
(
BASE_PAGE_SIZE
-
1
)));
base
=
pte_val
(
pte_ent
)
&
_PAGE_PADDR
;
return
(
base
+
(
promva
&
(
BASE_PAGE_SIZE
-
1
)));
}
static
void
inherit_prom_mappings
(
void
)
/* 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
)
{
struct
linux_prom_translation
*
trans
;
unsigned
long
phys_page
,
tte_vaddr
,
tte_data
;
void
(
*
remap_func
)(
unsigned
long
,
unsigned
long
,
int
);
pmd_t
*
pmdp
;
pte_t
*
ptep
;
int
node
,
n
,
i
,
tsz
;
extern
unsigned
int
obp_iaddr_patch
[
2
],
obp_daddr_patch
[
2
];
unsigned
long
vaddr
;
node
=
prom_finddevice
(
"/virtual-memory"
);
n
=
prom_getproplen
(
node
,
"translations"
);
if
(
n
==
0
||
n
==
-
1
)
{
prom_printf
(
"Couldn't get translation property
\n
"
);
prom_halt
();
}
n
+=
5
*
sizeof
(
struct
linux_prom_translation
);
for
(
tsz
=
1
;
tsz
<
n
;
tsz
<<=
1
)
/* empty */
;
trans
=
__alloc_bootmem
(
tsz
,
SMP_CACHE_BYTES
,
bootmap_base
);
if
(
trans
==
NULL
)
{
prom_printf
(
"inherit_prom_mappings: Cannot alloc translations.
\n
"
);
prom_halt
();
}
memset
(
trans
,
0
,
tsz
);
for
(
vaddr
=
start
;
vaddr
<
end
;
vaddr
+=
BASE_PAGE_SIZE
)
{
unsigned
long
val
,
pte_phys
,
pmd_phys
;
pmd_t
pmd_ent
;
int
i
;
if
((
n
=
prom_getproperty
(
node
,
"translations"
,
(
char
*
)
trans
,
tsz
))
==
-
1
)
{
prom_printf
(
"Couldn't get translation property
\n
"
);
p
rom_halt
(
);
}
n
=
n
/
sizeof
(
*
trans
);
pmd_phys
=
(
prom_pmd_phys
+
(((
vaddr
>>
23
)
&
0x7ff
)
*
sizeof
(
pmd_t
))
);
p
md_val
(
pmd_ent
)
=
load_phys32
(
pmd_phys
);
if
(
pmd_none
(
pmd_ent
))
{
pte_phys
=
early_alloc_phys
(
BASE_PAGE_SIZE
);
/*
* The obp translations are saved based on 8k pagesize, since obp can
* use a mixture of pagesizes. Misses to the 0xf0000000 - 0x100000000,
* ie obp range, are handled in entry.S and do not use the vpte scheme
* (see rant in inherit_locked_prom_mappings()).
*/
#define OBP_PMD_SIZE 2048
prompmd
=
__alloc_bootmem
(
OBP_PMD_SIZE
,
OBP_PMD_SIZE
,
bootmap_base
);
if
(
prompmd
==
NULL
)
early_pgtable_allocfail
(
"pmd"
);
memset
(
prompmd
,
0
,
OBP_PMD_SIZE
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
unsigned
long
vaddr
;
if
(
trans
[
i
].
virt
>=
LOW_OBP_ADDRESS
&&
trans
[
i
].
virt
<
HI_OBP_ADDRESS
)
{
for
(
vaddr
=
trans
[
i
].
virt
;
((
vaddr
<
trans
[
i
].
virt
+
trans
[
i
].
size
)
&&
(
vaddr
<
HI_OBP_ADDRESS
));
vaddr
+=
BASE_PAGE_SIZE
)
{
unsigned
long
val
;
pmdp
=
prompmd
+
((
vaddr
>>
23
)
&
0x7ff
);
if
(
pmd_none
(
*
pmdp
))
{
ptep
=
__alloc_bootmem
(
BASE_PAGE_SIZE
,
BASE_PAGE_SIZE
,
bootmap_base
);
if
(
ptep
==
NULL
)
early_pgtable_allocfail
(
"pte"
);
memset
(
ptep
,
0
,
BASE_PAGE_SIZE
);
pmd_set
(
pmdp
,
ptep
);
}
ptep
=
(
pte_t
*
)
__pmd_page
(
*
pmdp
)
+
((
vaddr
>>
13
)
&
0x3ff
);
for
(
i
=
0
;
i
<
BASE_PAGE_SIZE
/
sizeof
(
pte_t
);
i
++
)
store_phys64
(
pte_phys
+
i
*
sizeof
(
pte_t
),
0
);
val
=
trans
[
i
].
data
;
pmd_val
(
pmd_ent
)
=
pte_phys
>>
11UL
;
store_phys32
(
pmd_phys
,
pmd_val
(
pmd_ent
));
}
/* Clear diag TTE bits. */
if
(
tlb_type
==
spitfire
)
val
&=
~
0x0003fe0000000000UL
;
pte_phys
=
(
unsigned
long
)
pmd_val
(
pmd_ent
)
<<
11UL
;
pte_phys
+=
(((
vaddr
>>
13
)
&
0x3ff
)
*
sizeof
(
pte_t
));
set_pte_at
(
&
init_mm
,
vaddr
,
ptep
,
__pte
(
val
|
_PAGE_MODIFIED
));
trans
[
i
].
data
+=
BASE_PAGE_SIZE
;
}
}
}
phys_page
=
__pa
(
prompmd
);
obp_iaddr_patch
[
0
]
|=
(
phys_page
>>
10
);
obp_iaddr_patch
[
1
]
|=
(
phys_page
&
0x3ff
);
flushi
((
long
)
&
obp_iaddr_patch
[
0
]);
obp_daddr_patch
[
0
]
|=
(
phys_page
>>
10
);
obp_daddr_patch
[
1
]
|=
(
phys_page
&
0x3ff
);
flushi
((
long
)
&
obp_daddr_patch
[
0
]);
val
=
data
;
/* Now fixup OBP's idea about where we really are mapped. */
prom_printf
(
"Remapping the kernel... "
);
/* Clear diag TTE bits. */
if
(
tlb_type
==
spitfire
)
val
&=
~
0x0003fe0000000000UL
;
/* Spitfire Errata #32 workaround */
/* NOTE: Using plain zero for the context value is
* correct here, we are not using the Linux trap
* tables yet so we should not use the special
* UltraSPARC-III+ page size encodings yet.
*/
__asm__
__volatile__
(
"stxa %0, [%1] %2
\n\t
"
"flush %%g6"
:
/* No outputs */
:
"r"
(
0
),
"r"
(
PRIMARY_CONTEXT
),
"i"
(
ASI_DMMU
));
switch
(
tlb_type
)
{
default:
case
spitfire
:
phys_page
=
spitfire_get_dtlb_data
(
sparc64_highest_locked_tlbent
());
break
;
case
cheetah
:
case
cheetah_plus
:
phys_page
=
cheetah_get_litlb_data
(
sparc64_highest_locked_tlbent
());
break
;
};
phys_page
&=
_PAGE_PADDR
;
phys_page
+=
((
unsigned
long
)
&
prom_boot_page
-
(
unsigned
long
)
KERNBASE
);
store_phys64
(
pte_phys
,
val
|
_PAGE_MODIFIED
);
if
(
tlb_type
==
spitfire
)
{
/* Lock this into i/d tlb entry 59 */
__asm__
__volatile__
(
"stxa %%g0, [%2] %3
\n\t
"
"stxa %0, [%1] %4
\n\t
"
"membar #Sync
\n\t
"
"flush %%g6
\n\t
"
"stxa %%g0, [%2] %5
\n\t
"
"stxa %0, [%1] %6
\n\t
"
"membar #Sync
\n\t
"
"flush %%g6"
:
:
"r"
(
phys_page
|
_PAGE_VALID
|
_PAGE_SZ8K
|
_PAGE_CP
|
_PAGE_CV
|
_PAGE_P
|
_PAGE_L
|
_PAGE_W
),
"r"
(
59
<<
3
),
"r"
(
TLB_TAG_ACCESS
),
"i"
(
ASI_DMMU
),
"i"
(
ASI_DTLB_DATA_ACCESS
),
"i"
(
ASI_IMMU
),
"i"
(
ASI_ITLB_DATA_ACCESS
)
:
"memory"
);
}
else
if
(
tlb_type
==
cheetah
||
tlb_type
==
cheetah_plus
)
{
/* Lock this into i/d tlb-0 entry 11 */
__asm__
__volatile__
(
"stxa %%g0, [%2] %3
\n\t
"
"stxa %0, [%1] %4
\n\t
"
"membar #Sync
\n\t
"
"flush %%g6
\n\t
"
"stxa %%g0, [%2] %5
\n\t
"
"stxa %0, [%1] %6
\n\t
"
"membar #Sync
\n\t
"
"flush %%g6"
:
:
"r"
(
phys_page
|
_PAGE_VALID
|
_PAGE_SZ8K
|
_PAGE_CP
|
_PAGE_CV
|
_PAGE_P
|
_PAGE_L
|
_PAGE_W
),
"r"
((
0
<<
16
)
|
(
11
<<
3
)),
"r"
(
TLB_TAG_ACCESS
),
"i"
(
ASI_DMMU
),
"i"
(
ASI_DTLB_DATA_ACCESS
),
"i"
(
ASI_IMMU
),
"i"
(
ASI_ITLB_DATA_ACCESS
)
:
"memory"
);
}
else
{
/* Implement me :-) */
BUG
();
data
+=
BASE_PAGE_SIZE
;
}
}
tte_vaddr
=
(
unsigned
long
)
KERNBASE
;
static
inline
int
in_obp_range
(
unsigned
long
vaddr
)
{
return
(
vaddr
>=
LOW_OBP_ADDRESS
&&
vaddr
<
HI_OBP_ADDRESS
);
}
/* Spitfire Errata #32 workaround */
/* NOTE: Using plain zero for the context value is
* correct here, we are not using the Linux trap
* tables yet so we should not use the special
* UltraSPARC-III+ page size encodings yet.
*/
__asm__
__volatile__
(
"stxa %0, [%1] %2
\n\t
"
"flush %%g6"
:
/* No outputs */
:
"r"
(
0
),
"r"
(
PRIMARY_CONTEXT
),
"i"
(
ASI_DMMU
));
if
(
tlb_type
==
spitfire
)
tte_data
=
spitfire_get_dtlb_data
(
sparc64_highest_locked_tlbent
());
else
tte_data
=
cheetah_get_ldtlb_data
(
sparc64_highest_locked_tlbent
());
#define OBP_PMD_SIZE 2048
static
void
__init
build_obp_pgtable
(
int
prom_trans_ents
)
{
unsigned
long
i
;
kern_locked_tte_data
=
tte_data
;
prom_pmd_phys
=
early_alloc_phys
(
OBP_PMD_SIZE
);
for
(
i
=
0
;
i
<
OBP_PMD_SIZE
;
i
+=
4
)
store_phys32
(
prom_pmd_phys
+
i
,
0
);
for
(
i
=
0
;
i
<
prom_trans_ents
;
i
++
)
{
unsigned
long
start
,
end
;
remap_func
=
(
void
*
)
((
unsigned
long
)
&
prom_remap
-
(
unsigned
long
)
&
prom_boot_page
)
;
if
(
!
in_obp_range
(
prom_trans
[
i
].
virt
))
continue
;
start
=
prom_trans
[
i
].
virt
;
end
=
start
+
prom_trans
[
i
].
size
;
if
(
end
>
HI_OBP_ADDRESS
)
end
=
HI_OBP_ADDRESS
;
/* Spitfire Errata #32 workaround */
/* NOTE: Using plain zero for the context value is
* correct here, we are not using the Linux trap
* tables yet so we should not use the special
* UltraSPARC-III+ page size encodings yet.
*/
__asm__
__volatile__
(
"stxa %0, [%1] %2
\n\t
"
"flush %%g6"
:
/* No outputs */
:
"r"
(
0
),
"r"
(
PRIMARY_CONTEXT
),
"i"
(
ASI_DMMU
));
remap_func
((
tlb_type
==
spitfire
?
(
spitfire_get_dtlb_data
(
sparc64_highest_locked_tlbent
())
&
_PAGE_PADDR
)
:
(
cheetah_get_litlb_data
(
sparc64_highest_locked_tlbent
())
&
_PAGE_PADDR
)),
(
unsigned
long
)
KERNBASE
,
prom_get_mmu_ihandle
());
if
(
bigkernel
)
remap_func
(((
tte_data
+
0x400000
)
&
_PAGE_PADDR
),
(
unsigned
long
)
KERNBASE
+
0x400000
,
prom_get_mmu_ihandle
());
/* Flush out that temporary mapping. */
spitfire_flush_dtlb_nucleus_page
(
0x0
);
spitfire_flush_itlb_nucleus_page
(
0x0
);
/* Now lock us back into the TLBs via OBP. */
prom_dtlb_load
(
sparc64_highest_locked_tlbent
(),
tte_data
,
tte_vaddr
);
prom_itlb_load
(
sparc64_highest_locked_tlbent
(),
tte_data
,
tte_vaddr
);
if
(
bigkernel
)
{
prom_dtlb_load
(
sparc64_highest_locked_tlbent
()
-
1
,
tte_data
+
0x400000
,
tte_vaddr
+
0x400000
);
prom_itlb_load
(
sparc64_highest_locked_tlbent
()
-
1
,
tte_data
+
0x400000
,
tte_vaddr
+
0x400000
);
build_obp_range
(
start
,
end
,
prom_trans
[
i
].
data
);
}
}
/* Re-read translations property. */
if
((
n
=
prom_getproperty
(
node
,
"translations"
,
(
char
*
)
trans
,
tsz
))
==
-
1
)
{
prom_printf
(
"Couldn't get translation property
\n
"
);
/* Read OBP translations property into 'prom_trans[]'.
* Return the number of entries.
*/
static
int
__init
read_obp_translations
(
void
)
{
int
n
,
node
;
node
=
prom_finddevice
(
"/virtual-memory"
);
n
=
prom_getproplen
(
node
,
"translations"
);
if
(
unlikely
(
n
==
0
||
n
==
-
1
))
{
prom_printf
(
"prom_mappings: Couldn't get size.
\n
"
);
prom_halt
();
}
if
(
unlikely
(
n
>
sizeof
(
prom_trans
)))
{
prom_printf
(
"prom_mappings: Size %Zd is too big.
\n
"
,
n
);
prom_halt
();
}
n
=
n
/
sizeof
(
*
trans
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
unsigned
long
vaddr
=
trans
[
i
].
virt
;
unsigned
long
size
=
trans
[
i
].
size
;
if
((
n
=
prom_getproperty
(
node
,
"translations"
,
(
char
*
)
&
prom_trans
[
0
],
sizeof
(
prom_trans
)))
==
-
1
)
{
prom_printf
(
"prom_mappings: Couldn't get property.
\n
"
);
prom_halt
();
}
n
=
n
/
sizeof
(
struct
linux_prom_translation
);
return
n
;
}
if
(
vaddr
<
0xf0000000UL
)
{
unsigned
long
avoid_start
=
(
unsigned
long
)
KERNBASE
;
unsigned
long
avoid_end
=
avoid_start
+
(
4
*
1024
*
1024
);
static
void
__init
remap_kernel
(
void
)
{
unsigned
long
phys_page
,
tte_vaddr
,
tte_data
;
int
tlb_ent
=
sparc64_highest_locked_tlbent
();
if
(
bigkernel
)
avoid_end
+=
(
4
*
1024
*
1024
);
if
(
vaddr
<
avoid_start
)
{
unsigned
long
top
=
vaddr
+
size
;
tte_vaddr
=
(
unsigned
long
)
KERNBASE
;
phys_page
=
(
prom_boot_mapping_phys_low
>>
22UL
)
<<
22UL
;
tte_data
=
(
phys_page
|
(
_PAGE_VALID
|
_PAGE_SZ4MB
|
_PAGE_CP
|
_PAGE_CV
|
_PAGE_P
|
_PAGE_L
|
_PAGE_W
));
if
(
top
>
avoid_start
)
top
=
avoid_start
;
prom_unmap
(
top
-
vaddr
,
vaddr
);
}
if
((
vaddr
+
size
)
>
avoid_end
)
{
unsigned
long
bottom
=
vaddr
;
kern_locked_tte_data
=
tte_data
;
if
(
bottom
<
avoid_end
)
bottom
=
avoid_end
;
prom_unmap
((
vaddr
+
size
)
-
bottom
,
bottom
);
}
}
/* Now lock us into the TLBs via OBP. */
prom_dtlb_load
(
tlb_ent
,
tte_data
,
tte_vaddr
);
prom_itlb_load
(
tlb_ent
,
tte_data
,
tte_vaddr
);
if
(
bigkernel
)
{
prom_dtlb_load
(
tlb_ent
-
1
,
tte_data
+
0x400000
,
tte_vaddr
+
0x400000
);
prom_itlb_load
(
tlb_ent
-
1
,
tte_data
+
0x400000
,
tte_vaddr
+
0x400000
);
}
}
static
void
__init
inherit_prom_mappings
(
void
)
{
int
n
;
n
=
read_obp_translations
();
build_obp_pgtable
(
n
);
/* Now fixup OBP's idea about where we really are mapped. */
prom_printf
(
"Remapping the kernel... "
);
remap_kernel
();
prom_printf
(
"done.
\n
"
);
...
...
@@ -1347,8 +1277,6 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
#endif
bootmap_size
=
init_bootmem_node
(
NODE_DATA
(
0
),
bootmap_pfn
,
pfn_base
,
end_pfn
);
bootmap_base
=
bootmap_pfn
<<
PAGE_SHIFT
;
/* Now register the available physical memory with the
* allocator.
*/
...
...
@@ -1398,120 +1326,142 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
return
end_pfn
;
}
#ifdef CONFIG_DEBUG_PAGEALLOC
static
unsigned
long
kernel_map_range
(
unsigned
long
pstart
,
unsigned
long
pend
,
pgprot_t
prot
)
{
unsigned
long
vstart
=
PAGE_OFFSET
+
pstart
;
unsigned
long
vend
=
PAGE_OFFSET
+
pend
;
unsigned
long
alloc_bytes
=
0UL
;
if
((
vstart
&
~
PAGE_MASK
)
||
(
vend
&
~
PAGE_MASK
))
{
prom_printf
(
"kernel_map: Unaligned sp_banks[%lx:%lx]
\n
"
,
vstart
,
vend
);
prom_halt
();
}
while
(
vstart
<
vend
)
{
unsigned
long
this_end
,
paddr
=
__pa
(
vstart
);
pgd_t
*
pgd
=
pgd_offset_k
(
vstart
);
pud_t
*
pud
;
pmd_t
*
pmd
;
pte_t
*
pte
;
pud
=
pud_offset
(
pgd
,
vstart
);
if
(
pud_none
(
*
pud
))
{
pmd_t
*
new
;
new
=
__alloc_bootmem
(
PAGE_SIZE
,
PAGE_SIZE
,
PAGE_SIZE
);
alloc_bytes
+=
PAGE_SIZE
;
pud_populate
(
&
init_mm
,
pud
,
new
);
}
pmd
=
pmd_offset
(
pud
,
vstart
);
if
(
!
pmd_present
(
*
pmd
))
{
pte_t
*
new
;
new
=
__alloc_bootmem
(
PAGE_SIZE
,
PAGE_SIZE
,
PAGE_SIZE
);
alloc_bytes
+=
PAGE_SIZE
;
pmd_populate_kernel
(
&
init_mm
,
pmd
,
new
);
}
pte
=
pte_offset_kernel
(
pmd
,
vstart
);
this_end
=
(
vstart
+
PMD_SIZE
)
&
PMD_MASK
;
if
(
this_end
>
vend
)
this_end
=
vend
;
while
(
vstart
<
this_end
)
{
pte_val
(
*
pte
)
=
(
paddr
|
pgprot_val
(
prot
));
vstart
+=
PAGE_SIZE
;
paddr
+=
PAGE_SIZE
;
pte
++
;
}
}
return
alloc_bytes
;
}
extern
struct
linux_mlist_p1275
*
prom_ptot_ptr
;
extern
unsigned
int
kvmap_linear_patch
[
1
];
static
void
__init
kernel_physical_mapping_init
(
void
)
{
struct
linux_mlist_p1275
*
p
=
prom_ptot_ptr
;
unsigned
long
mem_alloced
=
0UL
;
while
(
p
)
{
unsigned
long
phys_start
,
phys_end
;
phys_start
=
p
->
start_adr
;
phys_end
=
phys_start
+
p
->
num_bytes
;
mem_alloced
+=
kernel_map_range
(
phys_start
,
phys_end
,
PAGE_KERNEL
);
p
=
p
->
theres_more
;
}
printk
(
"Allocated %ld bytes for kernel page tables.
\n
"
,
mem_alloced
);
kvmap_linear_patch
[
0
]
=
0x01000000
;
/* nop */
flushi
(
&
kvmap_linear_patch
[
0
]);
__flush_tlb_all
();
}
void
kernel_map_pages
(
struct
page
*
page
,
int
numpages
,
int
enable
)
{
unsigned
long
phys_start
=
page_to_pfn
(
page
)
<<
PAGE_SHIFT
;
unsigned
long
phys_end
=
phys_start
+
(
numpages
*
PAGE_SIZE
);
kernel_map_range
(
phys_start
,
phys_end
,
(
enable
?
PAGE_KERNEL
:
__pgprot
(
0
)));
/* we should perform an IPI and flush all tlbs,
* but that can deadlock->flush only current cpu.
*/
__flush_tlb_kernel_range
(
PAGE_OFFSET
+
phys_start
,
PAGE_OFFSET
+
phys_end
);
}
#endif
/* paging_init() sets up the page tables */
extern
void
cheetah_ecache_flush_init
(
void
);
static
unsigned
long
last_valid_pfn
;
pgd_t
swapper_pg_dir
[
2048
];
void
__init
paging_init
(
void
)
{
extern
pmd_t
swapper_pmd_dir
[
1024
];
extern
unsigned
int
sparc64_vpte_patchme1
[
1
];
extern
unsigned
int
sparc64_vpte_patchme2
[
1
];
unsigned
long
alias_base
=
kern_base
+
PAGE_OFFSET
;
unsigned
long
second_alias_page
=
0
;
unsigned
long
pt
,
flags
,
end_pfn
,
pages_avail
;
unsigned
long
shift
=
alias_base
-
((
unsigned
long
)
KERNBASE
);
unsigned
long
end_pfn
,
pages_avail
,
shift
;
unsigned
long
real_end
;
set_bit
(
0
,
mmu_context_bmap
);
shift
=
kern_base
+
PAGE_OFFSET
-
((
unsigned
long
)
KERNBASE
);
real_end
=
(
unsigned
long
)
_end
;
if
((
real_end
>
((
unsigned
long
)
KERNBASE
+
0x400000
)))
bigkernel
=
1
;
#ifdef CONFIG_BLK_DEV_INITRD
if
(
sparc_ramdisk_image
||
sparc_ramdisk_image64
)
real_end
=
(
PAGE_ALIGN
(
real_end
)
+
PAGE_ALIGN
(
sparc_ramdisk_size
));
#endif
/* We assume physical memory starts at some 4mb multiple,
* if this were not true we wouldn't boot up to this point
* anyways.
*/
pt
=
kern_base
|
_PAGE_VALID
|
_PAGE_SZ4MB
;
pt
|=
_PAGE_CP
|
_PAGE_CV
|
_PAGE_P
|
_PAGE_L
|
_PAGE_W
;
local_irq_save
(
flags
);
if
(
tlb_type
==
spitfire
)
{
__asm__
__volatile__
(
" stxa %1, [%0] %3
\n
"
" stxa %2, [%5] %4
\n
"
" membar #Sync
\n
"
" flush %%g6
\n
"
" nop
\n
"
" nop
\n
"
" nop
\n
"
:
/* No outputs */
:
"r"
(
TLB_TAG_ACCESS
),
"r"
(
alias_base
),
"r"
(
pt
),
"i"
(
ASI_DMMU
),
"i"
(
ASI_DTLB_DATA_ACCESS
),
"r"
(
61
<<
3
)
:
"memory"
);
if
(
real_end
>=
KERNBASE
+
0x340000
)
{
second_alias_page
=
alias_base
+
0x400000
;
__asm__
__volatile__
(
" stxa %1, [%0] %3
\n
"
" stxa %2, [%5] %4
\n
"
" membar #Sync
\n
"
" flush %%g6
\n
"
" nop
\n
"
" nop
\n
"
" nop
\n
"
:
/* No outputs */
:
"r"
(
TLB_TAG_ACCESS
),
"r"
(
second_alias_page
),
"r"
(
pt
+
0x400000
),
"i"
(
ASI_DMMU
),
"i"
(
ASI_DTLB_DATA_ACCESS
),
"r"
(
60
<<
3
)
:
"memory"
);
}
}
else
if
(
tlb_type
==
cheetah
||
tlb_type
==
cheetah_plus
)
{
__asm__
__volatile__
(
" stxa %1, [%0] %3
\n
"
" stxa %2, [%5] %4
\n
"
" membar #Sync
\n
"
" flush %%g6
\n
"
" nop
\n
"
" nop
\n
"
" nop
\n
"
:
/* No outputs */
:
"r"
(
TLB_TAG_ACCESS
),
"r"
(
alias_base
),
"r"
(
pt
),
"i"
(
ASI_DMMU
),
"i"
(
ASI_DTLB_DATA_ACCESS
),
"r"
((
0
<<
16
)
|
(
13
<<
3
))
:
"memory"
);
if
(
real_end
>=
KERNBASE
+
0x340000
)
{
second_alias_page
=
alias_base
+
0x400000
;
__asm__
__volatile__
(
" stxa %1, [%0] %3
\n
"
" stxa %2, [%5] %4
\n
"
" membar #Sync
\n
"
" flush %%g6
\n
"
" nop
\n
"
" nop
\n
"
" nop
\n
"
:
/* No outputs */
:
"r"
(
TLB_TAG_ACCESS
),
"r"
(
second_alias_page
),
"r"
(
pt
+
0x400000
),
"i"
(
ASI_DMMU
),
"i"
(
ASI_DTLB_DATA_ACCESS
),
"r"
((
0
<<
16
)
|
(
12
<<
3
))
:
"memory"
);
}
if
((
real_end
>
((
unsigned
long
)
KERNBASE
+
0x800000
)))
{
prom_printf
(
"paging_init: Kernel > 8MB, too large.
\n
"
);
prom_halt
();
}
local_irq_restore
(
flags
);
/* Now set kernel pgd to upper alias so physical page computations
/* Set kernel pgd to upper alias so physical page computations
* work.
*/
init_mm
.
pgd
+=
((
shift
)
/
(
sizeof
(
pgd_t
)));
memset
(
swapper_
pmd_dir
,
0
,
sizeof
(
swapper
_pmd_dir
));
memset
(
swapper_
low_pmd_dir
,
0
,
sizeof
(
swapper_low
_pmd_dir
));
/* Now can init the kernel/bad page tables. */
pud_set
(
pud_offset
(
&
swapper_pg_dir
[
0
],
0
),
swapper_pmd_dir
+
(
shift
/
sizeof
(
pgd_t
)));
swapper_
low_
pmd_dir
+
(
shift
/
sizeof
(
pgd_t
)));
sparc64_vpte_patchme1
[
0
]
|=
(((
unsigned
long
)
pgd_val
(
init_mm
.
pgd
[
0
]))
>>
10
);
sparc64_vpte_patchme2
[
0
]
|=
(((
unsigned
long
)
pgd_val
(
init_mm
.
pgd
[
0
]))
&
0x3ff
);
flushi
((
long
)
&
sparc64_vpte_patchme1
[
0
]);
swapper_pgd_zero
=
pgd_val
(
swapper_pg_dir
[
0
]);
/* Setup bootmem... */
pages_avail
=
0
;
last_valid_pfn
=
end_pfn
=
bootmem_init
(
&
pages_avail
);
/* Inherit non-locked OBP mappings. */
inherit_prom_mappings
();
...
...
@@ -1527,13 +1477,16 @@ void __init paging_init(void)
inherit_locked_prom_mappings
(
1
);
/* We only created DTLB mapping of this stuff. */
spitfire_flush_dtlb_nucleus_page
(
alias_base
);
if
(
second_alias_page
)
spitfire_flush_dtlb_nucleus_page
(
second_alias_page
);
__flush_tlb_all
();
/* Setup bootmem... */
pages_avail
=
0
;
last_valid_pfn
=
end_pfn
=
bootmem_init
(
&
pages_avail
);
#ifdef CONFIG_DEBUG_PAGEALLOC
kernel_physical_mapping_init
();
#endif
{
unsigned
long
zones_size
[
MAX_NR_ZONES
];
unsigned
long
zholes_size
[
MAX_NR_ZONES
];
...
...
@@ -1695,8 +1648,7 @@ void __init mem_init(void)
i
=
last_valid_pfn
>>
((
22
-
PAGE_SHIFT
)
+
6
);
i
+=
1
;
sparc64_valid_addr_bitmap
=
(
unsigned
long
*
)
__alloc_bootmem
(
i
<<
3
,
SMP_CACHE_BYTES
,
bootmap_base
);
sparc64_valid_addr_bitmap
=
(
unsigned
long
*
)
alloc_bootmem
(
i
<<
3
);
if
(
sparc64_valid_addr_bitmap
==
NULL
)
{
prom_printf
(
"mem_init: Cannot alloc valid_addr_bitmap.
\n
"
);
prom_halt
();
...
...
@@ -1749,7 +1701,7 @@ void __init mem_init(void)
cheetah_ecache_flush_init
();
}
void
free_initmem
(
void
)
void
free_initmem
(
void
)
{
unsigned
long
addr
,
initend
;
...
...
arch/sparc64/mm/ultra.S
View file @
95001ee9
...
...
@@ -144,42 +144,29 @@ __flush_icache_page: /* %o0 = phys_page */
#define DTAG_MASK 0x3
/
*
This
routine
is
Spitfire
specific
so
the
hardcoded
*
D
-
cache
size
and
line
-
size
are
OK
.
*/
.
align
64
.
globl
__flush_dcache_page
__flush_dcache_page
:
/
*
%
o0
=
kaddr
,
%
o1
=
flush_icache
*/
sethi
%
uhi
(
PAGE_OFFSET
),
%
g1
sllx
%
g1
,
32
,
%
g1
sub
%
o0
,
%
g1
,
%
o0
clr
%
o4
srlx
%
o0
,
11
,
%
o0
sethi
%
hi
(
1
<<
14
),
%
o2
1
:
ldxa
[%
o4
]
ASI_DCACHE_TAG
,
%
o3
!
LSU
Group
add
%
o4
,
(
1
<<
5
),
%
o4
!
IEU0
ldxa
[%
o4
]
ASI_DCACHE_TAG
,
%
g1
!
LSU
Group
add
%
o4
,
(
1
<<
5
),
%
o4
!
IEU0
ldxa
[%
o4
]
ASI_DCACHE_TAG
,
%
g2
!
LSU
Group
o3
available
add
%
o4
,
(
1
<<
5
),
%
o4
!
IEU0
andn
%
o3
,
DTAG_MASK
,
%
o3
!
IEU1
ldxa
[%
o4
]
ASI_DCACHE_TAG
,
%
g3
!
LSU
Group
add
%
o4
,
(
1
<<
5
),
%
o4
!
IEU0
andn
%
g1
,
DTAG_MASK
,
%
g1
!
IEU1
cmp
%
o0
,
%
o3
!
IEU1
Group
be
,
a
,
pn
%
xcc
,
dflush1
!
CTI
sub
%
o4
,
(
4
<<
5
),
%
o4
!
IEU0
(
Group
)
cmp
%
o0
,
%
g1
!
IEU1
Group
andn
%
g2
,
DTAG_MASK
,
%
g2
!
IEU0
be
,
a
,
pn
%
xcc
,
dflush2
!
CTI
sub
%
o4
,
(
3
<<
5
),
%
o4
!
IEU0
(
Group
)
cmp
%
o0
,
%
g2
!
IEU1
Group
andn
%
g3
,
DTAG_MASK
,
%
g3
!
IEU0
be
,
a
,
pn
%
xcc
,
dflush3
!
CTI
sub
%
o4
,
(
2
<<
5
),
%
o4
!
IEU0
(
Group
)
cmp
%
o0
,
%
g3
!
IEU1
Group
be
,
a
,
pn
%
xcc
,
dflush4
!
CTI
sub
%
o4
,
(
1
<<
5
),
%
o4
!
IEU0
2
:
cmp
%
o4
,
%
o2
!
IEU1
Group
bne
,
pt
%
xcc
,
1
b
!
CTI
nop
!
IEU0
sub
%
o0
,
%
g1
,
%
o0
!
physical
address
srlx
%
o0
,
11
,
%
o0
!
make
D
-
cache
TAG
sethi
%
hi
(
1
<<
14
),
%
o2
!
D
-
cache
size
sub
%
o2
,
(
1
<<
5
),
%
o2
!
D
-
cache
line
size
1
:
ldxa
[%
o2
]
ASI_DCACHE_TAG
,
%
o3
!
load
D
-
cache
TAG
andcc
%
o3
,
DTAG_MASK
,
%
g0
!
Valid
?
be
,
pn
%
xcc
,
2
f
!
Nope
,
branch
andn
%
o3
,
DTAG_MASK
,
%
o3
!
Clear
valid
bits
cmp
%
o3
,
%
o0
!
TAG
match
?
bne
,
pt
%
xcc
,
2
f
!
Nope
,
branch
nop
stxa
%
g0
,
[%
o2
]
ASI_DCACHE_TAG
!
Invalidate
TAG
membar
#
Sync
2
:
brnz
,
pt
%
o2
,
1
b
sub
%
o2
,
(
1
<<
5
),
%
o2
!
D
-
cache
line
size
/
*
The
I
-
cache
does
not
snoop
local
stores
so
we
*
better
flush
that
too
when
necessary
.
...
...
@@ -189,48 +176,9 @@ __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */
retl
nop
dflush1
:
stxa
%
g0
,
[%
o4
]
ASI_DCACHE_TAG
add
%
o4
,
(
1
<<
5
),
%
o4
dflush2
:
stxa
%
g0
,
[%
o4
]
ASI_DCACHE_TAG
add
%
o4
,
(
1
<<
5
),
%
o4
dflush3
:
stxa
%
g0
,
[%
o4
]
ASI_DCACHE_TAG
add
%
o4
,
(
1
<<
5
),
%
o4
dflush4
:
stxa
%
g0
,
[%
o4
]
ASI_DCACHE_TAG
add
%
o4
,
(
1
<<
5
),
%
o4
membar
#
Sync
ba
,
pt
%
xcc
,
2
b
nop
#endif /* DCACHE_ALIASING_POSSIBLE */
.
previous
.
text
.
align
32
__prefill_dtlb
:
rdpr
%
pstate
,
%
g7
wrpr
%
g7
,
PSTATE_IE
,
%
pstate
mov
TLB_TAG_ACCESS
,
%
g1
stxa
%
o5
,
[%
g1
]
ASI_DMMU
stxa
%
o2
,
[%
g0
]
ASI_DTLB_DATA_IN
flush
%
g6
retl
wrpr
%
g7
,
%
pstate
__prefill_itlb
:
rdpr
%
pstate
,
%
g7
wrpr
%
g7
,
PSTATE_IE
,
%
pstate
mov
TLB_TAG_ACCESS
,
%
g1
stxa
%
o5
,
[%
g1
]
ASI_IMMU
stxa
%
o2
,
[%
g0
]
ASI_ITLB_DATA_IN
flush
%
g6
retl
wrpr
%
g7
,
%
pstate
.
globl
__update_mmu_cache
__update_mmu_cache
:
/
*
%
o0
=
hw_context
,
%
o1
=
address
,
%
o2
=
pte
,
%
o3
=
fault_code
*/
srlx
%
o1
,
PAGE_SHIFT
,
%
o1
andcc
%
o3
,
FAULT_CODE_DTLB
,
%
g0
sllx
%
o1
,
PAGE_SHIFT
,
%
o5
bne
,
pt
%
xcc
,
__prefill_dtlb
or
%
o5
,
%
o0
,
%
o5
ba
,
a
,
pt
%
xcc
,
__prefill_itlb
.
previous
/
*
Cheetah
specific
versions
,
patched
at
boot
time
.
*/
__cheetah_flush_tlb_mm
:
/
*
18
insns
*/
...
...
@@ -283,7 +231,7 @@ __cheetah_flush_tlb_pending: /* 26 insns */
wrpr
%
g7
,
0x0
,
%
pstate
#ifdef DCACHE_ALIASING_POSSIBLE
flush_dcpage_cheetah
:
/
*
11
insns
*/
__cheetah_flush_dcache_page
:
/
*
11
insns
*/
sethi
%
uhi
(
PAGE_OFFSET
),
%
g1
sllx
%
g1
,
32
,
%
g1
sub
%
o0
,
%
g1
,
%
o0
...
...
@@ -329,8 +277,8 @@ cheetah_patch_cachetlbops:
#ifdef DCACHE_ALIASING_POSSIBLE
sethi
%
hi
(
__flush_dcache_page
),
%
o0
or
%
o0
,
%
lo
(
__flush_dcache_page
),
%
o0
sethi
%
hi
(
flush_dcpage_cheetah
),
%
o1
or
%
o1
,
%
lo
(
flush_dcpage_cheetah
),
%
o1
sethi
%
hi
(
__cheetah_flush_dcache_page
),
%
o1
or
%
o1
,
%
lo
(
__cheetah_flush_dcache_page
),
%
o1
call
cheetah_patch_one
mov
11
,
%
o2
#endif /* DCACHE_ALIASING_POSSIBLE */
...
...
arch/sparc64/prom/Makefile
View file @
95001ee9
...
...
@@ -7,4 +7,4 @@ EXTRA_AFLAGS := -ansi
EXTRA_CFLAGS
:=
-Werror
lib-y
:=
bootstr.o devops.o init.o memory.o misc.o
\
tree.o console.o printf.o p1275.o
map.o
cif.o
tree.o console.o printf.o p1275.o cif.o
arch/sparc64/prom/console.c
View file @
95001ee9
...
...
@@ -67,7 +67,7 @@ prom_putchar(char c)
}
void
prom_puts
(
char
*
s
,
int
len
)
prom_puts
(
c
onst
c
har
*
s
,
int
len
)
{
p1275_cmd
(
"write"
,
P1275_ARG
(
1
,
P1275_ARG_IN_BUF
)
|
P1275_INOUT
(
3
,
1
),
...
...
arch/sparc64/prom/devops.c
View file @
95001ee9
...
...
@@ -16,7 +16,7 @@
* Returns 0 on failure.
*/
int
prom_devopen
(
char
*
dstr
)
prom_devopen
(
c
onst
c
har
*
dstr
)
{
return
p1275_cmd
(
"open"
,
P1275_ARG
(
0
,
P1275_ARG_IN_STRING
)
|
P1275_INOUT
(
1
,
1
),
...
...
arch/sparc64/prom/init.c
View file @
95001ee9
...
...
@@ -46,7 +46,7 @@ void __init prom_init(void *cif_handler, void *cif_stack)
if
((
prom_root_node
==
0
)
||
(
prom_root_node
==
-
1
))
prom_halt
();
prom_chosen_node
=
prom_finddevice
(
"/chosen"
);
prom_chosen_node
=
prom_finddevice
(
prom_chosen_path
);
if
(
!
prom_chosen_node
||
prom_chosen_node
==
-
1
)
prom_halt
();
...
...
arch/sparc64/prom/map.S
deleted
100644 → 0
View file @
63906e41
/*
$Id
:
map
.
S
,
v
1
.2
1999
/
11
/
19
05
:
53
:
02
davem
Exp
$
*
map
.
S
:
Tricky
coding
required
to
fixup
the
kernel
OBP
maps
*
properly
.
*
*
Copyright
(
C
)
1999
David
S
.
Miller
(
davem
@
redhat
.
com
)
*/
.
text
.
align
8192
.
globl
prom_boot_page
prom_boot_page
:
call_method
:
.
asciz
"call-method"
.
align
8
map
:
.
asciz
"map"
.
align
8
/
*
When
we
are
invoked
,
our
caller
has
remapped
us
to
*
page
zero
,
therefore
we
must
use
PC
relative
addressing
*
for
everything
after
we
begin
performing
the
unmap
/
map
*
calls
.
*/
.
globl
prom_remap
prom_remap
:
/
*
%
o0
=
physpage
,
%
o1
=
virtpage
,
%
o2
=
mmu_ihandle
*/
rd
%
pc
,
%
g1
srl
%
o2
,
0
,
%
o2
!
kill
sign
extension
sethi
%
hi
(
p1275buf
),
%
g2
or
%
g2
,
%
lo
(
p1275buf
),
%
g2
ldx
[%
g2
+
0x10
],
%
g3
!
prom_cif_stack
save
%
g3
,
-(
192
+
128
),
%
sp
ldx
[%
g2
+
0x08
],
%
l0
!
prom_cif_handler
mov
%
g6
,
%
i3
mov
%
g4
,
%
i4
mov
%
g5
,
%
i5
flushw
sethi
%
hi
(
prom_remap
-
call_method
),
%
g7
or
%
g7
,
%
lo
(
prom_remap
-
call_method
),
%
g7
sub
%
g1
,
%
g7
,
%
l2
!
call
-
method
string
sethi
%
hi
(
prom_remap
-
map
),
%
g7
or
%
g7
,
%
lo
(
prom_remap
-
map
),
%
g7
sub
%
g1
,
%
g7
,
%
l4
!
map
string
/
*
OK
,
map
the
4
MB
region
we
really
live
at
.
*/
stx
%
l2
,
[%
sp
+
2047
+
128
+
0x00
]
!
call
-
method
mov
7
,
%
l5
stx
%
l5
,
[%
sp
+
2047
+
128
+
0x08
]
!
num_args
mov
1
,
%
l5
stx
%
l5
,
[%
sp
+
2047
+
128
+
0x10
]
!
num_rets
stx
%
l4
,
[%
sp
+
2047
+
128
+
0x18
]
!
map
stx
%
i2
,
[%
sp
+
2047
+
128
+
0x20
]
!
mmu_ihandle
mov
-
1
,
%
l5
stx
%
l5
,
[%
sp
+
2047
+
128
+
0x28
]
!
mode
==
default
sethi
%
hi
(
4
*
1024
*
1024
),
%
l5
stx
%
l5
,
[%
sp
+
2047
+
128
+
0x30
]
!
size
stx
%
i1
,
[%
sp
+
2047
+
128
+
0x38
]
!
vaddr
stx
%
g0
,
[%
sp
+
2047
+
128
+
0x40
]
!
filler
stx
%
i0
,
[%
sp
+
2047
+
128
+
0x48
]
!
paddr
call
%
l0
add
%
sp
,
(
2047
+
128
),
%
o0
!
argument
array
/
*
Restore
hard
-
coded
globals
.
*/
mov
%
i3
,
%
g6
mov
%
i4
,
%
g4
mov
%
i5
,
%
g5
/
*
Wheee
....
we
are
done
.
*/
ret
restore
.
align
8192
arch/sparc64/prom/misc.c
View file @
95001ee9
...
...
@@ -17,14 +17,14 @@
#include <asm/system.h>
/* Reset and reboot the machine with the command 'bcommand'. */
void
prom_reboot
(
char
*
bcommand
)
void
prom_reboot
(
c
onst
c
har
*
bcommand
)
{
p1275_cmd
(
"boot"
,
P1275_ARG
(
0
,
P1275_ARG_IN_STRING
)
|
P1275_INOUT
(
1
,
0
),
bcommand
);
}
/* Forth evaluate the expression contained in 'fstring'. */
void
prom_feval
(
char
*
fstring
)
void
prom_feval
(
c
onst
c
har
*
fstring
)
{
if
(
!
fstring
||
fstring
[
0
]
==
0
)
return
;
...
...
@@ -148,21 +148,19 @@ void prom_set_trap_table(unsigned long tba)
p1275_cmd
(
"SUNW,set-trap-table"
,
P1275_INOUT
(
1
,
0
),
tba
);
}
int
mmu_ihandle_cache
=
0
;
int
prom_get_mmu_ihandle
(
void
)
{
int
node
,
ret
;
if
(
mmu_ihandle_cache
!=
0
)
return
mmu_ihandle_cache
;
if
(
prom_
mmu_ihandle_cache
!=
0
)
return
prom_
mmu_ihandle_cache
;
node
=
prom_finddevice
(
"/chosen"
);
ret
=
prom_getint
(
node
,
"mmu"
);
node
=
prom_finddevice
(
prom_chosen_path
);
ret
=
prom_getint
(
node
,
prom_mmu_name
);
if
(
ret
==
-
1
||
ret
==
0
)
mmu_ihandle_cache
=
-
1
;
prom_
mmu_ihandle_cache
=
-
1
;
else
mmu_ihandle_cache
=
ret
;
prom_
mmu_ihandle_cache
=
ret
;
return
ret
;
}
...
...
@@ -190,7 +188,7 @@ long prom_itlb_load(unsigned long index,
unsigned
long
tte_data
,
unsigned
long
vaddr
)
{
return
p1275_cmd
(
"call-method"
,
return
p1275_cmd
(
prom_callmethod_name
,
(
P1275_ARG
(
0
,
P1275_ARG_IN_STRING
)
|
P1275_ARG
(
2
,
P1275_ARG_IN_64B
)
|
P1275_ARG
(
3
,
P1275_ARG_IN_64B
)
|
...
...
@@ -207,7 +205,7 @@ long prom_dtlb_load(unsigned long index,
unsigned
long
tte_data
,
unsigned
long
vaddr
)
{
return
p1275_cmd
(
"call-method"
,
return
p1275_cmd
(
prom_callmethod_name
,
(
P1275_ARG
(
0
,
P1275_ARG_IN_STRING
)
|
P1275_ARG
(
2
,
P1275_ARG_IN_64B
)
|
P1275_ARG
(
3
,
P1275_ARG_IN_64B
)
|
...
...
@@ -223,13 +221,13 @@ long prom_dtlb_load(unsigned long index,
int
prom_map
(
int
mode
,
unsigned
long
size
,
unsigned
long
vaddr
,
unsigned
long
paddr
)
{
int
ret
=
p1275_cmd
(
"call-method"
,
int
ret
=
p1275_cmd
(
prom_callmethod_name
,
(
P1275_ARG
(
0
,
P1275_ARG_IN_STRING
)
|
P1275_ARG
(
3
,
P1275_ARG_IN_64B
)
|
P1275_ARG
(
4
,
P1275_ARG_IN_64B
)
|
P1275_ARG
(
6
,
P1275_ARG_IN_64B
)
|
P1275_INOUT
(
7
,
1
)),
"map"
,
prom_map_name
,
prom_get_mmu_ihandle
(),
mode
,
size
,
...
...
@@ -244,12 +242,12 @@ int prom_map(int mode, unsigned long size,
void
prom_unmap
(
unsigned
long
size
,
unsigned
long
vaddr
)
{
p1275_cmd
(
"call-method"
,
p1275_cmd
(
prom_callmethod_name
,
(
P1275_ARG
(
0
,
P1275_ARG_IN_STRING
)
|
P1275_ARG
(
2
,
P1275_ARG_IN_64B
)
|
P1275_ARG
(
3
,
P1275_ARG_IN_64B
)
|
P1275_INOUT
(
4
,
0
)),
"unmap"
,
prom_unmap_name
,
prom_get_mmu_ihandle
(),
size
,
vaddr
);
...
...
@@ -258,7 +256,7 @@ void prom_unmap(unsigned long size, unsigned long vaddr)
/* Set aside physical memory which is not touched or modified
* across soft resets.
*/
unsigned
long
prom_retain
(
char
*
name
,
unsigned
long
prom_retain
(
c
onst
c
har
*
name
,
unsigned
long
pa_low
,
unsigned
long
pa_high
,
long
size
,
long
align
)
{
...
...
@@ -290,7 +288,7 @@ int prom_getunumber(int syndrome_code,
unsigned
long
phys_addr
,
char
*
buf
,
int
buflen
)
{
return
p1275_cmd
(
"call-method"
,
return
p1275_cmd
(
prom_callmethod_name
,
(
P1275_ARG
(
0
,
P1275_ARG_IN_STRING
)
|
P1275_ARG
(
3
,
P1275_ARG_OUT_BUF
)
|
P1275_ARG
(
6
,
P1275_ARG_IN_64B
)
|
...
...
arch/sparc64/prom/p1275.c
View file @
95001ee9
...
...
@@ -46,7 +46,7 @@ static inline unsigned long spitfire_get_primary_context(void)
*/
DEFINE_SPINLOCK
(
prom_entry_lock
);
long
p1275_cmd
(
char
*
service
,
long
fmt
,
...)
long
p1275_cmd
(
const
char
*
service
,
long
fmt
,
...)
{
char
*
p
,
*
q
;
unsigned
long
flags
;
...
...
arch/sparc64/prom/printf.c
View file @
95001ee9
...
...
@@ -34,7 +34,7 @@ prom_write(const char *buf, unsigned int n)
}
void
prom_printf
(
char
*
fmt
,
...)
prom_printf
(
c
onst
c
har
*
fmt
,
...)
{
va_list
args
;
int
i
;
...
...
arch/sparc64/prom/tree.c
View file @
95001ee9
...
...
@@ -69,7 +69,7 @@ prom_getsibling(int node)
* Return -1 on error.
*/
__inline__
int
prom_getproplen
(
int
node
,
char
*
prop
)
prom_getproplen
(
int
node
,
c
onst
c
har
*
prop
)
{
if
((
!
node
)
||
(
!
prop
))
return
-
1
;
return
p1275_cmd
(
"getproplen"
,
...
...
@@ -83,20 +83,20 @@ prom_getproplen(int node, char *prop)
* was successful the length will be returned, else -1 is returned.
*/
__inline__
int
prom_getproperty
(
int
node
,
char
*
prop
,
char
*
buffer
,
int
bufsize
)
prom_getproperty
(
int
node
,
c
onst
c
har
*
prop
,
char
*
buffer
,
int
bufsize
)
{
int
plen
;
plen
=
prom_getproplen
(
node
,
prop
);
if
((
plen
>
bufsize
)
||
(
plen
==
0
)
||
(
plen
==
-
1
))
if
((
plen
>
bufsize
)
||
(
plen
==
0
)
||
(
plen
==
-
1
))
{
return
-
1
;
else
{
}
else
{
/* Ok, things seem all right. */
return
p1275_cmd
(
"getprop"
,
P1275_ARG
(
1
,
P1275_ARG_IN_STRING
)
|
P1275_ARG
(
2
,
P1275_ARG_OUT_BUF
)
|
P1275_INOUT
(
4
,
1
),
node
,
prop
,
buffer
,
P1275_SIZE
(
plen
));
return
p1275_cmd
(
prom_getprop_name
,
P1275_ARG
(
1
,
P1275_ARG_IN_STRING
)
|
P1275_ARG
(
2
,
P1275_ARG_OUT_BUF
)
|
P1275_INOUT
(
4
,
1
),
node
,
prop
,
buffer
,
P1275_SIZE
(
plen
));
}
}
...
...
@@ -104,7 +104,7 @@ prom_getproperty(int node, char *prop, char *buffer, int bufsize)
* on failure.
*/
__inline__
int
prom_getint
(
int
node
,
char
*
prop
)
prom_getint
(
int
node
,
c
onst
c
har
*
prop
)
{
int
intprop
;
...
...
@@ -119,7 +119,7 @@ prom_getint(int node, char *prop)
*/
int
prom_getintdefault
(
int
node
,
char
*
property
,
int
deflt
)
prom_getintdefault
(
int
node
,
c
onst
c
har
*
property
,
int
deflt
)
{
int
retval
;
...
...
@@ -131,7 +131,7 @@ prom_getintdefault(int node, char *property, int deflt)
/* Acquire a boolean property, 1=TRUE 0=FALSE. */
int
prom_getbool
(
int
node
,
char
*
prop
)
prom_getbool
(
int
node
,
c
onst
c
har
*
prop
)
{
int
retval
;
...
...
@@ -145,7 +145,7 @@ prom_getbool(int node, char *prop)
* buffer.
*/
void
prom_getstring
(
int
node
,
char
*
prop
,
char
*
user_buf
,
int
ubuf_size
)
prom_getstring
(
int
node
,
c
onst
c
har
*
prop
,
char
*
user_buf
,
int
ubuf_size
)
{
int
len
;
...
...
@@ -160,7 +160,7 @@ prom_getstring(int node, char *prop, char *user_buf, int ubuf_size)
* YES = 1 NO = 0
*/
int
prom_nodematch
(
int
node
,
char
*
name
)
prom_nodematch
(
int
node
,
c
onst
c
har
*
name
)
{
char
namebuf
[
128
];
prom_getproperty
(
node
,
"name"
,
namebuf
,
sizeof
(
namebuf
));
...
...
@@ -172,7 +172,7 @@ prom_nodematch(int node, char *name)
* 'nodename'. Return node if successful, zero if not.
*/
int
prom_searchsiblings
(
int
node_start
,
char
*
nodename
)
prom_searchsiblings
(
int
node_start
,
c
onst
c
har
*
nodename
)
{
int
thisnode
,
error
;
...
...
@@ -294,7 +294,7 @@ prom_firstprop(int node, char *buffer)
* property types for this node.
*/
__inline__
char
*
prom_nextprop
(
int
node
,
char
*
oprop
,
char
*
buffer
)
prom_nextprop
(
int
node
,
c
onst
c
har
*
oprop
,
char
*
buffer
)
{
char
buf
[
32
];
...
...
@@ -314,15 +314,17 @@ prom_nextprop(int node, char *oprop, char *buffer)
}
int
prom_finddevice
(
char
*
name
)
prom_finddevice
(
c
onst
c
har
*
name
)
{
if
(
!
name
)
return
0
;
return
p1275_cmd
(
"finddevice"
,
P1275_ARG
(
0
,
P1275_ARG_IN_STRING
)
|
P1275_INOUT
(
1
,
1
),
name
);
if
(
!
name
)
return
0
;
return
p1275_cmd
(
prom_finddev_name
,
P1275_ARG
(
0
,
P1275_ARG_IN_STRING
)
|
P1275_INOUT
(
1
,
1
),
name
);
}
int
prom_node_has_property
(
int
node
,
char
*
prop
)
int
prom_node_has_property
(
int
node
,
c
onst
c
har
*
prop
)
{
char
buf
[
32
];
...
...
@@ -339,7 +341,7 @@ int prom_node_has_property(int node, char *prop)
* of 'size' bytes. Return the number of bytes the prom accepted.
*/
int
prom_setprop
(
int
node
,
char
*
pname
,
char
*
value
,
int
size
)
prom_setprop
(
int
node
,
c
onst
c
har
*
pname
,
char
*
value
,
int
size
)
{
if
(
size
==
0
)
return
0
;
if
((
pname
==
0
)
||
(
value
==
0
))
return
0
;
...
...
@@ -364,7 +366,7 @@ prom_inst2pkg(int inst)
* FIXME: Should work for v0 as well
*/
int
prom_pathtoinode
(
char
*
path
)
prom_pathtoinode
(
c
onst
c
har
*
path
)
{
int
node
,
inst
;
...
...
include/asm-sparc64/cacheflush.h
View file @
95001ee9
...
...
@@ -66,6 +66,11 @@ extern void flush_ptrace_access(struct vm_area_struct *, struct page *,
#define flush_cache_vmap(start, end) do { } while (0)
#define flush_cache_vunmap(start, end) do { } while (0)
#ifdef CONFIG_DEBUG_PAGEALLOC
/* internal debugging function */
void
kernel_map_pages
(
struct
page
*
page
,
int
numpages
,
int
enable
);
#endif
#endif
/* !__ASSEMBLY__ */
#endif
/* _SPARC64_CACHEFLUSH_H */
include/asm-sparc64/cpudata.h
View file @
95001ee9
...
...
@@ -22,6 +22,16 @@ typedef struct {
unsigned
int
__pad1
;
unsigned
long
*
pte_cache
[
2
];
unsigned
long
*
pgd_cache
;
/* Dcache line 3, rarely used */
unsigned
int
dcache_size
;
unsigned
int
dcache_line_size
;
unsigned
int
icache_size
;
unsigned
int
icache_line_size
;
unsigned
int
ecache_size
;
unsigned
int
ecache_line_size
;
unsigned
int
__pad2
;
unsigned
int
__pad3
;
}
cpuinfo_sparc
;
DECLARE_PER_CPU
(
cpuinfo_sparc
,
__cpu_data
);
...
...
include/asm-sparc64/oplib.h
View file @
95001ee9
...
...
@@ -38,6 +38,20 @@ extern int prom_stdin, prom_stdout;
*/
extern
int
prom_chosen_node
;
/* Helper values and strings in arch/sparc64/kernel/head.S */
extern
const
char
prom_finddev_name
[];
extern
const
char
prom_chosen_path
[];
extern
const
char
prom_getprop_name
[];
extern
const
char
prom_mmu_name
[];
extern
const
char
prom_callmethod_name
[];
extern
const
char
prom_translate_name
[];
extern
const
char
prom_map_name
[];
extern
const
char
prom_unmap_name
[];
extern
int
prom_mmu_ihandle_cache
;
extern
unsigned
int
prom_boot_mapped_pc
;
extern
unsigned
int
prom_boot_mapping_mode
;
extern
unsigned
long
prom_boot_mapping_phys_high
,
prom_boot_mapping_phys_low
;
struct
linux_mlist_p1275
{
struct
linux_mlist_p1275
*
theres_more
;
unsigned
long
start_adr
;
...
...
@@ -68,7 +82,7 @@ extern char *prom_getbootargs(void);
* of the string is different on V0 vs. V2->higher proms. The caller must
* know what he/she is doing! Returns the device descriptor, an int.
*/
extern
int
prom_devopen
(
char
*
device_string
);
extern
int
prom_devopen
(
c
onst
c
har
*
device_string
);
/* Close a previously opened device described by the passed integer
* descriptor.
...
...
@@ -98,10 +112,10 @@ extern struct linux_mem_p1275 *prom_meminfo(void);
/* Miscellaneous routines, don't really fit in any category per se. */
/* Reboot the machine with the command line passed. */
extern
void
prom_reboot
(
char
*
boot_command
);
extern
void
prom_reboot
(
c
onst
c
har
*
boot_command
);
/* Evaluate the forth string passed. */
extern
void
prom_feval
(
char
*
forth_string
);
extern
void
prom_feval
(
c
onst
c
har
*
forth_string
);
/* Enter the prom, with possibility of continuation with the 'go'
* command in newer proms.
...
...
@@ -154,7 +168,7 @@ extern char prom_getchar(void);
extern
void
prom_putchar
(
char
character
);
/* Prom's internal routines, don't use in kernel/boot code. */
extern
void
prom_printf
(
char
*
fmt
,
...);
extern
void
prom_printf
(
c
onst
c
har
*
fmt
,
...);
extern
void
prom_write
(
const
char
*
buf
,
unsigned
int
len
);
/* Query for input device type */
...
...
@@ -215,7 +229,7 @@ extern int prom_getunumber(int syndrome_code,
char
*
buf
,
int
buflen
);
/* Retain physical memory to the caller across soft resets. */
extern
unsigned
long
prom_retain
(
char
*
name
,
extern
unsigned
long
prom_retain
(
c
onst
c
har
*
name
,
unsigned
long
pa_low
,
unsigned
long
pa_high
,
long
size
,
long
align
);
...
...
@@ -269,28 +283,28 @@ extern int prom_getsibling(int node);
/* Get the length, at the passed node, of the given property type.
* Returns -1 on error (ie. no such property at this node).
*/
extern
int
prom_getproplen
(
int
thisnode
,
char
*
property
);
extern
int
prom_getproplen
(
int
thisnode
,
c
onst
c
har
*
property
);
/* Fetch the requested property using the given buffer. Returns
* the number of bytes the prom put into your buffer or -1 on error.
*/
extern
int
prom_getproperty
(
int
thisnode
,
char
*
property
,
extern
int
prom_getproperty
(
int
thisnode
,
c
onst
c
har
*
property
,
char
*
prop_buffer
,
int
propbuf_size
);
/* Acquire an integer property. */
extern
int
prom_getint
(
int
node
,
char
*
property
);
extern
int
prom_getint
(
int
node
,
c
onst
c
har
*
property
);
/* Acquire an integer property, with a default value. */
extern
int
prom_getintdefault
(
int
node
,
char
*
property
,
int
defval
);
extern
int
prom_getintdefault
(
int
node
,
c
onst
c
har
*
property
,
int
defval
);
/* Acquire a boolean property, 0=FALSE 1=TRUE. */
extern
int
prom_getbool
(
int
node
,
char
*
prop
);
extern
int
prom_getbool
(
int
node
,
c
onst
c
har
*
prop
);
/* Acquire a string property, null string on error. */
extern
void
prom_getstring
(
int
node
,
char
*
prop
,
char
*
buf
,
int
bufsize
);
extern
void
prom_getstring
(
int
node
,
c
onst
c
har
*
prop
,
char
*
buf
,
int
bufsize
);
/* Does the passed node have the given "name"? YES=1 NO=0 */
extern
int
prom_nodematch
(
int
thisnode
,
char
*
name
);
extern
int
prom_nodematch
(
int
thisnode
,
c
onst
c
har
*
name
);
/* Puts in buffer a prom name in the form name@x,y or name (x for which_io
* and y for first regs phys address
...
...
@@ -300,7 +314,7 @@ extern int prom_getname(int node, char *buf, int buflen);
/* Search all siblings starting at the passed node for "name" matching
* the given string. Returns the node on success, zero on failure.
*/
extern
int
prom_searchsiblings
(
int
node_start
,
char
*
name
);
extern
int
prom_searchsiblings
(
int
node_start
,
c
onst
c
har
*
name
);
/* Return the first property type, as a string, for the given node.
* Returns a null string on error. Buffer should be at least 32B long.
...
...
@@ -310,21 +324,21 @@ extern char *prom_firstprop(int node, char *buffer);
/* Returns the next property after the passed property for the given
* node. Returns null string on failure. Buffer should be at least 32B long.
*/
extern
char
*
prom_nextprop
(
int
node
,
char
*
prev_property
,
char
*
buffer
);
extern
char
*
prom_nextprop
(
int
node
,
c
onst
c
har
*
prev_property
,
char
*
buffer
);
/* Returns 1 if the specified node has given property. */
extern
int
prom_node_has_property
(
int
node
,
char
*
property
);
extern
int
prom_node_has_property
(
int
node
,
c
onst
c
har
*
property
);
/* Returns phandle of the path specified */
extern
int
prom_finddevice
(
char
*
name
);
extern
int
prom_finddevice
(
c
onst
c
har
*
name
);
/* Set the indicated property at the given node with the passed value.
* Returns the number of bytes of your value that the prom took.
*/
extern
int
prom_setprop
(
int
node
,
char
*
prop_name
,
char
*
prop_value
,
extern
int
prom_setprop
(
int
node
,
c
onst
c
har
*
prop_name
,
char
*
prop_value
,
int
value_size
);
extern
int
prom_pathtoinode
(
char
*
path
);
extern
int
prom_pathtoinode
(
c
onst
c
har
*
path
);
extern
int
prom_inst2pkg
(
int
);
/* CPU probing helpers. */
...
...
@@ -334,7 +348,7 @@ int cpu_find_by_mid(int mid, int *prom_node);
/* Client interface level routines. */
extern
void
prom_set_trap_table
(
unsigned
long
tba
);
extern
long
p1275_cmd
(
char
*
,
long
,
...);
extern
long
p1275_cmd
(
const
char
*
,
long
,
...);
#if 0
...
...
include/asm-sparc64/pgtable.h
View file @
95001ee9
...
...
@@ -60,13 +60,13 @@
* table can map
*/
#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3))
#define PMD_SIZE (
1UL
<< PMD_SHIFT)
#define PMD_SIZE (
_AC(1,UL)
<< PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))
#define PMD_BITS (PAGE_SHIFT - 2)
/* PGDIR_SHIFT determines what a third-level page table entry can map */
#define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS)
#define PGDIR_SIZE (
1UL
<< PGDIR_SHIFT)
#define PGDIR_SIZE (
_AC(1,UL)
<< PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
#define PGDIR_BITS (PAGE_SHIFT - 2)
...
...
@@ -336,7 +336,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *p
#define pte_clear(mm,addr,ptep) \
set_pte_at((mm), (addr), (ptep), __pte(0UL))
extern
pgd_t
swapper_pg_dir
[
1
];
extern
pgd_t
swapper_pg_dir
[
2048
];
extern
pmd_t
swapper_low_pmd_dir
[
2048
];
/* These do nothing with the way I have things setup. */
#define mmu_lockarea(vaddr, len) (vaddr)
...
...
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