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
a662c5a3
Commit
a662c5a3
authored
Jul 16, 2002
by
Pete Zaitcev
Committed by
David S. Miller
Jul 16, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SPARC32: First pass at getting this platform functional under 2.5.x
parent
d893a438
Changes
53
Show whitespace changes
Inline
Side-by-side
Showing
53 changed files
with
990 additions
and
454 deletions
+990
-454
arch/sparc/Makefile
arch/sparc/Makefile
+4
-3
arch/sparc/boot/Makefile
arch/sparc/boot/Makefile
+6
-4
arch/sparc/config.in
arch/sparc/config.in
+3
-0
arch/sparc/kernel/entry.S
arch/sparc/kernel/entry.S
+36
-21
arch/sparc/kernel/etrap.S
arch/sparc/kernel/etrap.S
+12
-8
arch/sparc/kernel/head.S
arch/sparc/kernel/head.S
+7
-6
arch/sparc/kernel/init_task.c
arch/sparc/kernel/init_task.c
+3
-3
arch/sparc/kernel/ioport.c
arch/sparc/kernel/ioport.c
+13
-8
arch/sparc/kernel/irq.c
arch/sparc/kernel/irq.c
+15
-8
arch/sparc/kernel/process.c
arch/sparc/kernel/process.c
+46
-15
arch/sparc/kernel/ptrace.c
arch/sparc/kernel/ptrace.c
+10
-9
arch/sparc/kernel/rtrap.S
arch/sparc/kernel/rtrap.S
+12
-10
arch/sparc/kernel/sclow.S
arch/sparc/kernel/sclow.S
+6
-0
arch/sparc/kernel/semaphore.c
arch/sparc/kernel/semaphore.c
+1
-0
arch/sparc/kernel/setup.c
arch/sparc/kernel/setup.c
+1
-1
arch/sparc/kernel/signal.c
arch/sparc/kernel/signal.c
+9
-7
arch/sparc/kernel/sparc-stub.c
arch/sparc/kernel/sparc-stub.c
+2
-0
arch/sparc/kernel/sparc_ksyms.c
arch/sparc/kernel/sparc_ksyms.c
+0
-1
arch/sparc/kernel/sun4d_irq.c
arch/sparc/kernel/sun4d_irq.c
+4
-2
arch/sparc/kernel/sun4d_smp.c
arch/sparc/kernel/sun4d_smp.c
+0
-1
arch/sparc/kernel/sun4m_smp.c
arch/sparc/kernel/sun4m_smp.c
+0
-1
arch/sparc/kernel/trampoline.S
arch/sparc/kernel/trampoline.S
+4
-4
arch/sparc/kernel/traps.c
arch/sparc/kernel/traps.c
+17
-0
arch/sparc/kernel/windows.c
arch/sparc/kernel/windows.c
+1
-1
arch/sparc/kernel/wof.S
arch/sparc/kernel/wof.S
+16
-12
arch/sparc/kernel/wuf.S
arch/sparc/kernel/wuf.S
+6
-4
arch/sparc/mm/btfixup.c
arch/sparc/mm/btfixup.c
+1
-0
arch/sparc/mm/fault.c
arch/sparc/mm/fault.c
+4
-4
arch/sparc/mm/generic.c
arch/sparc/mm/generic.c
+8
-1
arch/sparc/mm/init.c
arch/sparc/mm/init.c
+21
-1
arch/sparc/mm/io-unit.c
arch/sparc/mm/io-unit.c
+6
-1
arch/sparc/mm/iommu.c
arch/sparc/mm/iommu.c
+8
-3
arch/sparc/mm/srmmu.c
arch/sparc/mm/srmmu.c
+75
-35
arch/sparc/mm/sun4c.c
arch/sparc/mm/sun4c.c
+87
-61
drivers/sbus/sbus.c
drivers/sbus/sbus.c
+2
-1
include/asm-sparc/bitops.h
include/asm-sparc/bitops.h
+91
-1
include/asm-sparc/cacheflush.h
include/asm-sparc/cacheflush.h
+69
-0
include/asm-sparc/current.h
include/asm-sparc/current.h
+36
-5
include/asm-sparc/elf.h
include/asm-sparc/elf.h
+1
-1
include/asm-sparc/highmem.h
include/asm-sparc/highmem.h
+2
-0
include/asm-sparc/kmap_types.h
include/asm-sparc/kmap_types.h
+2
-0
include/asm-sparc/mmu_context.h
include/asm-sparc/mmu_context.h
+0
-23
include/asm-sparc/page.h
include/asm-sparc/page.h
+5
-4
include/asm-sparc/pgalloc.h
include/asm-sparc/pgalloc.h
+17
-86
include/asm-sparc/pgtable.h
include/asm-sparc/pgtable.h
+29
-21
include/asm-sparc/pgtsrmmu.h
include/asm-sparc/pgtsrmmu.h
+2
-1
include/asm-sparc/processor.h
include/asm-sparc/processor.h
+6
-27
include/asm-sparc/spinlock.h
include/asm-sparc/spinlock.h
+17
-25
include/asm-sparc/system.h
include/asm-sparc/system.h
+42
-24
include/asm-sparc/thread_info.h
include/asm-sparc/thread_info.h
+138
-0
include/asm-sparc/tlb.h
include/asm-sparc/tlb.h
+23
-0
include/asm-sparc/tlbflush.h
include/asm-sparc/tlbflush.h
+63
-0
include/asm-sparc/uaccess.h
include/asm-sparc/uaccess.h
+1
-0
No files found.
arch/sparc/Makefile
View file @
a662c5a3
...
...
@@ -41,15 +41,16 @@ SUBDIRS += arch/sparc/kernel arch/sparc/lib arch/sparc/prom \
CORE_FILES
:=
arch
/sparc/kernel/kernel.o
arch
/sparc/mm/mm.o
$(CORE_FILES)
\
arch
/sparc/math-emu/math-emu.o
LIBS
:=
$(TOPDIR)
/lib/lib.a
$(LIBS)
$(TOPDIR)
/arch/sparc/prom/promlib.a
\
$(TOPDIR)
/arch/sparc/lib/lib.a
LIBS
:=
$(LIBS)
arch
/sparc/prom/promlib.a
arch
/sparc/lib/lib.a
# This one has to come last
SUBDIRS
+=
arch
/sparc/boot
CORE_FILES_NO_BTFIX
:=
$(CORE_FILES)
CORE_FILES
+=
arch
/sparc/boot/btfix.o
# Export what is needed by arch/sparc/boot/Makefile
export
CORE_FILES_NO_BTFIX
export
INIT
archclean
:
rm
-f
$(TOPDIR)
/vmlinux.aout
...
...
@@ -60,7 +61,7 @@ archmrproper:
prepare
:
check_asm
check_asm
:
include/linux/version.h include/
linux/
asm include/config/MARKER
check_asm
:
include/linux/version.h include/asm include/config/MARKER
$(MAKE)
-C
arch
/sparc/kernel check_asm
tftpboot.img
:
...
...
arch/sparc/boot/Makefile
View file @
a662c5a3
...
...
@@ -22,9 +22,12 @@ btfixupprep: btfixupprep.c
clean
:
rm
-f
btfixupprep piggyback tftpboot.img btfix.o btfix.s
BTOBJS
:=
$(HEAD)
init/main.o init/version.o
BTLIBS
:=
$(CORE_FILES_NO_BTFIX)
$(FILESYSTEMS)
\
$(DRIVERS)
$(NETWORKS)
#BTOBJS := $(HEAD) init/main.o init/version.o
BTOBJS
:=
$(HEAD)
$(INIT)
#BTLIBS := $(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \
# $(DRIVERS) $(NETWORKS)
# Threw away drivers because they must not have btfixup definitions.
BTLIBS
:=
$(CORE_FILES_NO_BTFIX)
$(LIBS)
# I wanted to make this depend upon BTOBJS so that a parallel
# build would work, but this fails because $(HEAD) cannot work
...
...
@@ -34,7 +37,6 @@ vmlinux.o: FORCE
$(LD)
$(LDFLAGS)
-r
$(
patsubst
%,
$(TOPDIR)
/%,
$(BTOBJS)
)
\
--start-group
\
$(
patsubst
%,
$(TOPDIR)
/%,
$(BTLIBS)
)
\
$(LIBS)
\
--end-group
-o
vmlinux.o
btfix.s
:
btfixupprep vmlinux.o
...
...
arch/sparc/config.in
View file @
a662c5a3
...
...
@@ -239,7 +239,10 @@ endmenu
mainmenu_option next_comment
comment 'Kernel hacking'
bool 'Debug memory allocations' CONFIG_DEBUG_SLAB
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
bool 'Spinlock debugging' CONFIG_DEBUG_SPINLOCK
endmenu
source lib/Config.in
arch/sparc/kernel/entry.S
View file @
a662c5a3
...
...
@@ -31,6 +31,7 @@
#include <asm/signal.h>
#include <asm/obio.h>
#include <asm/mxcc.h>
#include <asm/thread_info.h>
#include <asm/asmmacro.h>
...
...
@@ -1234,7 +1235,8 @@ C_LABEL(sys_ptrace):
call
C_LABEL
(
do_ptrace
)
add
%
sp
,
REGWIN_SZ
,
%
o0
ld
[%
curptr
+
AOFF_task_ptrace
],
%
l5
ld
[%
curptr
+
TI_TASK
],
%
l5
ld
[%
l5
+
AOFF_task_ptrace
],
%
l5
andcc
%
l5
,
0x02
,
%
g0
be
1
f
nop
...
...
@@ -1284,7 +1286,8 @@ C_LABEL(sys_sigpause):
call
C_LABEL
(
do_sigpause
)
add
%
sp
,
REGWIN_SZ
,
%
o1
ld
[%
curptr
+
AOFF_task_ptrace
],
%
l5
ld
[%
curptr
+
TI_TASK
],
%
l5
ld
[%
l5
+
AOFF_task_ptrace
],
%
l5
andcc
%
l5
,
0x02
,
%
g0
be
1
f
nop
...
...
@@ -1302,7 +1305,8 @@ C_LABEL(sys_sigsuspend):
call
C_LABEL
(
do_sigsuspend
)
add
%
sp
,
REGWIN_SZ
,
%
o0
ld
[%
curptr
+
AOFF_task_ptrace
],
%
l5
ld
[%
curptr
+
TI_TASK
],
%
l5
ld
[%
l5
+
AOFF_task_ptrace
],
%
l5
andcc
%
l5
,
0x02
,
%
g0
be
1
f
nop
...
...
@@ -1321,7 +1325,8 @@ C_LABEL(sys_rt_sigsuspend):
call
C_LABEL
(
do_rt_sigsuspend
)
add
%
sp
,
REGWIN_SZ
,
%
o2
ld
[%
curptr
+
AOFF_task_ptrace
],
%
l5
ld
[%
curptr
+
TI_TASK
],
%
l5
ld
[%
l5
+
AOFF_task_ptrace
],
%
l5
andcc
%
l5
,
0x02
,
%
g0
be
1
f
nop
...
...
@@ -1339,7 +1344,8 @@ C_LABEL(sys_sigreturn):
call
C_LABEL
(
do_sigreturn
)
add
%
sp
,
REGWIN_SZ
,
%
o0
ld
[%
curptr
+
AOFF_task_ptrace
],
%
l5
ld
[%
curptr
+
TI_TASK
],
%
l5
ld
[%
l5
+
AOFF_task_ptrace
],
%
l5
andcc
%
l5
,
0x02
,
%
g0
be
1
f
nop
...
...
@@ -1359,7 +1365,8 @@ C_LABEL(sys_rt_sigreturn):
call
C_LABEL
(
do_rt_sigreturn
)
add
%
sp
,
REGWIN_SZ
,
%
o0
ld
[%
curptr
+
AOFF_task_ptrace
],
%
l5
ld
[%
curptr
+
TI_TASK
],
%
l5
ld
[%
l5
+
AOFF_task_ptrace
],
%
l5
andcc
%
l5
,
0x02
,
%
g0
be
1
f
nop
...
...
@@ -1384,16 +1391,17 @@ C_LABEL(sys_fork):
mov
%
o7
,
%
l5
flush_patch_two
:
FLUSH_ALL_KERNEL_WINDOWS
;
ld
[%
curptr
+
TI_TASK
],
%
o4
rd
%
psr
,
%
g4
WRITE_PAUSE
mov
SIGCHLD
,
%
o0
!
arg0
:
clone
flags
rd
%
wim
,
%
g5
WRITE_PAUSE
mov
%
fp
,
%
o1
!
arg1
:
usp
std
%
g4
,
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_fork_kpsr
]
std
%
g4
,
[%
o4
+
AOFF_task_thread
+
AOFF_thread_fork_kpsr
]
add
%
sp
,
REGWIN_SZ
,
%
o2
!
arg2
:
pt_regs
ptr
mov
0
,
%
o3
call
C_LABEL
(
do_fork_FIXME_NOW_RETURNS_TASK_STRUCT
)
call
C_LABEL
(
sparc_do_fork
)
mov
%
l5
,
%
o7
/
*
Whee
,
kernel
threads
!
*/
...
...
@@ -1402,6 +1410,7 @@ C_LABEL(sys_clone):
mov
%
o7
,
%
l5
flush_patch_three
:
FLUSH_ALL_KERNEL_WINDOWS
;
ld
[%
curptr
+
TI_TASK
],
%
o4
rd
%
psr
,
%
g4
WRITE_PAUSE
...
...
@@ -1413,11 +1422,10 @@ flush_patch_three:
mov
%
fp
,
%
o1
!
yes
,
use
callers
usp
andn
%
o1
,
7
,
%
o1
!
no
,
align
to
8
bytes
1
:
std
%
g4
,
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_fork_kpsr
]
std
%
g4
,
[%
o4
+
AOFF_task_thread
+
AOFF_thread_fork_kpsr
]
add
%
sp
,
REGWIN_SZ
,
%
o2
!
arg2
:
pt_regs
ptr
mov
0
,
%
o3
/
*
FIXME
:
remove
CLONE_IDLETASK
from
flags
first
*/
call
C_LABEL
(
do_fork_WITHOUT_CLONE_IDLETASK
)
call
C_LABEL
(
sparc_do_fork
)
mov
%
l5
,
%
o7
/
*
Whee
,
real
vfork
!
*/
...
...
@@ -1425,17 +1433,18 @@ flush_patch_three:
C_LABEL
(
sys_vfork
):
flush_patch_four
:
FLUSH_ALL_KERNEL_WINDOWS
;
ld
[%
curptr
+
TI_TASK
],
%
o4
rd
%
psr
,
%
g4
WRITE_PAUSE
rd
%
wim
,
%
g5
WRITE_PAUSE
std
%
g4
,
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_fork_kpsr
]
std
%
g4
,
[%
o4
+
AOFF_task_thread
+
AOFF_thread_fork_kpsr
]
sethi
%
hi
(
0x4000
| 0x0100 |
SIGCHLD
),
%
o0
mov
%
fp
,
%
o1
or
%
o0
,
%
lo
(
0x4000
| 0x0100 |
SIGCHLD
),
%
o0
sethi
%
hi
(
C_LABEL
(
do_fork_FIXME_NOW_RETURNS_TASK_STRUCT
)),
%
l1
sethi
%
hi
(
C_LABEL
(
sparc_do_fork
)),
%
l1
mov
0
,
%
o3
jmpl
%
l1
+
%
lo
(
C_LABEL
(
do_fork_FIXME_NOW_RETURNS_TASK_STRUCT
)),
%
g0
jmpl
%
l1
+
%
lo
(
C_LABEL
(
sparc_do_fork
)),
%
g0
add
%
sp
,
REGWIN_SZ
,
%
o2
.
align
4
...
...
@@ -1464,8 +1473,11 @@ linux_syscall_trace:
.
globl
C_LABEL
(
ret_from_fork
)
C_LABEL
(
ret_from_fork
):
#if CONFIG_SMP || CONFIG_PREEMPT
/*
XXX
Wrong
location
:
call
schedule_tail
in
every
ret_sys_call
.
*/
call
schedule_tail
mov
%
g3
,
%
o0
#endif
b
C_LABEL
(
ret_sys_call
)
ld
[%
sp
+
REGWIN_SZ
+
PT_I0
],
%
o0
...
...
@@ -1492,7 +1504,8 @@ syscall_is_too_hard:
mov
%
i1
,
%
o1
mov
%
i2
,
%
o2
ld
[%
curptr
+
AOFF_task_ptrace
],
%
l5
ld
[%
curptr
+
TI_TASK
],
%
l5
ld
[%
l5
+
AOFF_task_ptrace
],
%
l5
mov
%
i3
,
%
o3
andcc
%
l5
,
0x02
,
%
g0
mov
%
i4
,
%
o4
...
...
@@ -1506,7 +1519,8 @@ syscall_is_too_hard:
.
globl
C_LABEL
(
ret_sys_call
)
C_LABEL
(
ret_sys_call
):
ld
[%
curptr
+
AOFF_task_ptrace
],
%
l6
ld
[%
curptr
+
TI_TASK
],
%
l6
ld
[%
l6
+
AOFF_task_ptrace
],
%
l6
cmp
%
o0
,
-
ENOIOCTLCMD
ld
[%
sp
+
REGWIN_SZ
+
PT_PSR
],
%
g3
set
PSR_C
,
%
g2
...
...
@@ -1858,7 +1872,7 @@ kuw_patch1_7win: sll %o3, 6, %o3
*
traps
with
the
old
method
of
just
doing
flush_user_windows
()
.
*/
C_LABEL
(
kill_user_windows
):
ld
[%
g6
+
AOFF_task_thread
+
AOFF_thread_uwinmask
],
%
o0
!
get
current
umask
ld
[%
g6
+
TI_UWINMASK
],
%
o0
!
get
current
umask
orcc
%
g0
,
%
o0
,
%
g0
!
if
no
bits
set
,
we
are
done
be
3
f
!
nothing
to
do
rd
%
psr
,
%
o5
!
must
clear
interrupts
...
...
@@ -1866,7 +1880,7 @@ C_LABEL(kill_user_windows):
wr
%
o4
,
0x0
,
%
psr
!
the
uwinmask
state
WRITE_PAUSE
!
burn
them
cycles
1
:
ld
[%
g6
+
AOFF_task_thread
+
AOFF_thread_uwinmask
],
%
o0
!
get
consistant
state
ld
[%
g6
+
TI_UWINMASK
],
%
o0
!
get
consistant
state
orcc
%
g0
,
%
o0
,
%
g0
!
did
an
interrupt
come
in
?
be
4
f
!
yep
,
we
are
done
rd
%
wim
,
%
o3
!
get
current
wim
...
...
@@ -1878,13 +1892,14 @@ kuw_patch1:
bne
kuw_patch1
!
not
done
yet
srl
%
o3
,
1
,
%
o4
!
begin
another
save
simulation
wr
%
o3
,
0x0
,
%
wim
!
set
the
new
wim
st
%
g0
,
[%
g6
+
AOFF_task_thread
+
AOFF_thread_uwinmask
]
!
clear
uwinmask
st
%
g0
,
[%
g6
+
TI_UWINMASK
]
!
clear
uwinmask
4
:
wr
%
o5
,
0x0
,
%
psr
!
re
-
enable
interrupts
WRITE_PAUSE
!
burn
baby
burn
3
:
ld
[%
g6
+
TI_TASK
],
%
o4
retl
!
return
st
%
g0
,
[%
g6
+
AOFF_task_thread
+
AOFF_thread_w_saved
]
!
no
windows
saved
st
%
g0
,
[%
o4
+
AOFF_task_thread
+
AOFF_thread_w_saved
]
!
no
windows
saved
.
align
4
.
globl
C_LABEL
(
restore_current
)
...
...
arch/sparc/kernel/etrap.S
View file @
a662c5a3
...
...
@@ -14,6 +14,7 @@
#include <asm/ptrace.h>
#include <asm/winmacro.h>
#include <asm/asmmacro.h>
#include <asm/thread_info.h>
/*
Registers
to
not
touch
at
all
.
*/
#define t_psr l0 /* Set by caller */
...
...
@@ -101,7 +102,7 @@ trap_setup:
mov
%
t_kstack
,
%
sp
!
jump
onto
new
stack
trap_setup_kernel_spill
:
ld
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_uwinmask
],
%
g1
ld
[%
curptr
+
TI_UWINMASK
],
%
g1
orcc
%
g0
,
%
g1
,
%
g0
bne
trap_setup_user_spill
!
there
are
some
user
windows
,
yuck
/
*
Spill
from
kernel
,
but
only
kernel
windows
,
adjust
...
...
@@ -127,7 +128,8 @@ tsetup_patch2:
jmpl
%
t_retpc
+
0x8
,
%
g0
!
return
to
caller
mov
%
t_kstack
,
%
sp
!
and
onto
new
kernel
stack
#define STACK_OFFSET (TASK_UNION_SIZE - (TRACEREG_SZ + REGWIN_SZ))
#define STACK_OFFSET (THREAD_SIZE - (TRACEREG_SZ + REGWIN_SZ))
trap_setup_from_user
:
/
*
We
can
't use %curptr yet. */
LOAD_CURRENT
(
t_kstack
,
t_twinmask
)
...
...
@@ -143,18 +145,19 @@ trap_setup_from_user:
STORE_PT_ALL
(
t_kstack
,
t_psr
,
t_pc
,
t_npc
,
g2
)
#if 0
/
*
If
we
're sure every task_struct is T
ASK_UNION
_SIZE aligned,
/
*
If
we
're sure every task_struct is T
HREAD
_SIZE aligned,
we
can
speed
this
up
.
*/
sethi
%
hi
(
STACK_OFFSET
),
%
curptr
or
%
curptr
,
%
lo
(
STACK_OFFSET
),
%
curptr
sub
%
t_kstack
,
%
curptr
,
%
curptr
#else
sethi
%
hi
(
~
(
T
ASK_UNION
_SIZE
-
1
)),
%
curptr
sethi
%
hi
(
~
(
T
HREAD
_SIZE
-
1
)),
%
curptr
and
%
t_kstack
,
%
curptr
,
%
curptr
#endif
/
*
Clear
current
->
thread
.
w_saved
*/
st
%
g0
,
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_w_saved
]
ld
[%
curptr
+
TI_TASK
],
%
g2
st
%
g0
,
[%
g2
+
AOFF_task_thread
+
AOFF_thread_w_saved
]
/
*
See
if
we
are
in
the
trap
window
.
*/
andcc
%
t_twinmask
,
%
t_wim
,
%
g0
...
...
@@ -185,7 +188,7 @@ trap_setup_from_user:
andn
%
g2
,
%
t_twinmask
,
%
g2
tsetup_patch3
:
and
%
g2
,
0xff
,
%
g2
!
patched
on
7
win
Sparcs
st
%
g2
,
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_uwinmask
]
!
store
new
umask
st
%
g2
,
[%
curptr
+
TI_UWINMASK
]
!
store
new
umask
jmpl
%
t_retpc
+
0x8
,
%
g0
!
return
to
caller
mov
%
t_kstack
,
%
sp
!
and
onto
kernel
stack
...
...
@@ -206,7 +209,7 @@ tsetup_patch5:
tsetup_patch6
:
and
%
g2
,
0xff
,
%
g2
!
patched
on
7
win
Sparcs
andn
%
g1
,
%
g2
,
%
g1
!
clear
this
bit
in
%
g1
st
%
g1
,
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_uwinmask
]
st
%
g1
,
[%
curptr
+
TI_UWINMASK
]
save
%
g0
,
%
g0
,
%
g0
...
...
@@ -288,7 +291,8 @@ trap_setup_user_stack_is_bolixed:
/
*
From
user
/
kernel
into
invalid
window
w
/
bad
user
*
stack
.
Save
bad
user
stack
,
and
return
to
caller
.
*/
SAVE_BOLIXED_USER_STACK
(
curptr
,
g3
)
ld
[%
curptr
+
TI_TASK
],
%
glob_tmp
SAVE_BOLIXED_USER_STACK
(
glob_tmp
,
g3
)
restore
%
g0
,
%
g0
,
%
g0
jmpl
%
t_retpc
+
0x8
,
%
g0
...
...
arch/sparc/kernel/head.S
View file @
a662c5a3
...
...
@@ -23,6 +23,7 @@
#include <asm/page.h>
#include <asm/kdebug.h>
#include <asm/winmacro.h>
#include <asm/thread_info.h> /* TI_UWINMASK */
#include <asm/errno.h>
.
data
...
...
@@ -749,7 +750,7 @@ go_to_highmem:
jmpl
%
g1
,
%
g0
nop
/
*
This
is
to
align
init_t
ask
_union
properly
,
be
careful
.
-
DaveM
*/
/
*
This
is
to
align
init_t
hread
_union
properly
,
be
careful
.
-
DaveM
*/
.
align
8192
/*
The
code
above
should
be
at
beginning
and
we
have
to
take
care
about
...
...
@@ -1010,8 +1011,8 @@ sun4c_continue_boot:
WRITE_PAUSE
/
*
I
want
a
kernel
stack
NOW
!
*/
set
C_LABEL
(
init_t
ask
_union
),
%
g1
set
(
T
ASK_UNION
_SIZE
-
REGWIN_SZ
),
%
g2
set
C_LABEL
(
init_t
hread
_union
),
%
g1
set
(
T
HREAD
_SIZE
-
REGWIN_SZ
),
%
g2
add
%
g1
,
%
g2
,
%
sp
mov
0
,
%
fp
/*
And
for
good
luck
*/
...
...
@@ -1025,10 +1026,10 @@ sun4c_continue_boot:
bl
1
b
add
%
o0
,
0x1
,
%
o0
/
*
Initialize
the
u
mask
value
for
init_
task
just
in
case
.
/
*
Initialize
the
u
winmask
value
for
init
task
just
in
case
.
*
But
first
make
current_set
[
boot_cpu_id
]
point
to
something
useful
.
*/
set
C_LABEL
(
init_t
ask
_union
),
%
g6
set
C_LABEL
(
init_t
hread
_union
),
%
g6
set
C_LABEL
(
current_set
),
%
g2
#ifdef CONFIG_SMP
sethi
%
hi
(
C_LABEL
(
boot_cpu_id4
)),
%
g3
...
...
@@ -1038,7 +1039,7 @@ sun4c_continue_boot:
#endif
st
%
g6
,
[%
g2
]
st
%
g0
,
[%
g6
+
AOFF_task_thread
+
AOFF_thread_uwinmask
]
st
%
g0
,
[%
g6
+
TI_UWINMASK
]
/*
Compute
NWINDOWS
and
stash
it
away
.
Now
uses
%
wim
trick
explained
*
in
the
V8
manual
.
Ok
,
this
method
seems
to
work
,
Sparc
is
cool
...
...
...
arch/sparc/kernel/init_task.c
View file @
a662c5a3
...
...
@@ -9,12 +9,12 @@ static struct fs_struct init_fs = INIT_FS;
static
struct
files_struct
init_files
=
INIT_FILES
;
static
struct
signal_struct
init_signals
=
INIT_SIGNALS
;
struct
mm_struct
init_mm
=
INIT_MM
(
init_mm
);
struct
task_struct
init_task
=
INIT_TASK
(
init_task
);
/* .text section in head.S is aligned at 8k boundry and this gets linked
* right after that so that the init_t
ask
_union is aligned properly as well.
* right after that so that the init_t
hread
_union is aligned properly as well.
* If this is not aligned on a 8k boundry, then you should change code
* in etrap.S which assumes it.
*/
__asm__
(
".section
\"
.text
\"
,#alloc
\n
"
);
union
task_union
init_task_union
=
{
INIT_TASK
(
init_task_union
.
task
)
};
union
thread_union
init_thread_union
=
{
INIT_THREAD_INFO
(
init_task
)
};
arch/sparc/kernel/ioport.c
View file @
a662c5a3
...
...
@@ -530,7 +530,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba)
}
}
*
pba
=
virt_to_
bus
(
va
);
*
pba
=
virt_to_
phys
(
va
);
/* equals virt_to_bus (R.I.P.) for us. */
return
(
void
*
)
res
->
start
;
}
...
...
@@ -565,7 +565,7 @@ void pci_free_consistent(struct pci_dev *pdev, size_t n, void *p, dma_addr_t ba)
return
;
}
pgp
=
(
unsigned
long
)
bus_to_virt
(
ba
);
pgp
=
(
unsigned
long
)
phys_to_virt
(
ba
);
/* bus_to_virt actually */
mmu_inval_dma_area
(
pgp
,
n
);
{
int
x
;
...
...
@@ -592,7 +592,7 @@ dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size,
if
(
direction
==
PCI_DMA_NONE
)
BUG
();
/* IIep is write-through, not flushing. */
return
virt_to_
bu
s
(
ptr
);
return
virt_to_
phy
s
(
ptr
);
}
/* Unmap a single streaming mode DMA translation. The dma_addr and size
...
...
@@ -608,7 +608,7 @@ void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t ba, size_t size,
if
(
direction
==
PCI_DMA_NONE
)
BUG
();
if
(
direction
!=
PCI_DMA_TODEVICE
)
{
mmu_inval_dma_area
((
unsigned
long
)
bu
s_to_virt
(
ba
),
mmu_inval_dma_area
((
unsigned
long
)
phy
s_to_virt
(
ba
),
(
size
+
PAGE_SIZE
-
1
)
&
PAGE_MASK
);
}
}
...
...
@@ -637,7 +637,8 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
BUG
();
/* IIep is write-through, not flushing. */
for
(
n
=
0
;
n
<
nents
;
n
++
)
{
sg
->
dvma_address
=
virt_to_bus
(
sg
->
address
);
if
(
page_address
(
sg
->
page
)
==
NULL
)
BUG
();
sg
->
dvma_address
=
virt_to_phys
(
page_address
(
sg
->
page
));
sg
->
dvma_length
=
sg
->
length
;
sg
++
;
}
...
...
@@ -657,7 +658,9 @@ void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
BUG
();
if
(
direction
!=
PCI_DMA_TODEVICE
)
{
for
(
n
=
0
;
n
<
nents
;
n
++
)
{
mmu_inval_dma_area
((
unsigned
long
)
sg
->
address
,
if
(
page_address
(
sg
->
page
)
==
NULL
)
BUG
();
mmu_inval_dma_area
(
(
unsigned
long
)
page_address
(
sg
->
page
),
(
sg
->
length
+
PAGE_SIZE
-
1
)
&
PAGE_MASK
);
sg
++
;
}
...
...
@@ -678,7 +681,7 @@ void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t ba, size_t size, int
if
(
direction
==
PCI_DMA_NONE
)
BUG
();
if
(
direction
!=
PCI_DMA_TODEVICE
)
{
mmu_inval_dma_area
((
unsigned
long
)
bu
s_to_virt
(
ba
),
mmu_inval_dma_area
((
unsigned
long
)
phy
s_to_virt
(
ba
),
(
size
+
PAGE_SIZE
-
1
)
&
PAGE_MASK
);
}
}
...
...
@@ -697,7 +700,9 @@ void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, i
BUG
();
if
(
direction
!=
PCI_DMA_TODEVICE
)
{
for
(
n
=
0
;
n
<
nents
;
n
++
)
{
mmu_inval_dma_area
((
unsigned
long
)
sg
->
address
,
if
(
page_address
(
sg
->
page
)
==
NULL
)
BUG
();
mmu_inval_dma_area
(
(
unsigned
long
)
page_address
(
sg
->
page
),
(
sg
->
length
+
PAGE_SIZE
-
1
)
&
PAGE_MASK
);
sg
++
;
}
...
...
arch/sparc/kernel/irq.c
View file @
a662c5a3
...
...
@@ -6,7 +6,7 @@
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
* Copyright (C) 1995 Pete A. Zaitcev (zaitcev@yahoo.com)
* Copyright (C) 1995
,2002
Pete A. Zaitcev (zaitcev@yahoo.com)
* Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
* Copyright (C) 1998-2000 Anton Blanchard (anton@samba.org)
*/
...
...
@@ -46,6 +46,7 @@
#include <asm/hardirq.h>
#include <asm/softirq.h>
#include <asm/pcic.h>
#include <asm/cacheflush.h>
/*
* Dave Redman (djhr@tadpole.co.uk)
...
...
@@ -119,9 +120,11 @@ int show_interrupts(struct seq_file *p, void *v)
#ifndef CONFIG_SMP
seq_printf
(
p
,
"%10u "
,
kstat_irqs
(
i
));
#else
for
(
j
=
0
;
j
<
smp_num_cpus
;
j
++
)
for
(
j
=
0
;
j
<
NR_CPUS
;
j
++
)
{
if
(
cpu_online
(
j
))
seq_printf
(
p
,
"%10u "
,
kstat
.
irqs
[
cpu_logical_map
(
j
)][
i
]);
}
#endif
seq_printf
(
p
,
" %c %s"
,
(
action
->
flags
&
SA_INTERRUPT
)
?
'+'
:
' '
,
...
...
@@ -214,12 +217,16 @@ static void show(char * str)
printk
(
"
\n
%s, CPU %d:
\n
"
,
str
,
cpu
);
printk
(
"irq: %d [ "
,
irqs_running
());
for
(
i
=
0
;
i
<
smp_num_cpus
;
i
++
)
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
if
(
cpu_online
(
i
))
printk
(
"%u "
,
__brlock_array
[
i
][
BR_GLOBALIRQ_LOCK
]);
}
printk
(
"]
\n
bh: %d [ "
,
(
spin_is_locked
(
&
global_bh_lock
)
?
1
:
0
));
for
(
i
=
0
;
i
<
smp_num_cpus
;
i
++
)
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
if
(
cpu_online
(
i
))
printk
(
"%u "
,
local_bh_count
(
i
));
}
printk
(
"]
\n
"
);
#ifdef VERBOSE_DEBUG_IRQLOCK
...
...
arch/sparc/kernel/process.c
View file @
a662c5a3
...
...
@@ -57,7 +57,14 @@ void (*pm_power_off)(void);
extern
void
fpsave
(
unsigned
long
*
,
unsigned
long
*
,
void
*
,
unsigned
long
*
);
struct
task_struct
*
last_task_used_math
=
NULL
;
struct
task_struct
*
current_set
[
NR_CPUS
]
=
{
&
init_task
,
};
struct
thread_info
*
current_set
[
NR_CPUS
];
/*
* default_idle is new in 2.5. XXX Review, currently stolen from sparc64.
*/
void
default_idle
(
void
)
{
}
#ifndef CONFIG_SMP
...
...
@@ -106,8 +113,8 @@ int cpu_idle(void)
restore_flags
(
flags
);
}
while
((
!
current
->
need_resched
)
&&
pm_idle
)
{
(
*
pm_idle
)();
while
((
!
need_resched
()
)
&&
pm_idle
)
{
(
*
pm_idle
)();
/* XXX Huh? On sparc?! */
}
schedule
();
...
...
@@ -306,7 +313,7 @@ void show_trace_task(struct task_struct *tsk)
if
(
!
tsk
)
return
;
fp
=
tsk
->
thread
.
ksp
;
fp
=
tsk
->
thread
_info
->
ksp
;
do
{
/* Bogus frame pointer? */
if
(
fp
<
(
task_base
+
sizeof
(
struct
task_struct
))
||
...
...
@@ -320,6 +327,14 @@ void show_trace_task(struct task_struct *tsk)
printk
(
"
\n
"
);
}
/*
* Note: sparc64 has a pretty intricated thread_saved_pc, check it out.
*/
unsigned
long
thread_saved_pc
(
struct
task_struct
*
tsk
)
{
return
tsk
->
thread_info
->
kpc
;
}
/*
* Free current thread data structures etc..
*/
...
...
@@ -372,7 +387,7 @@ void flush_thread(void)
/* We must fixup kregs as well. */
current
->
thread
.
kregs
=
(
struct
pt_regs
*
)
(((
unsigned
long
)
current
)
+
(
T
ASK_UNION
_SIZE
-
TRACEREG_SZ
));
(
T
HREAD
_SIZE
-
TRACEREG_SZ
));
}
}
...
...
@@ -445,6 +460,22 @@ clone_stackframe(struct sparc_stackf *dst, struct sparc_stackf *src)
return
sp
;
}
asmlinkage
int
sparc_do_fork
(
unsigned
long
clone_flags
,
unsigned
long
stack_start
,
struct
pt_regs
*
regs
,
unsigned
long
stack_size
)
{
struct
task_struct
*
p
;
/* XXX This was spelled in DaveM's will and testament. Why? */
if
(
clone_flags
&
CLONE_IDLETASK
)
{
printk
(
KERN_DEBUG
"Userland clone with CLONE_IDLETASK
\n
"
);
clone_flags
&=
~
CLONE_IDLETASK
;
}
p
=
do_fork
(
clone_flags
,
stack_start
,
regs
,
stack_size
);
return
IS_ERR
(
p
)
?
PTR_ERR
(
p
)
:
p
->
pid
;
}
/* Copy a Sparc thread. The fork() return value conventions
* under SunOS are nothing short of bletcherous:
...
...
@@ -457,6 +488,7 @@ clone_stackframe(struct sparc_stackf *dst, struct sparc_stackf *src)
* if the parent should sleep while trying to
* allocate the task_struct and kernel stack in
* do_fork().
* XXX See comment above sys_vfork in sparc64. todo.
*/
extern
void
ret_from_fork
(
void
);
...
...
@@ -464,6 +496,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
unsigned
long
unused
,
struct
task_struct
*
p
,
struct
pt_regs
*
regs
)
{
struct
thread_info
*
ti
=
p
->
thread_info
;
struct
pt_regs
*
childregs
;
struct
reg_window
*
new_stack
;
unsigned
long
stack_offset
;
...
...
@@ -482,19 +515,19 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
}
/* Calculate offset to stack_frame & pt_regs */
stack_offset
=
T
ASK_UNION
_SIZE
-
TRACEREG_SZ
;
stack_offset
=
T
HREAD
_SIZE
-
TRACEREG_SZ
;
if
(
regs
->
psr
&
PSR_PS
)
stack_offset
-=
REGWIN_SZ
;
childregs
=
((
struct
pt_regs
*
)
(((
unsigned
long
)
p
)
+
stack_offset
));
childregs
=
((
struct
pt_regs
*
)
(((
unsigned
long
)
ti
)
+
stack_offset
));
copy_regs
(
childregs
,
regs
);
new_stack
=
(((
struct
reg_window
*
)
childregs
)
-
1
);
copy_regwin
(
new_stack
,
(((
struct
reg_window
*
)
regs
)
-
1
));
p
->
thread
.
ksp
=
(
unsigned
long
)
new_stack
;
p
->
thread
.
kpc
=
(((
unsigned
long
)
ret_from_fork
)
-
0x8
);
p
->
thread
.
kpsr
=
current
->
thread
.
fork_kpsr
;
p
->
thread
.
kwim
=
current
->
thread
.
fork_kwim
;
ti
->
ksp
=
(
unsigned
long
)
new_stack
;
ti
->
kpc
=
(((
unsigned
long
)
ret_from_fork
)
-
0x8
);
ti
->
kpsr
=
current
->
thread
.
fork_kpsr
;
ti
->
kwim
=
current
->
thread
.
fork_kwim
;
/* This is used for sun4c only */
atomic_set
(
&
p
->
thread
.
refcount
,
1
);
...
...
@@ -504,16 +537,14 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
p
->
thread
.
kregs
=
&
fake_swapper_regs
;
new_stack
=
(
struct
reg_window
*
)
((((
unsigned
long
)
p
)
+
(
TASK_UNION_SIZE
))
-
(
REGWIN_SZ
));
((((
unsigned
long
)
ti
)
+
(
THREAD_SIZE
))
-
REGWIN_SZ
);
childregs
->
u_regs
[
UREG_FP
]
=
(
unsigned
long
)
new_stack
;
p
->
thread
.
flags
|=
SPARC_FLAG_KTHREAD
;
p
->
thread
.
current_ds
=
KERNEL_DS
;
memcpy
((
void
*
)
new_stack
,
(
void
*
)
regs
->
u_regs
[
UREG_FP
],
sizeof
(
struct
reg_window
));
childregs
->
u_regs
[
UREG_G6
]
=
(
unsigned
long
)
p
;
childregs
->
u_regs
[
UREG_G6
]
=
(
unsigned
long
)
ti
;
}
else
{
p
->
thread
.
kregs
=
childregs
;
childregs
->
u_regs
[
UREG_FP
]
=
sp
;
...
...
arch/sparc/kernel/ptrace.c
View file @
a662c5a3
...
...
@@ -92,16 +92,16 @@ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset,
}
switch
(
offset
)
{
case
0
:
v
=
t
->
ksp
;
v
=
t
sk
->
thread_info
->
ksp
;
break
;
case
4
:
v
=
t
->
kpc
;
v
=
t
sk
->
thread_info
->
kpc
;
break
;
case
8
:
v
=
t
->
kpsr
;
v
=
t
sk
->
thread_info
->
kpsr
;
break
;
case
12
:
v
=
t
->
uwinmask
;
v
=
t
sk
->
thread_info
->
uwinmask
;
break
;
case
832
:
v
=
t
->
w_saved
;
...
...
@@ -530,9 +530,9 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
if
(
request
==
PTRACE_SYSCALL
)
child
->
ptrace
|=
PT_TRACESYS
;
set_tsk_thread_flag
(
child
,
TIF_SYSCALL_TRACE
)
;
else
c
hild
->
ptrace
&=
~
PT_TRACESYS
;
c
lear_tsk_thread_flag
(
child
,
TIF_SYSCALL_TRACE
)
;
child
->
exit_code
=
data
;
#ifdef DEBUG_PTRACE
...
...
@@ -581,7 +581,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
out_tsk:
if
(
child
)
free
_task_struct
(
child
);
put
_task_struct
(
child
);
out:
unlock_kernel
();
}
...
...
@@ -591,8 +591,9 @@ asmlinkage void syscall_trace(void)
#ifdef DEBUG_PTRACE
printk
(
"%s [%d]: syscall_trace
\n
"
,
current
->
comm
,
current
->
pid
);
#endif
if
((
current
->
ptrace
&
(
PT_PTRACED
|
PT_TRACESYS
))
!=
(
PT_PTRACED
|
PT_TRACESYS
))
if
(
!
test_thread_flag
(
TIF_SYSCALL_TRACE
))
return
;
if
(
!
(
current
->
ptrace
&
PT_PTRACED
))
return
;
current
->
exit_code
=
SIGTRAP
;
current
->
state
=
TASK_STOPPED
;
...
...
arch/sparc/kernel/rtrap.S
View file @
a662c5a3
...
...
@@ -13,6 +13,7 @@
#include <asm/contregs.h>
#include <asm/winmacro.h>
#include <asm/asmmacro.h>
#include <asm/thread_info.h>
#define t_psr l0
#define t_pc l1
...
...
@@ -58,17 +59,17 @@ C_LABEL(ret_trap_lockless_ipi):
nop
1
:
#error ld [%curptr + AOFF_task_need_resched
], %g2
orcc
%
g2
,
%
g0
,
%
g0
ld
[%
curptr
+
TI_FLAGS
],
%
g2
andcc
%
g2
,
(
_TIF_NEED_RESCHED
)
,
%
g0
be
signal_p
#error ld [%curptr + AOFF_task_sigpending], %g2
nop
call
C_LABEL
(
schedule
)
nop
#error ld [%curptr + AOFF_task_sigpending
], %g2
ld
[%
curptr
+
TI_FLAGS
],
%
g2
signal_p
:
cmp
%
g2
,
0
andcc
%
g2
,
(
_TIF_NOTIFY_RESUME
|
_TIF_SIGPENDING
),
%
g
0
bz
,
a
ret_trap_continue
ld
[%
sp
+
REGWIN_SZ
+
PT_PSR
],
%
t_psr
...
...
@@ -98,7 +99,7 @@ ret_trap_continue:
add
%
sp
,
REGWIN_SZ
,
%
o0
b
signal_p
#error ld [%curptr + AOFF_task_sigpending
], %g2
ld
[%
curptr
+
TI_FLAGS
],
%
g2
ret_trap_nobufwins
:
/
*
Load
up
the
user
's out registers so we can pull
...
...
@@ -109,7 +110,7 @@ ret_trap_nobufwins:
/
*
If
there
are
already
live
user
windows
in
the
*
set
we
can
return
from
trap
safely
.
*/
ld
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_uwinmask
],
%
twin_tmp1
ld
[%
curptr
+
TI_UWINMASK
],
%
twin_tmp1
orcc
%
g0
,
%
twin_tmp1
,
%
g0
bne
ret_trap_userwins_ok
nop
...
...
@@ -168,7 +169,7 @@ ret_trap_unaligned_pc:
nop
b
signal_p
#error ld [%curptr + AOFF_task_sigpending
], %g2
ld
[%
curptr
+
TI_FLAGS
],
%
g2
ret_trap_kernel
:
/
*
Will
the
rett
land
us
in
the
invalid
window
?
*/
...
...
@@ -218,7 +219,8 @@ ret_trap_user_stack_is_bolixed:
add
%
sp
,
REGWIN_SZ
,
%
o0
b
signal_p
#error ld [%curptr + AOFF_task_sigpending], %g2
ld
[%
curptr
+
TI_FLAGS
],
%
g2
.
globl
C_LABEL
(
sun4c_rett_stackchk
)
C_LABEL
(
sun4c_rett_stackchk
):
...
...
arch/sparc/kernel/sclow.S
View file @
a662c5a3
...
...
@@ -10,6 +10,7 @@
#include <asm/ptrace.h>
#include <asm/errno.h>
#include <asm/winmacro.h>
#include <asm/thread_info.h>
#include <asm/psr.h>
#include <asm/page.h>
...
...
@@ -40,6 +41,7 @@ LABEL(sunosnop):
.
globl
LABEL
(
sunosgetpid
)
LABEL
(
sunosgetpid
):
LOAD_CURRENT
(
l4
,
l5
)
ld
[%
l4
+
TI_TASK
],
%
l4
ld
[%
l4
+
AOFF_task_pid
],
%
i0
ld
[%
l4
+
AOFF_task_p_opptr
],
%
l5
ld
[%
l5
+
AOFF_task_pid
],
%
i1
...
...
@@ -50,6 +52,7 @@ LABEL(sunosgetpid):
.
globl
LABEL
(
sunosgetuid
)
LABEL
(
sunosgetuid
):
LOAD_CURRENT
(
l4
,
l5
)
ld
[%
l4
+
TI_TASK
],
%
l4
lduh
[%
l4
+
AOFF_task_uid
],
%
i0
lduh
[%
l4
+
AOFF_task_euid
],
%
i1
CC_AND_RETT
...
...
@@ -59,6 +62,7 @@ LABEL(sunosgetuid):
.
globl
LABEL
(
sunosgetgid
)
LABEL
(
sunosgetgid
):
LOAD_CURRENT
(
l4
,
l5
)
ld
[%
l4
+
TI_TASK
],
%
l4
lduh
[%
l4
+
AOFF_task_gid
],
%
i0
lduh
[%
l4
+
AOFF_task_egid
],
%
i1
CC_AND_RETT
...
...
@@ -77,6 +81,7 @@ LABEL(sunosgdtsize):
.
globl
LABEL
(
sunossblock
)
LABEL
(
sunossblock
):
LOAD_CURRENT
(
l4
,
l5
)
ld
[%
l4
+
TI_TASK
],
%
l4
set
-
65793
,
%
l5
and
%
i0
,
%
l5
,
%
l5
ld
[%
l4
+
AOFF_task_blocked
],
%
i0
...
...
@@ -87,6 +92,7 @@ LABEL(sunossblock):
.
globl
LABEL
(
sunossmask
)
LABEL
(
sunossmask
):
LOAD_CURRENT
(
l4
,
l5
)
ld
[%
l4
+
TI_TASK
],
%
l4
set
-
65793
,
%
l5
and
%
i0
,
%
l5
,
%
l5
ld
[%
l4
+
AOFF_task_blocked
],
%
i0
...
...
arch/sparc/kernel/semaphore.c
View file @
a662c5a3
...
...
@@ -3,6 +3,7 @@
/* sparc32 semaphore implementation, based on i386 version */
#include <linux/sched.h>
#include <linux/errno.h>
#include <asm/semaphore.h>
...
...
arch/sparc/kernel/setup.c
View file @
a662c5a3
...
...
@@ -481,7 +481,7 @@ static int show_cpuinfo(struct seq_file *m, void *__unused)
(
short
)
romvec
->
pv_printrev
,
&
cputypval
,
linux_num_cpus
,
smp_num_cpus
num_online_cpus
()
#ifndef CONFIG_SMP
,
loops_per_jiffy
/
(
500000
/
HZ
),
(
loops_per_jiffy
/
(
5000
/
HZ
))
%
100
...
...
arch/sparc/kernel/signal.c
View file @
a662c5a3
...
...
@@ -19,6 +19,7 @@
#include <linux/tty.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/binfmts.h>
/* do_coredum */
#include <asm/uaccess.h>
#include <asm/bitops.h>
...
...
@@ -26,6 +27,7 @@
#include <asm/svr4.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/cacheflush.h>
/* flush_sig_insns */
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
...
...
@@ -34,7 +36,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
extern
void
fpload
(
unsigned
long
*
fpregs
,
unsigned
long
*
fsr
);
asmlinkage
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
,
unsigned
long
orig_o0
,
int
re
t_from
_syscall
);
unsigned
long
orig_o0
,
int
re
start
_syscall
);
/* This turned off for production... */
/* #define DEBUG_SIGNALS 1 */
...
...
@@ -229,7 +231,7 @@ restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
{
int
err
;
#ifdef CONFIG_SMP
if
(
current
->
flags
&
PF_USEDFPU
)
if
(
test_tsk_thread_flag
(
current
,
TIF_USEDFPU
)
)
regs
->
psr
&=
~
PSR_EF
;
#else
if
(
current
==
last_task_used_math
)
{
...
...
@@ -238,7 +240,7 @@ restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
}
#endif
current
->
used_math
=
1
;
c
urrent
->
flags
&=
~
PF_USEDFPU
;
c
lear_tsk_thread_flag
(
current
,
TIF_USEDFPU
)
;
if
(
verify_area
(
VERIFY_READ
,
fpu
,
sizeof
(
*
fpu
)))
return
-
EFAULT
;
...
...
@@ -586,12 +588,12 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
{
int
err
=
0
;
#ifdef CONFIG_SMP
if
(
current
->
flags
&
PF_USEDFPU
)
{
if
(
test_tsk_thread_flag
(
current
,
TIF_USEDFPU
)
)
{
put_psr
(
get_psr
()
|
PSR_EF
);
fpsave
(
&
current
->
thread
.
float_regs
[
0
],
&
current
->
thread
.
fsr
,
&
current
->
thread
.
fpqueue
[
0
],
&
current
->
thread
.
fpqdepth
);
regs
->
psr
&=
~
(
PSR_EF
);
c
urrent
->
flags
&=
~
(
P
F_USEDFPU
);
c
lear_tsk_thread_flag
(
current
,
TI
F_USEDFPU
);
}
#else
if
(
current
==
last_task_used_math
)
{
...
...
@@ -1295,7 +1297,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
/* fall through */
default:
sigaddset
(
&
current
->
pending
.
signal
,
signr
);
recalc_sigpending
(
current
);
recalc_sigpending
();
current
->
flags
|=
PF_SIGNALED
;
do_exit
(
exit_code
);
/* NOT REACHED */
...
...
arch/sparc/kernel/sparc-stub.c
View file @
a662c5a3
...
...
@@ -109,6 +109,8 @@
#include <asm/kgdb.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/cacheflush.h>
/*
*
* external low-level support routines
...
...
arch/sparc/kernel/sparc_ksyms.c
View file @
a662c5a3
...
...
@@ -142,7 +142,6 @@ EXPORT_SYMBOL(__global_save_flags);
EXPORT_SYMBOL
(
__global_restore_flags
);
/* Misc SMP information */
EXPORT_SYMBOL
(
smp_num_cpus
);
EXPORT_SYMBOL
(
__cpu_number_map
);
EXPORT_SYMBOL
(
__cpu_logical_map
);
#endif
...
...
arch/sparc/kernel/sun4d_irq.c
View file @
a662c5a3
...
...
@@ -99,9 +99,11 @@ found_it: seq_printf(p, "%3d: ", i);
#ifndef CONFIG_SMP
seq_printf
(
p
,
"%10u "
,
kstat_irqs
(
i
));
#else
for
(
x
=
0
;
x
<
smp_num_cpus
;
x
++
)
for
(
x
=
0
;
x
<
NR_CPUS
;
x
++
)
{
if
(
cpu_online
)
seq_printf
(
p
,
"%10u "
,
kstat
.
irqs
[
cpu_logical_map
(
x
)][
i
]);
}
#endif
seq_printf
(
p
,
"%c %s"
,
(
action
->
flags
&
SA_INTERRUPT
)
?
'+'
:
' '
,
...
...
arch/sparc/kernel/sun4d_smp.c
View file @
a662c5a3
...
...
@@ -43,7 +43,6 @@ extern int linux_num_cpus;
extern
void
calibrate_delay
(
void
);
extern
struct
task_struct
*
current_set
[
NR_CPUS
];
extern
volatile
int
smp_processors_ready
;
extern
unsigned
long
cpu_present_map
;
extern
int
smp_num_cpus
;
...
...
arch/sparc/kernel/sun4m_smp.c
View file @
a662c5a3
...
...
@@ -40,7 +40,6 @@ extern int linux_num_cpus;
extern
void
calibrate_delay
(
void
);
extern
struct
task_struct
*
current_set
[
NR_CPUS
];
extern
volatile
int
smp_processors_ready
;
extern
unsigned
long
cpu_present_map
;
extern
int
smp_num_cpus
;
...
...
arch/sparc/kernel/trampoline.S
View file @
a662c5a3
...
...
@@ -63,8 +63,8 @@ cpu3_startup:
and
%
g4
,
0xc
,
%
g4
ld
[%
g5
+
%
g4
],
%
g6
sethi
%
hi
(
T
ASK_UNION
_SIZE
-
REGWIN_SZ
),
%
sp
or
%
sp
,
%
lo
(
T
ASK_UNION
_SIZE
-
REGWIN_SZ
),
%
sp
sethi
%
hi
(
T
HREAD
_SIZE
-
REGWIN_SZ
),
%
sp
or
%
sp
,
%
lo
(
T
HREAD
_SIZE
-
REGWIN_SZ
),
%
sp
add
%
g6
,
%
sp
,
%
sp
/
*
Turn
on
traps
(
PSR_ET
)
.
*/
...
...
@@ -142,8 +142,8 @@ C_LABEL(sun4d_cpu_startup):
srl
%
g3
,
1
,
%
g4
ld
[%
g5
+
%
g4
],
%
g6
sethi
%
hi
(
T
ASK_UNION
_SIZE
-
REGWIN_SZ
),
%
sp
or
%
sp
,
%
lo
(
T
ASK_UNION
_SIZE
-
REGWIN_SZ
),
%
sp
sethi
%
hi
(
T
HREAD
_SIZE
-
REGWIN_SZ
),
%
sp
or
%
sp
,
%
lo
(
T
HREAD
_SIZE
-
REGWIN_SZ
),
%
sp
add
%
g6
,
%
sp
,
%
sp
/
*
Turn
on
traps
(
PSR_ET
)
.
*/
...
...
arch/sparc/kernel/traps.c
View file @
a662c5a3
...
...
@@ -475,6 +475,23 @@ int thiscpus_mid;
void
trap_init
(
void
)
{
extern
void
thread_info_offsets_are_bolixed_pete
(
void
);
/* Force linker to barf if mismatched */
if
(
TI_UWINMASK
!=
offsetof
(
struct
thread_info
,
uwinmask
)
||
TI_TASK
!=
offsetof
(
struct
thread_info
,
task
)
||
TI_EXECDOMAIN
!=
offsetof
(
struct
thread_info
,
exec_domain
)
||
TI_FLAGS
!=
offsetof
(
struct
thread_info
,
flags
)
||
TI_CPU
!=
offsetof
(
struct
thread_info
,
cpu
)
||
TI_PREEMPT
!=
offsetof
(
struct
thread_info
,
preempt_count
)
||
TI_SOFTIRQ
!=
offsetof
(
struct
thread_info
,
softirq_count
)
||
TI_HARDIRQ
!=
offsetof
(
struct
thread_info
,
hardirq_count
)
||
TI_KSP
!=
offsetof
(
struct
thread_info
,
ksp
)
||
TI_KPC
!=
offsetof
(
struct
thread_info
,
kpc
)
||
TI_KPSR
!=
offsetof
(
struct
thread_info
,
kpsr
)
||
TI_KWIM
!=
offsetof
(
struct
thread_info
,
kwim
))
thread_info_offsets_are_bolixed_pete
();
/* Attach to the address space of init_task. */
atomic_inc
(
&
init_mm
.
mm_count
);
current
->
active_mm
=
&
init_mm
;
...
...
arch/sparc/kernel/windows.c
View file @
a662c5a3
...
...
@@ -32,7 +32,7 @@ void flush_user_windows(void)
" restore %%g0, %%g0, %%g0
\n
"
:
"=&r"
(
ctr
)
:
"0"
(
ctr
),
"i"
((
const
unsigned
long
)
(
&
(((
struct
task_struct
*
)
0
)
->
thread
.
uwinmask
))
)
"i"
((
const
unsigned
long
)
TI_UWINMASK
)
:
"g4"
,
"cc"
);
}
...
...
arch/sparc/kernel/wof.S
View file @
a662c5a3
...
...
@@ -13,6 +13,7 @@
#include <asm/asi.h>
#include <asm/winmacro.h>
#include <asm/asmmacro.h>
#include <asm/thread_info.h>
/*
WARNING
:
This
routine
is
hairy
and
_very_
complicated
,
but
it
*
must
be
as
fast
as
possible
as
it
handles
the
allocation
...
...
@@ -62,7 +63,7 @@ spnwin_patch3_7win: and %twin_tmp, 0x7f, %twin_tmp
*
andcc
%
l0
,
PSR_PS
,
%
g0
*/
/
*
Datum
current
->
thread
.
uwinmask
contains
at
all
times
a
bitmask
/
*
Datum
current
_thread_info
->
uwinmask
contains
at
all
times
a
bitmask
*
where
if
any
user
windows
are
active
,
at
least
one
bit
will
*
be
set
in
to
mask
.
If
no
user
windows
are
active
,
the
bitmask
*
will
be
all
zeroes
.
...
...
@@ -96,10 +97,10 @@ spnwin_patch2: and %glob_tmp, 0xff, %glob_tmp
save
%
g0
,
%
g0
,
%
g0
!
Go
where
saving
will
occur
/
*
See
if
any
user
windows
are
active
in
the
set
.
*/
ld
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_uwinmask
],
%
twin_tmp
!
grab
win
mask
ld
[%
curptr
+
TI_UWINMASK
],
%
twin_tmp
!
grab
win
mask
orcc
%
g0
,
%
twin_tmp
,
%
g0
!
check
for
set
bits
bne
spwin_exist_uwins
!
yep
,
there
are
some
andn
%
twin_tmp
,
%
glob_tmp
,
%
twin_tmp
!
compute
new
umask
andn
%
twin_tmp
,
%
glob_tmp
,
%
twin_tmp
!
compute
new
u
win
mask
/
*
Save
into
the
window
which
must
be
saved
and
do
it
.
*
Basically
if
we
are
here
,
this
means
that
we
trapped
...
...
@@ -139,7 +140,7 @@ spwin_exist_uwins:
*
But
first
,
store
the
new
user
window
mask
calculated
*
above
.
*/
st
%
twin_tmp
,
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_uwinmask
]
st
%
twin_tmp
,
[%
curptr
+
TI_UWINMASK
]
save
%
g0
,
%
g0
,
%
g0
!
Go
to
where
the
saving
will
occur
spwin_fromuser
:
...
...
@@ -209,18 +210,20 @@ spwin_user_stack_is_bolixed:
bne
spwin_bad_ustack_from_kernel
nop
ld
[%
curptr
+
TI_TASK
],
%
glob_tmp
/
*
Oh
well
,
throw
this
one
window
into
the
per
-
task
window
*
buffer
,
the
first
one
.
*/
st
%
sp
,
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_rwbuf_stkptrs
]
STORE_WINDOW
(
curptr
+
AOFF_task_thread
+
AOFF_thread_reg_window
)
st
%
sp
,
[%
glob_tmp
+
AOFF_task_thread
+
AOFF_thread_rwbuf_stkptrs
]
STORE_WINDOW
(
glob_tmp
+
AOFF_task_thread
+
AOFF_thread_reg_window
)
restore
%
g0
,
%
g0
,
%
g0
/
*
LOCATION
:
Trap
Window
*/
/
*
Back
in
the
trap
window
,
update
winbuffer
save
count
.
*/
mov
1
,
%
glob
_tmp
st
%
glob_tmp
,
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_w_saved
]
mov
1
,
%
twin
_tmp
st
%
twin_tmp
,
[%
glob_tmp
+
AOFF_task_thread
+
AOFF_thread_w_saved
]
/
*
Compute
new
user
window
mask
.
What
we
are
basically
*
doing
is
taking
two
windows
,
the
invalid
one
at
trap
...
...
@@ -232,9 +235,9 @@ spwin_user_stack_is_bolixed:
or
%
twin_tmp
,
%
t_wim
,
%
twin_tmp
not
%
twin_tmp
spnwin_patch3
:
and
%
twin_tmp
,
0xff
,
%
twin_tmp
!
patched
on
7
win
Sparcs
st
%
twin_tmp
,
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_uwinmask
]
st
%
twin_tmp
,
[%
curptr
+
TI_UWINMASK
]
#define STACK_OFFSET (T
ASK_UNION
_SIZE - TRACEREG_SZ - REGWIN_SZ)
#define STACK_OFFSET (T
HREAD
_SIZE - TRACEREG_SZ - REGWIN_SZ)
sethi
%
hi
(
STACK_OFFSET
),
%
sp
or
%
sp
,
%
lo
(
STACK_OFFSET
),
%
sp
...
...
@@ -247,7 +250,7 @@ spnwin_patch3: and %twin_tmp, 0xff, %twin_tmp ! patched on 7win Sparcs
sethi
%
hi
(
STACK_OFFSET
),
%
g6
or
%
g6
,
%
lo
(
STACK_OFFSET
),
%
g6
sub
%
sp
,
%
g6
,
%
g6
sub
%
sp
,
%
g6
,
%
g6
!
curptr
/
*
Turn
on
traps
and
call
c
-
code
to
deal
with
it
.
*/
wr
%
t_psr
,
PSR_ET
,
%
psr
...
...
@@ -271,7 +274,8 @@ spwin_bad_ustack_from_kernel:
*
a
per
-
process
window
buffer
until
we
can
properly
handle
*
this
later
on
.
*/
SAVE_BOLIXED_USER_STACK
(
curptr
,
glob_tmp
)
ld
[%
curptr
+
TI_TASK
],
%
glob_tmp
/*
Using
curptr
one
last
time
*/
SAVE_BOLIXED_USER_STACK
(
glob_tmp
,
g6
)
/*
...
now
using
g6
as
scratch
*/
restore
%
g0
,
%
g0
,
%
g0
/
*
LOCATION
:
Trap
window
*/
...
...
arch/sparc/kernel/wuf.S
View file @
a662c5a3
...
...
@@ -13,6 +13,7 @@
#include <asm/asi.h>
#include <asm/winmacro.h>
#include <asm/asmmacro.h>
#include <asm/thread_info.h>
/*
Just
like
the
overflow
handler
we
define
macros
for
registers
*
with
fixed
meanings
in
this
routine
.
...
...
@@ -40,7 +41,7 @@
*
andcc
%
l0
,
PSR_PS
,
%
g0
*/
/
*
Datum
current
->
thread
.
uwinmask
contains
at
all
times
a
bitmask
/
*
Datum
current
_thread_info
->
uwinmask
contains
at
all
times
a
bitmask
*
where
if
any
user
windows
are
active
,
at
least
one
bit
will
*
be
set
in
to
mask
.
If
no
user
windows
are
active
,
the
bitmask
*
will
be
all
zeroes
.
...
...
@@ -138,7 +139,7 @@ fwin_from_user:
C_LABEL
(
fwin_mmu_patchme
):
b
C_LABEL
(
sun4c_fwin_stackchk
)
andcc
%
sp
,
0x7
,
%
g0
#define STACK_OFFSET (T
ASK_UNION
_SIZE - TRACEREG_SZ - REGWIN_SZ)
#define STACK_OFFSET (T
HREAD
_SIZE - TRACEREG_SZ - REGWIN_SZ)
fwin_user_stack_is_bolixed
:
/
*
LOCATION
:
Window
'W'
*/
...
...
@@ -184,8 +185,9 @@ fwin_user_stack_is_bolixed:
/
*
Fix
users
window
mask
and
buffer
save
count
.
*/
mov
0x1
,
%
g5
sll
%
g5
,
%
g3
,
%
g5
st
%
g5
,
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_uwinmask
]
!
one
live
user
window
still
st
%
g0
,
[%
curptr
+
AOFF_task_thread
+
AOFF_thread_w_saved
]
!
no
windows
in
the
buffer
st
%
g5
,
[%
curptr
+
TI_UWINMASK
]
!
one
live
user
window
still
ld
[%
curptr
+
TI_TASK
],
%
g5
st
%
g0
,
[%
g5
+
AOFF_task_thread
+
AOFF_thread_w_saved
]
!
no
windows
in
the
buffer
wr
%
t_psr
,
PSR_ET
,
%
psr
!
enable
traps
nop
...
...
arch/sparc/mm/btfixup.c
View file @
a662c5a3
...
...
@@ -15,6 +15,7 @@
#include <asm/pgtable.h>
#include <asm/oplib.h>
#include <asm/system.h>
#include <asm/cacheflush.h>
#define BTFIXUP_OPTIMIZE_NOP
#define BTFIXUP_OPTIMIZE_OTHER
...
...
arch/sparc/mm/fault.c
View file @
a662c5a3
...
...
@@ -138,8 +138,8 @@ static void unhandled_fault(unsigned long address, struct task_struct *tsk,
struct
pt_regs
*
regs
)
{
if
((
unsigned
long
)
address
<
PAGE_SIZE
)
{
printk
(
KERN_ALERT
"Unable to handle kernel NULL "
"pointer dereference
"
);
printk
(
KERN_ALERT
"Unable to handle kernel NULL pointer dereference
\n
"
);
}
else
{
printk
(
KERN_ALERT
"Unable to handle kernel paging request "
"at virtual address %08lx
\n
"
,
address
);
...
...
@@ -401,7 +401,7 @@ asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
{
extern
void
sun4c_update_mmu_cache
(
struct
vm_area_struct
*
,
unsigned
long
,
pte_t
);
extern
pte_t
*
sun4c_pte_offset
(
pmd_t
*
,
unsigned
long
);
extern
pte_t
*
sun4c_pte_offset
_kernel
(
pmd_t
*
,
unsigned
long
);
struct
task_struct
*
tsk
=
current
;
struct
mm_struct
*
mm
=
tsk
->
mm
;
pgd_t
*
pgdp
;
...
...
@@ -421,7 +421,7 @@ asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
}
pgdp
=
pgd_offset
(
mm
,
address
);
ptep
=
sun4c_pte_offset
((
pmd_t
*
)
pgdp
,
address
);
ptep
=
sun4c_pte_offset
_kernel
((
pmd_t
*
)
pgdp
,
address
);
if
(
pgd_val
(
*
pgdp
))
{
if
(
write
)
{
...
...
arch/sparc/mm/generic.c
View file @
a662c5a3
...
...
@@ -16,6 +16,7 @@
static
inline
void
forget_pte
(
pte_t
page
)
{
#if 0 /* old 2.4 code */
if (pte_none(page))
return;
if (pte_present(page)) {
...
...
@@ -30,6 +31,12 @@ static inline void forget_pte(pte_t page)
return;
}
swap_free(pte_to_swp_entry(page));
#else
if
(
!
pte_none
(
page
))
{
printk
(
"forget_pte: old mapping existed!
\n
"
);
BUG
();
}
#endif
}
/* Remap IO memory, the same way as remap_page_range(), but use
...
...
@@ -69,7 +76,7 @@ static inline int io_remap_pmd_range(pmd_t * pmd, unsigned long address, unsigne
end
=
PGDIR_SIZE
;
offset
-=
address
;
do
{
pte_t
*
pte
=
pte_alloc
(
current
->
mm
,
pmd
,
address
);
pte_t
*
pte
=
pte_alloc
_map
(
current
->
mm
,
pmd
,
address
);
if
(
!
pte
)
return
-
ENOMEM
;
io_remap_pte_range
(
pte
,
address
,
end
-
address
,
address
+
offset
,
prot
,
space
);
...
...
arch/sparc/mm/init.c
View file @
a662c5a3
...
...
@@ -32,6 +32,7 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/vaddrs.h>
#include <asm/pgalloc.h>
/* bug in asm-generic/tlb.h: check_pgt_cache */
#include <asm/tlb.h>
mmu_gather_t
mmu_gathers
[
NR_CPUS
];
...
...
@@ -60,7 +61,7 @@ pte_t *kmap_pte;
pgprot_t
kmap_prot
;
#define kmap_get_fixed_pte(vaddr) \
pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
pte_offset
_kernel
(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
void
__init
kmap_init
(
void
)
{
...
...
@@ -77,11 +78,13 @@ void show_mem(void)
nr_swap_pages
<<
(
PAGE_SHIFT
-
10
));
printk
(
"%ld pages of RAM
\n
"
,
totalram_pages
);
printk
(
"%d free pages
\n
"
,
nr_free_pages
());
#if 0 /* undefined pgtable_cache_size, pgd_cache_size */
printk("%ld pages in page table cache\n",pgtable_cache_size);
#ifndef CONFIG_SMP
if (sparc_cpu_model == sun4m || sparc_cpu_model == sun4d)
printk("%ld entries in page dir cache\n",pgd_cache_size);
#endif
#endif
}
extern
pgprot_t
protection_map
[
16
];
...
...
@@ -309,6 +312,23 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
return
max_pfn
;
}
/*
* check_pgt_cache
*
* This is called at the end of unmapping of VMA (zap_page_range),
* to rescan the page cache for architecture specific things,
* presumably something like sun4/sun4c PMEGs. Most architectures
* define check_pgt_cache empty.
*
* We simply copy the 2.4 implementation for now.
*/
int
pgt_cache_water
[
2
]
=
{
25
,
50
};
void
check_pgt_cache
(
void
)
{
do_check_pgt_cache
(
pgt_cache_water
[
0
],
pgt_cache_water
[
1
]);
}
/*
* paging_init() sets up the page tables: We call the MMU specific
* init routine based upon the Sun model type on the Sparc.
...
...
arch/sparc/mm/io-unit.c
View file @
a662c5a3
...
...
@@ -9,6 +9,9 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/highmem.h>
/* pte_offset_map => kmap_atomic */
#include <asm/scatterlist.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
...
...
@@ -17,6 +20,8 @@
#include <asm/io-unit.h>
#include <asm/mxcc.h>
#include <asm/bitops.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
/* #define IOUNIT_DEBUG */
#ifdef IOUNIT_DEBUG
...
...
@@ -188,7 +193,7 @@ static void iounit_map_dma_area(unsigned long va, __u32 addr, int len)
pgdp
=
pgd_offset
(
init_task
.
mm
,
addr
);
pmdp
=
pmd_offset
(
pgdp
,
addr
);
ptep
=
pte_offset
(
pmdp
,
addr
);
ptep
=
pte_offset
_map
(
pmdp
,
addr
);
set_pte
(
ptep
,
pte_val
(
mk_pte
(
virt_to_page
(
page
),
dvma_prot
)));
...
...
arch/sparc/mm/iommu.c
View file @
a662c5a3
/*
$Id: iommu.c,v 1.22 2001/12/17 07:05:09 davem Exp $
/*
* iommu.c: IOMMU specific routines for memory management.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1995
Pete Zaitcev
* Copyright (C) 1995
,2002 Pete Zaitcev (zaitcev@yahoo.com)
* Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
*/
...
...
@@ -12,6 +12,8 @@
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/highmem.h>
/* pte_offset_map => kmap_atomic */
#include <asm/scatterlist.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
...
...
@@ -19,6 +21,8 @@
#include <asm/io.h>
#include <asm/mxcc.h>
#include <asm/mbus.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
/* srmmu.c */
extern
int
viking_mxcc_present
;
...
...
@@ -245,7 +249,8 @@ static void iommu_map_dma_area(unsigned long va, __u32 addr, int len)
pgdp
=
pgd_offset
(
&
init_mm
,
addr
);
pmdp
=
pmd_offset
(
pgdp
,
addr
);
ptep
=
pte_offset
(
pmdp
,
addr
);
ptep
=
pte_offset_map
(
pmdp
,
addr
);
/* XXX What if we run out of atomic maps above */
set_pte
(
ptep
,
mk_pte
(
virt_to_page
(
page
),
dvma_prot
));
if
(
ipte_cache
!=
0
)
{
...
...
arch/sparc/mm/srmmu.c
View file @
a662c5a3
/*
$Id: srmmu.c,v 1.234 2001/12/21 04:56:15 davem Exp $
/*
* srmmu.c: SRMMU specific routines for memory management.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1995
Pete Zaitcev
* Copyright (C) 1995
,2002 Pete Zaitcev (zaitcev@yahoo.com)
* Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
* Copyright (C) 1999,2000 Anton Blanchard (anton@samba.org)
...
...
@@ -132,11 +132,32 @@ spinlock_t srmmu_nocache_spinlock;
static
inline
unsigned
long
srmmu_pgd_page
(
pgd_t
pgd
)
{
return
srmmu_device_memory
(
pgd_val
(
pgd
))
?~
0
:
(
unsigned
long
)
__nocache_va
((
pgd_val
(
pgd
)
&
SRMMU_PTD_PMASK
)
<<
4
);
}
static
inline
unsigned
long
srmmu_pmd_page
(
pmd_t
pmd
)
{
return
srmmu_device_memory
(
pmd_val
(
pmd
))
?~
0
:
(
unsigned
long
)
__nocache_va
((
pmd_val
(
pmd
)
&
SRMMU_PTD_PMASK
)
<<
4
);
}
static
inline
unsigned
long
srmmu_pmd_page_kernel
(
pmd_t
pmd
)
{
return
(
unsigned
long
)
__nocache_va
((
pmd_val
(
pmd
)
&
SRMMU_PTD_PMASK
)
<<
4
);
}
static
struct
page
*
srmmu_pmd_page
(
pmd_t
pmd
)
/* XXX inline later */
{
if
(
srmmu_device_memory
(
pmd_val
(
pmd
)))
{
/* XXX Anton obviously had something in mind when he did this.
* But what?
*/
/* return (struct page *)~0; */
BUG
();
/* NO WAY */
}
return
virt_to_page
(
srmmu_pmd_page_kernel
(
pmd
));
}
static
inline
struct
page
*
srmmu_pte_page
(
pte_t
pte
)
{
return
(
mem_map
+
(
unsigned
long
)(
srmmu_device_memory
(
pte_val
(
pte
))
?~
0
:
(((
pte_val
(
pte
)
&
SRMMU_PTE_PMASK
)
<<
4
)
>>
PAGE_SHIFT
)));
}
static
inline
unsigned
long
srmmu_pte_pfn
(
pte_t
pte
)
{
if
(
srmmu_device_memory
(
pte_val
(
pte
)))
BUG
();
return
(
unsigned
long
)
(((
pte_val
(
pte
)
&
SRMMU_PTE_PMASK
)
<<
4
)
>>
PAGE_SHIFT
);
}
static
inline
int
srmmu_pte_none
(
pte_t
pte
)
{
return
!
(
pte_val
(
pte
)
&
0xFFFFFFF
);
}
...
...
@@ -219,7 +240,16 @@ static inline void srmmu_pgd_set(pgd_t * pgdp, pmd_t * pmdp)
{
srmmu_set_pte
((
pte_t
*
)
pgdp
,
(
SRMMU_ET_PTD
|
(
__nocache_pa
((
unsigned
long
)
pmdp
)
>>
4
)));
}
static
inline
void
srmmu_pmd_set
(
pmd_t
*
pmdp
,
pte_t
*
ptep
)
{
srmmu_set_pte
((
pte_t
*
)
pmdp
,
(
SRMMU_ET_PTD
|
(
__nocache_pa
((
unsigned
long
)
ptep
)
>>
4
)));
}
{
srmmu_set_pte
((
pte_t
*
)
pmdp
,
(
SRMMU_ET_PTD
|
(
__nocache_pa
((
unsigned
long
)
ptep
)
>>
4
)));
}
static
inline
void
srmmu_pmd_populate
(
pmd_t
*
pmdp
,
struct
page
*
ptep
)
{
srmmu_set_pte
((
pte_t
*
)
pmdp
,
(
SRMMU_ET_PTD
|
(((
ptep
-
mem_map
)
<<
PAGE_SHIFT
)
>>
4
)));
}
static
inline
pte_t
srmmu_pte_modify
(
pte_t
pte
,
pgprot_t
newprot
)
{
return
__pte
((
pte_val
(
pte
)
&
SRMMU_CHG_MASK
)
|
pgprot_val
(
newprot
));
}
...
...
@@ -234,7 +264,13 @@ static inline pmd_t *srmmu_pmd_offset(pgd_t * dir, unsigned long address)
/* Find an entry in the third-level page table.. */
static
inline
pte_t
*
srmmu_pte_offset
(
pmd_t
*
dir
,
unsigned
long
address
)
{
return
(
pte_t
*
)
srmmu_pmd_page
(
*
dir
)
+
((
address
>>
PAGE_SHIFT
)
&
(
SRMMU_PTRS_PER_PTE
-
1
));
}
{
unsigned
long
pte
;
pte
=
srmmu_pmd_page_kernel
(
*
dir
);
return
(
pte_t
*
)
pte
+
((
address
>>
PAGE_SHIFT
)
&
(
SRMMU_PTRS_PER_PTE
-
1
));
}
unsigned
long
__srmmu_get_nocache
(
int
size
,
int
align
)
{
...
...
@@ -387,14 +423,14 @@ static void srmmu_free_pgd_fast(pgd_t *pgd)
srmmu_free_nocache
((
unsigned
long
)
pgd
,
SRMMU_PGD_TABLE_SIZE
);
}
static
pte_t
*
srmmu_pte_alloc_one_
fast
(
struct
mm_struct
*
mm
,
unsigned
long
address
)
static
pte_t
*
srmmu_pte_alloc_one_
kernel
(
struct
mm_struct
*
mm
,
unsigned
long
address
)
{
return
(
pte_t
*
)
srmmu_get_nocache
(
SRMMU_PTE_TABLE_SIZE
,
SRMMU_PTE_TABLE_SIZE
);
}
static
pte_t
*
srmmu_pte_alloc_one
(
struct
mm_struct
*
mm
,
unsigned
long
address
)
static
struct
page
*
srmmu_pte_alloc_one
(
struct
mm_struct
*
mm
,
unsigned
long
address
)
{
return
NULL
;
return
virt_to_page
(
srmmu_pte_alloc_one_kernel
(
mm
,
address
))
;
}
static
void
srmmu_free_pte_fast
(
pte_t
*
pte
)
...
...
@@ -402,6 +438,11 @@ static void srmmu_free_pte_fast(pte_t *pte)
srmmu_free_nocache
((
unsigned
long
)
pte
,
SRMMU_PTE_TABLE_SIZE
);
}
static
void
srmmu_pte_free
(
struct
page
*
pte
)
{
srmmu_free_nocache
((
unsigned
long
)
page_address
(
pte
),
SRMMU_PTE_TABLE_SIZE
);
}
static
pmd_t
*
srmmu_pmd_alloc_one_fast
(
struct
mm_struct
*
mm
,
unsigned
long
address
)
{
return
(
pmd_t
*
)
srmmu_get_nocache
(
SRMMU_PMD_TABLE_SIZE
,
SRMMU_PMD_TABLE_SIZE
);
...
...
@@ -517,19 +558,15 @@ void srmmu_unmapioaddr(unsigned long virt_addr)
* mappings on the kernel stack without any special code as we did
* need on the sun4c.
*/
struct
task_struct
*
srmmu_alloc_task_struct
(
void
)
{
return
(
struct
task_struct
*
)
__get_free_pages
(
GFP_KERNEL
,
1
);
}
static
void
srmmu_free_task_struct
(
struct
task_struct
*
tsk
)
struct
thread_info
*
srmmu_alloc_thread_info
(
void
)
{
free_pages
((
unsigned
long
)
tsk
,
1
);
return
(
struct
thread_info
*
)
__get_free_pages
(
GFP_KERNEL
,
THREAD_INFO_ORDER
);
}
static
void
srmmu_
get_task_struct
(
struct
task_struct
*
tsk
)
static
void
srmmu_
free_thread_info
(
struct
thread_info
*
ti
)
{
atomic_inc
(
&
virt_to_page
(
tsk
)
->
count
);
free_pages
((
unsigned
long
)
ti
,
THREAD_INFO_ORDER
);
}
/* tsunami.S */
...
...
@@ -1170,8 +1207,8 @@ void __init srmmu_paging_init(void)
srmmu_allocate_ptable_skeleton
(
PKMAP_BASE
,
PKMAP_BASE_END
);
pgd
=
pgd_offset_k
(
PKMAP_BASE
);
pmd
=
pmd_offset
(
pgd
,
PKMAP_BASE
);
pte
=
pte_offset
(
pmd
,
PKMAP_BASE
);
pmd
=
srmmu_
pmd_offset
(
pgd
,
PKMAP_BASE
);
pte
=
srmmu_
pte_offset
(
pmd
,
PKMAP_BASE
);
pkmap_page_table
=
pte
;
flush_cache_all
();
...
...
@@ -1209,6 +1246,10 @@ void __init srmmu_paging_init(void)
free_area_init_node
(
0
,
NULL
,
NULL
,
zones_size
,
phys_base
,
zholes_size
);
}
/* P3: easy to fix, todo. Current code is utterly broken, though. */
if
(
phys_base
!=
0
)
panic
(
"phys_base nonzero"
);
}
static
void
srmmu_mmu_info
(
struct
seq_file
*
m
)
...
...
@@ -1282,7 +1323,7 @@ static void __init init_vac_layout(void)
if
(
vac_line_size
<
min_line_size
)
min_line_size
=
vac_line_size
;
cpu
++
;
if
(
cpu
==
smp_num_cpus
)
if
(
cpu
>=
NR_CPUS
||
!
cpu_online
(
cpu
)
)
break
;
#else
break
;
...
...
@@ -1944,9 +1985,8 @@ static void __init get_srmmu_type(void)
}
/* dont laugh, static pagetables */
static
int
srmmu_check_pgt_cache
(
int
low
,
int
high
)
static
void
srmmu_check_pgt_cache
(
int
low
,
int
high
)
{
return
0
;
}
extern
unsigned
long
spwin_mmu_patchme
,
fwin_mmu_patchme
,
...
...
@@ -2017,16 +2057,16 @@ void __init ld_mmu_srmmu(void)
#ifndef CONFIG_SMP
BTFIXUPSET_CALL
(
___xchg32
,
___xchg32_sun4md
,
BTFIXUPCALL_SWAPG1G2
);
#endif
BTFIXUPSET_CALL
(
do_check_pgt_cache
,
srmmu_check_pgt_cache
,
BTFIXUPCALL_NO
RM
);
BTFIXUPSET_CALL
(
do_check_pgt_cache
,
srmmu_check_pgt_cache
,
BTFIXUPCALL_NO
P
);
BTFIXUPSET_CALL
(
set_pte
,
srmmu_set_pte
,
BTFIXUPCALL_SWAPO0O1
);
BTFIXUPSET_CALL
(
switch_mm
,
srmmu_switch_mm
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_p
age
,
srmmu_pte_page
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_p
fn
,
srmmu_pte_pfn
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pmd_page
,
srmmu_pmd_page
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pgd_page
,
srmmu_pgd_page
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_SETHI
(
none_mask
,
0xF0000000
);
/* XXX P3: is it used? */
BTFIXUPSET_SETHI
(
none_mask
,
0xF0000000
);
BTFIXUPSET_CALL
(
pte_present
,
srmmu_pte_present
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_clear
,
srmmu_pte_clear
,
BTFIXUPCALL_SWAPO0G0
);
...
...
@@ -2041,16 +2081,18 @@ void __init ld_mmu_srmmu(void)
BTFIXUPSET_CALL
(
pgd_clear
,
srmmu_pgd_clear
,
BTFIXUPCALL_SWAPO0G0
);
BTFIXUPSET_CALL
(
mk_pte
,
srmmu_mk_pte
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pfn_pte
,
srmmu_pfn_pte
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
mk_pte_phys
,
srmmu_mk_pte_phys
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
mk_pte_io
,
srmmu_mk_pte_io
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pgd_set
,
srmmu_pgd_set
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pmd_set
,
srmmu_pmd_set
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pmd_populate
,
srmmu_pmd_populate
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_INT
(
pte_modify_mask
,
SRMMU_CHG_MASK
);
BTFIXUPSET_CALL
(
pmd_offset
,
srmmu_pmd_offset
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_offset
,
srmmu_pte_offset
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_offset
_kernel
,
srmmu_pte_offset
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
free_pte_fast
,
srmmu_free_pte_fast
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_alloc_one_fast
,
srmmu_pte_alloc_one_fast
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_free
,
srmmu_pte_free
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_alloc_one_kernel
,
srmmu_pte_alloc_one_kernel
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_alloc_one
,
srmmu_pte_alloc_one
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
free_pmd_fast
,
srmmu_free_pmd_fast
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pmd_alloc_one_fast
,
srmmu_pmd_alloc_one_fast
,
BTFIXUPCALL_NORM
);
...
...
@@ -2071,10 +2113,8 @@ void __init ld_mmu_srmmu(void)
BTFIXUPSET_CALL
(
mmu_info
,
srmmu_mmu_info
,
BTFIXUPCALL_NORM
);
/* Task struct and kernel stack allocating/freeing. */
BTFIXUPSET_CALL
(
alloc_task_struct
,
srmmu_alloc_task_struct
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
free_task_struct
,
srmmu_free_task_struct
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
get_task_struct
,
srmmu_get_task_struct
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
alloc_thread_info
,
srmmu_alloc_thread_info
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
free_thread_info
,
srmmu_free_thread_info
,
BTFIXUPCALL_NORM
);
get_srmmu_type
();
patch_window_trap_handlers
();
...
...
arch/sparc/mm/sun4c.c
View file @
a662c5a3
...
...
@@ -36,6 +36,8 @@
#include <asm/sun4paddr.h>
#include <asm/highmem.h>
#include <asm/btfixup.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
/* Because of our dynamic kernel TLB miss strategy, and how
* our DVMA mapping allocation works, you _MUST_:
...
...
@@ -43,7 +45,7 @@
* 1) Disable interrupts _and_ not touch any dynamic kernel
* memory while messing with kernel MMU state. By
* dynamic memory I mean any object which is not in
* the kernel image itself or a t
ask_struct
(both of
* the kernel image itself or a t
hread_union
(both of
* which are locked into the MMU).
* 2) Disable interrupts while messing with user MMU state.
*/
...
...
@@ -1015,27 +1017,21 @@ static inline void garbage_collect(int entry)
free_locked_segment
(
BUCKET_ADDR
(
entry
));
}
#ifdef CONFIG_SUN4
#define TASK_STRUCT_ORDER 0
#else
#define TASK_STRUCT_ORDER 1
#endif
static
struct
task_struct
*
sun4c_alloc_task_struct
(
void
)
static
struct
thread_info
*
sun4c_alloc_thread_info
(
void
)
{
unsigned
long
addr
,
pages
;
int
entry
;
pages
=
__get_free_pages
(
GFP_KERNEL
,
T
ASK_STRUCT
_ORDER
);
pages
=
__get_free_pages
(
GFP_KERNEL
,
T
HREAD_INFO
_ORDER
);
if
(
!
pages
)
return
(
struct
task_struct
*
)
0
;
return
NULL
;
for
(
entry
=
sun4c_lowbucket_avail
;
entry
<
NR_TASK_BUCKETS
;
entry
++
)
if
(
sun4c_bucket
[
entry
]
==
BUCKET_EMPTY
)
break
;
if
(
entry
==
NR_TASK_BUCKETS
)
{
free_pages
(
pages
,
T
ASK_STRUCT
_ORDER
);
return
(
struct
task_struct
*
)
0
;
free_pages
(
pages
,
T
HREAD_INFO
_ORDER
);
return
NULL
;
}
if
(
entry
>=
sun4c_lowbucket_avail
)
sun4c_lowbucket_avail
=
entry
+
1
;
...
...
@@ -1057,46 +1053,43 @@ static struct task_struct *sun4c_alloc_task_struct(void)
#ifndef CONFIG_SUN4
sun4c_put_pte
(
addr
+
PAGE_SIZE
,
BUCKET_PTE
(
pages
+
PAGE_SIZE
));
#endif
return
(
struct
t
ask_struct
*
)
addr
;
return
(
struct
t
hread_info
*
)
addr
;
}
static
void
sun4c_free_t
ask_struct
(
struct
task_struct
*
tsk
)
static
void
sun4c_free_t
hread_info
(
struct
thread_info
*
ti
)
{
unsigned
long
t
saddr
=
(
unsigned
long
)
tsk
;
unsigned
long
pages
=
BUCKET_PTE_PAGE
(
sun4c_get_pte
(
t
s
addr
));
int
entry
=
BUCKET_NUM
(
t
s
addr
);
unsigned
long
t
iaddr
=
(
unsigned
long
)
ti
;
unsigned
long
pages
=
BUCKET_PTE_PAGE
(
sun4c_get_pte
(
t
i
addr
));
int
entry
=
BUCKET_NUM
(
t
i
addr
);
if
(
atomic_dec_and_test
(
&
(
tsk
)
->
thread
.
refcount
))
{
if
(
atomic_dec_and_test
(
&
ti
->
task
->
thread
.
refcount
))
{
/* We are deleting a mapping, so the flush here is mandatory. */
sun4c_flush_page
(
t
s
addr
);
sun4c_flush_page
(
t
i
addr
);
#ifndef CONFIG_SUN4
sun4c_flush_page
(
t
s
addr
+
PAGE_SIZE
);
sun4c_flush_page
(
t
i
addr
+
PAGE_SIZE
);
#endif
sun4c_put_pte
(
t
s
addr
,
0
);
sun4c_put_pte
(
t
i
addr
,
0
);
#ifndef CONFIG_SUN4
sun4c_put_pte
(
t
s
addr
+
PAGE_SIZE
,
0
);
sun4c_put_pte
(
t
i
addr
+
PAGE_SIZE
,
0
);
#endif
sun4c_bucket
[
entry
]
=
BUCKET_EMPTY
;
if
(
entry
<
sun4c_lowbucket_avail
)
sun4c_lowbucket_avail
=
entry
;
free_pages
(
pages
,
T
ASK_STRUCT
_ORDER
);
free_pages
(
pages
,
T
HREAD_INFO
_ORDER
);
garbage_collect
(
entry
);
}
}
static
void
sun4c_get_task_struct
(
struct
task_struct
*
tsk
)
{
atomic_inc
(
&
(
tsk
)
->
thread
.
refcount
);
}
static
void
__init
sun4c_init_buckets
(
void
)
{
int
entry
;
if
(
sizeof
(
union
task_union
)
!=
(
PAGE_SIZE
<<
TASK_STRUCT_ORDER
))
{
prom_printf
(
"task union not %d page(s)!
\n
"
,
1
<<
TASK_STRUCT_ORDER
);
if
(
sizeof
(
union
thread_union
)
!=
(
PAGE_SIZE
<<
THREAD_INFO_ORDER
))
{
extern
void
thread_info_size_is_bolixed_pete
(
void
);
thread_info_size_is_bolixed_pete
();
}
for
(
entry
=
0
;
entry
<
NR_TASK_BUCKETS
;
entry
++
)
sun4c_bucket
[
entry
]
=
BUCKET_EMPTY
;
sun4c_lowbucket_avail
=
0
;
...
...
@@ -1375,7 +1368,7 @@ static void sun4c_flush_cache_mm(struct mm_struct *mm)
}
}
static
void
sun4c_flush_cache_range
_sw
(
struct
vm_area_struct
*
vma
,
unsigned
long
start
,
unsigned
long
end
)
static
void
sun4c_flush_cache_range
(
struct
vm_area_struct
*
vma
,
unsigned
long
start
,
unsigned
long
end
)
{
struct
mm_struct
*
mm
=
vma
->
vm_mm
;
int
new_ctx
=
mm
->
context
;
...
...
@@ -1530,7 +1523,7 @@ static void sun4c_flush_tlb_mm(struct mm_struct *mm)
}
}
static
void
sun4c_flush_tlb_range
_sw
(
struct
vm_area_struct
*
vma
,
unsigned
long
start
,
unsigned
long
end
)
static
void
sun4c_flush_tlb_range
(
struct
vm_area_struct
*
vma
,
unsigned
long
start
,
unsigned
long
end
)
{
struct
mm_struct
*
mm
=
vma
->
vm_mm
;
int
new_ctx
=
mm
->
context
;
...
...
@@ -1720,6 +1713,12 @@ static void sun4c_pmd_set(pmd_t * pmdp, pte_t * ptep)
*
pmdp
=
__pmd
(
PGD_TABLE
|
(
unsigned
long
)
ptep
);
}
static
void
sun4c_pmd_populate
(
pmd_t
*
pmdp
,
struct
page
*
ptep
)
{
if
(
page_address
(
ptep
)
==
NULL
)
BUG
();
/* No highmem on sun4c */
*
pmdp
=
__pmd
(
PGD_TABLE
|
(
unsigned
long
)
page_address
(
ptep
));
}
static
int
sun4c_pte_present
(
pte_t
pte
)
{
return
((
pte_val
(
pte
)
&
(
_SUN4C_PAGE_PRESENT
|
_SUN4C_PAGE_PRIV
))
!=
0
);
...
...
@@ -1790,16 +1789,21 @@ static pte_t sun4c_mk_pte_io(unsigned long page, pgprot_t pgprot, int space)
return
__pte
(((
page
-
PAGE_OFFSET
)
>>
PAGE_SHIFT
)
|
pgprot_val
(
pgprot
));
}
static
struct
page
*
sun4c_pte_page
(
pte_t
pte
)
static
unsigned
long
sun4c_pte_pfn
(
pte_t
pte
)
{
return
(
mem_map
+
(
unsigned
long
)(
pte_val
(
pte
)
&
SUN4C_PFN_MASK
)
);
return
(
unsigned
long
)(
pte_val
(
pte
)
&
SUN4C_PFN_MASK
);
}
static
inline
unsigned
long
sun4c_pmd_page
(
pmd_t
pmd
)
static
__inline__
unsigned
long
sun4c_pmd_page_v
(
pmd_t
pmd
)
{
return
(
pmd_val
(
pmd
)
&
PAGE_MASK
);
}
static
struct
page
*
sun4c_pmd_page
(
pmd_t
pmd
)
{
return
virt_to_page
(
sun4c_pmd_page_v
(
pmd
));
}
static
unsigned
long
sun4c_pgd_page
(
pgd_t
pgd
)
{
return
0
;
}
/* to find an entry in a page-table-directory */
...
...
@@ -1815,9 +1819,10 @@ static pmd_t *sun4c_pmd_offset(pgd_t * dir, unsigned long address)
}
/* Find an entry in the third-level page table.. */
pte_t
*
sun4c_pte_offset
(
pmd_t
*
dir
,
unsigned
long
address
)
pte_t
*
sun4c_pte_offset
_kernel
(
pmd_t
*
dir
,
unsigned
long
address
)
{
return
(
pte_t
*
)
sun4c_pmd_page
(
*
dir
)
+
((
address
>>
PAGE_SHIFT
)
&
(
SUN4C_PTRS_PER_PTE
-
1
));
return
(
pte_t
*
)
sun4c_pmd_page_v
(
*
dir
)
+
((
address
>>
PAGE_SHIFT
)
&
(
SUN4C_PTRS_PER_PTE
-
1
));
}
static
void
sun4c_free_pte_slow
(
pte_t
*
pte
)
...
...
@@ -1857,15 +1862,9 @@ static void sun4c_free_pgd_fast(pgd_t *pgd)
pgtable_cache_size
++
;
}
static
pte_t
*
sun4c_pte_alloc_one
(
struct
mm_struct
*
mm
,
unsigned
long
address
)
{
pte_t
*
pte
=
(
pte_t
*
)
__get_free_page
(
GFP_KERNEL
);
if
(
pte
)
memset
(
pte
,
0
,
PAGE_SIZE
);
return
pte
;
}
pte_t
*
sun4c_pte_alloc_one_fast
(
struct
mm_struct
*
mm
,
unsigned
long
address
)
static
__inline__
pte_t
*
sun4c_pte_alloc_one_fast
(
struct
mm_struct
*
mm
,
unsigned
long
address
)
{
unsigned
long
*
ret
;
...
...
@@ -1877,6 +1876,27 @@ pte_t *sun4c_pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
return
(
pte_t
*
)
ret
;
}
static
pte_t
*
sun4c_pte_alloc_one_kernel
(
struct
mm_struct
*
mm
,
unsigned
long
address
)
{
pte_t
*
pte
;
if
((
pte
=
sun4c_pte_alloc_one_fast
(
mm
,
address
))
!=
NULL
)
return
pte
;
pte
=
(
pte_t
*
)
__get_free_page
(
GFP_KERNEL
);
if
(
pte
)
memset
(
pte
,
0
,
PAGE_SIZE
);
return
pte
;
}
static
struct
page
*
sun4c_pte_alloc_one
(
struct
mm_struct
*
mm
,
unsigned
long
address
)
{
pte_t
*
pte
=
sun4c_pte_alloc_one_kernel
(
mm
,
address
);
if
(
pte
==
NULL
)
return
NULL
;
return
virt_to_page
(
pte
);
}
static
__inline__
void
sun4c_free_pte_fast
(
pte_t
*
pte
)
{
*
(
unsigned
long
*
)
pte
=
(
unsigned
long
)
pte_quicklist
;
...
...
@@ -1884,6 +1904,11 @@ static __inline__ void sun4c_free_pte_fast(pte_t *pte)
pgtable_cache_size
++
;
}
static
void
sun4c_pte_free
(
struct
page
*
pte
)
{
sun4c_free_pte_fast
(
page_address
(
pte
));
}
/*
* allocating and freeing a pmd is trivial: the 1-entry pmd is
* inside the pgd, so has no extra memory associated with it.
...
...
@@ -1896,18 +1921,16 @@ static pmd_t *sun4c_pmd_alloc_one_fast(struct mm_struct *mm, unsigned long addre
static
void
sun4c_free_pmd_fast
(
pmd_t
*
pmd
)
{
}
static
int
sun4c_check_pgt_cache
(
int
low
,
int
high
)
static
void
sun4c_check_pgt_cache
(
int
low
,
int
high
)
{
int
freed
=
0
;
if
(
pgtable_cache_size
>
high
)
{
do
{
if
(
pgd_quicklist
)
sun4c_free_pgd_slow
(
sun4c_get_pgd_fast
())
,
freed
++
;
sun4c_free_pgd_slow
(
sun4c_get_pgd_fast
());
if
(
pte_quicklist
)
sun4c_free_pte_slow
(
sun4c_pte_alloc_one_fast
(
NULL
,
0
))
,
freed
++
;
sun4c_free_pte_slow
(
sun4c_pte_alloc_one_fast
(
NULL
,
0
));
}
while
(
pgtable_cache_size
>
low
);
}
return
freed
;
}
/* An experiment, turn off by default for now... -DaveM */
...
...
@@ -1937,7 +1960,7 @@ void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, p
if
(
!
pgdp
)
goto
no_mapping
;
ptep
=
sun4c_pte_offset
((
pmd_t
*
)
pgdp
,
start
);
ptep
=
sun4c_pte_offset
_kernel
((
pmd_t
*
)
pgdp
,
start
);
if
(
!
ptep
||
!
(
pte_val
(
*
ptep
)
&
_SUN4C_PAGE_PRESENT
))
goto
no_mapping
;
sun4c_put_pte
(
start
,
pte_val
(
*
ptep
));
...
...
@@ -2110,7 +2133,6 @@ void __init ld_mmu_sun4c(void)
BTFIXUPSET_CALL
(
flush_tlb_page
,
sun4c_flush_tlb_page
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
flush_tlb_range
,
sun4c_flush_tlb_range
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
flush_cache_range
,
sun4c_flush_cache_range
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
free_task_struct
,
sun4c_free_task_struct
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
__flush_page_to_ram
,
sun4c_flush_page_to_ram
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
flush_tlb_all
,
sun4c_flush_tlb_all
,
BTFIXUPCALL_NORM
);
...
...
@@ -2118,13 +2140,17 @@ void __init ld_mmu_sun4c(void)
BTFIXUPSET_CALL
(
set_pte
,
sun4c_set_pte
,
BTFIXUPCALL_STO1O0
);
BTFIXUPSET_CALL
(
pte_page
,
sun4c_pte_page
,
BTFIXUPCALL_NORM
);
#if PAGE_SHIFT <= 12
/* The 2.4.18 code does not set this on sun4c, how does it work? XXX */
/* BTFIXUPSET_SETHI(none_mask, 0x00000000); */
/* Defaults to zero? */
BTFIXUPSET_CALL
(
pte_pfn
,
sun4c_pte_pfn
,
BTFIXUPCALL_NORM
);
#if 0 /* PAGE_SHIFT <= 12 */ /* Eek. Investigate. XXX */
BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_ANDNINT(PAGE_SIZE - 1));
#else
BTFIXUPSET_CALL
(
pmd_page
,
sun4c_pmd_page
,
BTFIXUPCALL_NORM
);
#endif
BTFIXUPSET_CALL
(
pmd_set
,
sun4c_pmd_set
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pmd_populate
,
sun4c_pmd_populate
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_present
,
sun4c_pte_present
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_clear
,
sun4c_pte_clear
,
BTFIXUPCALL_STG0O0
);
...
...
@@ -2139,15 +2165,16 @@ void __init ld_mmu_sun4c(void)
BTFIXUPSET_CALL
(
pgd_clear
,
sun4c_pgd_clear
,
BTFIXUPCALL_NOP
);
BTFIXUPSET_CALL
(
mk_pte
,
sun4c_mk_pte
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pfn_pte
,
sun4c_pfn_pte
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
mk_pte_phys
,
sun4c_mk_pte_phys
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
mk_pte_io
,
sun4c_mk_pte_io
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_INT
(
pte_modify_mask
,
_SUN4C_PAGE_CHG_MASK
);
BTFIXUPSET_CALL
(
pmd_offset
,
sun4c_pmd_offset
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_offset
,
sun4c_pte_offset
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_offset
_kernel
,
sun4c_pte_offset_kernel
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
free_pte_fast
,
sun4c_free_pte_fast
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_free
,
sun4c_pte_free
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_alloc_one_kernel
,
sun4c_pte_alloc_one_kernel
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_alloc_one
,
sun4c_pte_alloc_one
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
pte_alloc_one_fast
,
sun4c_pte_alloc_one_fast
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
free_pmd_fast
,
sun4c_free_pmd_fast
,
BTFIXUPCALL_NOP
);
BTFIXUPSET_CALL
(
pmd_alloc_one_fast
,
sun4c_pmd_alloc_one_fast
,
BTFIXUPCALL_RETO0
);
BTFIXUPSET_CALL
(
free_pgd_fast
,
sun4c_free_pgd_fast
,
BTFIXUPCALL_NORM
);
...
...
@@ -2176,9 +2203,8 @@ void __init ld_mmu_sun4c(void)
BTFIXUPSET_CALL
(
mmu_unmap_dma_area
,
sun4c_unmap_dma_area
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
mmu_translate_dvma
,
sun4c_translate_dvma
,
BTFIXUPCALL_NORM
);
/* Task struct and kernel stack allocating/freeing. */
BTFIXUPSET_CALL
(
alloc_task_struct
,
sun4c_alloc_task_struct
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
get_task_struct
,
sun4c_get_task_struct
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
alloc_thread_info
,
sun4c_alloc_thread_info
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
free_thread_info
,
sun4c_free_thread_info
,
BTFIXUPCALL_NORM
);
BTFIXUPSET_CALL
(
mmu_info
,
sun4c_mmu_info
,
BTFIXUPCALL_NORM
);
...
...
drivers/sbus/sbus.c
View file @
a662c5a3
...
...
@@ -16,6 +16,7 @@
#include <asm/oplib.h>
#include <asm/bpp.h>
#include <asm/irq.h>
#include <asm/pcic.h>
/* pcic_present */
struct
sbus_bus
*
sbus_root
=
NULL
;
...
...
@@ -334,7 +335,7 @@ static int __init sbus_init(void)
(
nd
=
prom_getchild
(
iommund
))
==
0
||
(
nd
=
prom_searchsiblings
(
nd
,
"sbus"
))
==
0
)
{
#ifdef CONFIG_PCI
if
(
!
pci
bios_present
())
{
if
(
!
pci
c_present
())
{
prom_printf
(
"Neither SBUS nor PCI found.
\n
"
);
prom_halt
();
}
...
...
include/asm-sparc/bitops.h
View file @
a662c5a3
...
...
@@ -207,12 +207,74 @@ static __inline__ unsigned long ffz(unsigned long word)
return
result
;
}
/**
* __ffs - find first bit in word.
* @word: The word to search
*
* Undefined if no bit exists, so code should check against 0 first.
*/
static
__inline__
int
__ffs
(
unsigned
long
word
)
{
int
num
=
0
;
if
((
word
&
0xffff
)
==
0
)
{
num
+=
16
;
word
>>=
16
;
}
if
((
word
&
0xff
)
==
0
)
{
num
+=
8
;
word
>>=
8
;
}
if
((
word
&
0xf
)
==
0
)
{
num
+=
4
;
word
>>=
4
;
}
if
((
word
&
0x3
)
==
0
)
{
num
+=
2
;
word
>>=
2
;
}
if
((
word
&
0x1
)
==
0
)
num
+=
1
;
return
num
;
}
/*
* Every architecture must define this function. It's the fastest
* way of searching a 140-bit bitmap where the first 100 bits are
* unlikely to be set. It's guaranteed that at least one of the 140
* bits is cleared.
*/
static
__inline__
int
sched_find_first_bit
(
unsigned
long
*
b
)
{
if
(
unlikely
(
b
[
0
]))
return
__ffs
(
b
[
0
]);
if
(
unlikely
(
b
[
1
]))
return
__ffs
(
b
[
1
])
+
32
;
if
(
unlikely
(
b
[
2
]))
return
__ffs
(
b
[
2
])
+
64
;
if
(
b
[
3
])
return
__ffs
(
b
[
3
])
+
96
;
return
__ffs
(
b
[
4
])
+
128
;
}
/*
* ffs: find first bit set. This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
#define ffs(x) generic_ffs(x)
static
__inline__
int
ffs
(
int
x
)
{
if
(
!
x
)
return
0
;
return
__ffs
((
unsigned
long
)
x
);
}
/*
* fls: find last (most-significant) bit set.
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
*/
#define fls(x) generic_fls(x)
/*
* hweightN: returns the hamming weight (i.e. the number
...
...
@@ -272,6 +334,34 @@ static __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long siz
#define find_first_zero_bit(addr, size) \
find_next_zero_bit((addr), (size), 0)
/**
* find_next_bit - find the first set bit in a memory region
* @addr: The address to base the search on
* @offset: The bitnumber to start searching at
* @size: The maximum size to search
*
* Scheduler induced bitop, do not use.
*/
static
__inline__
int
find_next_bit
(
unsigned
long
*
addr
,
int
size
,
int
offset
)
{
unsigned
long
*
p
=
addr
+
(
offset
>>
5
);
int
num
=
offset
&
~
0x1f
;
unsigned
long
word
;
word
=
*
p
++
;
word
&=
~
((
1
<<
(
offset
&
0x1f
))
-
1
);
while
(
num
<
size
)
{
if
(
word
!=
0
)
{
return
__ffs
(
word
)
+
num
;
}
word
=
*
p
++
;
num
+=
0x20
;
}
return
num
;
}
/*
*/
static
__inline__
int
test_le_bit
(
int
nr
,
__const__
void
*
addr
)
{
__const__
unsigned
char
*
ADDR
=
(
__const__
unsigned
char
*
)
addr
;
...
...
include/asm-sparc/cacheflush.h
0 → 100644
View file @
a662c5a3
#ifndef _SPARC_CACHEFLUSH_H
#define _SPARC_CACHEFLUSH_H
#include <linux/config.h>
#include <linux/mm.h>
/* Common for other includes */
// #include <linux/kernel.h> from pgalloc.h
// #include <linux/sched.h> from pgalloc.h
// #include <asm/page.h>
#include <asm/btfixup.h>
/*
* Fine grained cache flushing.
*/
#ifdef CONFIG_SMP
BTFIXUPDEF_CALL
(
void
,
local_flush_cache_all
,
void
)
BTFIXUPDEF_CALL
(
void
,
local_flush_cache_mm
,
struct
mm_struct
*
)
BTFIXUPDEF_CALL
(
void
,
local_flush_cache_range
,
struct
vm_area_struct
*
,
unsigned
long
,
unsigned
long
)
BTFIXUPDEF_CALL
(
void
,
local_flush_cache_page
,
struct
vm_area_struct
*
,
unsigned
long
)
#define local_flush_cache_all() BTFIXUP_CALL(local_flush_cache_all)()
#define local_flush_cache_mm(mm) BTFIXUP_CALL(local_flush_cache_mm)(mm)
#define local_flush_cache_range(vma,start,end) BTFIXUP_CALL(local_flush_cache_range)(vma,start,end)
#define local_flush_cache_page(vma,addr) BTFIXUP_CALL(local_flush_cache_page)(vma,addr)
BTFIXUPDEF_CALL
(
void
,
local_flush_page_to_ram
,
unsigned
long
)
BTFIXUPDEF_CALL
(
void
,
local_flush_sig_insns
,
struct
mm_struct
*
,
unsigned
long
)
#define local_flush_page_to_ram(addr) BTFIXUP_CALL(local_flush_page_to_ram)(addr)
#define local_flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(local_flush_sig_insns)(mm,insn_addr)
extern
void
smp_flush_cache_all
(
void
);
extern
void
smp_flush_cache_mm
(
struct
mm_struct
*
mm
);
extern
void
smp_flush_cache_range
(
struct
vm_area_struct
*
vma
,
unsigned
long
start
,
unsigned
long
end
);
extern
void
smp_flush_cache_page
(
struct
vm_area_struct
*
vma
,
unsigned
long
page
);
extern
void
smp_flush_page_to_ram
(
unsigned
long
page
);
extern
void
smp_flush_sig_insns
(
struct
mm_struct
*
mm
,
unsigned
long
insn_addr
);
#endif
/* CONFIG_SMP */
BTFIXUPDEF_CALL
(
void
,
flush_cache_all
,
void
)
BTFIXUPDEF_CALL
(
void
,
flush_cache_mm
,
struct
mm_struct
*
)
BTFIXUPDEF_CALL
(
void
,
flush_cache_range
,
struct
vm_area_struct
*
,
unsigned
long
,
unsigned
long
)
BTFIXUPDEF_CALL
(
void
,
flush_cache_page
,
struct
vm_area_struct
*
,
unsigned
long
)
#define flush_cache_all() BTFIXUP_CALL(flush_cache_all)()
#define flush_cache_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
#define flush_cache_range(vma,start,end) BTFIXUP_CALL(flush_cache_range)(vma,start,end)
#define flush_cache_page(vma,addr) BTFIXUP_CALL(flush_cache_page)(vma,addr)
#define flush_icache_range(start, end) do { } while (0)
#define flush_icache_page(vma, pg) do { } while (0)
#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
BTFIXUPDEF_CALL
(
void
,
__flush_page_to_ram
,
unsigned
long
)
BTFIXUPDEF_CALL
(
void
,
flush_sig_insns
,
struct
mm_struct
*
,
unsigned
long
)
#define __flush_page_to_ram(addr) BTFIXUP_CALL(__flush_page_to_ram)(addr)
#define flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(flush_sig_insns)(mm,insn_addr)
extern
void
flush_page_to_ram
(
struct
page
*
page
);
#define flush_dcache_page(page) do { } while (0)
#endif
/* _SPARC_CACHEFLUSH_H */
include/asm-sparc/current.h
View file @
a662c5a3
#ifndef _SPARC_CURRENT_H
#define _SPARC_CURRENT_H
/*
* include/asm-sparc/current.h
*
* Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Copyright (C) 2002 Pete Zaitcev (zaitcev@yahoo.com)
*
* Derived from "include/asm-s390/current.h" by
* Martin Schwidefsky (schwidefsky@de.ibm.com)
* Derived from "include/asm-i386/current.h"
*/
#ifndef _ASM_CURRENT_H
#define _ASM_CURRENT_H
/* Sparc rules... */
register
struct
task_struct
*
current
asm
(
"g6"
);
/*
* At the sparc64 DaveM keeps current_thread_info in %g4.
* We might want to consider doing the same to shave a few cycles.
*/
#endif
/* !(_SPARC_CURRENT_H) */
// Applications do not include kernel headers anymore, period.
// #ifdef __KERNEL__
#ifndef _ASM_THREAD_INFO_H
#include <asm/thread_info.h>
#endif
struct
task_struct
;
/* Two stage process (inline + #define) for type-checking. */
/* We also obfuscate get_current() to check if anyone used that by mistake. */
static
inline
struct
task_struct
*
__get_current
(
void
)
{
return
current_thread_info
()
->
task
;
}
#define current __get_current()
// #endif /* __KERNEL__ */
#endif
/* !(_ASM_CURRENT_H) */
include/asm-sparc/elf.h
View file @
a662c5a3
...
...
@@ -41,7 +41,7 @@ do { unsigned long *dest = &(__elf_regs[0]); \
dest[34] = src->npc; \
dest[35] = src->y; \
dest[36] = dest[37] = 0;
/* XXX */
\
} while(0)
} while(0)
;
/* Janitors: Don't touch this colon. */
typedef
struct
{
union
{
...
...
include/asm-sparc/highmem.h
View file @
a662c5a3
...
...
@@ -25,6 +25,8 @@
#include <asm/vaddrs.h>
#include <asm/kmap_types.h>
#include <asm/pgtable.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
/* undef for production */
#define HIGHMEM_DEBUG 1
...
...
include/asm-sparc/kmap_types.h
View file @
a662c5a3
...
...
@@ -9,6 +9,8 @@ enum km_type {
KM_USER1
,
KM_BIO_SRC_IRQ
,
KM_BIO_DST_IRQ
,
KM_PTE0
,
KM_PTE1
,
KM_TYPE_NR
};
...
...
include/asm-sparc/mmu_context.h
View file @
a662c5a3
...
...
@@ -5,29 +5,6 @@
#ifndef __ASSEMBLY__
/*
* Every architecture must define this function. It's the fastest
* way of searching a 168-bit bitmap where the first 128 bits are
* unlikely to be clear. It's guaranteed that at least one of the 168
* bits is cleared.
*/
#if MAX_RT_PRIO != 128 || MAX_PRIO != 168
# error update this function.
#endif
static
inline
int
sched_find_first_zero_bit
(
unsigned
long
*
b
)
{
unsigned
int
rt
;
rt
=
b
[
0
]
&
b
[
1
]
&
b
[
2
]
&
b
[
3
];
if
(
unlikely
(
rt
!=
0xffffffff
))
return
find_first_zero_bit
(
b
,
MAX_RT_PRIO
);
if
(
b
[
4
]
!=
~
0
)
return
ffz
(
b
[
4
])
+
MAX_RT_PRIO
;
return
ffz
(
b
[
5
])
+
32
+
MAX_RT_PRIO
;
}
static
inline
void
enter_lazy_tlb
(
struct
mm_struct
*
mm
,
struct
task_struct
*
tsk
,
unsigned
cpu
)
{
}
...
...
include/asm-sparc/page.h
View file @
a662c5a3
...
...
@@ -27,9 +27,6 @@
#include <asm/head.h>
/* for KERNBASE */
#include <asm/btfixup.h>
/* This is always 2048*sizeof(long), doesn't change with PAGE_SIZE */
#define TASK_UNION_SIZE 8192
#ifndef __ASSEMBLY__
/*
...
...
@@ -176,8 +173,12 @@ extern __inline__ int get_order(unsigned long size)
#define PAGE_OFFSET 0xf0000000
#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET))
#define pfn_to_page(pfn) (mem_map + (pfn))
#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
#define virt_to_page(kaddr) (mem_map + (__pa(kaddr) >> PAGE_SHIFT))
#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
#define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
...
...
include/asm-sparc/pgalloc.h
View file @
a662c5a3
...
...
@@ -9,85 +9,7 @@
#include <asm/page.h>
#include <asm/btfixup.h>
/* Fine grained cache/tlb flushing. */
#ifdef CONFIG_SMP
BTFIXUPDEF_CALL
(
void
,
local_flush_cache_all
,
void
)
BTFIXUPDEF_CALL
(
void
,
local_flush_cache_mm
,
struct
mm_struct
*
)
BTFIXUPDEF_CALL
(
void
,
local_flush_cache_range
,
struct
vm_area_struct
*
,
unsigned
long
,
unsigned
long
)
BTFIXUPDEF_CALL
(
void
,
local_flush_cache_page
,
struct
vm_area_struct
*
,
unsigned
long
)
#define local_flush_cache_all() BTFIXUP_CALL(local_flush_cache_all)()
#define local_flush_cache_mm(mm) BTFIXUP_CALL(local_flush_cache_mm)(mm)
#define local_flush_cache_range(vma,start,end) BTFIXUP_CALL(local_flush_cache_range)(vma,start,end)
#define local_flush_cache_page(vma,addr) BTFIXUP_CALL(local_flush_cache_page)(vma,addr)
BTFIXUPDEF_CALL
(
void
,
local_flush_tlb_all
,
void
)
BTFIXUPDEF_CALL
(
void
,
local_flush_tlb_mm
,
struct
mm_struct
*
)
BTFIXUPDEF_CALL
(
void
,
local_flush_tlb_range
,
struct
vm_area_struct
*
,
unsigned
long
,
unsigned
long
)
BTFIXUPDEF_CALL
(
void
,
local_flush_tlb_page
,
struct
vm_area_struct
*
,
unsigned
long
)
#define local_flush_tlb_all() BTFIXUP_CALL(local_flush_tlb_all)()
#define local_flush_tlb_mm(mm) BTFIXUP_CALL(local_flush_tlb_mm)(mm)
#define local_flush_tlb_range(vma,start,end) BTFIXUP_CALL(local_flush_tlb_range)(vma,start,end)
#define local_flush_tlb_page(vma,addr) BTFIXUP_CALL(local_flush_tlb_page)(vma,addr)
BTFIXUPDEF_CALL
(
void
,
local_flush_page_to_ram
,
unsigned
long
)
BTFIXUPDEF_CALL
(
void
,
local_flush_sig_insns
,
struct
mm_struct
*
,
unsigned
long
)
#define local_flush_page_to_ram(addr) BTFIXUP_CALL(local_flush_page_to_ram)(addr)
#define local_flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(local_flush_sig_insns)(mm,insn_addr)
extern
void
smp_flush_cache_all
(
void
);
extern
void
smp_flush_cache_mm
(
struct
mm_struct
*
mm
);
extern
void
smp_flush_cache_range
(
struct
vm_area_struct
*
vma
,
unsigned
long
start
,
unsigned
long
end
);
extern
void
smp_flush_cache_page
(
struct
vm_area_struct
*
vma
,
unsigned
long
page
);
extern
void
smp_flush_tlb_all
(
void
);
extern
void
smp_flush_tlb_mm
(
struct
mm_struct
*
mm
);
extern
void
smp_flush_tlb_range
(
struct
vm_area_struct
*
vma
,
unsigned
long
start
,
unsigned
long
end
);
extern
void
smp_flush_tlb_page
(
struct
vm_area_struct
*
mm
,
unsigned
long
page
);
extern
void
smp_flush_page_to_ram
(
unsigned
long
page
);
extern
void
smp_flush_sig_insns
(
struct
mm_struct
*
mm
,
unsigned
long
insn_addr
);
#endif
BTFIXUPDEF_CALL
(
void
,
flush_cache_all
,
void
)
BTFIXUPDEF_CALL
(
void
,
flush_cache_mm
,
struct
mm_struct
*
)
BTFIXUPDEF_CALL
(
void
,
flush_cache_range
,
struct
vm_area_struct
*
,
unsigned
long
,
unsigned
long
)
BTFIXUPDEF_CALL
(
void
,
flush_cache_page
,
struct
vm_area_struct
*
,
unsigned
long
)
#define flush_cache_all() BTFIXUP_CALL(flush_cache_all)()
#define flush_cache_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
#define flush_cache_range(vma,start,end) BTFIXUP_CALL(flush_cache_range)(vma,start,end)
#define flush_cache_page(vma,addr) BTFIXUP_CALL(flush_cache_page)(vma,addr)
#define flush_icache_range(start, end) do { } while (0)
BTFIXUPDEF_CALL
(
void
,
flush_tlb_all
,
void
)
BTFIXUPDEF_CALL
(
void
,
flush_tlb_mm
,
struct
mm_struct
*
)
BTFIXUPDEF_CALL
(
void
,
flush_tlb_range
,
struct
vm_area_struct
*
,
unsigned
long
,
unsigned
long
)
BTFIXUPDEF_CALL
(
void
,
flush_tlb_page
,
struct
vm_area_struct
*
,
unsigned
long
)
extern
__inline__
void
flush_tlb_pgtables
(
struct
mm_struct
*
mm
,
unsigned
long
start
,
unsigned
long
end
)
{
}
#define flush_tlb_all() BTFIXUP_CALL(flush_tlb_all)()
#define flush_tlb_mm(mm) BTFIXUP_CALL(flush_tlb_mm)(mm)
#define flush_tlb_range(vma,start,end) BTFIXUP_CALL(flush_tlb_range)(vma,start,end)
#define flush_tlb_page(vma,addr) BTFIXUP_CALL(flush_tlb_page)(vma,addr)
BTFIXUPDEF_CALL
(
void
,
__flush_page_to_ram
,
unsigned
long
)
BTFIXUPDEF_CALL
(
void
,
flush_sig_insns
,
struct
mm_struct
*
,
unsigned
long
)
#define __flush_page_to_ram(addr) BTFIXUP_CALL(__flush_page_to_ram)(addr)
#define flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(flush_sig_insns)(mm,insn_addr)
extern
void
flush_page_to_ram
(
struct
page
*
page
);
#define flush_dcache_page(page) do { } while (0)
struct
page
;
extern
struct
pgtable_cache_struct
{
unsigned
long
*
pgd_cache
;
...
...
@@ -101,7 +23,8 @@ extern struct pgtable_cache_struct {
#define pgtable_cache_size (pgt_quicklists.pgtable_cache_sz)
#define pgd_cache_size (pgt_quicklists.pgd_cache_sz)
BTFIXUPDEF_CALL
(
int
,
do_check_pgt_cache
,
int
,
int
)
extern
void
check_pgt_cache
(
void
);
BTFIXUPDEF_CALL
(
void
,
do_check_pgt_cache
,
int
,
int
)
#define do_check_pgt_cache(low,high) BTFIXUP_CALL(do_check_pgt_cache)(low,high)
BTFIXUPDEF_CALL
(
pgd_t
*
,
get_pgd_fast
,
void
)
...
...
@@ -113,6 +36,8 @@ BTFIXUPDEF_CALL(void, free_pgd_fast, pgd_t *)
#define pgd_free(pgd) free_pgd_fast(pgd)
#define pgd_alloc(mm) get_pgd_fast()
BTFIXUPDEF_CALL
(
void
,
pgd_set
,
pgd_t
*
,
pmd_t
*
)
#define pgd_set(pgdp,pmdp) BTFIXUP_CALL(pgd_set)(pgdp,pmdp)
#define pgd_populate(MM, PGD, PMD) pgd_set(PGD, PMD)
static
__inline__
pmd_t
*
pmd_alloc_one
(
struct
mm_struct
*
mm
,
unsigned
long
address
)
...
...
@@ -127,18 +52,24 @@ BTFIXUPDEF_CALL(void, free_pmd_fast, pmd_t *)
#define free_pmd_fast(pmd) BTFIXUP_CALL(free_pmd_fast)(pmd)
#define pmd_free(pmd) free_pmd_fast(pmd)
#define pmd_free_tlb(tlb, pmd) pmd_free(pmd)
#define pmd_populate(MM, PMD, PTE) pmd_set(PMD, PTE)
BTFIXUPDEF_CALL
(
void
,
pmd_populate
,
pmd_t
*
,
struct
page
*
)
#define pmd_populate(MM, PMD, PTE) BTFIXUP_CALL(pmd_populate)(PMD, PTE)
BTFIXUPDEF_CALL
(
void
,
pmd_set
,
pmd_t
*
,
pte_t
*
)
#define pmd_populate_kernel(MM, PMD, PTE) BTFIXUP_CALL(pmd_set)(PMD, PTE)
BTFIXUPDEF_CALL
(
pte_t
*
,
pte_alloc_one
,
struct
mm_struct
*
,
unsigned
long
)
BTFIXUPDEF_CALL
(
struct
page
*
,
pte_alloc_one
,
struct
mm_struct
*
,
unsigned
long
)
#define pte_alloc_one(mm, address) BTFIXUP_CALL(pte_alloc_one)(mm, address)
BTFIXUPDEF_CALL
(
pte_t
*
,
pte_alloc_one_fast
,
struct
mm_struct
*
,
unsigned
long
)
#define pte_alloc_one_fast(mm, address) BTFIXUP_CALL(pte_alloc_one_fast)(mm, address)
BTFIXUPDEF_CALL
(
pte_t
*
,
pte_alloc_one_kernel
,
struct
mm_struct
*
,
unsigned
long
)
#define pte_alloc_one_kernel(mm, addr) BTFIXUP_CALL(pte_alloc_one_kernel)(mm, addr)
BTFIXUPDEF_CALL
(
void
,
free_pte_fast
,
pte_t
*
)
#define free_pte_fast(pte) BTFIXUP_CALL(free_pte_fast)(pte)
#define pte_free_kernel(pte) free_pte_fast(pte)
#define pte_free(pte) free_pte_fast(pte)
BTFIXUPDEF_CALL
(
void
,
pte_free
,
struct
page
*
)
#define pte_free(pte) BTFIXUP_CALL(pte_free)(pte)
#define pte_free_tlb(tlb, pte) pte_free(pte)
#endif
/* _SPARC_PGALLOC_H */
include/asm-sparc/pgtable.h
View file @
a662c5a3
...
...
@@ -11,6 +11,8 @@
#include <linux/config.h>
#include <linux/spinlock.h>
/* XXX This creates many nasty warnings. */
/* #include <linux/highmem.h> */
/* kmap_atomic in pte_offset_map */
#include <asm/asi.h>
#ifdef CONFIG_SUN4
#include <asm/pgtsun4.h>
...
...
@@ -26,6 +28,8 @@
#ifndef __ASSEMBLY__
struct
vm_area_struct
;
extern
void
load_mmu
(
void
);
extern
unsigned
long
calc_highpages
(
void
);
...
...
@@ -183,7 +187,7 @@ extern unsigned long empty_zero_page;
#define BAD_PAGETABLE __bad_pagetable()
#define BAD_PAGE __bad_page()
#define ZERO_PAGE(vaddr) (
mem_map + (((unsigned long)&empty_zero_page - PAGE_OFFSET + phys_base) >> PAGE_SHIFT
))
#define ZERO_PAGE(vaddr) (
virt_to_page(empty_zero_page
))
/* number of bits that fit into a memory pointer */
#define BITS_PER_PTR (8*sizeof(unsigned long))
...
...
@@ -193,7 +197,7 @@ extern unsigned long empty_zero_page;
#define SIZEOF_PTR_LOG2 2
BTFIXUPDEF_CALL_CONST
(
unsigned
long
,
pmd_page
,
pmd_t
)
BTFIXUPDEF_CALL_CONST
(
struct
page
*
,
pmd_page
,
pmd_t
)
BTFIXUPDEF_CALL_CONST
(
unsigned
long
,
pgd_page
,
pgd_t
)
#define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd)
...
...
@@ -291,13 +295,12 @@ BTFIXUPDEF_CALL_CONST(pte_t, pte_mkyoung, pte_t)
#define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte)
#define page_pte_prot(page, prot) mk_pte(page, prot)
#define page_pte(page) page_pte_prot(page, __pgprot(0))
/* Permanent address of a page. */
#define page_address(page) ((page)->virtual)
#define page_pte(page) mk_pte(page, __pgprot(0))
#define pfn_pte(pfn, prot) mk_pte(pfn_to_page(pfn), prot)
BTFIXUPDEF_CALL
(
struct
page
*
,
pte_page
,
pte_t
)
#define pte_page(pte) BTFIXUP_CALL(pte_page)(pte)
BTFIXUPDEF_CALL
(
unsigned
long
,
pte_pfn
,
pte_t
)
#define pte_pfn(pte) BTFIXUP_CALL(pte_pfn)(pte)
#define pte_page(pte) pfn_to_page(pte_pfn(pte))
/*
* Conversion functions: convert a page and protection to a page entry,
...
...
@@ -312,12 +315,6 @@ BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_io, unsigned long, pgprot_t, int)
#define mk_pte_phys(page,pgprot) BTFIXUP_CALL(mk_pte_phys)(page,pgprot)
#define mk_pte_io(page,pgprot,space) BTFIXUP_CALL(mk_pte_io)(page,pgprot,space)
BTFIXUPDEF_CALL
(
void
,
pgd_set
,
pgd_t
*
,
pmd_t
*
)
BTFIXUPDEF_CALL
(
void
,
pmd_set
,
pmd_t
*
,
pte_t
*
)
#define pgd_set(pgdp,pmdp) BTFIXUP_CALL(pgd_set)(pgdp,pmdp)
#define pmd_set(pmdp,ptep) BTFIXUP_CALL(pmd_set)(pmdp,ptep)
BTFIXUPDEF_INT
(
pte_modify_mask
)
extern
pte_t
pte_modify
(
pte_t
pte
,
pgprot_t
newprot
)
__attribute__
((
const
));
...
...
@@ -335,21 +332,32 @@ extern __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot)
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
BTFIXUPDEF_CALL
(
pmd_t
*
,
pmd_offset
,
pgd_t
*
,
unsigned
long
)
BTFIXUPDEF_CALL
(
pte_t
*
,
pte_offset
,
pmd_t
*
,
unsigned
long
)
/* Find an entry in the second-level page table.. */
BTFIXUPDEF_CALL
(
pmd_t
*
,
pmd_offset
,
pgd_t
*
,
unsigned
long
)
#define pmd_offset(dir,addr) BTFIXUP_CALL(pmd_offset)(dir,addr)
/* Find an entry in the third-level page table.. */
#define pte_offset(dir,addr) BTFIXUP_CALL(pte_offset)(dir,addr)
BTFIXUPDEF_CALL
(
pte_t
*
,
pte_offset_kernel
,
pmd_t
*
,
unsigned
long
)
#define pte_offset_kernel(dir,addr) BTFIXUP_CALL(pte_offset_kernel)(dir,addr)
/* __pte_offset is not BTFIXUP-ed, but PTRS_PER_PTE is, so it's ok. */
#define __pte_offset(address) \
(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
#if 0 /* XXX Should we expose pmd_page_kernel? */
#define pte_offset_kernel(dir, addr) \
((pte_t *) pmd_page_kernel(*(dir)) + __pte_offset(addr))
#endif
#define pte_offset_map(dir, addr) \
((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE0) + __pte_offset(addr))
#define pte_offset_map_nested(dir, addr) \
((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE1) + __pte_offset(addr))
#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1)
/* The permissions for pgprot_val to make a page mapped on the obio space */
extern
unsigned
int
pg_iobits
;
#define flush_icache_page(vma, pg) do { } while(0)
#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
/* Certain architectures need to do special things when pte's
* within a page table are directly modified. Thus, the following
* hook is made available.
...
...
include/asm-sparc/pgtsrmmu.h
View file @
a662c5a3
...
...
@@ -8,6 +8,7 @@
#define _SPARC_PGTSRMMU_H
#include <asm/page.h>
#include <asm/thread_info.h>
/* TI_UWINMASK for WINDOW_FLUSH */
/* PMD_SHIFT determines the size of the area a second-level page table can map */
#define SRMMU_PMD_SHIFT 18
...
...
@@ -87,7 +88,7 @@
#define WINDOW_FLUSH(tmp1, tmp2) \
mov 0, tmp1; \
98: ld [%g6 +
AOFF_task_thread + AOFF_thread_uwinmask], tmp2;
\
98: ld [%g6 +
TI_UWINMASK], tmp2;
\
orcc %g0, tmp2, %g0; \
add tmp1, 1, tmp1; \
bne 98b; \
...
...
include/asm-sparc/processor.h
View file @
a662c5a3
...
...
@@ -44,6 +44,8 @@
*/
#define TASK_SIZE PAGE_OFFSET
struct
task_struct
;
struct
fpq
{
unsigned
long
*
insn_addr
;
unsigned
long
insn
;
...
...
@@ -55,15 +57,8 @@ typedef struct {
/* The Sparc processor specific thread struct. */
struct
thread_struct
{
unsigned
long
uwinmask
__attribute__
((
aligned
(
8
)));
struct
pt_regs
*
kregs
;
/* Context switch saved kernel state. */
unsigned
long
ksp
__attribute__
((
aligned
(
8
)));
unsigned
long
kpc
;
unsigned
long
kpsr
;
unsigned
long
kwim
;
/* Special child fork kpsr/kwim values. */
unsigned
long
fork_kpsr
__attribute__
((
aligned
(
8
)));
unsigned
long
fork_kwim
;
...
...
@@ -92,8 +87,8 @@ struct thread_struct {
#define SPARC_FLAG_UNALIGNED 0x2
/* is allowed to do unaligned accesses */
#define INIT_THREAD { \
/*
uwinmask, kregs, ksp, kpc, kpsr, kwim
*/
\
0,
0, 0, 0, 0, 0,
\
/*
kregs,
*/
\
0, \
/* fork_kpsr, fork_kwim */
\
0, 0, \
/* reg_window */
\
...
...
@@ -115,10 +110,7 @@ struct thread_struct {
}
/* Return saved PC of a blocked thread. */
extern
__inline__
unsigned
long
thread_saved_pc
(
struct
thread_struct
*
t
)
{
return
t
->
kpc
;
}
extern
unsigned
long
thread_saved_pc
(
struct
task_struct
*
t
);
/* Do necessary setup to start up a newly executed thread. */
extern
__inline__
void
start_thread
(
struct
pt_regs
*
regs
,
unsigned
long
pc
,
...
...
@@ -163,7 +155,7 @@ extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
if (!(__TSK) || (__TSK) == current || \
(__TSK)->state == TASK_RUNNING) \
goto __out; \
fp = (__TSK)->thread
.
ksp + bias; \
fp = (__TSK)->thread
_info->
ksp + bias; \
do { \
/* Bogus frame pointer? */
\
if (fp < (task_base + sizeof(struct task_struct)) || \
...
...
@@ -185,22 +177,9 @@ __out: __ret; \
#define KSTK_ESP(tsk) ((tsk)->thread.kregs->u_regs[UREG_FP])
#ifdef __KERNEL__
#define THREAD_SIZE (2*PAGE_SIZE)
extern
struct
task_struct
*
last_task_used_math
;
/* Allocation and freeing of basic task resources. */
BTFIXUPDEF_CALL
(
struct
task_struct
*
,
alloc_task_struct
,
void
)
BTFIXUPDEF_CALL
(
void
,
free_task_struct
,
struct
task_struct
*
)
BTFIXUPDEF_CALL
(
void
,
get_task_struct
,
struct
task_struct
*
)
#define alloc_task_struct() BTFIXUP_CALL(alloc_task_struct)()
#define free_task_struct(tsk) BTFIXUP_CALL(free_task_struct)(tsk)
#define get_task_struct(tsk) BTFIXUP_CALL(get_task_struct)(tsk)
#define init_task (init_task_union.task)
#define init_stack (init_task_union.stack)
#define cpu_relax() do { } while (0)
#endif
...
...
include/asm-sparc/spinlock.h
View file @
a662c5a3
...
...
@@ -12,15 +12,7 @@
#include <asm/psr.h>
/*
* Define this to use the verbose/debugging versions in
* arch/sparc/lib/debuglocks.c
*
* Be sure to make dep whenever changing this option.
*/
#define SPIN_LOCK_DEBUG
#ifdef SPIN_LOCK_DEBUG
#ifdef CONFIG_DEBUG_SPINLOCK
struct
_spinlock_debug
{
unsigned
char
lock
;
unsigned
long
owner_pc
;
...
...
@@ -36,9 +28,9 @@ extern void _do_spin_lock(spinlock_t *lock, char *str);
extern
int
_spin_trylock
(
spinlock_t
*
lock
);
extern
void
_do_spin_unlock
(
spinlock_t
*
lock
);
#define spin_trylock(lp) _spin_trylock(lp)
#define
spin_lock(lock)
_do_spin_lock(lock, "spin_lock")
#define spin_unlock(lock) _do_spin_unlock(lock)
#define
_raw_
spin_trylock(lp) _spin_trylock(lp)
#define
_raw_spin_lock(lock)
_do_spin_lock(lock, "spin_lock")
#define
_raw_
spin_unlock(lock) _do_spin_unlock(lock)
struct
_rwlock_debug
{
volatile
unsigned
int
lock
;
...
...
@@ -56,35 +48,35 @@ extern void _do_read_unlock(rwlock_t *rw, char *str);
extern
void
_do_write_lock
(
rwlock_t
*
rw
,
char
*
str
);
extern
void
_do_write_unlock
(
rwlock_t
*
rw
);
#define read_lock(lock) \
#define
_raw_
read_lock(lock) \
do { unsigned long flags; \
__save_and_cli(flags); \
_do_read_lock(lock, "read_lock"); \
__restore_flags(flags); \
} while(0)
#define read_unlock(lock) \
#define
_raw_
read_unlock(lock) \
do { unsigned long flags; \
__save_and_cli(flags); \
_do_read_unlock(lock, "read_unlock"); \
__restore_flags(flags); \
} while(0)
#define write_lock(lock) \
#define
_raw_
write_lock(lock) \
do { unsigned long flags; \
__save_and_cli(flags); \
_do_write_lock(lock, "write_lock"); \
__restore_flags(flags); \
} while(0)
#define write_unlock(lock) \
#define
_raw_
write_unlock(lock) \
do { unsigned long flags; \
__save_and_cli(flags); \
_do_write_unlock(lock); \
__restore_flags(flags); \
} while(0)
#else
/* !
SPIN_LOCK_DEBUG
*/
#else
/* !
CONFIG_DEBUG_SPINLOCK
*/
typedef
unsigned
char
spinlock_t
;
#define SPIN_LOCK_UNLOCKED 0
...
...
@@ -97,7 +89,7 @@ do { \
barrier(); \
} while(*((volatile unsigned char *)lock))
extern
__inline__
void
spin_lock
(
spinlock_t
*
lock
)
extern
__inline__
void
_raw_
spin_lock
(
spinlock_t
*
lock
)
{
__asm__
__volatile__
(
"
\n
1:
\n\t
"
...
...
@@ -117,7 +109,7 @@ extern __inline__ void spin_lock(spinlock_t *lock)
:
"g2"
,
"memory"
,
"cc"
);
}
extern
__inline__
int
spin_trylock
(
spinlock_t
*
lock
)
extern
__inline__
int
_raw_
spin_trylock
(
spinlock_t
*
lock
)
{
unsigned
int
result
;
__asm__
__volatile__
(
"ldstub [%1], %0"
...
...
@@ -127,7 +119,7 @@ extern __inline__ int spin_trylock(spinlock_t *lock)
return
(
result
==
0
);
}
extern
__inline__
void
spin_unlock
(
spinlock_t
*
lock
)
extern
__inline__
void
_raw_
spin_unlock
(
spinlock_t
*
lock
)
{
__asm__
__volatile__
(
"stb %%g0, [%0]"
:
:
"r"
(
lock
)
:
"memory"
);
}
...
...
@@ -178,7 +170,7 @@ extern __inline__ void _read_lock(rwlock_t *rw)
:
"g2"
,
"g4"
,
"memory"
,
"cc"
);
}
#define read_lock(lock) \
#define
_raw_
read_lock(lock) \
do { unsigned long flags; \
__save_and_cli(flags); \
_read_lock(lock); \
...
...
@@ -198,14 +190,14 @@ extern __inline__ void _read_unlock(rwlock_t *rw)
:
"g2"
,
"g4"
,
"memory"
,
"cc"
);
}
#define read_unlock(lock) \
#define
_raw_
read_unlock(lock) \
do { unsigned long flags; \
__save_and_cli(flags); \
_read_unlock(lock); \
__restore_flags(flags); \
} while(0)
extern
__inline__
void
write_lock
(
rwlock_t
*
rw
)
extern
__inline__
void
_raw_
write_lock
(
rwlock_t
*
rw
)
{
register
rwlock_t
*
lp
asm
(
"g1"
);
lp
=
rw
;
...
...
@@ -218,9 +210,9 @@ extern __inline__ void write_lock(rwlock_t *rw)
:
"g2"
,
"g4"
,
"memory"
,
"cc"
);
}
#define write_unlock(rw) do { (rw)->lock = 0; } while(0)
#define
_raw_
write_unlock(rw) do { (rw)->lock = 0; } while(0)
#endif
/*
SPIN_LOCK_DEBUG
*/
#endif
/*
CONFIG_DEBUG_SPINLOCK
*/
#endif
/* !(__ASSEMBLY__) */
...
...
include/asm-sparc/system.h
View file @
a662c5a3
...
...
@@ -4,19 +4,18 @@
#ifndef __SPARC_SYSTEM_H
#define __SPARC_SYSTEM_H
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/threads.h>
/* NR_CPUS */
#include <asm/segment.h>
#ifdef __KERNEL__
#include <asm/thread_info.h>
#include <asm/page.h>
#include <asm/op
lib.h>
#include <asm/op
enprom.h>
/* romvec. XXX will be dealt later. Promise. */
#include <asm/psr.h>
#include <asm/ptrace.h>
#include <asm/btfixup.h>
#endif
/* __KERNEL__ */
#ifndef __ASSEMBLY__
/*
...
...
@@ -48,6 +47,8 @@ extern enum sparc_cpu sparc_cpu_model;
#define SUN4M_NCPUS 4
/* Architectural limit of sun4m. */
extern
struct
thread_info
*
current_set
[
NR_CPUS
];
extern
unsigned
long
empty_bad_page
;
extern
unsigned
long
empty_bad_page_table
;
extern
unsigned
long
empty_zero_page
;
...
...
@@ -67,28 +68,43 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
void
*
fpqueue
,
unsigned
long
*
fpqdepth
);
#ifdef CONFIG_SMP
#define SWITCH_ENTER \
if(prev->flags & PF_USEDFPU) { \
#define SWITCH_ENTER(prv) \
do { \
if (test_tsk_thread_flag(prv, TIF_USEDFPU) { \
put_psr(get_psr() | PSR_EF); \
fpsave(&prev->thread.float_regs[0], &prev->thread.fsr, \
&prev->thread.fpqueue[0], &prev->thread.fpqdepth); \
prev->flags &= ~PF_USEDFPU; \
prev->thread.kregs->psr &= ~PSR_EF; \
}
#define SWITCH_DO_LAZY_FPU
fpsave(&(prv)->thread.float_regs[0], &(prv)->thread.fsr, \
&(prv)->thread.fpqueue[0], &(prv)->thread.fpqdepth); \
clear_tsk_thread_flag(prv, TIF_USEDFPU); \
(prv)->thread.kregs->psr &= ~PSR_EF; \
} \
} while(0)
#define SWITCH_DO_LAZY_FPU(next)
/* */
#else
#define SWITCH_ENTER
#define SWITCH_DO_LAZY_FPU if(last_task_used_math != next) next->thread.kregs->psr&=~PSR_EF;
#define SWITCH_ENTER(prv)
/* */
#define SWITCH_DO_LAZY_FPU(nxt) \
do { \
if (last_task_used_math != (nxt)) \
(nxt)->thread.kregs->psr&=~PSR_EF; \
} while(0)
#endif
// #define prepare_arch_schedule(prev) task_lock(prev)
// #define finish_arch_schedule(prev) task_unlock(prev)
#define prepare_arch_schedule(prev) do{ }while(0)
#define finish_arch_schedule(prev) do{ }while(0)
/*
* Flush windows so that the VM switch which follows
* would not pull the stack from under us.
*
* SWITCH_ENTER and SWITH_DO_LAZY_FPU do not work yet (e.g. SMP does not work)
* XXX WTF is the above comment? Found in late teen 2.4.x.
*
* XXX prepare_arch_switch() is much smarter than this in sparc64, are we sure?
* XXX Cosider if doing it the flush_user_windows way is faster (by uwinmask).
*/
#define prepare_
to_switch(
) do { \
#define prepare_
arch_switch(rq
) do { \
__asm__ __volatile__( \
".globl\tflush_patch_switch\nflush_patch_switch:\n\t" \
"save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \
...
...
@@ -96,6 +112,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
"save %sp, -0x40, %sp\n\t" \
"restore; restore; restore; restore; restore; restore; restore"); \
} while(0)
#define finish_arch_switch(rq) do{ }while(0)
/* Much care has gone into this code, do not touch it.
*
...
...
@@ -111,9 +128,8 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
#define switch_to(prev, next, last) do { \
__label__ here; \
register unsigned long task_pc asm("o7"); \
extern struct task_struct *current_set[NR_CPUS]; \
SWITCH_ENTER \
SWITCH_DO_LAZY_FPU \
SWITCH_ENTER(prev); \
SWITCH_DO_LAZY_FPU(next); \
next->active_mm->cpu_vm_mask |= (1 << smp_processor_id()); \
task_pc = ((unsigned long) &&here) - 0x8; \
__asm__ __volatile__( \
...
...
@@ -140,11 +156,13 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
"nop\n\t" \
"nop\n\t" \
"jmpl %%o7 + 0x8, %%g0\n\t" \
"
mov %%g3
, %0\n\t" \
"
ld [%%g3 + %5]
, %0\n\t" \
: "=&r" (last) \
: "r" (&(current_set[hard_smp_processor_id()])), "r" (next), \
"i" ((const unsigned long)(&((struct task_struct *)0)->thread.kpsr)), \
"i" ((const unsigned long)(&((struct task_struct *)0)->thread.ksp)), \
: "r" (&(current_set[hard_smp_processor_id()])), \
"r" ((next)->thread_info), \
"i" (TI_KPSR), \
"i" (TI_KSP), \
"i" (TI_TASK), \
"r" (task_pc) \
: "g1", "g2", "g3", "g4", "g5", "g7", "l0", "l1", \
"l4", "l5", "l6", "l7", "i0", "i1", "i2", "i3", "i4", "i5", "o0", "o1", "o2", \
...
...
include/asm-sparc/thread_info.h
0 → 100644
View file @
a662c5a3
/*
* thread_info.h: sparc low-level thread information
* adapted from the ppc version by Pete Zaitcev, which was
* adapted from the i386 version by Paul Mackerras
*
* Copyright (C) 2002 David Howells (dhowells@redhat.com)
* Copyright (c) 2002 Pete Zaitcev (zaitcev@yahoo.com)
* - Incorporating suggestions made by Linus Torvalds and Dave Miller
*/
#ifndef _ASM_THREAD_INFO_H
#define _ASM_THREAD_INFO_H
// XXX todo: comment thread_info components and see what breaks.
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#include <asm/btfixup.h>
/*
* Low level task data.
*
* If you change this, change the TI_* offsets below to match. XXX check_asm.
*
* The uwinmask is a first class citizen among w_saved and friends.
* XXX Is this a good idea? wof.S/wuf.S have to use w_saved anyway,
* so they waste a register on current, and an ld on fetching it.
*/
struct
thread_info
{
unsigned
long
uwinmask
;
struct
task_struct
*
task
;
/* main task structure */
struct
exec_domain
*
exec_domain
;
/* execution domain */
unsigned
long
flags
;
/* low level flags */
int
cpu
;
/* cpu we're on */
int
preempt_count
;
int
softirq_count
;
int
hardirq_count
;
/* Context switch saved kernel state. */
unsigned
long
ksp
;
/* ... ksp __attribute__ ((aligned (8))); */
unsigned
long
kpc
;
unsigned
long
kpsr
;
unsigned
long
kwim
;
};
/*
* macros/functions for gaining access to the thread information structure
*/
#define INIT_THREAD_INFO(tsk) \
{ \
uwinmask: 0, \
task: &tsk, \
exec_domain: &default_exec_domain, \
flags: 0, \
cpu: 0, \
}
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
/* how to get the thread information struct from C */
register
struct
thread_info
*
current_thread_info_reg
asm
(
"g6"
);
#define current_thread_info() (current_thread_info_reg)
/*
* thread information allocation
*/
#ifdef CONFIG_SUN4
#define THREAD_INFO_ORDER 0
#else
#define THREAD_INFO_ORDER 1
#endif
BTFIXUPDEF_CALL
(
struct
thread_info
*
,
alloc_thread_info
,
void
)
#define alloc_thread_info() BTFIXUP_CALL(alloc_thread_info)()
BTFIXUPDEF_CALL
(
void
,
free_thread_info
,
struct
thread_info
*
)
#define free_thread_info(ti) BTFIXUP_CALL(free_thread_info)(ti)
#define get_thread_info(ti) get_task_struct((ti)->task)
#define put_thread_info(ti) put_task_struct((ti)->task)
#endif
/* __ASSEMBLY__ */
/*
* Size of kernel stack for each process.
* Observe the order of get_free_pages() in alloc_thread_info().
* The sun4 has 8K stack too, because it's short on memory, and 16K is a waste.
*
* XXX Watch how INIT_THREAD_SIZE evolves in linux/sched.h and elsewhere.
* On 2.5.24 it happens to match 8192 magically.
*/
#define THREAD_SIZE 8192
/*
* Offsets in thread_info structure, used in assembly code
*/
#define TI_UWINMASK 0x00
/* uwinmask */
#define TI_TASK 0x04
#define TI_EXECDOMAIN 0x08
/* exec_domain */
#define TI_FLAGS 0x0c
#define TI_CPU 0x10
#define TI_PREEMPT 0x14
/* preempt_count */
#define TI_SOFTIRQ 0x18
/* softirq_count */
#define TI_HARDIRQ 0x1c
/* hardirq_count */
#define TI_KSP 0x20
/* ksp */
#define TI_KPC 0x24
/* kpc (ldd'ed with kpc) */
#define TI_KPSR 0x28
/* kpsr */
#define TI_KWIM 0x2c
/* kwim (ldd'ed with kpsr) */
#define PREEMPT_ACTIVE 0x4000000
/*
* thread information flag bit numbers
*/
#define TIF_SYSCALL_TRACE 0
/* syscall trace active */
#define TIF_NOTIFY_RESUME 1
/* resumption notification requested */
#define TIF_SIGPENDING 2
/* signal pending */
#define TIF_NEED_RESCHED 3
/* rescheduling necessary */
#define TIF_USEDFPU 8
/* FPU was used by this task
* this quantum (SMP) */
#define TIF_POLLING_NRFLAG 9
/* true if poll_idle() is polling
* TIF_NEED_RESCHED */
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#endif
/* __KERNEL__ */
#endif
/* _ASM_THREAD_INFO_H */
include/asm-sparc/tlb.h
View file @
a662c5a3
#ifndef _SPARC_TLB_H
#define _SPARC_TLB_H
#define tlb_start_vma(tlb, vma) \
do { \
flush_cache_range(vma, vma->vm_start, vma->vm_end); \
} while (0)
#define tlb_end_vma(tlb, vma) \
do { \
flush_tlb_range(vma, vma->vm_start, vma->vm_end); \
} while (0)
#define tlb_remove_tlb_entry(tlb, pte, address) \
do { } while (0)
#define tlb_flush(tlb) \
do { \
flush_tlb_mm((tlb)->mm); \
} while (0)
#include <asm-generic/tlb.h>
#endif
/* _SPARC_TLB_H */
include/asm-sparc/tlbflush.h
0 → 100644
View file @
a662c5a3
#ifndef _SPARC_TLBFLUSH_H
#define _SPARC_TLBFLUSH_H
#include <linux/config.h>
#include <linux/mm.h>
// #include <asm/processor.h>
/*
* TLB flushing:
*
* - flush_tlb() flushes the current mm struct TLBs XXX Exists?
* - flush_tlb_all() flushes all processes TLBs
* - flush_tlb_mm(mm) flushes the specified mm context TLB's
* - flush_tlb_page(vma, vmaddr) flushes one page
* - flush_tlb_range(vma, start, end) flushes a range of pages
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
* - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
*/
#ifdef CONFIG_SMP
BTFIXUPDEF_CALL
(
void
,
local_flush_tlb_all
,
void
)
BTFIXUPDEF_CALL
(
void
,
local_flush_tlb_mm
,
struct
mm_struct
*
)
BTFIXUPDEF_CALL
(
void
,
local_flush_tlb_range
,
struct
vm_area_struct
*
,
unsigned
long
,
unsigned
long
)
BTFIXUPDEF_CALL
(
void
,
local_flush_tlb_page
,
struct
vm_area_struct
*
,
unsigned
long
)
#define local_flush_tlb_all() BTFIXUP_CALL(local_flush_tlb_all)()
#define local_flush_tlb_mm(mm) BTFIXUP_CALL(local_flush_tlb_mm)(mm)
#define local_flush_tlb_range(vma,start,end) BTFIXUP_CALL(local_flush_tlb_range)(vma,start,end)
#define local_flush_tlb_page(vma,addr) BTFIXUP_CALL(local_flush_tlb_page)(vma,addr)
extern
void
smp_flush_tlb_all
(
void
);
extern
void
smp_flush_tlb_mm
(
struct
mm_struct
*
mm
);
extern
void
smp_flush_tlb_range
(
struct
vm_area_struct
*
vma
,
unsigned
long
start
,
unsigned
long
end
);
extern
void
smp_flush_tlb_page
(
struct
vm_area_struct
*
mm
,
unsigned
long
page
);
#endif
/* CONFIG_SMP */
BTFIXUPDEF_CALL
(
void
,
flush_tlb_all
,
void
)
BTFIXUPDEF_CALL
(
void
,
flush_tlb_mm
,
struct
mm_struct
*
)
BTFIXUPDEF_CALL
(
void
,
flush_tlb_range
,
struct
vm_area_struct
*
,
unsigned
long
,
unsigned
long
)
BTFIXUPDEF_CALL
(
void
,
flush_tlb_page
,
struct
vm_area_struct
*
,
unsigned
long
)
// Thanks to Anton Blanchard, our pagetables became uncached in 2.4. Wee!
// extern void flush_tlb_pgtables(struct mm_struct *mm,
// unsigned long start, unsigned long end);
#define flush_tlb_pgtables(mm, start, end) do{ }while(0)
#define flush_tlb_all() BTFIXUP_CALL(flush_tlb_all)()
#define flush_tlb_mm(mm) BTFIXUP_CALL(flush_tlb_mm)(mm)
#define flush_tlb_range(vma,start,end) BTFIXUP_CALL(flush_tlb_range)(vma,start,end)
#define flush_tlb_page(vma,addr) BTFIXUP_CALL(flush_tlb_page)(vma,addr)
// #define flush_tlb() flush_tlb_mm(current->active_mm) /* XXX Sure? */
/*
* This is a kludge, until I know better. --zaitcev XXX
*/
#define flush_tlb_kernel_range(start, end) flush_tlb_all()
#endif
/* _SPARC_TLBFLUSH_H */
include/asm-sparc/uaccess.h
View file @
a662c5a3
...
...
@@ -10,6 +10,7 @@
#ifdef __KERNEL__
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <asm/vac-ops.h>
#include <asm/a.out.h>
#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