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
12cceb62
Commit
12cceb62
authored
Aug 24, 2009
by
Paul Mundt
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'sh/st-integration'
parents
f1332786
05ecd5a1
Changes
29
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
476 additions
and
155 deletions
+476
-155
arch/sh/Kconfig
arch/sh/Kconfig
+23
-4
arch/sh/boot/compressed/head_32.S
arch/sh/boot/compressed/head_32.S
+1
-1
arch/sh/drivers/pci/pci.c
arch/sh/drivers/pci/pci.c
+4
-0
arch/sh/include/asm/Kbuild
arch/sh/include/asm/Kbuild
+1
-1
arch/sh/include/asm/cachectl.h
arch/sh/include/asm/cachectl.h
+19
-0
arch/sh/include/asm/entry-macros.S
arch/sh/include/asm/entry-macros.S
+1
-1
arch/sh/include/asm/io.h
arch/sh/include/asm/io.h
+15
-1
arch/sh/include/asm/unistd_32.h
arch/sh/include/asm/unistd_32.h
+1
-1
arch/sh/include/asm/unistd_64.h
arch/sh/include/asm/unistd_64.h
+1
-1
arch/sh/kernel/cpu/irq/ipr.c
arch/sh/kernel/cpu/irq/ipr.c
+1
-0
arch/sh/kernel/cpu/sh3/entry.S
arch/sh/kernel/cpu/sh3/entry.S
+1
-1
arch/sh/kernel/entry-common.S
arch/sh/kernel/entry-common.S
+3
-2
arch/sh/kernel/io.c
arch/sh/kernel/io.c
+76
-21
arch/sh/kernel/io_generic.c
arch/sh/kernel/io_generic.c
+8
-42
arch/sh/kernel/irq.c
arch/sh/kernel/irq.c
+1
-1
arch/sh/kernel/kgdb.c
arch/sh/kernel/kgdb.c
+0
-2
arch/sh/kernel/process_32.c
arch/sh/kernel/process_32.c
+20
-0
arch/sh/kernel/setup.c
arch/sh/kernel/setup.c
+5
-1
arch/sh/kernel/signal_32.c
arch/sh/kernel/signal_32.c
+11
-1
arch/sh/kernel/sys_sh.c
arch/sh/kernel/sys_sh.c
+43
-0
arch/sh/kernel/syscalls_32.S
arch/sh/kernel/syscalls_32.S
+1
-1
arch/sh/kernel/syscalls_64.S
arch/sh/kernel/syscalls_64.S
+1
-1
arch/sh/kernel/traps_32.c
arch/sh/kernel/traps_32.c
+166
-22
arch/sh/lib/clear_page.S
arch/sh/lib/clear_page.S
+1
-1
arch/sh/lib/delay.c
arch/sh/lib/delay.c
+3
-2
arch/sh/mm/cache-sh4.c
arch/sh/mm/cache-sh4.c
+45
-0
arch/sh/mm/ioremap_32.c
arch/sh/mm/ioremap_32.c
+0
-8
drivers/sh/intc.c
drivers/sh/intc.c
+24
-38
include/linux/sh_intc.h
include/linux/sh_intc.h
+0
-1
No files found.
arch/sh/Kconfig
View file @
12cceb62
...
...
@@ -767,12 +767,31 @@ config UBC_WAKEUP
If unsure, say N.
config CMDLINE_BOOL
bool "Default bootloader kernel arguments"
choice
prompt "Kernel command line"
optional
default CMDLINE_OVERWRITE
help
Setting this option allows the kernel command line arguments
to be set.
config CMDLINE_OVERWRITE
bool "Overwrite bootloader kernel arguments"
help
Given string will overwrite any arguments passed in by
a bootloader.
config CMDLINE_EXTEND
bool "Extend bootloader kernel arguments"
help
Given string will be concatenated with arguments passed in
by a bootloader.
endchoice
config CMDLINE
string "
Initial kernel command
string"
depends on CMDLINE_
BOOL
string "
Kernel command line arguments
string"
depends on CMDLINE_
OVERWRITE || CMDLINE_EXTEND
default "console=ttySC1,115200"
endmenu
...
...
arch/sh/boot/compressed/head_32.S
View file @
12cceb62
...
...
@@ -22,7 +22,7 @@ startup:
bt
clear_bss
sub
r0
,
r2
mov.l
bss_start_addr
,
r0
mov
#
0xe0
,
r1
mov
#
0x
ffffff
e0
,
r1
and
r1
,
r0
!
align
cache
line
mov.l
text_start_addr
,
r3
mov
r0
,
r1
...
...
arch/sh/drivers/pci/pci.c
View file @
12cceb62
...
...
@@ -295,6 +295,8 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
vma
->
vm_page_prot
);
}
#ifndef CONFIG_GENERIC_IOMAP
static
void
__iomem
*
ioport_map_pci
(
struct
pci_dev
*
dev
,
unsigned
long
port
,
unsigned
int
nr
)
{
...
...
@@ -346,6 +348,8 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
}
EXPORT_SYMBOL
(
pci_iounmap
);
#endif
/* CONFIG_GENERIC_IOMAP */
#ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL
(
pcibios_resource_to_bus
);
EXPORT_SYMBOL
(
pcibios_bus_to_resource
);
...
...
arch/sh/include/asm/Kbuild
View file @
12cceb62
include include/asm-generic/Kbuild.asm
header-y += cpu-features.h
header-y += c
achectl.h c
pu-features.h
unifdef-y += unistd_32.h
unifdef-y += unistd_64.h
...
...
arch/sh/include/asm/cachectl.h
0 → 100644
View file @
12cceb62
#ifndef _SH_CACHECTL_H
#define _SH_CACHECTL_H
/* Definitions for the cacheflush system call. */
#define CACHEFLUSH_D_INVAL 0x1
/* invalidate (without write back) */
#define CACHEFLUSH_D_WB 0x2
/* write back (without invalidate) */
#define CACHEFLUSH_D_PURGE 0x3
/* writeback and invalidate */
#define CACHEFLUSH_I 0x4
/*
* Options for cacheflush system call
*/
#define ICACHE CACHEFLUSH_I
/* flush instruction cache */
#define DCACHE CACHEFLUSH_D_PURGE
/* writeback and flush data cache */
#define BCACHE (ICACHE|DCACHE)
/* flush both caches */
#endif
/* _SH_CACHECTL_H */
arch/sh/include/asm/entry-macros.S
View file @
12cceb62
...
...
@@ -7,7 +7,7 @@
.
endm
.
macro
sti
mov
#
0xf0
,
r11
mov
#
0xf
ffffff
0
,
r11
extu.b
r11
,
r11
not
r11
,
r11
stc
sr
,
r10
...
...
arch/sh/include/asm/io.h
View file @
12cceb62
...
...
@@ -92,8 +92,12 @@
static
inline
void
ctrl_delay
(
void
)
{
#ifdef P2SEG
#ifdef CONFIG_CPU_SH4
__raw_readw
(
CCN_PVR
);
#elif defined(P2SEG)
__raw_readw
(
P2SEG
);
#else
#error "Need a dummy address for delay"
#endif
}
...
...
@@ -146,6 +150,7 @@ __BUILD_MEMORY_STRING(q, u64)
#define readl_relaxed(a) readl(a)
#define readq_relaxed(a) readq(a)
#ifndef CONFIG_GENERIC_IOMAP
/* Simple MMIO */
#define ioread8(a) __raw_readb(a)
#define ioread16(a) __raw_readw(a)
...
...
@@ -166,6 +171,15 @@ __BUILD_MEMORY_STRING(q, u64)
#define iowrite8_rep(a, s, c) __raw_writesb((a), (s), (c))
#define iowrite16_rep(a, s, c) __raw_writesw((a), (s), (c))
#define iowrite32_rep(a, s, c) __raw_writesl((a), (s), (c))
#endif
#define mmio_insb(p,d,c) __raw_readsb(p,d,c)
#define mmio_insw(p,d,c) __raw_readsw(p,d,c)
#define mmio_insl(p,d,c) __raw_readsl(p,d,c)
#define mmio_outsb(p,s,c) __raw_writesb(p,s,c)
#define mmio_outsw(p,s,c) __raw_writesw(p,s,c)
#define mmio_outsl(p,s,c) __raw_writesl(p,s,c)
/* synco on SH-4A, otherwise a nop */
#define mmiowb() wmb()
...
...
arch/sh/include/asm/unistd_32.h
View file @
12cceb62
...
...
@@ -132,7 +132,7 @@
#define __NR_clone 120
#define __NR_setdomainname 121
#define __NR_uname 122
#define __NR_
modify_ldt
123
#define __NR_
cacheflush
123
#define __NR_adjtimex 124
#define __NR_mprotect 125
#define __NR_sigprocmask 126
...
...
arch/sh/include/asm/unistd_64.h
View file @
12cceb62
...
...
@@ -137,7 +137,7 @@
#define __NR_clone 120
#define __NR_setdomainname 121
#define __NR_uname 122
#define __NR_
modify_ldt
123
#define __NR_
cacheflush
123
#define __NR_adjtimex 124
#define __NR_mprotect 125
#define __NR_sigprocmask 126
...
...
arch/sh/kernel/cpu/irq/ipr.c
View file @
12cceb62
...
...
@@ -35,6 +35,7 @@ static void disable_ipr_irq(unsigned int irq)
unsigned
long
addr
=
get_ipr_desc
(
irq
)
->
ipr_offsets
[
p
->
ipr_idx
];
/* Set the priority in IPR to 0 */
__raw_writew
(
__raw_readw
(
addr
)
&
(
0xffff
^
(
0xf
<<
p
->
shift
)),
addr
);
(
void
)
__raw_readw
(
addr
);
/* Read back to flush write posting */
}
static
void
enable_ipr_irq
(
unsigned
int
irq
)
...
...
arch/sh/kernel/cpu/sh3/entry.S
View file @
12cceb62
...
...
@@ -257,7 +257,7 @@ restore_all:
!
!
Calculate
new
SR
value
mov
k3
,
k2
!
original
SR
value
mov
#
0xf0
,
k1
mov
#
0xf
ffffff
0
,
k1
extu.b
k1
,
k1
not
k1
,
k1
and
k1
,
k2
!
Mask
original
SR
value
...
...
arch/sh/kernel/entry-common.S
View file @
12cceb62
...
...
@@ -98,8 +98,9 @@ need_resched:
mov
#
OFF_SR
,
r0
mov.l
@
(
r0
,
r15
),
r0
!
get
status
register
and
#
0xf0
,
r0
!
interrupts
off
(
exception
path
)?
cmp
/
eq
#
0xf0
,
r0
shlr
r0
and
#(
0xf0
>>
1
),
r0
!
interrupts
off
(
exception
path
)?
cmp
/
eq
#(
0xf0
>>
1
),
r0
bt
noresched
mov.l
3
f
,
r0
jsr
@
r0
!
call
preempt_schedule_irq
...
...
arch/sh/kernel/io.c
View file @
12cceb62
/*
*
linux/arch/sh/kernel/io.c
*
arch/sh/kernel/io.c - Machine independent I/O functions.
*
* Copyright (C) 2000 Stuart Menefy
* Copyright (C) 2000
- 2009
Stuart Menefy
* Copyright (C) 2005 Paul Mundt
*
* Provide real functions which expand to whatever the header file defined.
* Also definitions of machine independent IO functions.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
...
...
@@ -18,33 +15,87 @@
/*
* Copy data from IO memory space to "real" memory space.
* This needs to be optimized.
*/
void
memcpy_fromio
(
void
*
to
,
const
volatile
void
__iomem
*
from
,
unsigned
long
count
)
{
unsigned
char
*
p
=
to
;
while
(
count
)
{
count
--
;
*
p
=
readb
(
from
);
p
++
;
from
++
;
}
/*
* Would it be worthwhile doing byte and long transfers first
* to try and get aligned?
*/
#ifdef CONFIG_CPU_SH4
if
((
count
>=
0x20
)
&&
(((
u32
)
to
&
0x1f
)
==
0
)
&&
(((
u32
)
from
&
0x3
)
==
0
))
{
int
tmp2
,
tmp3
,
tmp4
,
tmp5
,
tmp6
;
__asm__
__volatile__
(
"1:
\n\t
"
"mov.l @%7+, r0
\n\t
"
"mov.l @%7+, %2
\n\t
"
"movca.l r0, @%0
\n\t
"
"mov.l @%7+, %3
\n\t
"
"mov.l @%7+, %4
\n\t
"
"mov.l @%7+, %5
\n\t
"
"mov.l @%7+, %6
\n\t
"
"mov.l @%7+, r7
\n\t
"
"mov.l @%7+, r0
\n\t
"
"mov.l %2, @(0x04,%0)
\n\t
"
"mov #0x20, %2
\n\t
"
"mov.l %3, @(0x08,%0)
\n\t
"
"sub %2, %1
\n\t
"
"mov.l %4, @(0x0c,%0)
\n\t
"
"cmp/hi %1, %2 ! T if 32 > count
\n\t
"
"mov.l %5, @(0x10,%0)
\n\t
"
"mov.l %6, @(0x14,%0)
\n\t
"
"mov.l r7, @(0x18,%0)
\n\t
"
"mov.l r0, @(0x1c,%0)
\n\t
"
"bf.s 1b
\n\t
"
" add #0x20, %0
\n\t
"
:
"=&r"
(
to
),
"=&r"
(
count
),
"=&r"
(
tmp2
),
"=&r"
(
tmp3
),
"=&r"
(
tmp4
),
"=&r"
(
tmp5
),
"=&r"
(
tmp6
),
"=&r"
(
from
)
:
"7"
(
from
),
"0"
(
to
),
"1"
(
count
)
:
"r0"
,
"r7"
,
"t"
,
"memory"
);
}
#endif
if
((((
u32
)
to
|
(
u32
)
from
)
&
0x3
)
==
0
)
{
for
(;
count
>
3
;
count
-=
4
)
{
*
(
u32
*
)
to
=
*
(
volatile
u32
*
)
from
;
to
+=
4
;
from
+=
4
;
}
}
for
(;
count
>
0
;
count
--
)
{
*
(
u8
*
)
to
=
*
(
volatile
u8
*
)
from
;
to
++
;
from
++
;
}
mb
();
}
EXPORT_SYMBOL
(
memcpy_fromio
);
/*
* Copy data from "real" memory space to IO memory space.
* This needs to be optimized.
*/
void
memcpy_toio
(
volatile
void
__iomem
*
to
,
const
void
*
from
,
unsigned
long
count
)
{
const
unsigned
char
*
p
=
from
;
while
(
count
)
{
count
--
;
writeb
(
*
p
,
to
);
p
++
;
to
++
;
}
if
((((
u32
)
to
|
(
u32
)
from
)
&
0x3
)
==
0
)
{
for
(
;
count
>
3
;
count
-=
4
)
{
*
(
volatile
u32
*
)
to
=
*
(
u32
*
)
from
;
to
+=
4
;
from
+=
4
;
}
}
for
(;
count
>
0
;
count
--
)
{
*
(
volatile
u8
*
)
to
=
*
(
u8
*
)
from
;
to
++
;
from
++
;
}
mb
();
}
EXPORT_SYMBOL
(
memcpy_toio
);
...
...
@@ -62,6 +113,8 @@ void memset_io(volatile void __iomem *dst, int c, unsigned long count)
}
EXPORT_SYMBOL
(
memset_io
);
#ifndef CONFIG_GENERIC_IOMAP
void
__iomem
*
ioport_map
(
unsigned
long
port
,
unsigned
int
nr
)
{
void
__iomem
*
ret
;
...
...
@@ -79,3 +132,5 @@ void ioport_unmap(void __iomem *addr)
sh_mv
.
mv_ioport_unmap
(
addr
);
}
EXPORT_SYMBOL
(
ioport_unmap
);
#endif
/* CONFIG_GENERIC_IOMAP */
arch/sh/kernel/io_generic.c
View file @
12cceb62
...
...
@@ -73,35 +73,19 @@ u32 generic_inl_p(unsigned long port)
void
generic_insb
(
unsigned
long
port
,
void
*
dst
,
unsigned
long
count
)
{
volatile
u8
*
port_addr
;
u8
*
buf
=
dst
;
port_addr
=
(
volatile
u8
__force
*
)
__ioport_map
(
port
,
1
);
while
(
count
--
)
*
buf
++
=
*
port_addr
;
__raw_readsb
(
__ioport_map
(
port
,
1
),
dst
,
count
);
dummy_read
();
}
void
generic_insw
(
unsigned
long
port
,
void
*
dst
,
unsigned
long
count
)
{
volatile
u16
*
port_addr
;
u16
*
buf
=
dst
;
port_addr
=
(
volatile
u16
__force
*
)
__ioport_map
(
port
,
2
);
while
(
count
--
)
*
buf
++
=
*
port_addr
;
__raw_readsw
(
__ioport_map
(
port
,
2
),
dst
,
count
);
dummy_read
();
}
void
generic_insl
(
unsigned
long
port
,
void
*
dst
,
unsigned
long
count
)
{
volatile
u32
*
port_addr
;
u32
*
buf
=
dst
;
port_addr
=
(
volatile
u32
__force
*
)
__ioport_map
(
port
,
4
);
while
(
count
--
)
*
buf
++
=
*
port_addr
;
__raw_readsl
(
__ioport_map
(
port
,
4
),
dst
,
count
);
dummy_read
();
}
...
...
@@ -145,37 +129,19 @@ void generic_outl_p(u32 b, unsigned long port)
*/
void
generic_outsb
(
unsigned
long
port
,
const
void
*
src
,
unsigned
long
count
)
{
volatile
u8
*
port_addr
;
const
u8
*
buf
=
src
;
port_addr
=
(
volatile
u8
__force
*
)
__ioport_map
(
port
,
1
);
while
(
count
--
)
*
port_addr
=
*
buf
++
;
__raw_writesb
(
__ioport_map
(
port
,
1
),
src
,
count
);
dummy_read
();
}
void
generic_outsw
(
unsigned
long
port
,
const
void
*
src
,
unsigned
long
count
)
{
volatile
u16
*
port_addr
;
const
u16
*
buf
=
src
;
port_addr
=
(
volatile
u16
__force
*
)
__ioport_map
(
port
,
2
);
while
(
count
--
)
*
port_addr
=
*
buf
++
;
__raw_writesw
(
__ioport_map
(
port
,
2
),
src
,
count
);
dummy_read
();
}
void
generic_outsl
(
unsigned
long
port
,
const
void
*
src
,
unsigned
long
count
)
{
volatile
u32
*
port_addr
;
const
u32
*
buf
=
src
;
port_addr
=
(
volatile
u32
__force
*
)
__ioport_map
(
port
,
4
);
while
(
count
--
)
*
port_addr
=
*
buf
++
;
__raw_writesl
(
__ioport_map
(
port
,
4
),
src
,
count
);
dummy_read
();
}
...
...
arch/sh/kernel/irq.c
View file @
12cceb62
...
...
@@ -114,7 +114,7 @@ asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs)
#endif
irq_enter
();
irq
=
irq_demux
(
intc_
evt2irq
(
irq
));
irq
=
irq_demux
(
evt2irq
(
irq
));
#ifdef CONFIG_IRQSTACKS
curctx
=
(
union
irq_ctx
*
)
current_thread_info
();
...
...
arch/sh/kernel/kgdb.c
View file @
12cceb62
...
...
@@ -195,8 +195,6 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
regs
->
gbr
=
gdb_regs
[
GDB_GBR
];
regs
->
mach
=
gdb_regs
[
GDB_MACH
];
regs
->
macl
=
gdb_regs
[
GDB_MACL
];
__asm__
__volatile__
(
"ldc %0, vbr"
:
:
"r"
(
gdb_regs
[
GDB_VBR
]));
}
void
sleeping_thread_to_gdb_regs
(
unsigned
long
*
gdb_regs
,
struct
task_struct
*
p
)
...
...
arch/sh/kernel/process_32.c
View file @
12cceb62
...
...
@@ -32,15 +32,35 @@
#include <asm/ubc.h>
#include <asm/fpu.h>
#include <asm/syscalls.h>
#include <asm/watchdog.h>
int
ubc_usercnt
=
0
;
#ifdef CONFIG_32BIT
static
void
watchdog_trigger_immediate
(
void
)
{
sh_wdt_write_cnt
(
0xFF
);
sh_wdt_write_csr
(
0xC2
);
}
void
machine_restart
(
char
*
__unused
)
{
local_irq_disable
();
/* Use watchdog timer to trigger reset */
watchdog_trigger_immediate
();
while
(
1
)
cpu_sleep
();
}
#else
void
machine_restart
(
char
*
__unused
)
{
/* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
asm
volatile
(
"ldc %0, sr
\n\t
"
"mov.l @%1, %0"
:
:
"r"
(
0x10000000
),
"r"
(
0x80000001
));
}
#endif
void
machine_halt
(
void
)
{
...
...
arch/sh/kernel/setup.c
View file @
12cceb62
...
...
@@ -404,10 +404,14 @@ void __init setup_arch(char **cmdline_p)
if
(
!
memory_end
)
memory_end
=
memory_start
+
__MEMORY_SIZE
;
#ifdef CONFIG_CMDLINE_
BOOL
#ifdef CONFIG_CMDLINE_
OVERWRITE
strlcpy
(
command_line
,
CONFIG_CMDLINE
,
sizeof
(
command_line
));
#else
strlcpy
(
command_line
,
COMMAND_LINE
,
sizeof
(
command_line
));
#ifdef CONFIG_CMDLINE_EXTEND
strlcat
(
command_line
,
" "
,
sizeof
(
command_line
));
strlcat
(
command_line
,
CONFIG_CMDLINE
,
sizeof
(
command_line
));
#endif
#endif
/* Save unparsed command line copy for /proc/cmdline */
...
...
arch/sh/kernel/signal_32.c
View file @
12cceb62
...
...
@@ -40,6 +40,16 @@ struct fdpic_func_descriptor {
unsigned
long
GOT
;
};
/*
* The following define adds a 64 byte gap between the signal
* stack frame and previous contents of the stack. This allows
* frame unwinding in a function epilogue but only if a frame
* pointer is used in the function. This is necessary because
* current gcc compilers (<4.3) do not generate unwind info on
* SH for function epilogues.
*/
#define UNWINDGUARD 64
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
...
...
@@ -327,7 +337,7 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
sp
=
current
->
sas_ss_sp
+
current
->
sas_ss_size
;
}
return
(
void
__user
*
)((
sp
-
frame_size
)
&
-
8ul
);
return
(
void
__user
*
)((
sp
-
(
frame_size
+
UNWINDGUARD
)
)
&
-
8ul
);
}
/* These symbols are defined with the addresses in the vsyscall page.
...
...
arch/sh/kernel/sys_sh.c
View file @
12cceb62
...
...
@@ -25,6 +25,8 @@
#include <asm/syscalls.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include <asm/cacheflush.h>
#include <asm/cachectl.h>
static
inline
long
do_mmap2
(
unsigned
long
addr
,
unsigned
long
len
,
unsigned
long
prot
,
...
...
@@ -179,6 +181,47 @@ asmlinkage int sys_ipc(uint call, int first, int second,
return
-
EINVAL
;
}
/* sys_cacheflush -- flush (part of) the processor cache. */
asmlinkage
int
sys_cacheflush
(
unsigned
long
addr
,
unsigned
long
len
,
int
op
)
{
struct
vm_area_struct
*
vma
;
if
((
op
<=
0
)
||
(
op
>
(
CACHEFLUSH_D_PURGE
|
CACHEFLUSH_I
)))
return
-
EINVAL
;
/*
* Verify that the specified address region actually belongs
* to this process.
*/
if
(
addr
+
len
<
addr
)
return
-
EFAULT
;
down_read
(
&
current
->
mm
->
mmap_sem
);
vma
=
find_vma
(
current
->
mm
,
addr
);
if
(
vma
==
NULL
||
addr
<
vma
->
vm_start
||
addr
+
len
>
vma
->
vm_end
)
{
up_read
(
&
current
->
mm
->
mmap_sem
);
return
-
EFAULT
;
}
switch
(
op
&
CACHEFLUSH_D_PURGE
)
{
case
CACHEFLUSH_D_INVAL
:
__flush_invalidate_region
((
void
*
)
addr
,
len
);
break
;
case
CACHEFLUSH_D_WB
:
__flush_wback_region
((
void
*
)
addr
,
len
);
break
;
case
CACHEFLUSH_D_PURGE
:
__flush_purge_region
((
void
*
)
addr
,
len
);
break
;
}
if
(
op
&
CACHEFLUSH_I
)
flush_cache_all
();
up_read
(
&
current
->
mm
->
mmap_sem
);
return
0
;
}
asmlinkage
int
sys_uname
(
struct
old_utsname
__user
*
name
)
{
int
err
;
...
...
arch/sh/kernel/syscalls_32.S
View file @
12cceb62
...
...
@@ -139,7 +139,7 @@ ENTRY(sys_call_table)
.
long
sys_clone
/*
120
*/
.
long
sys_setdomainname
.
long
sys_newuname
.
long
sys_
ni_syscall
/*
sys_modify_ldt
*/
.
long
sys_
cacheflush
/*
x86
:
sys_modify_ldt
*/
.
long
sys_adjtimex
.
long
sys_mprotect
/*
125
*/
.
long
sys_sigprocmask
...
...
arch/sh/kernel/syscalls_64.S
View file @
12cceb62
...
...
@@ -143,7 +143,7 @@ sys_call_table:
.
long
sys_clone
/*
120
*/
.
long
sys_setdomainname
.
long
sys_newuname
.
long
sys_
ni_syscall
/*
sys_modify_ldt
*/
.
long
sys_
cacheflush
/*
x86
:
sys_modify_ldt
*/
.
long
sys_adjtimex
.
long
sys_mprotect
/*
125
*/
.
long
sys_sigprocmask
...
...
arch/sh/kernel/traps_32.c
View file @
12cceb62
...
...
@@ -24,6 +24,7 @@
#include <linux/kdebug.h>
#include <linux/kexec.h>
#include <linux/limits.h>
#include <linux/proc_fs.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/fpu.h>
...
...
@@ -44,6 +45,87 @@
#define TRAP_ILLEGAL_SLOT_INST 13
#endif
static
unsigned
long
se_user
;
static
unsigned
long
se_sys
;
static
unsigned
long
se_skipped
;
static
unsigned
long
se_half
;
static
unsigned
long
se_word
;
static
unsigned
long
se_dword
;
static
unsigned
long
se_multi
;
/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not
valid! */
static
int
se_usermode
=
3
;
/* 0: no warning 1: print a warning message */
static
int
se_kernmode_warn
=
1
;
#ifdef CONFIG_PROC_FS
static
const
char
*
se_usermode_action
[]
=
{
"ignored"
,
"warn"
,
"fixup"
,
"fixup+warn"
,
"signal"
,
"signal+warn"
};
static
int
proc_alignment_read
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
char
*
p
=
page
;
int
len
;
p
+=
sprintf
(
p
,
"User:
\t\t
%lu
\n
"
,
se_user
);
p
+=
sprintf
(
p
,
"System:
\t\t
%lu
\n
"
,
se_sys
);
p
+=
sprintf
(
p
,
"Skipped:
\t
%lu
\n
"
,
se_skipped
);
p
+=
sprintf
(
p
,
"Half:
\t\t
%lu
\n
"
,
se_half
);
p
+=
sprintf
(
p
,
"Word:
\t\t
%lu
\n
"
,
se_word
);
p
+=
sprintf
(
p
,
"DWord:
\t\t
%lu
\n
"
,
se_dword
);
p
+=
sprintf
(
p
,
"Multi:
\t\t
%lu
\n
"
,
se_multi
);
p
+=
sprintf
(
p
,
"User faults:
\t
%i (%s)
\n
"
,
se_usermode
,
se_usermode_action
[
se_usermode
]);
p
+=
sprintf
(
p
,
"Kernel faults:
\t
%i (fixup%s)
\n
"
,
se_kernmode_warn
,
se_kernmode_warn
?
"+warn"
:
""
);
len
=
(
p
-
page
)
-
off
;
if
(
len
<
0
)
len
=
0
;
*
eof
=
(
len
<=
count
)
?
1
:
0
;
*
start
=
page
+
off
;
return
len
;
}
static
int
proc_alignment_write
(
struct
file
*
file
,
const
char
__user
*
buffer
,
unsigned
long
count
,
void
*
data
)
{
char
mode
;
if
(
count
>
0
)
{
if
(
get_user
(
mode
,
buffer
))
return
-
EFAULT
;
if
(
mode
>=
'0'
&&
mode
<=
'5'
)
se_usermode
=
mode
-
'0'
;
}
return
count
;
}
static
int
proc_alignment_kern_write
(
struct
file
*
file
,
const
char
__user
*
buffer
,
unsigned
long
count
,
void
*
data
)
{
char
mode
;
if
(
count
>
0
)
{
if
(
get_user
(
mode
,
buffer
))
return
-
EFAULT
;
if
(
mode
>=
'0'
&&
mode
<=
'1'
)
se_kernmode_warn
=
mode
-
'0'
;
}
return
count
;
}
#endif
static
void
dump_mem
(
const
char
*
str
,
unsigned
long
bottom
,
unsigned
long
top
)
{
unsigned
long
p
;
...
...
@@ -194,6 +276,13 @@ static int handle_unaligned_ins(insn_size_t instruction, struct pt_regs *regs,
count
=
1
<<
(
instruction
&
3
);
switch
(
count
)
{
case
1
:
se_half
+=
1
;
break
;
case
2
:
se_word
+=
1
;
break
;
case
4
:
se_dword
+=
1
;
break
;
case
8
:
se_multi
+=
1
;
break
;
/* ??? */
}
ret
=
-
EFAULT
;
switch
(
instruction
>>
12
)
{
case
0
:
/* mov.[bwl] to/from memory via r0+rn */
...
...
@@ -359,13 +448,6 @@ static inline int handle_delayslot(struct pt_regs *regs,
#define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4)
#define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4)
/*
* XXX: SH-2A needs this too, but it needs an overhaul thanks to mixed 32-bit
* opcodes..
*/
static
int
handle_unaligned_notify_count
=
10
;
int
handle_unaligned_access
(
insn_size_t
instruction
,
struct
pt_regs
*
regs
,
struct
mem_access
*
ma
)
{
...
...
@@ -375,15 +457,13 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
index
=
(
instruction
>>
8
)
&
15
;
/* 0x0F00 */
rm
=
regs
->
regs
[
index
];
/* shout about the first ten userspace fixups */
if
(
user_mode
(
regs
)
&&
handle_unaligned_notify_count
>
0
)
{
handle_unaligned_notify_count
--
;
printk
(
KERN_NOTICE
"Fixing up unaligned userspace access "
/* shout about fixups */
if
(
printk_ratelimit
())
printk
(
KERN_NOTICE
"Fixing up unaligned %s access "
"in
\"
%s
\"
pid=%d pc=0x%p ins=0x%04hx
\n
"
,
user_mode
(
regs
)
?
"userspace"
:
"kernel"
,
current
->
comm
,
task_pid_nr
(
current
),
(
void
*
)
regs
->
pc
,
instruction
);
}
ret
=
-
EFAULT
;
switch
(
instruction
&
0xF000
)
{
...
...
@@ -539,6 +619,36 @@ asmlinkage void do_address_error(struct pt_regs *regs,
local_irq_enable
();
se_user
+=
1
;
#ifndef CONFIG_CPU_SH2A
set_fs
(
USER_DS
);
if
(
copy_from_user
(
&
instruction
,
(
u16
*
)(
regs
->
pc
&
~
1
),
2
))
{
set_fs
(
oldfs
);
goto
uspace_segv
;
}
set_fs
(
oldfs
);
/* shout about userspace fixups */
if
(
se_usermode
&
1
)
printk
(
KERN_NOTICE
"Unaligned userspace access "
"in
\"
%s
\"
pid=%d pc=0x%p ins=0x%04hx
\n
"
,
current
->
comm
,
current
->
pid
,
(
void
*
)
regs
->
pc
,
instruction
);
#endif
if
(
se_usermode
&
2
)
goto
fixup
;
if
(
se_usermode
&
4
)
goto
uspace_segv
;
else
{
/* ignore */
regs
->
pc
+=
instruction_size
(
instruction
);
return
;
}
fixup:
/* bad PC is not something we can fix */
if
(
regs
->
pc
&
1
)
{
si_code
=
BUS_ADRALN
;
...
...
@@ -546,15 +656,6 @@ asmlinkage void do_address_error(struct pt_regs *regs,
}
set_fs
(
USER_DS
);
if
(
copy_from_user
(
&
instruction
,
(
void
__user
*
)(
regs
->
pc
),
sizeof
(
instruction
)))
{
/* Argh. Fault on the instruction itself.
This should never happen non-SMP
*/
set_fs
(
oldfs
);
goto
uspace_segv
;
}
tmp
=
handle_unaligned_access
(
instruction
,
regs
,
&
user_mem_access
);
set_fs
(
oldfs
);
...
...
@@ -572,6 +673,14 @@ asmlinkage void do_address_error(struct pt_regs *regs,
info
.
si_addr
=
(
void
__user
*
)
address
;
force_sig_info
(
SIGBUS
,
&
info
,
current
);
}
else
{
se_sys
+=
1
;
if
(
se_kernmode_warn
)
printk
(
KERN_NOTICE
"Unaligned kernel access "
"on behalf of
\"
%s
\"
pid=%d pc=0x%p ins=0x%04hx
\n
"
,
current
->
comm
,
current
->
pid
,
(
void
*
)
regs
->
pc
,
instruction
);
if
(
regs
->
pc
&
1
)
die
(
"unaligned program counter"
,
regs
,
error_code
);
...
...
@@ -881,3 +990,38 @@ void dump_stack(void)
show_stack
(
NULL
,
NULL
);
}
EXPORT_SYMBOL
(
dump_stack
);
#ifdef CONFIG_PROC_FS
/*
* This needs to be done after sysctl_init, otherwise sys/ will be
* overwritten. Actually, this shouldn't be in sys/ at all since
* it isn't a sysctl, and it doesn't contain sysctl information.
* We now locate it in /proc/cpu/alignment instead.
*/
static
int
__init
alignment_init
(
void
)
{
struct
proc_dir_entry
*
dir
,
*
res
;
dir
=
proc_mkdir
(
"cpu"
,
NULL
);
if
(
!
dir
)
return
-
ENOMEM
;
res
=
create_proc_entry
(
"alignment"
,
S_IWUSR
|
S_IRUGO
,
dir
);
if
(
!
res
)
return
-
ENOMEM
;
res
->
read_proc
=
proc_alignment_read
;
res
->
write_proc
=
proc_alignment_write
;
res
=
create_proc_entry
(
"kernel_alignment"
,
S_IWUSR
|
S_IRUGO
,
dir
);
if
(
!
res
)
return
-
ENOMEM
;
res
->
read_proc
=
proc_alignment_read
;
res
->
write_proc
=
proc_alignment_kern_write
;
return
0
;
}
fs_initcall
(
alignment_init
);
#endif
arch/sh/lib/clear_page.S
View file @
12cceb62
...
...
@@ -57,7 +57,7 @@ ENTRY(clear_page)
ENTRY
(
__clear_user
)
!
mov
#
0
,
r0
mov
#
0x
e0
,
r1
!
0xffffffe0
mov
#
0x
ffffffe0
,
r1
!
!
r4
..
(
r4
+
31
)&
~
32
--------
not
aligned
[
Area
0
]
!
(
r4
+
31
)&
~
32
..
(
r4
+
r5
)&
~
32
--------
aligned
[
Area
1
]
...
...
arch/sh/lib/delay.c
View file @
12cceb62
...
...
@@ -21,13 +21,14 @@ void __delay(unsigned long loops)
inline
void
__const_udelay
(
unsigned
long
xloops
)
{
xloops
*=
4
;
__asm__
(
"dmulu.l %0, %2
\n\t
"
"sts mach, %0"
:
"=r"
(
xloops
)
:
"0"
(
xloops
),
"r"
(
HZ
*
cpu_data
[
raw_smp_processor_id
()].
loops_per_jiffy
)
"r"
(
cpu_data
[
raw_smp_processor_id
()].
loops_per_jiffy
*
(
HZ
/
4
)
)
:
"macl"
,
"mach"
);
__delay
(
xloops
);
__delay
(
++
xloops
);
}
void
__udelay
(
unsigned
long
usecs
)
...
...
arch/sh/mm/cache-sh4.c
View file @
12cceb62
...
...
@@ -581,6 +581,31 @@ static void __flush_cache_4096(unsigned long addr, unsigned long phys,
* Break the 1, 2 and 4 way variants of this out into separate functions to
* avoid nearly all the overhead of having the conditional stuff in the function
* bodies (+ the 1 and 2 way cases avoid saving any registers too).
*
* We want to eliminate unnecessary bus transactions, so this code uses
* a non-obvious technique.
*
* Loop over a cache way sized block of, one cache line at a time. For each
* line, use movca.a to cause the current cache line contents to be written
* back, but without reading anything from main memory. However this has the
* side effect that the cache is now caching that memory location. So follow
* this with a cache invalidate to mark the cache line invalid. And do all
* this with interrupts disabled, to avoid the cache line being accidently
* evicted while it is holding garbage.
*
* This also breaks in a number of circumstances:
* - if there are modifications to the region of memory just above
* empty_zero_page (for example because a breakpoint has been placed
* there), then these can be lost.
*
* This is because the the memory address which the cache temporarily
* caches in the above description is empty_zero_page. So the
* movca.l hits the cache (it is assumed that it misses, or at least
* isn't dirty), modifies the line and then invalidates it, losing the
* required change.
*
* - If caches are disabled or configured in write-through mode, then
* the movca.l writes garbage directly into memory.
*/
static
void
__flush_dcache_segment_1way
(
unsigned
long
start
,
unsigned
long
extent_per_way
)
...
...
@@ -630,6 +655,25 @@ static void __flush_dcache_segment_1way(unsigned long start,
}
while
(
a0
<
a0e
);
}
#ifdef CONFIG_CACHE_WRITETHROUGH
/* This method of cache flushing avoids the problems discussed
* in the comment above if writethrough caches are enabled. */
static
void
__flush_dcache_segment_2way
(
unsigned
long
start
,
unsigned
long
extent_per_way
)
{
unsigned
long
array_addr
;
array_addr
=
CACHE_OC_ADDRESS_ARRAY
|
(
start
&
cpu_data
->
dcache
.
entry_mask
);
while
(
extent_per_way
)
{
ctrl_outl
(
0
,
array_addr
);
ctrl_outl
(
0
,
array_addr
+
cpu_data
->
dcache
.
way_incr
);
array_addr
+=
cpu_data
->
dcache
.
linesz
;
extent_per_way
-=
cpu_data
->
dcache
.
linesz
;
}
}
#else
static
void
__flush_dcache_segment_2way
(
unsigned
long
start
,
unsigned
long
extent_per_way
)
{
...
...
@@ -688,6 +732,7 @@ static void __flush_dcache_segment_2way(unsigned long start,
a1
+=
linesz
;
}
while
(
a0
<
a0e
);
}
#endif
static
void
__flush_dcache_segment_4way
(
unsigned
long
start
,
unsigned
long
extent_per_way
)
...
...
arch/sh/mm/ioremap_32.c
View file @
12cceb62
...
...
@@ -57,14 +57,6 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
if
(
is_pci_memory_fixed_range
(
phys_addr
,
size
))
return
(
void
__iomem
*
)
phys_addr
;
#if !defined(CONFIG_PMB_FIXED)
/*
* Don't allow anybody to remap normal RAM that we're using..
*/
if
(
phys_addr
<
virt_to_phys
(
high_memory
))
return
NULL
;
#endif
/*
* Mappings have to be page-aligned
*/
...
...
drivers/sh/intc.c
View file @
12cceb62
...
...
@@ -77,7 +77,7 @@ static unsigned long ack_handle[NR_IRQS];
static
inline
struct
intc_desc_int
*
get_intc_desc
(
unsigned
int
irq
)
{
struct
irq_chip
*
chip
=
get_irq_chip
(
irq
);
return
(
void
*
)((
char
*
)
chip
-
offsetof
(
struct
intc_desc_int
,
chip
)
);
return
container_of
(
chip
,
struct
intc_desc_int
,
chip
);
}
static
inline
unsigned
int
set_field
(
unsigned
int
value
,
...
...
@@ -95,16 +95,19 @@ static inline unsigned int set_field(unsigned int value,
static
void
write_8
(
unsigned
long
addr
,
unsigned
long
h
,
unsigned
long
data
)
{
__raw_writeb
(
set_field
(
0
,
data
,
h
),
addr
);
(
void
)
__raw_readb
(
addr
);
/* Defeat write posting */
}
static
void
write_16
(
unsigned
long
addr
,
unsigned
long
h
,
unsigned
long
data
)
{
__raw_writew
(
set_field
(
0
,
data
,
h
),
addr
);
(
void
)
__raw_readw
(
addr
);
/* Defeat write posting */
}
static
void
write_32
(
unsigned
long
addr
,
unsigned
long
h
,
unsigned
long
data
)
{
__raw_writel
(
set_field
(
0
,
data
,
h
),
addr
);
(
void
)
__raw_readl
(
addr
);
/* Defeat write posting */
}
static
void
modify_8
(
unsigned
long
addr
,
unsigned
long
h
,
unsigned
long
data
)
...
...
@@ -112,6 +115,7 @@ static void modify_8(unsigned long addr, unsigned long h, unsigned long data)
unsigned
long
flags
;
local_irq_save
(
flags
);
__raw_writeb
(
set_field
(
__raw_readb
(
addr
),
data
,
h
),
addr
);
(
void
)
__raw_readb
(
addr
);
/* Defeat write posting */
local_irq_restore
(
flags
);
}
...
...
@@ -120,6 +124,7 @@ static void modify_16(unsigned long addr, unsigned long h, unsigned long data)
unsigned
long
flags
;
local_irq_save
(
flags
);
__raw_writew
(
set_field
(
__raw_readw
(
addr
),
data
,
h
),
addr
);
(
void
)
__raw_readw
(
addr
);
/* Defeat write posting */
local_irq_restore
(
flags
);
}
...
...
@@ -128,6 +133,7 @@ static void modify_32(unsigned long addr, unsigned long h, unsigned long data)
unsigned
long
flags
;
local_irq_save
(
flags
);
__raw_writel
(
set_field
(
__raw_readl
(
addr
),
data
,
h
),
addr
);
(
void
)
__raw_readl
(
addr
);
/* Defeat write posting */
local_irq_restore
(
flags
);
}
...
...
@@ -657,16 +663,9 @@ static unsigned int __init save_reg(struct intc_desc_int *d,
return
0
;
}
static
unsigned
char
*
intc_evt2irq_table
;
unsigned
int
intc_evt2irq
(
unsigned
int
vector
)
static
void
intc_redirect_irq
(
unsigned
int
irq
,
struct
irq_desc
*
desc
)
{
unsigned
int
irq
=
evt2irq
(
vector
);
if
(
intc_evt2irq_table
&&
intc_evt2irq_table
[
irq
])
irq
=
intc_evt2irq_table
[
irq
];
return
irq
;
generic_handle_irq
((
unsigned
int
)
get_irq_data
(
irq
));
}
void
__init
register_intc_controller
(
struct
intc_desc
*
desc
)
...
...
@@ -739,34 +738,6 @@ void __init register_intc_controller(struct intc_desc *desc)
BUG_ON
(
k
>
256
);
/* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
/* keep the first vector only if same enum is used multiple times */
for
(
i
=
0
;
i
<
desc
->
nr_vectors
;
i
++
)
{
struct
intc_vect
*
vect
=
desc
->
vectors
+
i
;
int
first_irq
=
evt2irq
(
vect
->
vect
);
if
(
!
vect
->
enum_id
)
continue
;
for
(
k
=
i
+
1
;
k
<
desc
->
nr_vectors
;
k
++
)
{
struct
intc_vect
*
vect2
=
desc
->
vectors
+
k
;
if
(
vect
->
enum_id
!=
vect2
->
enum_id
)
continue
;
vect2
->
enum_id
=
0
;
if
(
!
intc_evt2irq_table
)
intc_evt2irq_table
=
kzalloc
(
NR_IRQS
,
GFP_NOWAIT
);
if
(
!
intc_evt2irq_table
)
{
pr_warning
(
"intc: cannot allocate evt2irq!
\n
"
);
continue
;
}
intc_evt2irq_table
[
evt2irq
(
vect2
->
vect
)]
=
first_irq
;
}
}
/* register the vectors one by one */
for
(
i
=
0
;
i
<
desc
->
nr_vectors
;
i
++
)
{
struct
intc_vect
*
vect
=
desc
->
vectors
+
i
;
...
...
@@ -783,6 +754,21 @@ void __init register_intc_controller(struct intc_desc *desc)
}
intc_register_irq
(
desc
,
d
,
vect
->
enum_id
,
irq
);
for
(
k
=
i
+
1
;
k
<
desc
->
nr_vectors
;
k
++
)
{
struct
intc_vect
*
vect2
=
desc
->
vectors
+
k
;
unsigned
int
irq2
=
evt2irq
(
vect2
->
vect
);
if
(
vect
->
enum_id
!=
vect2
->
enum_id
)
continue
;
vect2
->
enum_id
=
0
;
/* redirect this interrupts to the first one */
set_irq_chip_and_handler_name
(
irq2
,
&
d
->
chip
,
intc_redirect_irq
,
"redirect"
);
set_irq_data
(
irq2
,
(
void
*
)
irq
);
}
}
}
...
...
include/linux/sh_intc.h
View file @
12cceb62
...
...
@@ -85,7 +85,6 @@ struct intc_desc symbol __initdata = { \
}
#endif
unsigned
int
intc_evt2irq
(
unsigned
int
vector
);
void
__init
register_intc_controller
(
struct
intc_desc
*
desc
);
int
intc_set_priority
(
unsigned
int
irq
,
unsigned
int
prio
);
...
...
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