Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
12cceb62
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
12cceb62
编写于
8月 24, 2009
作者:
P
Paul Mundt
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'sh/st-integration'
上级
f1332786
05ecd5a1
变更
29
隐藏空白更改
内联
并排
Showing
29 changed file
with
476 addition
and
155 deletion
+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
未找到文件。
arch/sh/Kconfig
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录