Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (29 commits) sh: enable maple_keyb in dreamcast_defconfig. SH2(A) cache update nommu: Provide vmalloc_exec(). add addrespace definition for sh2a. sh: Kill off ARCH_SUPPORTS_AOUT and remnants of a.out support. sh: define GENERIC_HARDIRQS_NO__DO_IRQ. sh: define GENERIC_LOCKBREAK. sh: Save NUMA node data in vmcore for crash dumps. sh: module_alloc() should be using vmalloc_exec(). sh: Fix up __bug_table handling in module loader. sh: Add documentation and integrate into docbook build. sh: Fix up broken kerneldoc comments. maple: Kill useless private_data pointer. maple: Clean up maple_driver_register/unregister routines. input: Clean up maple keyboard driver maple: allow removal and reinsertion of keyboard driver module sh: /proc/asids depends on MMU. arch/sh/boards/mach-se/7343/irq.c: removed duplicated #include arch/sh/boards/board-ap325rxa.c: removed duplicated #include sh/boards/Makefile typo fix ...
This commit is contained in:
commit
2e1e9212ed
|
@ -12,7 +12,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
|
|||
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
|
||||
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
|
||||
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
|
||||
mac80211.xml debugobjects.xml
|
||||
mac80211.xml debugobjects.xml sh.xml
|
||||
|
||||
###
|
||||
# The build process is as follows (targets):
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
||||
|
||||
<book id="sh-drivers">
|
||||
<bookinfo>
|
||||
<title>SuperH Interfaces Guide</title>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Paul</firstname>
|
||||
<surname>Mundt</surname>
|
||||
<affiliation>
|
||||
<address>
|
||||
<email>lethal@linux-sh.org</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<copyright>
|
||||
<year>2008</year>
|
||||
<holder>Paul Mundt</holder>
|
||||
</copyright>
|
||||
<copyright>
|
||||
<year>2008</year>
|
||||
<holder>Renesas Technology Corp.</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>
|
||||
This documentation is free software; you can redistribute
|
||||
it and/or modify it under the terms of the GNU General Public
|
||||
License version 2 as published by the Free Software Foundation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This program is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
MA 02111-1307 USA
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For more details see the file COPYING in the source
|
||||
distribution of Linux.
|
||||
</para>
|
||||
</legalnotice>
|
||||
</bookinfo>
|
||||
|
||||
<toc></toc>
|
||||
|
||||
<chapter id="mm">
|
||||
<title>Memory Management</title>
|
||||
<sect1 id="sh4">
|
||||
<title>SH-4</title>
|
||||
<sect2 id="sq">
|
||||
<title>Store Queue API</title>
|
||||
!Earch/sh/kernel/cpu/sh4/sq.c
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="sh5">
|
||||
<title>SH-5</title>
|
||||
<sect2 id="tlb">
|
||||
<title>TLB Interfaces</title>
|
||||
!Iarch/sh/mm/tlb-sh5.c
|
||||
!Iarch/sh/include/asm/tlb_64.h
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
<chapter id="clk">
|
||||
<title>Clock Framework Extensions</title>
|
||||
!Iarch/sh/include/asm/clock.h
|
||||
</chapter>
|
||||
<chapter id="mach">
|
||||
<title>Machine Specific Interfaces</title>
|
||||
<sect1 id="dreamcast">
|
||||
<title>mach-dreamcast</title>
|
||||
!Iarch/sh/boards/mach-dreamcast/rtc.c
|
||||
</sect1>
|
||||
<sect1 id="x3proto">
|
||||
<title>mach-x3proto</title>
|
||||
!Earch/sh/boards/mach-x3proto/ilsel.c
|
||||
</sect1>
|
||||
</chapter>
|
||||
<chapter id="busses">
|
||||
<title>Busses</title>
|
||||
<sect1 id="superhyway">
|
||||
<title>SuperHyway</title>
|
||||
!Edrivers/sh/superhyway/superhyway.c
|
||||
</sect1>
|
||||
|
||||
<sect1 id="maple">
|
||||
<title>Maple</title>
|
||||
!Edrivers/sh/maple/maple.c
|
||||
</sect1>
|
||||
</chapter>
|
||||
</book>
|
|
@ -48,6 +48,9 @@ config GENERIC_HWEIGHT
|
|||
config GENERIC_HARDIRQS
|
||||
def_bool y
|
||||
|
||||
config GENERIC_HARDIRQS_NO__DO_IRQ
|
||||
def_bool y
|
||||
|
||||
config GENERIC_IRQ_PROBE
|
||||
def_bool y
|
||||
|
||||
|
@ -63,6 +66,10 @@ config GENERIC_TIME
|
|||
config GENERIC_CLOCKEVENTS
|
||||
def_bool n
|
||||
|
||||
config GENERIC_LOCKBREAK
|
||||
def_bool y
|
||||
depends on SMP && PREEMPT
|
||||
|
||||
config SYS_SUPPORTS_PM
|
||||
bool
|
||||
|
||||
|
@ -94,9 +101,6 @@ config ARCH_HAS_ILOG2_U64
|
|||
config ARCH_NO_VIRT_TO_BUS
|
||||
def_bool y
|
||||
|
||||
config ARCH_SUPPORTS_AOUT
|
||||
def_bool y
|
||||
|
||||
config IO_TRAPPED
|
||||
bool
|
||||
|
||||
|
@ -483,6 +487,23 @@ config CRASH_DUMP
|
|||
|
||||
For more details see Documentation/kdump/kdump.txt
|
||||
|
||||
config SECCOMP
|
||||
bool "Enable seccomp to safely compute untrusted bytecode"
|
||||
depends on PROC_FS
|
||||
default y
|
||||
help
|
||||
This kernel feature is useful for number crunching applications
|
||||
that may need to compute untrusted bytecode during their
|
||||
execution. By using pipes or other transports made available to
|
||||
the process as file descriptors supporting the read/write
|
||||
syscalls, it's possible to isolate those applications in
|
||||
their own address space using seccomp. Once seccomp is
|
||||
enabled via prctl, it cannot be disabled and the task is only
|
||||
allowed to execute a few safe syscalls defined by each seccomp
|
||||
mode.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config SMP
|
||||
bool "Symmetric multi-processing support"
|
||||
depends on SYS_SUPPORTS_SMP
|
||||
|
|
|
@ -182,7 +182,7 @@ if SUPERH64
|
|||
|
||||
config SH64_PROC_ASIDS
|
||||
bool "Debug: report ASIDs through /proc/asids"
|
||||
depends on PROC_FS
|
||||
depends on PROC_FS && MMU
|
||||
|
||||
config SH64_SR_WATCH
|
||||
bool "Debug: set SR.WATCH to enable hardware watchpoints and trace"
|
||||
|
|
|
@ -95,8 +95,6 @@ head-y := arch/sh/kernel/init_task.o
|
|||
head-$(CONFIG_SUPERH32) += arch/sh/kernel/head_32.o
|
||||
head-$(CONFIG_SUPERH64) += arch/sh/kernel/head_64.o
|
||||
|
||||
LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
|
||||
|
||||
core-y += arch/sh/kernel/ arch/sh/mm/ arch/sh/boards/
|
||||
core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/
|
||||
|
||||
|
@ -145,10 +143,6 @@ cpuincdir-$(CONFIG_CPU_SH4) += cpu-sh4
|
|||
cpuincdir-$(CONFIG_CPU_SH5) += cpu-sh5
|
||||
cpuincdir-y += cpu-common # Must be last
|
||||
|
||||
libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y)
|
||||
libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y)
|
||||
libs-y += $(LIBGCC)
|
||||
|
||||
drivers-y += arch/sh/drivers/
|
||||
drivers-$(CONFIG_OPROFILE) += arch/sh/oprofile/
|
||||
|
||||
|
@ -161,10 +155,16 @@ KBUILD_CFLAGS += -pipe $(cflags-y)
|
|||
KBUILD_CPPFLAGS += $(cflags-y)
|
||||
KBUILD_AFLAGS += $(cflags-y)
|
||||
|
||||
LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
|
||||
|
||||
libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y)
|
||||
libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y)
|
||||
libs-y += $(LIBGCC)
|
||||
|
||||
PHONY += maketools FORCE
|
||||
|
||||
maketools: include/linux/version.h FORCE
|
||||
$(Q)$(MAKE) $(build)=arch/sh/tools arch/sh/include/asm/machtypes.h
|
||||
$(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h
|
||||
|
||||
all: $(KBUILD_IMAGE)
|
||||
|
||||
|
@ -215,4 +215,4 @@ arch/sh/lib64/syscalltab.h: arch/sh/kernel/syscalls_64.S
|
|||
$(call filechk,gen-syscalltab)
|
||||
|
||||
CLEAN_FILES += arch/sh/lib64/syscalltab.h \
|
||||
arch/sh/include/asm/machtypes.h
|
||||
include/asm-sh/machtypes.h
|
||||
|
|
|
@ -5,4 +5,4 @@ obj-$(CONFIG_SH_AP325RXA) += board-ap325rxa.o
|
|||
obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o
|
||||
obj-$(CONFIG_SH_RSK7203) += board-rsk7203.o
|
||||
obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o
|
||||
obj-$(CONFIG_SH_SHMIN) += board-shmin..o
|
||||
obj-$(CONFIG_SH_SHMIN) += board-shmin.o
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/smc911x.h>
|
||||
#include <media/soc_camera_platform.h>
|
||||
#include <media/sh_mobile_ceu.h>
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <mach-se/mach/se7343.h>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.26
|
||||
# Wed Jul 30 01:34:24 2008
|
||||
# Linux kernel version: 2.6.27-rc1
|
||||
# Mon Aug 4 16:49:13 2008
|
||||
#
|
||||
CONFIG_SUPERH=y
|
||||
CONFIG_SUPERH32=y
|
||||
|
@ -11,6 +11,7 @@ CONFIG_GENERIC_BUG=y
|
|||
CONFIG_GENERIC_FIND_NEXT_BIT=y
|
||||
CONFIG_GENERIC_HWEIGHT=y
|
||||
CONFIG_GENERIC_HARDIRQS=y
|
||||
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
|
||||
CONFIG_GENERIC_IRQ_PROBE=y
|
||||
CONFIG_GENERIC_CALIBRATE_DELAY=y
|
||||
CONFIG_GENERIC_TIME=y
|
||||
|
@ -21,7 +22,6 @@ CONFIG_LOCKDEP_SUPPORT=y
|
|||
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
|
||||
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
|
||||
CONFIG_ARCH_NO_VIRT_TO_BUS=y
|
||||
CONFIG_ARCH_SUPPORTS_AOUT=y
|
||||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||
|
||||
#
|
||||
|
@ -87,6 +87,7 @@ CONFIG_HAVE_OPROFILE=y
|
|||
# CONFIG_USE_GENERIC_SMP_HELPERS is not set
|
||||
CONFIG_HAVE_CLK=y
|
||||
CONFIG_PROC_PAGE_MONITOR=y
|
||||
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
|
||||
CONFIG_SLABINFO=y
|
||||
CONFIG_RT_MUTEXES=y
|
||||
# CONFIG_TINY_SHMEM is not set
|
||||
|
@ -284,6 +285,7 @@ CONFIG_HZ=250
|
|||
# CONFIG_SCHED_HRTICK is not set
|
||||
# CONFIG_KEXEC is not set
|
||||
# CONFIG_CRASH_DUMP is not set
|
||||
CONFIG_SECCOMP=y
|
||||
# CONFIG_PREEMPT_NONE is not set
|
||||
# CONFIG_PREEMPT_VOLUNTARY is not set
|
||||
CONFIG_PREEMPT=y
|
||||
|
@ -317,10 +319,6 @@ CONFIG_PCI_LEGACY=y
|
|||
#
|
||||
CONFIG_BINFMT_ELF=y
|
||||
# CONFIG_BINFMT_MISC is not set
|
||||
|
||||
#
|
||||
# Networking
|
||||
#
|
||||
CONFIG_NET=y
|
||||
|
||||
#
|
||||
|
@ -555,7 +553,7 @@ CONFIG_INPUT_KEYBOARD=y
|
|||
# CONFIG_KEYBOARD_XTKBD is not set
|
||||
# CONFIG_KEYBOARD_NEWTON is not set
|
||||
# CONFIG_KEYBOARD_STOWAWAY is not set
|
||||
# CONFIG_KEYBOARD_MAPLE is not set
|
||||
CONFIG_KEYBOARD_MAPLE=y
|
||||
# CONFIG_KEYBOARD_SH_KEYSC is not set
|
||||
CONFIG_INPUT_MOUSE=y
|
||||
# CONFIG_MOUSE_PS2 is not set
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef __ASM_SH_A_OUT_H
|
||||
#define __ASM_SH_A_OUT_H
|
||||
|
||||
struct exec
|
||||
{
|
||||
unsigned long a_info; /* Use macros N_MAGIC, etc for access */
|
||||
unsigned a_text; /* length of text, in bytes */
|
||||
unsigned a_data; /* length of data, in bytes */
|
||||
unsigned a_bss; /* length of uninitialized data area for file, in bytes */
|
||||
unsigned a_syms; /* length of symbol table data in file, in bytes */
|
||||
unsigned a_entry; /* start address */
|
||||
unsigned a_trsize; /* length of relocation info for text, in bytes */
|
||||
unsigned a_drsize; /* length of relocation info for data, in bytes */
|
||||
};
|
||||
|
||||
#define N_TRSIZE(a) ((a).a_trsize)
|
||||
#define N_DRSIZE(a) ((a).a_drsize)
|
||||
#define N_SYMSIZE(a) ((a).a_syms)
|
||||
|
||||
#endif /* __ASM_SH_A_OUT_H */
|
|
@ -104,6 +104,15 @@ struct pt_dspregs {
|
|||
|
||||
extern void show_regs(struct pt_regs *);
|
||||
|
||||
/*
|
||||
* These are defined as per linux/ptrace.h.
|
||||
*/
|
||||
struct task_struct;
|
||||
|
||||
#define arch_has_single_step() (1)
|
||||
extern void user_enable_single_step(struct task_struct *);
|
||||
extern void user_disable_single_step(struct task_struct *);
|
||||
|
||||
#ifdef CONFIG_SH_DSP
|
||||
#define task_pt_regs(task) \
|
||||
((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef __ASM_SECCOMP_H
|
||||
|
||||
#include <linux/unistd.h>
|
||||
|
||||
#define __NR_seccomp_read __NR_read
|
||||
#define __NR_seccomp_write __NR_write
|
||||
#define __NR_seccomp_exit __NR_exit
|
||||
#define __NR_seccomp_sigreturn __NR_rt_sigreturn
|
||||
|
||||
#endif /* __ASM_SECCOMP_H */
|
|
@ -117,24 +117,45 @@ static inline struct thread_info *current_thread_info(void)
|
|||
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
|
||||
#define TIF_RESTORE_SIGMASK 3 /* restore signal mask in do_signal() */
|
||||
#define TIF_SINGLESTEP 4 /* singlestepping active */
|
||||
#define TIF_SYSCALL_AUDIT 5
|
||||
#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
|
||||
#define TIF_SECCOMP 6 /* secure computing */
|
||||
#define TIF_NOTIFY_RESUME 7 /* callback before returning to user */
|
||||
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
|
||||
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
|
||||
#define TIF_MEMDIE 18
|
||||
#define TIF_FREEZE 19
|
||||
#define TIF_FREEZE 19 /* Freezing for suspend */
|
||||
|
||||
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
|
||||
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
|
||||
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
|
||||
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
|
||||
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
|
||||
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
|
||||
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
|
||||
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
|
||||
#define _TIF_FREEZE (1<<TIF_FREEZE)
|
||||
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
|
||||
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
|
||||
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
|
||||
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
|
||||
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
|
||||
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
|
||||
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
|
||||
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
|
||||
#define _TIF_USEDFPU (1 << TIF_USEDFPU)
|
||||
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
|
||||
#define _TIF_FREEZE (1 << TIF_FREEZE)
|
||||
|
||||
#define _TIF_WORK_MASK 0x000000FE /* work to do on interrupt/exception return */
|
||||
#define _TIF_ALLWORK_MASK 0x000000FF /* work to do on any return to u-space */
|
||||
/*
|
||||
* _TIF_ALLWORK_MASK and _TIF_WORK_MASK need to fit within a byte, or we
|
||||
* blow the tst immediate size constraints and need to fix up
|
||||
* arch/sh/kernel/entry-common.S.
|
||||
*/
|
||||
|
||||
/* work to do in syscall trace */
|
||||
#define _TIF_WORK_SYSCALL_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
|
||||
_TIF_SYSCALL_AUDIT | _TIF_SECCOMP)
|
||||
|
||||
/* work to do on any return to u-space */
|
||||
#define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \
|
||||
_TIF_NEED_RESCHED | _TIF_SYSCALL_AUDIT | \
|
||||
_TIF_SINGLESTEP | _TIF_RESTORE_SIGMASK | \
|
||||
_TIF_NOTIFY_RESUME)
|
||||
|
||||
/* work to do on interrupt/exception return */
|
||||
#define _TIF_WORK_MASK (_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \
|
||||
_TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP))
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
|
|
@ -21,11 +21,9 @@
|
|||
#ifndef __ASSEMBLY__
|
||||
|
||||
/**
|
||||
* for_each_dtlb_entry
|
||||
* for_each_dtlb_entry - Iterate over free (non-wired) DTLB entries
|
||||
*
|
||||
* @tlb: TLB entry
|
||||
*
|
||||
* Iterate over free (non-wired) DTLB entries
|
||||
*/
|
||||
#define for_each_dtlb_entry(tlb) \
|
||||
for (tlb = cpu_data->dtlb.first; \
|
||||
|
@ -33,11 +31,9 @@
|
|||
tlb += cpu_data->dtlb.step)
|
||||
|
||||
/**
|
||||
* for_each_itlb_entry
|
||||
* for_each_itlb_entry - Iterate over free (non-wired) ITLB entries
|
||||
*
|
||||
* @tlb: TLB entry
|
||||
*
|
||||
* Iterate over free (non-wired) ITLB entries
|
||||
*/
|
||||
#define for_each_itlb_entry(tlb) \
|
||||
for (tlb = cpu_data->itlb.first; \
|
||||
|
@ -45,11 +41,9 @@
|
|||
tlb += cpu_data->itlb.step)
|
||||
|
||||
/**
|
||||
* __flush_tlb_slot
|
||||
* __flush_tlb_slot - Flushes TLB slot @slot.
|
||||
*
|
||||
* @slot: Address of TLB slot.
|
||||
*
|
||||
* Flushes TLB slot @slot.
|
||||
*/
|
||||
static inline void __flush_tlb_slot(unsigned long long slot)
|
||||
{
|
||||
|
|
|
@ -21,11 +21,11 @@
|
|||
#define CCR 0xffffffec
|
||||
|
||||
#define CCR_CACHE_CE 0x01 /* Cache enable */
|
||||
#define CCR_CACHE_WT 0x06 /* CCR[bit1=1,bit2=1] */
|
||||
#define CCR_CACHE_WT 0x02 /* CCR[bit1=1,bit2=1] */
|
||||
/* 0x00000000-0x7fffffff: Write-through */
|
||||
/* 0x80000000-0x9fffffff: Write-back */
|
||||
/* 0xc0000000-0xdfffffff: Write-through */
|
||||
#define CCR_CACHE_CB 0x00 /* CCR[bit1=0,bit2=0] */
|
||||
#define CCR_CACHE_CB 0x04 /* CCR[bit1=0,bit2=0] */
|
||||
/* 0x00000000-0x7fffffff: Write-back */
|
||||
/* 0x80000000-0x9fffffff: Write-through */
|
||||
/* 0xc0000000-0xdfffffff: Write-back */
|
||||
|
@ -36,6 +36,8 @@
|
|||
|
||||
#define CCR_CACHE_ENABLE CCR_CACHE_CE
|
||||
#define CCR_CACHE_INVALIDATE CCR_CACHE_CF
|
||||
#define CACHE_PHYSADDR_MASK 0x1ffffc00
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_CPU_SH2_CACHE_H */
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef __ASM_SH_CPU_SH2A_ADDRSPACE_H
|
||||
#define __ASM_SH_CPU_SH2A_ADDRSPACE_H
|
||||
|
||||
#define P0SEG 0x00000000
|
||||
#define P1SEG 0x00000000
|
||||
#define P2SEG 0x20000000
|
||||
#define P3SEG 0x40000000
|
||||
#define P4SEG 0x60000000
|
||||
|
||||
#endif /* __ASM_SH_CPU_SH2A_ADDRSPACE_H */
|
|
@ -36,5 +36,8 @@
|
|||
|
||||
#define CCR_CACHE_ENABLE (CCR_CACHE_OCE | CCR_CACHE_ICE)
|
||||
#define CCR_CACHE_INVALIDATE (CCR_CACHE_OCI | CCR_CACHE_ICI)
|
||||
#define CCR_ICACHE_INVALIDATE CCR_CACHE_ICI
|
||||
#define CCR_OCACHE_INVALIDATE CCR_CACHE_OCI
|
||||
#define CACHE_PHYSADDR_MASK 0x1ffffc00
|
||||
|
||||
#endif /* __ASM_CPU_SH2A_CACHE_H */
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef __ASM_CPU_SH2A_CACHEFLUSH_H
|
||||
#define __ASM_CPU_SH2A_CACHEFLUSH_H
|
||||
|
||||
/*
|
||||
* Cache flushing:
|
||||
*
|
||||
* - flush_cache_all() flushes entire cache
|
||||
* - flush_cache_mm(mm) flushes the specified mm context's cache lines
|
||||
* - flush_cache_dup mm(mm) handles cache flushing when forking
|
||||
* - flush_cache_page(mm, vmaddr, pfn) flushes a single page
|
||||
* - flush_cache_range(vma, start, end) flushes a range of pages
|
||||
*
|
||||
* - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache
|
||||
* - flush_icache_range(start, end) flushes(invalidates) a range for icache
|
||||
* - flush_icache_page(vma, pg) flushes(invalidates) a page for icache
|
||||
*
|
||||
* Caches are indexed (effectively) by physical address on SH-2, so
|
||||
* we don't need them.
|
||||
*/
|
||||
#define flush_cache_all() do { } while (0)
|
||||
#define flush_cache_mm(mm) do { } while (0)
|
||||
#define flush_cache_dup_mm(mm) do { } while (0)
|
||||
#define flush_cache_range(vma, start, end) do { } while (0)
|
||||
#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
|
||||
#define flush_dcache_page(page) do { } while (0)
|
||||
#define flush_dcache_mmap_lock(mapping) do { } while (0)
|
||||
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
|
||||
void flush_icache_range(unsigned long start, unsigned long end);
|
||||
#define flush_icache_page(vma,pg) do { } while (0)
|
||||
#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
|
||||
#define flush_cache_sigtramp(vaddr) do { } while (0)
|
||||
|
||||
#define p3_cache_init() do { } while (0)
|
||||
#endif /* __ASM_CPU_SH2A_CACHEFLUSH_H */
|
|
@ -199,7 +199,7 @@ EXPORT_SYMBOL(sq_remap);
|
|||
|
||||
/**
|
||||
* sq_unmap - Unmap a Store Queue allocation
|
||||
* @map: Pre-allocated Store Queue mapping.
|
||||
* @vaddr: Pre-allocated Store Queue mapping.
|
||||
*
|
||||
* Unmaps the store queue allocation @map that was previously created by
|
||||
* sq_remap(). Also frees up the pte that was previously inserted into
|
||||
|
|
|
@ -987,11 +987,11 @@ work_resched:
|
|||
work_notifysig:
|
||||
gettr tr1, LINK
|
||||
|
||||
movi do_signal, r6
|
||||
movi do_notify_resume, r6
|
||||
ptabs r6, tr0
|
||||
or SP, ZERO, r2
|
||||
or ZERO, ZERO, r3
|
||||
blink tr0, LINK /* Call do_signal(regs, 0), return here */
|
||||
or r7, ZERO, r3
|
||||
blink tr0, LINK /* Call do_notify_resume(regs, current_thread_info->flags), return here */
|
||||
|
||||
restore_all:
|
||||
/* Do prefetches */
|
||||
|
@ -1300,18 +1300,20 @@ syscall_allowed:
|
|||
|
||||
getcon KCR0, r2
|
||||
ld.l r2, TI_FLAGS, r4
|
||||
movi (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | _TIF_SYSCALL_AUDIT), r6
|
||||
movi _TIF_WORK_SYSCALL_MASK, r6
|
||||
and r6, r4, r6
|
||||
beq/l r6, ZERO, tr0
|
||||
|
||||
/* Trace it by calling syscall_trace before and after */
|
||||
movi syscall_trace, r4
|
||||
movi do_syscall_trace_enter, r4
|
||||
or SP, ZERO, r2
|
||||
or ZERO, ZERO, r3
|
||||
ptabs r4, tr0
|
||||
blink tr0, LINK
|
||||
|
||||
/* Reload syscall number as r5 is trashed by syscall_trace */
|
||||
/* Save the retval */
|
||||
st.q SP, FRAME_R(2), r2
|
||||
|
||||
/* Reload syscall number as r5 is trashed by do_syscall_trace_enter */
|
||||
ld.q SP, FRAME_S(FSYSCALL_ID), r5
|
||||
andi r5, 0x1ff, r5
|
||||
|
||||
|
@ -1343,9 +1345,8 @@ syscall_ret_trace:
|
|||
/* We get back here only if under trace */
|
||||
st.q SP, FRAME_R(9), r2 /* Save return value */
|
||||
|
||||
movi syscall_trace, LINK
|
||||
movi do_syscall_trace_leave, LINK
|
||||
or SP, ZERO, r2
|
||||
movi 1, r3
|
||||
ptabs LINK, tr0
|
||||
blink tr0, LINK
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ work_resched:
|
|||
syscall_exit_work:
|
||||
! r0: current_thread_info->flags
|
||||
! r8: current_thread_info
|
||||
tst #_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | _TIF_SYSCALL_AUDIT, r0
|
||||
tst #_TIF_WORK_SYSCALL_MASK, r0
|
||||
bt/s work_pending
|
||||
tst #_TIF_NEED_RESCHED, r0
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
|
@ -211,10 +211,8 @@ syscall_exit_work:
|
|||
nop
|
||||
#endif
|
||||
sti
|
||||
! XXX setup arguments...
|
||||
mov r15, r4
|
||||
mov #1, r5
|
||||
mov.l 4f, r0 ! do_syscall_trace
|
||||
mov.l 8f, r0 ! do_syscall_trace_leave
|
||||
jsr @r0
|
||||
nop
|
||||
bra resume_userspace
|
||||
|
@ -223,12 +221,11 @@ syscall_exit_work:
|
|||
.align 2
|
||||
syscall_trace_entry:
|
||||
! Yes it is traced.
|
||||
! XXX setup arguments...
|
||||
mov r15, r4
|
||||
mov #0, r5
|
||||
mov.l 4f, r11 ! Call do_syscall_trace which notifies
|
||||
mov.l 7f, r11 ! Call do_syscall_trace_enter which notifies
|
||||
jsr @r11 ! superior (will chomp R[0-7])
|
||||
nop
|
||||
mov.l r0, @(OFF_R0,r15) ! Save return value
|
||||
! Reload R0-R4 from kernel stack, where the
|
||||
! parent may have modified them using
|
||||
! ptrace(POKEUSR). (Note that R0-R2 are
|
||||
|
@ -351,7 +348,7 @@ ENTRY(system_call)
|
|||
!
|
||||
get_current_thread_info r8, r10
|
||||
mov.l @(TI_FLAGS,r8), r8
|
||||
mov #(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT), r10
|
||||
mov #_TIF_WORK_SYSCALL_MASK, r10
|
||||
tst r10, r8
|
||||
bf syscall_trace_entry
|
||||
!
|
||||
|
@ -389,8 +386,9 @@ syscall_exit:
|
|||
#endif
|
||||
2: .long NR_syscalls
|
||||
3: .long sys_call_table
|
||||
4: .long do_syscall_trace
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
5: .long trace_hardirqs_on
|
||||
6: .long trace_hardirqs_off
|
||||
#endif
|
||||
7: .long do_syscall_trace_enter
|
||||
8: .long do_syscall_trace_leave
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/kexec.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/numa.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
@ -104,3 +105,10 @@ void machine_kexec(struct kimage *image)
|
|||
(*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg);
|
||||
}
|
||||
|
||||
void arch_crash_save_vmcoreinfo(void)
|
||||
{
|
||||
#ifdef CONFIG_NUMA
|
||||
VMCOREINFO_SYMBOL(node_data);
|
||||
VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <linux/moduleloader.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
|
@ -36,7 +37,8 @@ void *module_alloc(unsigned long size)
|
|||
{
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
return vmalloc(size);
|
||||
|
||||
return vmalloc_exec(size);
|
||||
}
|
||||
|
||||
|
||||
|
@ -145,9 +147,10 @@ int module_finalize(const Elf_Ehdr *hdr,
|
|||
const Elf_Shdr *sechdrs,
|
||||
struct module *me)
|
||||
{
|
||||
return 0;
|
||||
return module_bug_finalize(hdr, sechdrs, me);
|
||||
}
|
||||
|
||||
void module_arch_cleanup(struct module *mod)
|
||||
{
|
||||
module_bug_cleanup(mod);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include <linux/signal.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/system.h>
|
||||
|
@ -57,7 +59,23 @@ static inline int put_stack_long(struct task_struct *task, int offset,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ptrace_disable_singlestep(struct task_struct *child)
|
||||
void user_enable_single_step(struct task_struct *child)
|
||||
{
|
||||
struct pt_regs *regs = task_pt_regs(child);
|
||||
long pc;
|
||||
|
||||
pc = get_stack_long(child, (long)®s->pc);
|
||||
|
||||
/* Next scheduling will set up UBC */
|
||||
if (child->thread.ubc_pc == 0)
|
||||
ubc_usercnt += 1;
|
||||
|
||||
child->thread.ubc_pc = pc;
|
||||
|
||||
set_tsk_thread_flag(child, TIF_SINGLESTEP);
|
||||
}
|
||||
|
||||
void user_disable_single_step(struct task_struct *child)
|
||||
{
|
||||
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
|
||||
|
||||
|
@ -81,7 +99,7 @@ static void ptrace_disable_singlestep(struct task_struct *child)
|
|||
*/
|
||||
void ptrace_disable(struct task_struct *child)
|
||||
{
|
||||
ptrace_disable_singlestep(child);
|
||||
user_disable_single_step(child);
|
||||
}
|
||||
|
||||
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
|
@ -90,12 +108,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||
int ret;
|
||||
|
||||
switch (request) {
|
||||
/* when I and D space are separate, these will need to be fixed. */
|
||||
case PTRACE_PEEKTEXT: /* read word at location addr. */
|
||||
case PTRACE_PEEKDATA:
|
||||
ret = generic_ptrace_peekdata(child, addr, data);
|
||||
break;
|
||||
|
||||
/* read the word at location addr in the USER area. */
|
||||
case PTRACE_PEEKUSR: {
|
||||
unsigned long tmp;
|
||||
|
@ -125,12 +137,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||
break;
|
||||
}
|
||||
|
||||
/* when I and D space are separate, this will have to be fixed. */
|
||||
case PTRACE_POKETEXT: /* write the word at location addr. */
|
||||
case PTRACE_POKEDATA:
|
||||
ret = generic_ptrace_pokedata(child, addr, data);
|
||||
break;
|
||||
|
||||
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
|
||||
ret = -EIO;
|
||||
if ((addr & 3) || addr < 0 ||
|
||||
|
@ -151,67 +157,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||
}
|
||||
break;
|
||||
|
||||
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
|
||||
case PTRACE_CONT: { /* restart after signal. */
|
||||
ret = -EIO;
|
||||
if (!valid_signal(data))
|
||||
break;
|
||||
if (request == PTRACE_SYSCALL)
|
||||
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
|
||||
else
|
||||
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
|
||||
|
||||
ptrace_disable_singlestep(child);
|
||||
|
||||
child->exit_code = data;
|
||||
wake_up_process(child);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* make the child exit. Best I can do is send it a sigkill.
|
||||
* perhaps it should be put in the status that it wants to
|
||||
* exit.
|
||||
*/
|
||||
case PTRACE_KILL: {
|
||||
ret = 0;
|
||||
if (child->exit_state == EXIT_ZOMBIE) /* already dead */
|
||||
break;
|
||||
ptrace_disable_singlestep(child);
|
||||
child->exit_code = SIGKILL;
|
||||
wake_up_process(child);
|
||||
break;
|
||||
}
|
||||
|
||||
case PTRACE_SINGLESTEP: { /* set the trap flag. */
|
||||
long pc;
|
||||
struct pt_regs *regs = NULL;
|
||||
|
||||
ret = -EIO;
|
||||
if (!valid_signal(data))
|
||||
break;
|
||||
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
|
||||
if ((child->ptrace & PT_DTRACE) == 0) {
|
||||
/* Spurious delayed TF traps may occur */
|
||||
child->ptrace |= PT_DTRACE;
|
||||
}
|
||||
|
||||
pc = get_stack_long(child, (long)®s->pc);
|
||||
|
||||
/* Next scheduling will set up UBC */
|
||||
if (child->thread.ubc_pc == 0)
|
||||
ubc_usercnt += 1;
|
||||
child->thread.ubc_pc = pc;
|
||||
|
||||
set_tsk_thread_flag(child, TIF_SINGLESTEP);
|
||||
child->exit_code = data;
|
||||
/* give it a chance to run. */
|
||||
wake_up_process(child);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SH_DSP
|
||||
case PTRACE_GETDSPREGS: {
|
||||
unsigned long dp;
|
||||
|
@ -272,39 +217,49 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
|
||||
static inline int audit_arch(void)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
int arch = EM_SH;
|
||||
|
||||
if (unlikely(current->audit_context) && entryexit)
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]),
|
||||
regs->regs[0]);
|
||||
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||
arch |= __AUDIT_ARCH_LE;
|
||||
#endif
|
||||
|
||||
if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
|
||||
!test_thread_flag(TIF_SINGLESTEP))
|
||||
goto out;
|
||||
if (!(tsk->ptrace & PT_PTRACED))
|
||||
goto out;
|
||||
return arch;
|
||||
}
|
||||
|
||||
/* the 0x80 provides a way for the tracing parent to distinguish
|
||||
between a syscall stop and SIGTRAP delivery */
|
||||
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) &&
|
||||
!test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
|
||||
asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
|
||||
{
|
||||
long ret = 0;
|
||||
|
||||
secure_computing(regs->regs[0]);
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
|
||||
tracehook_report_syscall_entry(regs))
|
||||
/*
|
||||
* this isn't the same as continuing with a signal, but it will do
|
||||
* for normal use. strace only continues with a signal if the
|
||||
* stopping signal is not SIGTRAP. -brl
|
||||
* Tracing decided this syscall should not happen.
|
||||
* We'll return a bogus call number to get an ENOSYS
|
||||
* error, but leave the original number in regs->regs[0].
|
||||
*/
|
||||
if (tsk->exit_code) {
|
||||
send_sig(tsk->exit_code, tsk, 1);
|
||||
tsk->exit_code = 0;
|
||||
}
|
||||
ret = -1L;
|
||||
|
||||
out:
|
||||
if (unlikely(current->audit_context) && !entryexit)
|
||||
audit_syscall_entry(AUDIT_ARCH_SH, regs->regs[3],
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_entry(audit_arch(), regs->regs[3],
|
||||
regs->regs[4], regs->regs[5],
|
||||
regs->regs[6], regs->regs[7]);
|
||||
|
||||
return ret ?: regs->regs[0];
|
||||
}
|
||||
|
||||
asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
|
||||
{
|
||||
int step;
|
||||
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]),
|
||||
regs->regs[0]);
|
||||
|
||||
step = test_thread_flag(TIF_SINGLESTEP);
|
||||
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall_exit(regs, step);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include <linux/signal.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
@ -120,18 +122,23 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void user_enable_single_step(struct task_struct *child)
|
||||
{
|
||||
struct pt_regs *regs = child->thread.uregs;
|
||||
|
||||
regs->sr |= SR_SSTEP; /* auto-resetting upon exception */
|
||||
}
|
||||
|
||||
void user_disable_single_step(struct task_struct *child)
|
||||
{
|
||||
regs->sr &= ~SR_SSTEP;
|
||||
}
|
||||
|
||||
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (request) {
|
||||
/* when I and D space are separate, these will need to be fixed. */
|
||||
case PTRACE_PEEKTEXT: /* read word at location addr. */
|
||||
case PTRACE_PEEKDATA:
|
||||
ret = generic_ptrace_peekdata(child, addr, data);
|
||||
break;
|
||||
|
||||
/* read the word at location addr in the USER area. */
|
||||
case PTRACE_PEEKUSR: {
|
||||
unsigned long tmp;
|
||||
|
@ -154,12 +161,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||
break;
|
||||
}
|
||||
|
||||
/* when I and D space are separate, this will have to be fixed. */
|
||||
case PTRACE_POKETEXT: /* write the word at location addr. */
|
||||
case PTRACE_POKEDATA:
|
||||
ret = generic_ptrace_pokedata(child, addr, data);
|
||||
break;
|
||||
|
||||
case PTRACE_POKEUSR:
|
||||
/* write the word at location addr in the USER area. We must
|
||||
disallow any changes to certain SR bits or u_fpvalid, since
|
||||
|
@ -191,58 +192,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||
}
|
||||
break;
|
||||
|
||||
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
|
||||
case PTRACE_CONT: { /* restart after signal. */
|
||||
ret = -EIO;
|
||||
if (!valid_signal(data))
|
||||
break;
|
||||
if (request == PTRACE_SYSCALL)
|
||||
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
|
||||
else
|
||||
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
|
||||
child->exit_code = data;
|
||||
wake_up_process(child);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* make the child exit. Best I can do is send it a sigkill.
|
||||
* perhaps it should be put in the status that it wants to
|
||||
* exit.
|
||||
*/
|
||||
case PTRACE_KILL: {
|
||||
ret = 0;
|
||||
if (child->exit_state == EXIT_ZOMBIE) /* already dead */
|
||||
break;
|
||||
child->exit_code = SIGKILL;
|
||||
wake_up_process(child);
|
||||
break;
|
||||
}
|
||||
|
||||
case PTRACE_SINGLESTEP: { /* set the trap flag. */
|
||||
struct pt_regs *regs;
|
||||
|
||||
ret = -EIO;
|
||||
if (!valid_signal(data))
|
||||
break;
|
||||
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
|
||||
if ((child->ptrace & PT_DTRACE) == 0) {
|
||||
/* Spurious delayed TF traps may occur */
|
||||
child->ptrace |= PT_DTRACE;
|
||||
}
|
||||
|
||||
regs = child->thread.uregs;
|
||||
|
||||
regs->sr |= SR_SSTEP; /* auto-resetting upon exception */
|
||||
|
||||
child->exit_code = data;
|
||||
/* give it a chance to run. */
|
||||
wake_up_process(child);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ret = ptrace_request(child, request, addr, data);
|
||||
break;
|
||||
|
@ -273,38 +222,51 @@ asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
|
|||
return sys_ptrace(request, pid, addr, data);
|
||||
}
|
||||
|
||||
asmlinkage void syscall_trace(struct pt_regs *regs, int entryexit)
|
||||
static inline int audit_arch(void)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
int arch = EM_SH;
|
||||
|
||||
if (unlikely(current->audit_context) && entryexit)
|
||||
#ifdef CONFIG_64BIT
|
||||
arch |= __AUDIT_ARCH_64BIT;
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||
arch |= __AUDIT_ARCH_LE;
|
||||
#endif
|
||||
|
||||
return arch;
|
||||
}
|
||||
|
||||
asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs)
|
||||
{
|
||||
long long ret = 0;
|
||||
|
||||
secure_computing(regs->regs[9]);
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
|
||||
tracehook_report_syscall_entry(regs))
|
||||
/*
|
||||
* Tracing decided this syscall should not happen.
|
||||
* We'll return a bogus call number to get an ENOSYS
|
||||
* error, but leave the original number in regs->regs[0].
|
||||
*/
|
||||
ret = -1LL;
|
||||
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_entry(audit_arch(), regs->regs[1],
|
||||
regs->regs[2], regs->regs[3],
|
||||
regs->regs[4], regs->regs[5]);
|
||||
|
||||
return ret ?: regs->regs[9];
|
||||
}
|
||||
|
||||
asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
|
||||
{
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]),
|
||||
regs->regs[9]);
|
||||
|
||||
if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
|
||||
!test_thread_flag(TIF_SINGLESTEP))
|
||||
goto out;
|
||||
if (!(tsk->ptrace & PT_PTRACED))
|
||||
goto out;
|
||||
|
||||
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) &&
|
||||
!test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
|
||||
|
||||
/*
|
||||
* this isn't the same as continuing with a signal, but it will do
|
||||
* for normal use. strace only continues with a signal if the
|
||||
* stopping signal is not SIGTRAP. -brl
|
||||
*/
|
||||
if (tsk->exit_code) {
|
||||
send_sig(tsk->exit_code, tsk, 1);
|
||||
tsk->exit_code = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
if (unlikely(current->audit_context) && !entryexit)
|
||||
audit_syscall_entry(AUDIT_ARCH_SH, regs->regs[1],
|
||||
regs->regs[2], regs->regs[3],
|
||||
regs->regs[4], regs->regs[5]);
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall_exit(regs, 0);
|
||||
}
|
||||
|
||||
/* Called with interrupts disabled */
|
||||
|
@ -338,5 +300,5 @@ asmlinkage void do_software_break_point(unsigned long long vec,
|
|||
*/
|
||||
void ptrace_disable(struct task_struct *child)
|
||||
{
|
||||
/* nothing to do.. */
|
||||
user_disable_single_step(child);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/smp.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/crash_dump.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/page.h>
|
||||
|
@ -286,6 +287,25 @@ static void __init setup_memory(void)
|
|||
extern void __init setup_memory(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
|
||||
* is_kdump_kernel() to determine if we are booting after a panic. Hence
|
||||
* ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE.
|
||||
*/
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
/* elfcorehdr= specifies the location of elf core header
|
||||
* stored by the crashed kernel.
|
||||
*/
|
||||
static int __init parse_elfcorehdr(char *arg)
|
||||
{
|
||||
if (!arg)
|
||||
return -EINVAL;
|
||||
elfcorehdr_addr = memparse(arg, &arg);
|
||||
return 0;
|
||||
}
|
||||
early_param("elfcorehdr", parse_elfcorehdr);
|
||||
#endif
|
||||
|
||||
void __init setup_arch(char **cmdline_p)
|
||||
{
|
||||
enable_mmu();
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/binfmts.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/ucontext.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
@ -507,14 +508,13 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
|
|||
switch (regs->regs[0]) {
|
||||
case -ERESTART_RESTARTBLOCK:
|
||||
case -ERESTARTNOHAND:
|
||||
no_system_call_restart:
|
||||
regs->regs[0] = -EINTR;
|
||||
break;
|
||||
|
||||
case -ERESTARTSYS:
|
||||
if (!(ka->sa.sa_flags & SA_RESTART)) {
|
||||
regs->regs[0] = -EINTR;
|
||||
break;
|
||||
}
|
||||
if (!(ka->sa.sa_flags & SA_RESTART))
|
||||
goto no_system_call_restart;
|
||||
/* fallthrough */
|
||||
case -ERESTARTNOINTR:
|
||||
regs->regs[0] = save_r0;
|
||||
|
@ -589,12 +589,15 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
|
|||
* clear the TIF_RESTORE_SIGMASK flag */
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
|
||||
tracehook_signal_handler(signr, &info, &ka, regs,
|
||||
test_thread_flag(TIF_SINGLESTEP));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
no_signal:
|
||||
no_signal:
|
||||
/* Did we come from a system call? */
|
||||
if (regs->tra >= 0) {
|
||||
/* Restart the system call - no handlers present */
|
||||
|
@ -618,9 +621,14 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
|
|||
}
|
||||
|
||||
asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0,
|
||||
__u32 thread_info_flags)
|
||||
unsigned long thread_info_flags)
|
||||
{
|
||||
/* deal with pending signal delivery */
|
||||
if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
|
||||
if (thread_info_flags & _TIF_SIGPENDING)
|
||||
do_signal(regs, save_r0);
|
||||
|
||||
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
|
||||
clear_thread_flag(TIF_NOTIFY_RESUME);
|
||||
tracehook_notify_resume(regs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/ptrace.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <asm/ucontext.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
@ -42,7 +43,84 @@
|
|||
|
||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||
|
||||
asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
|
||||
/*
|
||||
* Note that 'init' is a special process: it doesn't get signals it doesn't
|
||||
* want to handle. Thus you cannot kill init even with a SIGKILL even by
|
||||
* mistake.
|
||||
*
|
||||
* Note that we go through the signals twice: once to check the signals that
|
||||
* the kernel can handle, and then we build all the user-level signal handling
|
||||
* stack-frames in one go after that.
|
||||
*/
|
||||
static int do_signal(struct pt_regs *regs, sigset_t *oldset)
|
||||
{
|
||||
siginfo_t info;
|
||||
int signr;
|
||||
struct k_sigaction ka;
|
||||
|
||||
/*
|
||||
* We want the common case to go fast, which
|
||||
* is why we may in certain cases get here from
|
||||
* kernel mode. Just return without doing anything
|
||||
* if so.
|
||||
*/
|
||||
if (!user_mode(regs))
|
||||
return 1;
|
||||
|
||||
if (try_to_freeze())
|
||||
goto no_signal;
|
||||
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
oldset = ¤t->saved_sigmask;
|
||||
else if (!oldset)
|
||||
oldset = ¤t->blocked;
|
||||
|
||||
signr = get_signal_to_deliver(&info, &ka, regs, 0);
|
||||
|
||||
if (signr > 0) {
|
||||
/* Whee! Actually deliver the signal. */
|
||||
handle_signal(signr, &info, &ka, oldset, regs);
|
||||
|
||||
/*
|
||||
* If a signal was successfully delivered, the saved sigmask
|
||||
* is in its frame, and we can clear the TIF_RESTORE_SIGMASK
|
||||
* flag.
|
||||
*/
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
|
||||
tracehook_signal_handler(signr, &info, &ka, regs, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
no_signal:
|
||||
/* Did we come from a system call? */
|
||||
if (regs->syscall_nr >= 0) {
|
||||
/* Restart the system call - no handlers present */
|
||||
switch (regs->regs[REG_RET]) {
|
||||
case -ERESTARTNOHAND:
|
||||
case -ERESTARTSYS:
|
||||
case -ERESTARTNOINTR:
|
||||
/* Decode Syscall # */
|
||||
regs->regs[REG_RET] = regs->syscall_nr;
|
||||
regs->pc -= 4;
|
||||
break;
|
||||
|
||||
case -ERESTART_RESTARTBLOCK:
|
||||
regs->regs[REG_RET] = __NR_restart_syscall;
|
||||
regs->pc -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* No signal to deliver -- put the saved sigmask back */
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Atomically swap in the new signal mask, and wait for a signal.
|
||||
|
@ -643,14 +721,13 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
|||
switch (regs->regs[REG_RET]) {
|
||||
case -ERESTART_RESTARTBLOCK:
|
||||
case -ERESTARTNOHAND:
|
||||
no_system_call_restart:
|
||||
regs->regs[REG_RET] = -EINTR;
|
||||
break;
|
||||
|
||||
case -ERESTARTSYS:
|
||||
if (!(ka->sa.sa_flags & SA_RESTART)) {
|
||||
regs->regs[REG_RET] = -EINTR;
|
||||
break;
|
||||
}
|
||||
if (!(ka->sa.sa_flags & SA_RESTART))
|
||||
goto no_system_call_restart;
|
||||
/* fallthrough */
|
||||
case -ERESTARTNOINTR:
|
||||
/* Decode syscall # */
|
||||
|
@ -673,80 +750,13 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
|||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that 'init' is a special process: it doesn't get signals it doesn't
|
||||
* want to handle. Thus you cannot kill init even with a SIGKILL even by
|
||||
* mistake.
|
||||
*
|
||||
* Note that we go through the signals twice: once to check the signals that
|
||||
* the kernel can handle, and then we build all the user-level signal handling
|
||||
* stack-frames in one go after that.
|
||||
*/
|
||||
int do_signal(struct pt_regs *regs, sigset_t *oldset)
|
||||
asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
|
||||
{
|
||||
siginfo_t info;
|
||||
int signr;
|
||||
struct k_sigaction ka;
|
||||
if (thread_info_flags & _TIF_SIGPENDING)
|
||||
do_signal(regs, 0);
|
||||
|
||||
/*
|
||||
* We want the common case to go fast, which
|
||||
* is why we may in certain cases get here from
|
||||
* kernel mode. Just return without doing anything
|
||||
* if so.
|
||||
*/
|
||||
if (!user_mode(regs))
|
||||
return 1;
|
||||
|
||||
if (try_to_freeze())
|
||||
goto no_signal;
|
||||
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
oldset = ¤t->saved_sigmask;
|
||||
else if (!oldset)
|
||||
oldset = ¤t->blocked;
|
||||
|
||||
signr = get_signal_to_deliver(&info, &ka, regs, 0);
|
||||
|
||||
if (signr > 0) {
|
||||
/* Whee! Actually deliver the signal. */
|
||||
handle_signal(signr, &info, &ka, oldset, regs);
|
||||
|
||||
/*
|
||||
* If a signal was successfully delivered, the saved sigmask
|
||||
* is in its frame, and we can clear the TIF_RESTORE_SIGMASK
|
||||
* flag.
|
||||
*/
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
|
||||
return 1;
|
||||
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
|
||||
clear_thread_flag(TIF_NOTIFY_RESUME);
|
||||
tracehook_notify_resume(regs);
|
||||
}
|
||||
|
||||
no_signal:
|
||||
/* Did we come from a system call? */
|
||||
if (regs->syscall_nr >= 0) {
|
||||
/* Restart the system call - no handlers present */
|
||||
switch (regs->regs[REG_RET]) {
|
||||
case -ERESTARTNOHAND:
|
||||
case -ERESTARTSYS:
|
||||
case -ERESTARTNOINTR:
|
||||
/* Decode Syscall # */
|
||||
regs->regs[REG_RET] = regs->syscall_nr;
|
||||
regs->pc -= 4;
|
||||
break;
|
||||
|
||||
case -ERESTART_RESTARTBLOCK:
|
||||
regs->regs[REG_RET] = __NR_restart_syscall;
|
||||
regs->pc -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* No signal to deliver -- put the saved sigmask back */
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -237,7 +237,6 @@ choice
|
|||
|
||||
config CACHE_WRITEBACK
|
||||
bool "Write-back"
|
||||
depends on CPU_SH2A || CPU_SH3 || CPU_SH4 || CPU_SH5
|
||||
|
||||
config CACHE_WRITETHROUGH
|
||||
bool "Write-through"
|
||||
|
|
|
@ -5,12 +5,15 @@
|
|||
obj-y := init.o extable_32.o consistent.o
|
||||
|
||||
ifndef CONFIG_CACHE_OFF
|
||||
obj-$(CONFIG_CPU_SH2) += cache-sh2.o
|
||||
obj-$(CONFIG_CPU_SH3) += cache-sh3.o
|
||||
obj-$(CONFIG_CPU_SH4) += cache-sh4.o
|
||||
obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o
|
||||
cache-$(CONFIG_CPU_SH2) := cache-sh2.o
|
||||
cache-$(CONFIG_CPU_SH2A) := cache-sh2a.o
|
||||
cache-$(CONFIG_CPU_SH3) := cache-sh3.o
|
||||
cache-$(CONFIG_CPU_SH4) := cache-sh4.o
|
||||
cache-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o
|
||||
endif
|
||||
|
||||
obj-y += $(cache-y)
|
||||
|
||||
mmu-y := tlb-nommu.o pg-nommu.o
|
||||
mmu-$(CONFIG_MMU) := fault_32.o tlbflush_32.o ioremap_32.o
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* arch/sh/mm/cache-sh2.c
|
||||
*
|
||||
* Copyright (C) 2002 Paul Mundt
|
||||
* Copyright (C) 2008 Yoshinori Sato
|
||||
*
|
||||
* Released under the terms of the GNU GPL v2.0.
|
||||
*/
|
||||
|
@ -24,8 +25,15 @@ void __flush_wback_region(void *start, int size)
|
|||
end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
|
||||
& ~(L1_CACHE_BYTES-1);
|
||||
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
|
||||
/* FIXME cache purge */
|
||||
ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008);
|
||||
unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0);
|
||||
int way;
|
||||
for (way = 0; way < 4; way++) {
|
||||
unsigned long data = ctrl_inl(addr | (way << 12));
|
||||
if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
|
||||
data &= ~SH_CACHE_UPDATED;
|
||||
ctrl_outl(data, addr | (way << 12));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,21 +45,40 @@ void __flush_purge_region(void *start, int size)
|
|||
begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
|
||||
end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
|
||||
& ~(L1_CACHE_BYTES-1);
|
||||
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
|
||||
ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008);
|
||||
}
|
||||
|
||||
for (v = begin; v < end; v+=L1_CACHE_BYTES)
|
||||
ctrl_outl((v & CACHE_PHYSADDR_MASK),
|
||||
CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
|
||||
}
|
||||
|
||||
void __flush_invalidate_region(void *start, int size)
|
||||
{
|
||||
#ifdef CONFIG_CACHE_WRITEBACK
|
||||
/*
|
||||
* SH-2 does not support individual line invalidation, only a
|
||||
* global invalidate.
|
||||
*/
|
||||
unsigned long ccr;
|
||||
unsigned long flags;
|
||||
local_irq_save(flags);
|
||||
jump_to_uncached();
|
||||
|
||||
ccr = ctrl_inl(CCR);
|
||||
ccr |= CCR_CACHE_INVALIDATE;
|
||||
ctrl_outl(ccr, CCR);
|
||||
|
||||
back_to_cached();
|
||||
local_irq_restore(flags);
|
||||
#else
|
||||
unsigned long v;
|
||||
unsigned long begin, end;
|
||||
|
||||
begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
|
||||
end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
|
||||
& ~(L1_CACHE_BYTES-1);
|
||||
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
|
||||
ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008);
|
||||
}
|
||||
}
|
||||
|
||||
for (v = begin; v < end; v+=L1_CACHE_BYTES)
|
||||
ctrl_outl((v & CACHE_PHYSADDR_MASK),
|
||||
CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* arch/sh/mm/cache-sh2a.c
|
||||
*
|
||||
* Copyright (C) 2008 Yoshinori Sato
|
||||
*
|
||||
* Released under the terms of the GNU GPL v2.0.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/cache.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
void __flush_wback_region(void *start, int size)
|
||||
{
|
||||
unsigned long v;
|
||||
unsigned long begin, end;
|
||||
unsigned long flags;
|
||||
|
||||
begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
|
||||
end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
|
||||
& ~(L1_CACHE_BYTES-1);
|
||||
|
||||
local_irq_save(flags);
|
||||
jump_to_uncached();
|
||||
|
||||
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
|
||||
unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0);
|
||||
int way;
|
||||
for (way = 0; way < 4; way++) {
|
||||
unsigned long data = ctrl_inl(addr | (way << 11));
|
||||
if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
|
||||
data &= ~SH_CACHE_UPDATED;
|
||||
ctrl_outl(data, addr | (way << 11));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
back_to_cached();
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
void __flush_purge_region(void *start, int size)
|
||||
{
|
||||
unsigned long v;
|
||||
unsigned long begin, end;
|
||||
unsigned long flags;
|
||||
|
||||
begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
|
||||
end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
|
||||
& ~(L1_CACHE_BYTES-1);
|
||||
|
||||
local_irq_save(flags);
|
||||
jump_to_uncached();
|
||||
|
||||
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
|
||||
ctrl_outl((v & CACHE_PHYSADDR_MASK),
|
||||
CACHE_OC_ADDRESS_ARRAY | (v & 0x000003f0) | 0x00000008);
|
||||
}
|
||||
back_to_cached();
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
void __flush_invalidate_region(void *start, int size)
|
||||
{
|
||||
unsigned long v;
|
||||
unsigned long begin, end;
|
||||
unsigned long flags;
|
||||
|
||||
begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
|
||||
end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
|
||||
& ~(L1_CACHE_BYTES-1);
|
||||
local_irq_save(flags);
|
||||
jump_to_uncached();
|
||||
|
||||
#ifdef CONFIG_CACHE_WRITEBACK
|
||||
ctrl_outl(ctrl_inl(CCR) | CCR_OCACHE_INVALIDATE, CCR);
|
||||
/* I-cache invalidate */
|
||||
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
|
||||
ctrl_outl((v & CACHE_PHYSADDR_MASK),
|
||||
CACHE_IC_ADDRESS_ARRAY | (v & 0x000003f0) | 0x00000008);
|
||||
}
|
||||
#else
|
||||
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
|
||||
ctrl_outl((v & CACHE_PHYSADDR_MASK),
|
||||
CACHE_IC_ADDRESS_ARRAY | (v & 0x000003f0) | 0x00000008);
|
||||
ctrl_outl((v & CACHE_PHYSADDR_MASK),
|
||||
CACHE_OC_ADDRESS_ARRAY | (v & 0x000003f0) | 0x00000008);
|
||||
}
|
||||
#endif
|
||||
back_to_cached();
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/* WBack O-Cache and flush I-Cache */
|
||||
void flush_icache_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
unsigned long v;
|
||||
unsigned long flags;
|
||||
|
||||
start = start & ~(L1_CACHE_BYTES-1);
|
||||
end = (end + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1);
|
||||
|
||||
local_irq_save(flags);
|
||||
jump_to_uncached();
|
||||
|
||||
for (v = start; v < end; v+=L1_CACHE_BYTES) {
|
||||
unsigned long addr = (v & 0x000007f0);
|
||||
int way;
|
||||
/* O-Cache writeback */
|
||||
for (way = 0; way < 4; way++) {
|
||||
unsigned long data = ctrl_inl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
|
||||
if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
|
||||
data &= ~SH_CACHE_UPDATED;
|
||||
ctrl_outl(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
|
||||
}
|
||||
}
|
||||
/* I-Cache invalidate */
|
||||
ctrl_outl(addr,
|
||||
CACHE_IC_ADDRESS_ARRAY | addr | 0x00000008);
|
||||
}
|
||||
|
||||
back_to_cached();
|
||||
local_irq_restore(flags);
|
||||
}
|
|
@ -15,9 +15,7 @@
|
|||
#include <asm/mmu_context.h>
|
||||
|
||||
/**
|
||||
* sh64_tlb_init
|
||||
*
|
||||
* Perform initial setup for the DTLB and ITLB.
|
||||
* sh64_tlb_init - Perform initial setup for the DTLB and ITLB.
|
||||
*/
|
||||
int __init sh64_tlb_init(void)
|
||||
{
|
||||
|
@ -46,9 +44,7 @@ int __init sh64_tlb_init(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* sh64_next_free_dtlb_entry
|
||||
*
|
||||
* Find the next available DTLB entry
|
||||
* sh64_next_free_dtlb_entry - Find the next available DTLB entry
|
||||
*/
|
||||
unsigned long long sh64_next_free_dtlb_entry(void)
|
||||
{
|
||||
|
@ -56,9 +52,7 @@ unsigned long long sh64_next_free_dtlb_entry(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* sh64_get_wired_dtlb_entry
|
||||
*
|
||||
* Allocate a wired (locked-in) entry in the DTLB
|
||||
* sh64_get_wired_dtlb_entry - Allocate a wired (locked-in) entry in the DTLB
|
||||
*/
|
||||
unsigned long long sh64_get_wired_dtlb_entry(void)
|
||||
{
|
||||
|
@ -71,12 +65,10 @@ unsigned long long sh64_get_wired_dtlb_entry(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* sh64_put_wired_dtlb_entry
|
||||
* sh64_put_wired_dtlb_entry - Free a wired (locked-in) entry in the DTLB.
|
||||
*
|
||||
* @entry: Address of TLB slot.
|
||||
*
|
||||
* Free a wired (locked-in) entry in the DTLB.
|
||||
*
|
||||
* Works like a stack, last one to allocate must be first one to free.
|
||||
*/
|
||||
int sh64_put_wired_dtlb_entry(unsigned long long entry)
|
||||
|
@ -115,7 +107,7 @@ int sh64_put_wired_dtlb_entry(unsigned long long entry)
|
|||
}
|
||||
|
||||
/**
|
||||
* sh64_setup_tlb_slot
|
||||
* sh64_setup_tlb_slot - Load up a translation in a wired slot.
|
||||
*
|
||||
* @config_addr: Address of TLB slot.
|
||||
* @eaddr: Virtual address.
|
||||
|
@ -154,7 +146,7 @@ inline void sh64_setup_tlb_slot(unsigned long long config_addr,
|
|||
}
|
||||
|
||||
/**
|
||||
* sh64_teardown_tlb_slot
|
||||
* sh64_teardown_tlb_slot - Teardown a translation.
|
||||
*
|
||||
* @config_addr: Address of TLB slot.
|
||||
*
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# Shamelessly cloned from ARM.
|
||||
#
|
||||
|
||||
arch/sh/include/asm/machtypes.h: $(src)/gen-mach-types $(src)/mach-types
|
||||
include/asm-sh/machtypes.h: $(src)/gen-mach-types $(src)/mach-types
|
||||
@echo ' Generating $@'
|
||||
$(Q)if [ ! -d arch/sh/include/asm ]; then mkdir -p arch/sh/include/asm; fi
|
||||
$(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi
|
||||
$(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; }
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* SEGA Dreamcast keyboard driver
|
||||
* Based on drivers/usb/usbkbd.c
|
||||
* Copyright YAEGASHI Takeshi, 2001
|
||||
* Porting to 2.6 Copyright Adrian McMenamin, 2007
|
||||
* Porting to 2.6 Copyright Adrian McMenamin, 2007, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -45,39 +45,51 @@ struct dc_kbd {
|
|||
};
|
||||
|
||||
static const unsigned short dc_kbd_keycode[NR_SCANCODES] = {
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_A, KEY_B, KEY_C, KEY_D,
|
||||
KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L,
|
||||
KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T,
|
||||
KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_1, KEY_2,
|
||||
KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0,
|
||||
KEY_ENTER, KEY_ESC, KEY_BACKSPACE, KEY_TAB, KEY_SPACE, KEY_MINUS, KEY_EQUAL, KEY_LEFTBRACE,
|
||||
KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_BACKSLASH, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_GRAVE, KEY_COMMA,
|
||||
KEY_DOT, KEY_SLASH, KEY_CAPSLOCK, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_A, KEY_B,
|
||||
KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L,
|
||||
KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V,
|
||||
KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6,
|
||||
KEY_7, KEY_8, KEY_9, KEY_0, KEY_ENTER, KEY_ESC, KEY_BACKSPACE,
|
||||
KEY_TAB, KEY_SPACE, KEY_MINUS, KEY_EQUAL, KEY_LEFTBRACE,
|
||||
KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_BACKSLASH, KEY_SEMICOLON,
|
||||
KEY_APOSTROPHE, KEY_GRAVE, KEY_COMMA, KEY_DOT, KEY_SLASH,
|
||||
KEY_CAPSLOCK, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6,
|
||||
KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12, KEY_SYSRQ,
|
||||
KEY_SCROLLLOCK, KEY_PAUSE, KEY_INSERT, KEY_HOME, KEY_PAGEUP, KEY_DELETE,
|
||||
KEY_END, KEY_PAGEDOWN, KEY_RIGHT, KEY_LEFT, KEY_DOWN, KEY_UP,
|
||||
KEY_NUMLOCK, KEY_KPSLASH, KEY_KPASTERISK, KEY_KPMINUS, KEY_KPPLUS, KEY_KPENTER, KEY_KP1, KEY_KP2,
|
||||
KEY_KP3, KEY_KP4, KEY_KP5, KEY_KP6, KEY_KP7, KEY_KP8, KEY_KP9, KEY_KP0, KEY_KPDOT,
|
||||
KEY_102ND, KEY_COMPOSE, KEY_POWER, KEY_KPEQUAL, KEY_F13, KEY_F14, KEY_F15,
|
||||
KEY_F16, KEY_F17, KEY_F18, KEY_F19, KEY_F20,
|
||||
KEY_F21, KEY_F22, KEY_F23, KEY_F24, KEY_OPEN, KEY_HELP, KEY_PROPS, KEY_FRONT,
|
||||
KEY_STOP, KEY_AGAIN, KEY_UNDO, KEY_CUT, KEY_COPY, KEY_PASTE, KEY_FIND, KEY_MUTE,
|
||||
KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_KPCOMMA, KEY_RESERVED, KEY_RO, KEY_KATAKANAHIRAGANA , KEY_YEN,
|
||||
KEY_HENKAN, KEY_MUHENKAN, KEY_KPJPCOMMA, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_HANGEUL, KEY_HANJA, KEY_KATAKANA, KEY_HIRAGANA, KEY_ZENKAKUHANKAKU, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_LEFTCTRL, KEY_LEFTSHIFT, KEY_LEFTALT, KEY_LEFTMETA, KEY_RIGHTCTRL, KEY_RIGHTSHIFT, KEY_RIGHTALT, KEY_RIGHTMETA,
|
||||
KEY_PLAYPAUSE, KEY_STOPCD, KEY_PREVIOUSSONG, KEY_NEXTSONG, KEY_EJECTCD, KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_MUTE,
|
||||
KEY_WWW, KEY_BACK, KEY_FORWARD, KEY_STOP, KEY_FIND, KEY_SCROLLUP, KEY_SCROLLDOWN, KEY_EDIT, KEY_SLEEP,
|
||||
KEY_SCREENLOCK, KEY_REFRESH, KEY_CALC, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED
|
||||
KEY_SCROLLLOCK, KEY_PAUSE, KEY_INSERT, KEY_HOME, KEY_PAGEUP,
|
||||
KEY_DELETE, KEY_END, KEY_PAGEDOWN, KEY_RIGHT, KEY_LEFT, KEY_DOWN,
|
||||
KEY_UP, KEY_NUMLOCK, KEY_KPSLASH, KEY_KPASTERISK, KEY_KPMINUS,
|
||||
KEY_KPPLUS, KEY_KPENTER, KEY_KP1, KEY_KP2, KEY_KP3, KEY_KP4, KEY_KP5,
|
||||
KEY_KP6, KEY_KP7, KEY_KP8, KEY_KP9, KEY_KP0, KEY_KPDOT, KEY_102ND,
|
||||
KEY_COMPOSE, KEY_POWER, KEY_KPEQUAL, KEY_F13, KEY_F14, KEY_F15,
|
||||
KEY_F16, KEY_F17, KEY_F18, KEY_F19, KEY_F20, KEY_F21, KEY_F22,
|
||||
KEY_F23, KEY_F24, KEY_OPEN, KEY_HELP, KEY_PROPS, KEY_FRONT, KEY_STOP,
|
||||
KEY_AGAIN, KEY_UNDO, KEY_CUT, KEY_COPY, KEY_PASTE, KEY_FIND, KEY_MUTE,
|
||||
KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_KPCOMMA, KEY_RESERVED, KEY_RO, KEY_KATAKANAHIRAGANA , KEY_YEN,
|
||||
KEY_HENKAN, KEY_MUHENKAN, KEY_KPJPCOMMA, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_HANGEUL, KEY_HANJA, KEY_KATAKANA, KEY_HIRAGANA,
|
||||
KEY_ZENKAKUHANKAKU, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
|
||||
KEY_RESERVED, KEY_RESERVED, KEY_LEFTCTRL, KEY_LEFTSHIFT, KEY_LEFTALT,
|
||||
KEY_LEFTMETA, KEY_RIGHTCTRL, KEY_RIGHTSHIFT, KEY_RIGHTALT,
|
||||
KEY_RIGHTMETA, KEY_PLAYPAUSE, KEY_STOPCD, KEY_PREVIOUSSONG,
|
||||
KEY_NEXTSONG, KEY_EJECTCD, KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_MUTE,
|
||||
KEY_WWW, KEY_BACK, KEY_FORWARD, KEY_STOP, KEY_FIND, KEY_SCROLLUP,
|
||||
KEY_SCROLLDOWN, KEY_EDIT, KEY_SLEEP, KEY_SCREENLOCK, KEY_REFRESH,
|
||||
KEY_CALC, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED
|
||||
};
|
||||
|
||||
static void dc_scan_kbd(struct dc_kbd *kbd)
|
||||
|
@ -127,12 +139,12 @@ static void dc_scan_kbd(struct dc_kbd *kbd)
|
|||
static void dc_kbd_callback(struct mapleq *mq)
|
||||
{
|
||||
struct maple_device *mapledev = mq->dev;
|
||||
struct dc_kbd *kbd = mapledev->private_data;
|
||||
struct dc_kbd *kbd = maple_get_drvdata(mapledev);
|
||||
unsigned long *buf = mq->recvbuf;
|
||||
|
||||
/*
|
||||
* We should always be getting the lock because the only
|
||||
* time it may be locked if driver is in cleanup phase.
|
||||
* We should always get the lock because the only
|
||||
* time it may be locked is if the driver is in the cleanup phase.
|
||||
*/
|
||||
if (likely(mutex_trylock(&maple_keyb_mutex))) {
|
||||
|
||||
|
@ -145,106 +157,96 @@ static void dc_kbd_callback(struct mapleq *mq)
|
|||
}
|
||||
}
|
||||
|
||||
static int dc_kbd_connect(struct maple_device *mdev)
|
||||
static int probe_maple_kbd(struct device *dev)
|
||||
{
|
||||
struct maple_device *mdev = to_maple_dev(dev);
|
||||
struct maple_driver *mdrv = to_maple_driver(dev->driver);
|
||||
int i, error;
|
||||
struct dc_kbd *kbd;
|
||||
struct input_dev *dev;
|
||||
struct input_dev *idev;
|
||||
|
||||
if (!(mdev->function & MAPLE_FUNC_KEYBOARD))
|
||||
return -EINVAL;
|
||||
|
||||
kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL);
|
||||
dev = input_allocate_device();
|
||||
if (!kbd || !dev) {
|
||||
idev = input_allocate_device();
|
||||
if (!kbd || !idev) {
|
||||
error = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
mdev->private_data = kbd;
|
||||
|
||||
kbd->dev = dev;
|
||||
kbd->dev = idev;
|
||||
memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode));
|
||||
|
||||
dev->name = mdev->product_name;
|
||||
dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
|
||||
dev->keycode = kbd->keycode;
|
||||
dev->keycodesize = sizeof (unsigned short);
|
||||
dev->keycodemax = ARRAY_SIZE(kbd->keycode);
|
||||
dev->id.bustype = BUS_HOST;
|
||||
dev->dev.parent = &mdev->dev;
|
||||
idev->name = mdev->product_name;
|
||||
idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
|
||||
idev->keycode = kbd->keycode;
|
||||
idev->keycodesize = sizeof(unsigned short);
|
||||
idev->keycodemax = ARRAY_SIZE(kbd->keycode);
|
||||
idev->id.bustype = BUS_HOST;
|
||||
idev->dev.parent = &mdev->dev;
|
||||
|
||||
for (i = 0; i < NR_SCANCODES; i++)
|
||||
__set_bit(dc_kbd_keycode[i], dev->keybit);
|
||||
__clear_bit(KEY_RESERVED, dev->keybit);
|
||||
__set_bit(dc_kbd_keycode[i], idev->keybit);
|
||||
__clear_bit(KEY_RESERVED, idev->keybit);
|
||||
|
||||
input_set_capability(dev, EV_MSC, MSC_SCAN);
|
||||
input_set_drvdata(dev, kbd);
|
||||
input_set_capability(idev, EV_MSC, MSC_SCAN);
|
||||
input_set_drvdata(idev, kbd);
|
||||
|
||||
error = input_register_device(dev);
|
||||
error = input_register_device(idev);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/* Maple polling is locked to VBLANK - which may be just 50/s */
|
||||
maple_getcond_callback(mdev, dc_kbd_callback, HZ/50, MAPLE_FUNC_KEYBOARD);
|
||||
return 0;
|
||||
maple_getcond_callback(mdev, dc_kbd_callback, HZ/50,
|
||||
MAPLE_FUNC_KEYBOARD);
|
||||
|
||||
fail:
|
||||
input_free_device(dev);
|
||||
mdev->driver = mdrv;
|
||||
|
||||
maple_set_drvdata(mdev, kbd);
|
||||
|
||||
return error;
|
||||
|
||||
fail:
|
||||
input_free_device(idev);
|
||||
kfree(kbd);
|
||||
mdev->private_data = NULL;
|
||||
maple_set_drvdata(mdev, NULL);
|
||||
return error;
|
||||
}
|
||||
|
||||
static void dc_kbd_disconnect(struct maple_device *mdev)
|
||||
static int remove_maple_kbd(struct device *dev)
|
||||
{
|
||||
struct dc_kbd *kbd;
|
||||
struct maple_device *mdev = to_maple_dev(dev);
|
||||
struct dc_kbd *kbd = maple_get_drvdata(mdev);
|
||||
|
||||
mutex_lock(&maple_keyb_mutex);
|
||||
|
||||
kbd = mdev->private_data;
|
||||
mdev->private_data = NULL;
|
||||
input_unregister_device(kbd->dev);
|
||||
kfree(kbd);
|
||||
|
||||
maple_set_drvdata(mdev, NULL);
|
||||
|
||||
mutex_unlock(&maple_keyb_mutex);
|
||||
}
|
||||
|
||||
/* allow the keyboard to be used */
|
||||
static int probe_maple_kbd(struct device *dev)
|
||||
{
|
||||
struct maple_device *mdev = to_maple_dev(dev);
|
||||
struct maple_driver *mdrv = to_maple_driver(dev->driver);
|
||||
int error;
|
||||
|
||||
error = dc_kbd_connect(mdev);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
mdev->driver = mdrv;
|
||||
mdev->registered = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct maple_driver dc_kbd_driver = {
|
||||
.function = MAPLE_FUNC_KEYBOARD,
|
||||
.connect = dc_kbd_connect,
|
||||
.disconnect = dc_kbd_disconnect,
|
||||
.drv = {
|
||||
.name = "Dreamcast_keyboard",
|
||||
.probe = probe_maple_kbd,
|
||||
.remove = remove_maple_kbd,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init dc_kbd_init(void)
|
||||
{
|
||||
return maple_driver_register(&dc_kbd_driver.drv);
|
||||
return maple_driver_register(&dc_kbd_driver);
|
||||
}
|
||||
|
||||
static void __exit dc_kbd_exit(void)
|
||||
{
|
||||
driver_unregister(&dc_kbd_driver.drv);
|
||||
maple_driver_unregister(&dc_kbd_driver);
|
||||
}
|
||||
|
||||
module_init(dc_kbd_init);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/se.h>
|
||||
#include <mach-se/mach/se.h>
|
||||
#include <asm/machvec.h>
|
||||
#ifdef CONFIG_SH_STANDARD_BIOS
|
||||
#include <asm/sh_bios.h>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Core maple bus functionality
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Adrian McMenamin
|
||||
* Copyright (C) 2001 - 2008 Paul Mundt
|
||||
*
|
||||
* Based on 2.4 code by:
|
||||
*
|
||||
|
@ -31,7 +32,7 @@
|
|||
#include <mach/dma.h>
|
||||
#include <mach/sysasic.h>
|
||||
|
||||
MODULE_AUTHOR("Yaegshi Takeshi, Paul Mundt, M.R. Brown, Adrian McMenamin");
|
||||
MODULE_AUTHOR("Yaegashi Takeshi, Paul Mundt, M. R. Brown, Adrian McMenamin");
|
||||
MODULE_DESCRIPTION("Maple bus driver for Dreamcast");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_SUPPORTED_DEVICE("{{SEGA, Dreamcast/Maple}}");
|
||||
|
@ -65,19 +66,36 @@ static bool checked[4];
|
|||
static struct maple_device *baseunits[4];
|
||||
|
||||
/**
|
||||
* maple_driver_register - register a device driver
|
||||
* automatically makes the driver bus a maple bus
|
||||
* @drv: the driver to be registered
|
||||
* maple_driver_register - register a maple driver
|
||||
* @drv: maple driver to be registered.
|
||||
*
|
||||
* Registers the passed in @drv, while updating the bus type.
|
||||
* Devices with matching function IDs will be automatically probed.
|
||||
*/
|
||||
int maple_driver_register(struct device_driver *drv)
|
||||
int maple_driver_register(struct maple_driver *drv)
|
||||
{
|
||||
if (!drv)
|
||||
return -EINVAL;
|
||||
drv->bus = &maple_bus_type;
|
||||
return driver_register(drv);
|
||||
|
||||
drv->drv.bus = &maple_bus_type;
|
||||
|
||||
return driver_register(&drv->drv);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(maple_driver_register);
|
||||
|
||||
/**
|
||||
* maple_driver_unregister - unregister a maple driver.
|
||||
* @drv: maple driver to unregister.
|
||||
*
|
||||
* Cleans up after maple_driver_register(). To be invoked in the exit
|
||||
* path of any module drivers.
|
||||
*/
|
||||
void maple_driver_unregister(struct maple_driver *drv)
|
||||
{
|
||||
driver_unregister(&drv->drv);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(maple_driver_unregister);
|
||||
|
||||
/* set hardware registers to enable next round of dma */
|
||||
static void maplebus_dma_reset(void)
|
||||
{
|
||||
|
@ -129,13 +147,13 @@ static void maple_release_device(struct device *dev)
|
|||
kfree(mdev);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* maple_add_packet - add a single instruction to the queue
|
||||
* @mdev - maple device
|
||||
* @function - function on device being queried
|
||||
* @command - maple command to add
|
||||
* @length - length of command string (in 32 bit words)
|
||||
* @data - remainder of command string
|
||||
* @mdev: maple device
|
||||
* @function: function on device being queried
|
||||
* @command: maple command to add
|
||||
* @length: length of command string (in 32 bit words)
|
||||
* @data: remainder of command string
|
||||
*/
|
||||
int maple_add_packet(struct maple_device *mdev, u32 function, u32 command,
|
||||
size_t length, void *data)
|
||||
|
@ -176,14 +194,15 @@ out:
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(maple_add_packet);
|
||||
|
||||
/*
|
||||
/**
|
||||
* maple_add_packet_sleeps - add a single instruction to the queue
|
||||
* - waits for lock to be free
|
||||
* @mdev - maple device
|
||||
* @function - function on device being queried
|
||||
* @command - maple command to add
|
||||
* @length - length of command string (in 32 bit words)
|
||||
* @data - remainder of command string
|
||||
* @mdev: maple device
|
||||
* @function: function on device being queried
|
||||
* @command: maple command to add
|
||||
* @length: length of command string (in 32 bit words)
|
||||
* @data: remainder of command string
|
||||
*
|
||||
* Same as maple_add_packet(), but waits for the lock to become free.
|
||||
*/
|
||||
int maple_add_packet_sleeps(struct maple_device *mdev, u32 function,
|
||||
u32 command, size_t length, void *data)
|
||||
|
@ -724,11 +743,9 @@ static int maple_get_dma_buffer(void)
|
|||
static int match_maple_bus_driver(struct device *devptr,
|
||||
struct device_driver *drvptr)
|
||||
{
|
||||
struct maple_driver *maple_drv;
|
||||
struct maple_device *maple_dev;
|
||||
struct maple_driver *maple_drv = to_maple_driver(drvptr);
|
||||
struct maple_device *maple_dev = to_maple_dev(devptr);
|
||||
|
||||
maple_drv = container_of(drvptr, struct maple_driver, drv);
|
||||
maple_dev = container_of(devptr, struct maple_device, dev);
|
||||
/* Trap empty port case */
|
||||
if (maple_dev->devinfo.function == 0xFFFFFFFF)
|
||||
return 0;
|
||||
|
|
|
@ -51,7 +51,6 @@ struct maple_devinfo {
|
|||
struct maple_device {
|
||||
struct maple_driver *driver;
|
||||
struct mapleq *mq;
|
||||
void *private_data;
|
||||
void (*callback) (struct mapleq * mq);
|
||||
unsigned long when, interval, function;
|
||||
struct maple_devinfo devinfo;
|
||||
|
@ -70,7 +69,9 @@ void maple_getcond_callback(struct maple_device *dev,
|
|||
void (*callback) (struct mapleq * mq),
|
||||
unsigned long interval,
|
||||
unsigned long function);
|
||||
int maple_driver_register(struct device_driver *drv);
|
||||
int maple_driver_register(struct maple_driver *);
|
||||
void maple_driver_unregister(struct maple_driver *);
|
||||
|
||||
int maple_add_packet_sleeps(struct maple_device *mdev, u32 function,
|
||||
u32 command, u32 length, void *data);
|
||||
void maple_clear_dev(struct maple_device *mdev);
|
||||
|
@ -78,4 +79,7 @@ void maple_clear_dev(struct maple_device *mdev);
|
|||
#define to_maple_dev(n) container_of(n, struct maple_device, dev)
|
||||
#define to_maple_driver(n) container_of(n, struct maple_driver, drv)
|
||||
|
||||
#define maple_get_drvdata(d) dev_get_drvdata(&(d)->dev)
|
||||
#define maple_set_drvdata(d,p) dev_set_drvdata(&(d)->dev, (p))
|
||||
|
||||
#endif /* __LINUX_MAPLE_H */
|
||||
|
|
21
mm/nommu.c
21
mm/nommu.c
|
@ -266,6 +266,27 @@ void *vmalloc_node(unsigned long size, int node)
|
|||
}
|
||||
EXPORT_SYMBOL(vmalloc_node);
|
||||
|
||||
#ifndef PAGE_KERNEL_EXEC
|
||||
# define PAGE_KERNEL_EXEC PAGE_KERNEL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* vmalloc_exec - allocate virtually contiguous, executable memory
|
||||
* @size: allocation size
|
||||
*
|
||||
* Kernel-internal function to allocate enough pages to cover @size
|
||||
* the page level allocator and map them into contiguous and
|
||||
* executable kernel virtual space.
|
||||
*
|
||||
* For tight control over page level allocator and protection flags
|
||||
* use __vmalloc() instead.
|
||||
*/
|
||||
|
||||
void *vmalloc_exec(unsigned long size)
|
||||
{
|
||||
return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC);
|
||||
}
|
||||
|
||||
/**
|
||||
* vmalloc_32 - allocate virtually contiguous memory (32bit addressable)
|
||||
* @size: allocation size
|
||||
|
|
Loading…
Reference in New Issue