Commit 66d857b0 authored by Greg Ungerer's avatar Greg Ungerer

m68k: merge m68k and m68knommu arch directories

There is a lot of common code that could be shared between the m68k
and m68knommu arch branches. It makes sense to merge the two branches
into a single directory structure so that we can more easily share
that common code.

This is a brute force merge, based on a script from Stephen King
<sfking@fdwdc.com>, which was originally written by Arnd Bergmann
<arnd@arndb.de>.

> The script was inspired by the script Sam Ravnborg used to merge the
> includes from m68knommu. For those files common to both arches but
> differing in content, the m68k version of the file is renamed to
> <file>_mm.<ext> and the m68knommu version of the file is moved into the
> corresponding m68k directory and renamed <file>_no.<ext> and a small
> wrapper file <file>.<ext> is used to select between the two version. Files
> that are common to both but don't differ are removed from the m68knommu
> tree and files and directories that are unique to the m68knommu tree are
> moved to the m68k tree. Finally, the arch/m68knommu tree is removed.
>
> To select between the the versions of the files, the wrapper uses
>
> #ifdef CONFIG_MMU
> #include <file>_mm.<ext>
> #else
> #include <file>_no.<ext>
> #endif

On top of this file merge I have done a simplistic merge of m68k and
m68knommu Kconfig, which primarily attempts to keep existing options and
menus in place. Other than a handful of options being moved it produces
identical .config outputs on m68k and m68knommu targets I tested it on.

With this in place there is now quite a bit of scope for merge cleanups
in future patches.
Signed-off-by: default avatarGreg Ungerer <gerg@uclinux.org>
parent d39dd11c
This diff is collapsed.
...@@ -2,4 +2,38 @@ menu "Kernel hacking" ...@@ -2,4 +2,38 @@ menu "Kernel hacking"
source "lib/Kconfig.debug" source "lib/Kconfig.debug"
if !MMU
config FULLDEBUG
bool "Full Symbolic/Source Debugging support"
help
Enable debugging symbols on kernel build.
config HIGHPROFILE
bool "Use fast second timer for profiling"
depends on COLDFIRE
help
Use a fast secondary clock to produce profiling information.
config BOOTPARAM
bool 'Compiled-in Kernel Boot Parameter'
config BOOTPARAM_STRING
string 'Kernel Boot Parameter'
default 'console=ttyS0,19200'
depends on BOOTPARAM
config NO_KERNEL_MSG
bool "Suppress Kernel BUG Messages"
help
Do not output any debug BUG messages within the kernel.
config BDM_DISABLE
bool "Disable BDM signals"
depends on (EXPERIMENTAL && COLDFIRE)
help
Disable the ColdFire CPU's BDM signals.
endif
endmenu endmenu
This diff is collapsed.
config M68K
bool
default y
select HAVE_IDE
select HAVE_GENERIC_HARDIRQS
select GENERIC_HARDIRQS_NO_DEPRECATED
config MMU
bool
default n
config NO_DMA
bool
depends on !COLDFIRE
default y
config FPU config FPU
bool bool
default n default n
config ZONE_DMA
bool
default y
config RWSEM_GENERIC_SPINLOCK
bool
default y
config RWSEM_XCHGADD_ALGORITHM
bool
default n
config ARCH_HAS_ILOG2_U32
bool
default n
config ARCH_HAS_ILOG2_U64
bool
default n
config GENERIC_FIND_NEXT_BIT config GENERIC_FIND_NEXT_BIT
bool bool
default y default y
...@@ -46,29 +10,14 @@ config GENERIC_GPIO ...@@ -46,29 +10,14 @@ config GENERIC_GPIO
bool bool
default n default n
config GENERIC_HWEIGHT
bool
default y
config GENERIC_CALIBRATE_DELAY
bool
default y
config GENERIC_CMOS_UPDATE config GENERIC_CMOS_UPDATE
bool bool
default y default y
config TIME_LOW_RES
bool
default y
config GENERIC_CLOCKEVENTS config GENERIC_CLOCKEVENTS
bool bool
default n default n
config NO_IOPORT
def_bool y
config COLDFIRE_SW_A7 config COLDFIRE_SW_A7
bool bool
default n default n
...@@ -85,12 +34,6 @@ config HAVE_MBAR ...@@ -85,12 +34,6 @@ config HAVE_MBAR
config HAVE_IPSBAR config HAVE_IPSBAR
bool bool
source "init/Kconfig"
source "kernel/Kconfig.freezer"
menu "Processor type and features"
choice choice
prompt "CPU" prompt "CPU"
default M68EZ328 default M68EZ328
...@@ -630,11 +573,6 @@ config 4KSTACKS ...@@ -630,11 +573,6 @@ config 4KSTACKS
running more threads on a system and also reduces the pressure running more threads on a system and also reduces the pressure
on the VM subsystem for higher order allocations. on the VM subsystem for higher order allocations.
config HZ
int
default 1000 if CLEOPATRA
default 100
comment "RAM configuration" comment "RAM configuration"
config RAMBASE config RAMBASE
...@@ -803,10 +741,6 @@ endif ...@@ -803,10 +741,6 @@ endif
source "kernel/time/Kconfig" source "kernel/time/Kconfig"
source "mm/Kconfig"
endmenu
config ISA_DMA_API config ISA_DMA_API
bool bool
depends on !M5272 depends on !M5272
...@@ -814,31 +748,3 @@ config ISA_DMA_API ...@@ -814,31 +748,3 @@ config ISA_DMA_API
source "drivers/pcmcia/Kconfig" source "drivers/pcmcia/Kconfig"
menu "Executable file formats"
source "fs/Kconfig.binfmt"
endmenu
menu "Power management options"
config PM
bool "Power Management support"
help
Support processor power management modes
endmenu
source "net/Kconfig"
source "drivers/Kconfig"
source "fs/Kconfig"
source "arch/m68knommu/Kconfig.debug"
source "security/Kconfig"
source "crypto/Kconfig"
source "lib/Kconfig"
#
# m68k/Makefile
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
# for "archclean" and "archdep" for cleaning up and making dependencies for
# this architecture
#
# 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.
#
# Copyright (C) 1994 by Hamish Macdonald
#
KBUILD_DEFCONFIG := multi_defconfig KBUILD_DEFCONFIG := multi_defconfig
# override top level makefile ifdef CONFIG_MMU
AS += -m68020 include $(srctree)/arch/m68k/Makefile_mm
LDFLAGS := -m m68kelf
KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
ifneq ($(SUBARCH),$(ARCH))
ifeq ($(CROSS_COMPILE),)
CROSS_COMPILE := $(call cc-cross-prefix, \
m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-)
endif
endif
ifdef CONFIG_SUN3
LDFLAGS_vmlinux = -N
endif
CHECKFLAGS += -D__mc68000__
# without -fno-strength-reduce the 53c7xx.c driver fails ;-(
KBUILD_CFLAGS += -pipe -fno-strength-reduce -ffixed-a2
# enable processor switch if compiled only for a single cpu
ifndef CONFIG_M68020
ifndef CONFIG_M68030
ifndef CONFIG_M68060
KBUILD_CFLAGS += -m68040
endif
ifndef CONFIG_M68040
KBUILD_CFLAGS += -m68060
endif
endif
endif
ifdef CONFIG_KGDB
# If configured for kgdb support, include debugging infos and keep the
# frame pointer
KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g
endif
ifndef CONFIG_SUN3
head-y := arch/m68k/kernel/head.o
else else
head-y := arch/m68k/kernel/sun3-head.o include $(srctree)/arch/m68k/Makefile_no
endif endif
core-y += arch/m68k/kernel/ arch/m68k/mm/
libs-y += arch/m68k/lib/
core-$(CONFIG_Q40) += arch/m68k/q40/
core-$(CONFIG_AMIGA) += arch/m68k/amiga/
core-$(CONFIG_ATARI) += arch/m68k/atari/
core-$(CONFIG_MAC) += arch/m68k/mac/
core-$(CONFIG_HP300) += arch/m68k/hp300/
core-$(CONFIG_APOLLO) += arch/m68k/apollo/
core-$(CONFIG_MVME147) += arch/m68k/mvme147/
core-$(CONFIG_MVME16x) += arch/m68k/mvme16x/
core-$(CONFIG_BVME6000) += arch/m68k/bvme6000/
core-$(CONFIG_SUN3X) += arch/m68k/sun3x/ arch/m68k/sun3/
core-$(CONFIG_SUN3) += arch/m68k/sun3/ arch/m68k/sun3/prom/
core-$(CONFIG_NATFEAT) += arch/m68k/emu/
core-$(CONFIG_M68040) += arch/m68k/fpsp040/
core-$(CONFIG_M68060) += arch/m68k/ifpsp060/
core-$(CONFIG_M68KFPU_EMU) += arch/m68k/math-emu/
all: zImage
lilo: vmlinux
if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi
if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
cat vmlinux > $(INSTALL_PATH)/vmlinux
cp System.map $(INSTALL_PATH)/System.map
if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
zImage compressed: vmlinux.gz
vmlinux.gz: vmlinux
ifndef CONFIG_KGDB
cp vmlinux vmlinux.tmp
$(STRIP) vmlinux.tmp
gzip -9c vmlinux.tmp >vmlinux.gz
rm vmlinux.tmp
else
gzip -9c vmlinux >vmlinux.gz
endif
bzImage: vmlinux.bz2
vmlinux.bz2: vmlinux
ifndef CONFIG_KGDB
cp vmlinux vmlinux.tmp
$(STRIP) vmlinux.tmp
bzip2 -1c vmlinux.tmp >vmlinux.bz2
rm vmlinux.tmp
else
bzip2 -1c vmlinux >vmlinux.bz2
endif
archclean:
rm -f vmlinux.gz vmlinux.bz2
install:
sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
#
# m68k/Makefile
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
# for "archclean" and "archdep" for cleaning up and making dependencies for
# this architecture
#
# 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.
#
# Copyright (C) 1994 by Hamish Macdonald
#
# override top level makefile
AS += -m68020
LDFLAGS := -m m68kelf
KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
ifneq ($(SUBARCH),$(ARCH))
ifeq ($(CROSS_COMPILE),)
CROSS_COMPILE := $(call cc-cross-prefix, \
m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-)
endif
endif
ifdef CONFIG_SUN3
LDFLAGS_vmlinux = -N
endif
CHECKFLAGS += -D__mc68000__
# without -fno-strength-reduce the 53c7xx.c driver fails ;-(
KBUILD_CFLAGS += -pipe -fno-strength-reduce -ffixed-a2
# enable processor switch if compiled only for a single cpu
ifndef CONFIG_M68020
ifndef CONFIG_M68030
ifndef CONFIG_M68060
KBUILD_CFLAGS += -m68040
endif
ifndef CONFIG_M68040
KBUILD_CFLAGS += -m68060
endif
endif
endif
ifdef CONFIG_KGDB
# If configured for kgdb support, include debugging infos and keep the
# frame pointer
KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g
endif
ifndef CONFIG_SUN3
head-y := arch/m68k/kernel/head.o
else
head-y := arch/m68k/kernel/sun3-head.o
endif
core-y += arch/m68k/kernel/ arch/m68k/mm/
libs-y += arch/m68k/lib/
core-$(CONFIG_Q40) += arch/m68k/q40/
core-$(CONFIG_AMIGA) += arch/m68k/amiga/
core-$(CONFIG_ATARI) += arch/m68k/atari/
core-$(CONFIG_MAC) += arch/m68k/mac/
core-$(CONFIG_HP300) += arch/m68k/hp300/
core-$(CONFIG_APOLLO) += arch/m68k/apollo/
core-$(CONFIG_MVME147) += arch/m68k/mvme147/
core-$(CONFIG_MVME16x) += arch/m68k/mvme16x/
core-$(CONFIG_BVME6000) += arch/m68k/bvme6000/
core-$(CONFIG_SUN3X) += arch/m68k/sun3x/ arch/m68k/sun3/
core-$(CONFIG_SUN3) += arch/m68k/sun3/ arch/m68k/sun3/prom/
core-$(CONFIG_NATFEAT) += arch/m68k/emu/
core-$(CONFIG_M68040) += arch/m68k/fpsp040/
core-$(CONFIG_M68060) += arch/m68k/ifpsp060/
core-$(CONFIG_M68KFPU_EMU) += arch/m68k/math-emu/
all: zImage
lilo: vmlinux
if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi
if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
cat vmlinux > $(INSTALL_PATH)/vmlinux
cp System.map $(INSTALL_PATH)/System.map
if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
zImage compressed: vmlinux.gz
vmlinux.gz: vmlinux
ifndef CONFIG_KGDB
cp vmlinux vmlinux.tmp
$(STRIP) vmlinux.tmp
gzip -9c vmlinux.tmp >vmlinux.gz
rm vmlinux.tmp
else
gzip -9c vmlinux >vmlinux.gz
endif
bzImage: vmlinux.bz2
vmlinux.bz2: vmlinux
ifndef CONFIG_KGDB
cp vmlinux vmlinux.tmp
$(STRIP) vmlinux.tmp
bzip2 -1c vmlinux.tmp >vmlinux.bz2
rm vmlinux.tmp
else
bzip2 -1c vmlinux >vmlinux.bz2
endif
archclean:
rm -f vmlinux.gz vmlinux.bz2
install:
sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
# #
# arch/m68knommu/Makefile # arch/m68k/Makefile
# #
# This file is subject to the terms and conditions of the GNU General Public # 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 # License. See the file "COPYING" in the main directory of this archive
...@@ -8,8 +8,6 @@ ...@@ -8,8 +8,6 @@
# (C) Copyright 2002, Greg Ungerer <gerg@snapgear.com> # (C) Copyright 2002, Greg Ungerer <gerg@snapgear.com>
# #
KBUILD_DEFCONFIG := m5208evb_defconfig
platform-$(CONFIG_M68328) := 68328 platform-$(CONFIG_M68328) := 68328
platform-$(CONFIG_M68EZ328) := 68EZ328 platform-$(CONFIG_M68EZ328) := 68EZ328
platform-$(CONFIG_M68VZ328) := 68VZ328 platform-$(CONFIG_M68VZ328) := 68VZ328
...@@ -82,7 +80,7 @@ cpuclass-$(CONFIG_M68360) := 68360 ...@@ -82,7 +80,7 @@ cpuclass-$(CONFIG_M68360) := 68360
CPUCLASS := $(cpuclass-y) CPUCLASS := $(cpuclass-y)
ifneq ($(CPUCLASS),$(PLATFORM)) ifneq ($(CPUCLASS),$(PLATFORM))
CLASSDIR := arch/m68knommu/platform/$(cpuclass-y)/ CLASSDIR := arch/m68k/platform/$(cpuclass-y)/
endif endif
export PLATFORM BOARD MODEL CPUCLASS export PLATFORM BOARD MODEL CPUCLASS
...@@ -114,13 +112,13 @@ KBUILD_CFLAGS += $(cflags-y) ...@@ -114,13 +112,13 @@ KBUILD_CFLAGS += $(cflags-y)
KBUILD_CFLAGS += -D__linux__ KBUILD_CFLAGS += -D__linux__
KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\" KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
head-y := arch/m68knommu/platform/$(cpuclass-y)/head.o head-y := arch/m68k/platform/$(cpuclass-y)/head.o
core-y += arch/m68knommu/kernel/ \ core-y += arch/m68k/kernel/ \
arch/m68knommu/mm/ \ arch/m68k/mm/ \
$(CLASSDIR) \ $(CLASSDIR) \
arch/m68knommu/platform/$(PLATFORM)/ arch/m68k/platform/$(PLATFORM)/
libs-y += arch/m68knommu/lib/ libs-y += arch/m68k/lib/
archclean: archclean:
# CONFIG_MMU is not set
CONFIG_EXPERIMENTAL=y CONFIG_EXPERIMENTAL=y
CONFIG_LOG_BUF_SHIFT=14 CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
...@@ -37,6 +38,7 @@ CONFIG_INET=y ...@@ -37,6 +38,7 @@ CONFIG_INET=y
# CONFIG_INET_LRO is not set # CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set # CONFIG_INET_DIAG is not set
# CONFIG_IPV6 is not set # CONFIG_IPV6 is not set
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y CONFIG_MTD_CHAR=y
......
# CONFIG_MMU is not set
CONFIG_EXPERIMENTAL=y CONFIG_EXPERIMENTAL=y
CONFIG_LOG_BUF_SHIFT=14 CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
...@@ -35,6 +36,7 @@ CONFIG_INET=y ...@@ -35,6 +36,7 @@ CONFIG_INET=y
# CONFIG_INET_LRO is not set # CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set # CONFIG_INET_DIAG is not set
# CONFIG_IPV6 is not set # CONFIG_IPV6 is not set
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y CONFIG_MTD_CHAR=y
......
# CONFIG_MMU is not set
CONFIG_EXPERIMENTAL=y CONFIG_EXPERIMENTAL=y
CONFIG_LOG_BUF_SHIFT=14 CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
...@@ -33,6 +34,7 @@ CONFIG_INET=y ...@@ -33,6 +34,7 @@ CONFIG_INET=y
# CONFIG_INET_LRO is not set # CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set # CONFIG_INET_DIAG is not set
# CONFIG_IPV6 is not set # CONFIG_IPV6 is not set
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y CONFIG_MTD_CHAR=y
......
# CONFIG_MMU is not set
CONFIG_EXPERIMENTAL=y CONFIG_EXPERIMENTAL=y
CONFIG_LOG_BUF_SHIFT=14 CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
...@@ -36,6 +37,7 @@ CONFIG_INET=y ...@@ -36,6 +37,7 @@ CONFIG_INET=y
# CONFIG_INET_LRO is not set # CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set # CONFIG_INET_DIAG is not set
# CONFIG_IPV6 is not set # CONFIG_IPV6 is not set
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y CONFIG_MTD_CHAR=y
......
# CONFIG_MMU is not set
CONFIG_EXPERIMENTAL=y CONFIG_EXPERIMENTAL=y
CONFIG_LOG_BUF_SHIFT=14 CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
...@@ -35,6 +36,7 @@ CONFIG_INET=y ...@@ -35,6 +36,7 @@ CONFIG_INET=y
# CONFIG_INET_LRO is not set # CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set # CONFIG_INET_DIAG is not set
# CONFIG_IPV6 is not set # CONFIG_IPV6 is not set
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y CONFIG_MTD_CHAR=y
......
# CONFIG_MMU is not set
CONFIG_EXPERIMENTAL=y CONFIG_EXPERIMENTAL=y
CONFIG_LOG_BUF_SHIFT=14 CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
...@@ -35,6 +36,7 @@ CONFIG_INET=y ...@@ -35,6 +36,7 @@ CONFIG_INET=y
# CONFIG_INET_LRO is not set # CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set # CONFIG_INET_DIAG is not set
# CONFIG_IPV6 is not set # CONFIG_IPV6 is not set
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y CONFIG_MTD_CHAR=y
......
# ifdef CONFIG_MMU
# Makefile for the linux kernel. include arch/m68k/kernel/Makefile_mm
#
ifndef CONFIG_SUN3
extra-y := head.o
else else
extra-y := sun3-head.o include arch/m68k/kernel/Makefile_no
endif endif
extra-y += vmlinux.lds
obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \
sys_m68k.o time.o setup.o m68k_ksyms.o devres.o
devres-y = ../../../kernel/irq/devres.o
obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo
#
# Makefile for the linux kernel.
#
ifndef CONFIG_SUN3
extra-y := head.o
else
extra-y := sun3-head.o
endif
extra-y += vmlinux.lds
obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \
sys_m68k.o time.o setup.o m68k_ksyms.o devres.o
devres-y = ../../../kernel/irq/devres.o
obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo
/*
* This program is used to generate definitions needed by
* assembly language modules.
*
* We use the technique used in the OSF Mach kernel code:
* generate asm statements containing #defines,
* compile this file to assembler, and then extract the
* #defines from the assembly-language output.
*/
#define ASM_OFFSETS_C
#include <linux/stddef.h>
#include <linux/sched.h>
#include <linux/kernel_stat.h>
#include <linux/kbuild.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/amigahw.h>
#include <linux/font.h>
int main(void)
{
/* offsets into the task struct */
DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
DEFINE(TASK_MM, offsetof(struct task_struct, mm));
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info)); #include "asm-offsets_mm.c"
#else
#include "asm-offsets_no.c"
#endif #endif
/* offsets into the thread struct */
DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));
DEFINE(THREAD_FS, offsetof(struct thread_struct, fs));
DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));
DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));
DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
/* offsets into the thread_info struct */
DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
/* offsets into the pt_regs */
DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));
DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));
DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));
DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));
DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));
DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));
DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));
DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));
DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));
DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));
DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));
DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));
/* bitfields are a bit difficult */
DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);
/* offsets into the irq_cpustat_t struct */
DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
/* offsets into the bi_record struct */
DEFINE(BIR_TAG, offsetof(struct bi_record, tag));
DEFINE(BIR_SIZE, offsetof(struct bi_record, size));
DEFINE(BIR_DATA, offsetof(struct bi_record, data));
/* offsets into font_desc (drivers/video/console/font.h) */
DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx));
DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name));
DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width));
DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height));
DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data));
DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref));
/* signal defines */
DEFINE(LSIGSEGV, SIGSEGV);
DEFINE(LSEGV_MAPERR, SEGV_MAPERR);
DEFINE(LSIGTRAP, SIGTRAP);
DEFINE(LTRAP_TRACE, TRAP_TRACE);
/* offsets into the custom struct */
DEFINE(CUSTOMBASE, &amiga_custom);
DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar));
DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr));
DEFINE(C_INTENA, offsetof(struct CUSTOM, intena));
DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq));
DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr));
DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat));
DEFINE(C_SERPER, offsetof(struct CUSTOM, serper));
DEFINE(CIAABASE, &ciaa);
DEFINE(CIABBASE, &ciab);
DEFINE(C_PRA, offsetof(struct CIA, pra));
DEFINE(ZTWOBASE, zTwoBase);
return 0;
}
/*
* This program is used to generate definitions needed by
* assembly language modules.
*
* We use the technique used in the OSF Mach kernel code:
* generate asm statements containing #defines,
* compile this file to assembler, and then extract the
* #defines from the assembly-language output.
*/
#define ASM_OFFSETS_C
#include <linux/stddef.h>
#include <linux/sched.h>
#include <linux/kernel_stat.h>
#include <linux/kbuild.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/amigahw.h>
#include <linux/font.h>
int main(void)
{
/* offsets into the task struct */
DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
DEFINE(TASK_MM, offsetof(struct task_struct, mm));
#ifdef CONFIG_MMU
DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info));
#endif
/* offsets into the thread struct */
DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));
DEFINE(THREAD_FS, offsetof(struct thread_struct, fs));
DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));
DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));
DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
/* offsets into the thread_info struct */
DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
/* offsets into the pt_regs */
DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));
DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));
DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));
DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));
DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));
DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));
DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));
DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));
DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));
DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));
DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));
DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));
/* bitfields are a bit difficult */
DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);
/* offsets into the irq_cpustat_t struct */
DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
/* offsets into the bi_record struct */
DEFINE(BIR_TAG, offsetof(struct bi_record, tag));
DEFINE(BIR_SIZE, offsetof(struct bi_record, size));
DEFINE(BIR_DATA, offsetof(struct bi_record, data));
/* offsets into font_desc (drivers/video/console/font.h) */
DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx));
DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name));
DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width));
DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height));
DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data));
DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref));
/* signal defines */
DEFINE(LSIGSEGV, SIGSEGV);
DEFINE(LSEGV_MAPERR, SEGV_MAPERR);
DEFINE(LSIGTRAP, SIGTRAP);
DEFINE(LTRAP_TRACE, TRAP_TRACE);
/* offsets into the custom struct */
DEFINE(CUSTOMBASE, &amiga_custom);
DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar));
DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr));
DEFINE(C_INTENA, offsetof(struct CUSTOM, intena));
DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq));
DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr));
DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat));
DEFINE(C_SERPER, offsetof(struct CUSTOM, serper));
DEFINE(CIAABASE, &ciaa);
DEFINE(CIABBASE, &ciab);
DEFINE(C_PRA, offsetof(struct CIA, pra));
DEFINE(ZTWOBASE, zTwoBase);
return 0;
}
/* #ifdef CONFIG_MMU
* This file is subject to the terms and conditions of the GNU General Public #include "dma_mm.c"
* License. See the file COPYING in the main directory of this archive #else
* for more details. #include "dma_no.c"
*/ #endif
#undef DEBUG
#include <linux/dma-mapping.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <asm/pgalloc.h>
void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *handle, gfp_t flag)
{
struct page *page, **map;
pgprot_t pgprot;
void *addr;
int i, order;
pr_debug("dma_alloc_coherent: %d,%x\n", size, flag);
size = PAGE_ALIGN(size);
order = get_order(size);
page = alloc_pages(flag, order);
if (!page)
return NULL;
*handle = page_to_phys(page);
map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA);
if (!map) {
__free_pages(page, order);
return NULL;
}
split_page(page, order);
order = 1 << order;
size >>= PAGE_SHIFT;
map[0] = page;
for (i = 1; i < size; i++)
map[i] = page + i;
for (; i < order; i++)
__free_page(page + i);
pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
if (CPU_IS_040_OR_060)
pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S;
else
pgprot_val(pgprot) |= _PAGE_NOCACHE030;
addr = vmap(map, size, VM_MAP, pgprot);
kfree(map);
return addr;
}
EXPORT_SYMBOL(dma_alloc_coherent);
void dma_free_coherent(struct device *dev, size_t size,
void *addr, dma_addr_t handle)
{
pr_debug("dma_free_coherent: %p, %x\n", addr, handle);
vfree(addr);
}
EXPORT_SYMBOL(dma_free_coherent);
void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
{
switch (dir) {
case DMA_TO_DEVICE:
cache_push(handle, size);
break;
case DMA_FROM_DEVICE:
cache_clear(handle, size);
break;
default:
if (printk_ratelimit())
printk("dma_sync_single_for_device: unsupported dir %u\n", dir);
break;
}
}
EXPORT_SYMBOL(dma_sync_single_for_device);
void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
int i;
for (i = 0; i < nents; sg++, i++)
dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
}
EXPORT_SYMBOL(dma_sync_sg_for_device);
dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size,
enum dma_data_direction dir)
{
dma_addr_t handle = virt_to_bus(addr);
dma_sync_single_for_device(dev, handle, size, dir);
return handle;
}
EXPORT_SYMBOL(dma_map_single);
dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
enum dma_data_direction dir)
{
dma_addr_t handle = page_to_phys(page) + offset;
dma_sync_single_for_device(dev, handle, size, dir);
return handle;
}
EXPORT_SYMBOL(dma_map_page);
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
int i;
for (i = 0; i < nents; sg++, i++) {
sg->dma_address = sg_phys(sg);
dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
}
return nents;
}
EXPORT_SYMBOL(dma_map_sg);
/*
* 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.
*/
#undef DEBUG
#include <linux/dma-mapping.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <asm/pgalloc.h>
void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *handle, gfp_t flag)
{
struct page *page, **map;
pgprot_t pgprot;
void *addr;
int i, order;
pr_debug("dma_alloc_coherent: %d,%x\n", size, flag);
size = PAGE_ALIGN(size);
order = get_order(size);
page = alloc_pages(flag, order);
if (!page)
return NULL;
*handle = page_to_phys(page);
map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA);
if (!map) {
__free_pages(page, order);
return NULL;
}
split_page(page, order);
order = 1 << order;
size >>= PAGE_SHIFT;
map[0] = page;
for (i = 1; i < size; i++)
map[i] = page + i;
for (; i < order; i++)
__free_page(page + i);
pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
if (CPU_IS_040_OR_060)
pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S;
else
pgprot_val(pgprot) |= _PAGE_NOCACHE030;
addr = vmap(map, size, VM_MAP, pgprot);
kfree(map);
return addr;
}
EXPORT_SYMBOL(dma_alloc_coherent);
void dma_free_coherent(struct device *dev, size_t size,
void *addr, dma_addr_t handle)
{
pr_debug("dma_free_coherent: %p, %x\n", addr, handle);
vfree(addr);
}
EXPORT_SYMBOL(dma_free_coherent);
void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
{
switch (dir) {
case DMA_TO_DEVICE:
cache_push(handle, size);
break;
case DMA_FROM_DEVICE:
cache_clear(handle, size);
break;
default:
if (printk_ratelimit())
printk("dma_sync_single_for_device: unsupported dir %u\n", dir);
break;
}
}
EXPORT_SYMBOL(dma_sync_single_for_device);
void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
int i;
for (i = 0; i < nents; sg++, i++)
dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
}
EXPORT_SYMBOL(dma_sync_sg_for_device);
dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size,
enum dma_data_direction dir)
{
dma_addr_t handle = virt_to_bus(addr);
dma_sync_single_for_device(dev, handle, size, dir);
return handle;
}
EXPORT_SYMBOL(dma_map_single);
dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
enum dma_data_direction dir)
{
dma_addr_t handle = page_to_phys(page) + offset;
dma_sync_single_for_device(dev, handle, size, dir);
return handle;
}
EXPORT_SYMBOL(dma_map_page);
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
int i;
for (i = 0; i < nents; sg++, i++) {
sg->dma_address = sg_phys(sg);
dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
}
return nents;
}
EXPORT_SYMBOL(dma_map_sg);
This diff is collapsed.
This diff is collapsed.
#include <linux/module.h> #ifdef CONFIG_MMU
#include "m68k_ksyms_mm.c"
asmlinkage long long __ashldi3 (long long, int); #else
asmlinkage long long __ashrdi3 (long long, int); #include "m68k_ksyms_no.c"
asmlinkage long long __lshrdi3 (long long, int); #endif
asmlinkage long long __muldi3 (long long, long long);
/* The following are special because they're not called
explicitly (the C compiler generates them). Fortunately,
their interface isn't gonna change any time soon now, so
it's OK to leave it out of version control. */
EXPORT_SYMBOL(__ashldi3);
EXPORT_SYMBOL(__ashrdi3);
EXPORT_SYMBOL(__lshrdi3);
EXPORT_SYMBOL(__muldi3);
#include <linux/module.h>
asmlinkage long long __ashldi3 (long long, int);
asmlinkage long long __ashrdi3 (long long, int);
asmlinkage long long __lshrdi3 (long long, int);
asmlinkage long long __muldi3 (long long, long long);
/* The following are special because they're not called
explicitly (the C compiler generates them). Fortunately,
their interface isn't gonna change any time soon now, so
it's OK to leave it out of version control. */
EXPORT_SYMBOL(__ashldi3);
EXPORT_SYMBOL(__ashrdi3);
EXPORT_SYMBOL(__lshrdi3);
EXPORT_SYMBOL(__muldi3);
/* #ifdef CONFIG_MMU
* This file is subject to the terms and conditions of the GNU General Public #include "module_mm.c"
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#include <linux/moduleloader.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/kernel.h>
#if 0
#define DEBUGP printk
#else #else
#define DEBUGP(fmt...) #include "module_no.c"
#endif #endif
#ifdef CONFIG_MODULES
void *module_alloc(unsigned long size)
{
if (size == 0)
return NULL;
return vmalloc(size);
}
/* Free memory returned from module_alloc */
void module_free(struct module *mod, void *module_region)
{
vfree(module_region);
}
/* We don't need anything special. */
int module_frob_arch_sections(Elf_Ehdr *hdr,
Elf_Shdr *sechdrs,
char *secstrings,
struct module *mod)
{
return 0;
}
int apply_relocate(Elf32_Shdr *sechdrs,
const char *strtab,
unsigned int symindex,
unsigned int relsec,
struct module *me)
{
unsigned int i;
Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
Elf32_Sym *sym;
uint32_t *location;
DEBUGP("Applying relocate section %u to %u\n", relsec,
sechdrs[relsec].sh_info);
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
/* This is where to make the change */
location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ rel[i].r_offset;
/* This is the symbol it is referring to. Note that all
undefined symbols have been resolved. */
sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+ ELF32_R_SYM(rel[i].r_info);
switch (ELF32_R_TYPE(rel[i].r_info)) {
case R_68K_32:
/* We add the value into the location given */
*location += sym->st_value;
break;
case R_68K_PC32:
/* Add the value, subtract its postition */
*location += sym->st_value - (uint32_t)location;
break;
default:
printk(KERN_ERR "module %s: Unknown relocation: %u\n",
me->name, ELF32_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}
}
return 0;
}
int apply_relocate_add(Elf32_Shdr *sechdrs,
const char *strtab,
unsigned int symindex,
unsigned int relsec,
struct module *me)
{
unsigned int i;
Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
Elf32_Sym *sym;
uint32_t *location;
DEBUGP("Applying relocate_add section %u to %u\n", relsec,
sechdrs[relsec].sh_info);
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
/* This is where to make the change */
location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ rel[i].r_offset;
/* This is the symbol it is referring to. Note that all
undefined symbols have been resolved. */
sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+ ELF32_R_SYM(rel[i].r_info);
switch (ELF32_R_TYPE(rel[i].r_info)) {
case R_68K_32:
/* We add the value into the location given */
*location = rel[i].r_addend + sym->st_value;
break;
case R_68K_PC32:
/* Add the value, subtract its postition */
*location = rel[i].r_addend + sym->st_value - (uint32_t)location;
break;
default:
printk(KERN_ERR "module %s: Unknown relocation: %u\n",
me->name, ELF32_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}
}
return 0;
}
int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *mod)
{
module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end);
return 0;
}
void module_arch_cleanup(struct module *mod)
{
}
#endif /* CONFIG_MODULES */
void module_fixup(struct module *mod, struct m68k_fixup_info *start,
struct m68k_fixup_info *end)
{
struct m68k_fixup_info *fixup;
for (fixup = start; fixup < end; fixup++) {
switch (fixup->type) {
case m68k_fixup_memoffset:
*(u32 *)fixup->addr = m68k_memoffset;
break;
case m68k_fixup_vnode_shift:
*(u16 *)fixup->addr += m68k_virt_to_node_shift;
break;
}
}
}
/*
* 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.
*/
#include <linux/moduleloader.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/kernel.h>
#if 0
#define DEBUGP printk
#else
#define DEBUGP(fmt...)
#endif
#ifdef CONFIG_MODULES
void *module_alloc(unsigned long size)
{
if (size == 0)
return NULL;
return vmalloc(size);
}
/* Free memory returned from module_alloc */
void module_free(struct module *mod, void *module_region)
{
vfree(module_region);
}
/* We don't need anything special. */
int module_frob_arch_sections(Elf_Ehdr *hdr,
Elf_Shdr *sechdrs,
char *secstrings,
struct module *mod)
{
return 0;
}
int apply_relocate(Elf32_Shdr *sechdrs,
const char *strtab,
unsigned int symindex,
unsigned int relsec,
struct module *me)
{
unsigned int i;
Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
Elf32_Sym *sym;
uint32_t *location;
DEBUGP("Applying relocate section %u to %u\n", relsec,
sechdrs[relsec].sh_info);
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
/* This is where to make the change */
location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ rel[i].r_offset;
/* This is the symbol it is referring to. Note that all
undefined symbols have been resolved. */
sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+ ELF32_R_SYM(rel[i].r_info);
switch (ELF32_R_TYPE(rel[i].r_info)) {
case R_68K_32:
/* We add the value into the location given */
*location += sym->st_value;
break;
case R_68K_PC32:
/* Add the value, subtract its postition */
*location += sym->st_value - (uint32_t)location;
break;
default:
printk(KERN_ERR "module %s: Unknown relocation: %u\n",
me->name, ELF32_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}
}
return 0;
}
int apply_relocate_add(Elf32_Shdr *sechdrs,
const char *strtab,
unsigned int symindex,
unsigned int relsec,
struct module *me)
{
unsigned int i;
Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
Elf32_Sym *sym;
uint32_t *location;
DEBUGP("Applying relocate_add section %u to %u\n", relsec,
sechdrs[relsec].sh_info);
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
/* This is where to make the change */
location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ rel[i].r_offset;
/* This is the symbol it is referring to. Note that all
undefined symbols have been resolved. */
sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+ ELF32_R_SYM(rel[i].r_info);
switch (ELF32_R_TYPE(rel[i].r_info)) {
case R_68K_32:
/* We add the value into the location given */
*location = rel[i].r_addend + sym->st_value;
break;
case R_68K_PC32:
/* Add the value, subtract its postition */
*location = rel[i].r_addend + sym->st_value - (uint32_t)location;
break;
default:
printk(KERN_ERR "module %s: Unknown relocation: %u\n",
me->name, ELF32_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}
}
return 0;
}
int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *mod)
{
module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end);
return 0;
}
void module_arch_cleanup(struct module *mod)
{
}
#endif /* CONFIG_MODULES */
void module_fixup(struct module *mod, struct m68k_fixup_info *start,
struct m68k_fixup_info *end)
{
struct m68k_fixup_info *fixup;
for (fixup = start; fixup < end; fixup++) {
switch (fixup->type) {
case m68k_fixup_memoffset:
*(u32 *)fixup->addr = m68k_memoffset;
break;
case m68k_fixup_vnode_shift:
*(u16 *)fixup->addr += m68k_virt_to_node_shift;
break;
}
}
}
/* #ifdef CONFIG_MMU
* linux/arch/m68k/kernel/process.c #include "process_mm.c"
*
* Copyright (C) 1995 Hamish Macdonald
*
* 68060 fixes by Jesper Skov
*/
/*
* This file handles the architecture-dependent parts of process handling..
*/
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/smp.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/reboot.h>
#include <linux/init_task.h>
#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/traps.h>
#include <asm/machdep.h>
#include <asm/setup.h>
#include <asm/pgtable.h>
/*
* Initial task/thread structure. Make this a per-architecture thing,
* because different architectures tend to have different
* alignment requirements and potentially different initial
* setup.
*/
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
union thread_union init_thread_union __init_task_data
__attribute__((aligned(THREAD_SIZE))) =
{ INIT_THREAD_INFO(init_task) };
/* initial task structure */
struct task_struct init_task = INIT_TASK(init_task);
EXPORT_SYMBOL(init_task);
asmlinkage void ret_from_fork(void);
/*
* Return saved PC from a blocked thread
*/
unsigned long thread_saved_pc(struct task_struct *tsk)
{
struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;
/* Check whether the thread is blocked in resume() */
if (in_sched_functions(sw->retpc))
return ((unsigned long *)sw->a6)[1];
else
return sw->retpc;
}
/*
* The idle loop on an m68k..
*/
static void default_idle(void)
{
if (!need_resched())
#if defined(MACH_ATARI_ONLY)
/* block out HSYNC on the atari (falcon) */
__asm__("stop #0x2200" : : : "cc");
#else #else
__asm__("stop #0x2000" : : : "cc"); #include "process_no.c"
#endif #endif
}
void (*idle)(void) = default_idle;
/*
* The idle thread. There's no useful work to be
* done, so just try to conserve power and have a
* low exit latency (ie sit in a loop waiting for
* somebody to say that they'd like to reschedule)
*/
void cpu_idle(void)
{
/* endless idle loop with no priority at all */
while (1) {
while (!need_resched())
idle();
preempt_enable_no_resched();
schedule();
preempt_disable();
}
}
void machine_restart(char * __unused)
{
if (mach_reset)
mach_reset();
for (;;);
}
void machine_halt(void)
{
if (mach_halt)
mach_halt();
for (;;);
}
void machine_power_off(void)
{
if (mach_power_off)
mach_power_off();
for (;;);
}
void (*pm_power_off)(void) = machine_power_off;
EXPORT_SYMBOL(pm_power_off);
void show_regs(struct pt_regs * regs)
{
printk("\n");
printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n",
regs->format, regs->vector, regs->pc, regs->sr, print_tainted());
printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n",
regs->orig_d0, regs->d0, regs->a2, regs->a1);
printk("A0: %08lx D5: %08lx D4: %08lx\n",
regs->a0, regs->d5, regs->d4);
printk("D3: %08lx D2: %08lx D1: %08lx\n",
regs->d3, regs->d2, regs->d1);
if (!(regs->sr & PS_S))
printk("USP: %08lx\n", rdusp());
}
/*
* Create a kernel thread
*/
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
int pid;
mm_segment_t fs;
fs = get_fs();
set_fs (KERNEL_DS);
{
register long retval __asm__ ("d0");
register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
retval = __NR_clone;
__asm__ __volatile__
("clrl %%d2\n\t"
"trap #0\n\t" /* Linux/m68k system call */
"tstl %0\n\t" /* child or parent */
"jne 1f\n\t" /* parent - jump */
"lea %%sp@(%c7),%6\n\t" /* reload current */
"movel %6@,%6\n\t"
"movel %3,%%sp@-\n\t" /* push argument */
"jsr %4@\n\t" /* call fn */
"movel %0,%%d1\n\t" /* pass exit value */
"movel %2,%%d0\n\t" /* exit */
"trap #0\n"
"1:"
: "+d" (retval)
: "i" (__NR_clone), "i" (__NR_exit),
"r" (arg), "a" (fn), "d" (clone_arg), "r" (current),
"i" (-THREAD_SIZE)
: "d2");
pid = retval;
}
set_fs (fs);
return pid;
}
EXPORT_SYMBOL(kernel_thread);
void flush_thread(void)
{
unsigned long zero = 0;
set_fs(USER_DS);
current->thread.fs = __USER_DS;
if (!FPU_IS_EMU)
asm volatile (".chip 68k/68881\n\t"
"frestore %0@\n\t"
".chip 68k" : : "a" (&zero));
}
/*
* "m68k_fork()".. By the time we get here, the
* non-volatile registers have also been saved on the
* stack. We do some ugly pointer stuff here.. (see
* also copy_thread)
*/
asmlinkage int m68k_fork(struct pt_regs *regs)
{
return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL);
}
asmlinkage int m68k_vfork(struct pt_regs *regs)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0,
NULL, NULL);
}
asmlinkage int m68k_clone(struct pt_regs *regs)
{
unsigned long clone_flags;
unsigned long newsp;
int __user *parent_tidptr, *child_tidptr;
/* syscall2 puts clone_flags in d1 and usp in d2 */
clone_flags = regs->d1;
newsp = regs->d2;
parent_tidptr = (int __user *)regs->d3;
child_tidptr = (int __user *)regs->d4;
if (!newsp)
newsp = rdusp();
return do_fork(clone_flags, newsp, regs, 0,
parent_tidptr, child_tidptr);
}
int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
struct switch_stack * childstack, *stack;
unsigned long *retp;
childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
*childregs = *regs;
childregs->d0 = 0;
retp = ((unsigned long *) regs);
stack = ((struct switch_stack *) retp) - 1;
childstack = ((struct switch_stack *) childregs) - 1;
*childstack = *stack;
childstack->retpc = (unsigned long)ret_from_fork;
p->thread.usp = usp;
p->thread.ksp = (unsigned long)childstack;
if (clone_flags & CLONE_SETTLS)
task_thread_info(p)->tp_value = regs->d5;
/*
* Must save the current SFC/DFC value, NOT the value when
* the parent was last descheduled - RGH 10-08-96
*/
p->thread.fs = get_fs().seg;
if (!FPU_IS_EMU) {
/* Copy the current fpu state */
asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");
if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2])
asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
"fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
: : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0])
: "memory");
/* Restore the state in case the fpu was busy */
asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
}
return 0;
}
/* Fill in the fpu structure for a core dump. */
int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
{
char fpustate[216];
if (FPU_IS_EMU) {
int i;
memcpy(fpu->fpcntl, current->thread.fpcntl, 12);
memcpy(fpu->fpregs, current->thread.fp, 96);
/* Convert internal fpu reg representation
* into long double format
*/
for (i = 0; i < 24; i += 3)
fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |
((fpu->fpregs[i] & 0x0000ffff) << 16);
return 1;
}
/* First dump the fpu context to avoid protocol violation. */
asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2])
return 0;
asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
:: "m" (fpu->fpcntl[0])
: "memory");
asm volatile ("fmovemx %/fp0-%/fp7,%0"
:: "m" (fpu->fpregs[0])
: "memory");
return 1;
}
EXPORT_SYMBOL(dump_fpu);
/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(const char __user *name,
const char __user *const __user *argv,
const char __user *const __user *envp)
{
int error;
char * filename;
struct pt_regs *regs = (struct pt_regs *) &name;
filename = getname(name);
error = PTR_ERR(filename);
if (IS_ERR(filename))
return error;
error = do_execve(filename, argv, envp, regs);
putname(filename);
return error;
}
unsigned long get_wchan(struct task_struct *p)
{
unsigned long fp, pc;
unsigned long stack_page;
int count = 0;
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
stack_page = (unsigned long)task_stack_page(p);
fp = ((struct switch_stack *)p->thread.ksp)->a6;
do {
if (fp < stack_page+sizeof(struct thread_info) ||
fp >= 8184+stack_page)
return 0;
pc = ((unsigned long *)fp)[1];
if (!in_sched_functions(pc))
return pc;
fp = *(unsigned long *) fp;
} while (count++ < 16);
return 0;
}
/*
* linux/arch/m68k/kernel/process.c
*
* Copyright (C) 1995 Hamish Macdonald
*
* 68060 fixes by Jesper Skov
*/
/*
* This file handles the architecture-dependent parts of process handling..
*/
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/smp.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/reboot.h>
#include <linux/init_task.h>
#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/traps.h>
#include <asm/machdep.h>
#include <asm/setup.h>
#include <asm/pgtable.h>
/*
* Initial task/thread structure. Make this a per-architecture thing,
* because different architectures tend to have different
* alignment requirements and potentially different initial
* setup.
*/
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
union thread_union init_thread_union __init_task_data
__attribute__((aligned(THREAD_SIZE))) =
{ INIT_THREAD_INFO(init_task) };
/* initial task structure */
struct task_struct init_task = INIT_TASK(init_task);
EXPORT_SYMBOL(init_task);
asmlinkage void ret_from_fork(void);
/*
* Return saved PC from a blocked thread
*/
unsigned long thread_saved_pc(struct task_struct *tsk)
{
struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;
/* Check whether the thread is blocked in resume() */
if (in_sched_functions(sw->retpc))
return ((unsigned long *)sw->a6)[1];
else
return sw->retpc;
}
/*
* The idle loop on an m68k..
*/
static void default_idle(void)
{
if (!need_resched())
#if defined(MACH_ATARI_ONLY)
/* block out HSYNC on the atari (falcon) */
__asm__("stop #0x2200" : : : "cc");
#else
__asm__("stop #0x2000" : : : "cc");
#endif
}
void (*idle)(void) = default_idle;
/*
* The idle thread. There's no useful work to be
* done, so just try to conserve power and have a
* low exit latency (ie sit in a loop waiting for
* somebody to say that they'd like to reschedule)
*/
void cpu_idle(void)
{
/* endless idle loop with no priority at all */
while (1) {
while (!need_resched())
idle();
preempt_enable_no_resched();
schedule();
preempt_disable();
}
}
void machine_restart(char * __unused)
{
if (mach_reset)
mach_reset();
for (;;);
}
void machine_halt(void)
{
if (mach_halt)
mach_halt();
for (;;);
}
void machine_power_off(void)
{
if (mach_power_off)
mach_power_off();
for (;;);
}
void (*pm_power_off)(void) = machine_power_off;
EXPORT_SYMBOL(pm_power_off);
void show_regs(struct pt_regs * regs)
{
printk("\n");
printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n",
regs->format, regs->vector, regs->pc, regs->sr, print_tainted());
printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n",
regs->orig_d0, regs->d0, regs->a2, regs->a1);
printk("A0: %08lx D5: %08lx D4: %08lx\n",
regs->a0, regs->d5, regs->d4);
printk("D3: %08lx D2: %08lx D1: %08lx\n",
regs->d3, regs->d2, regs->d1);
if (!(regs->sr & PS_S))
printk("USP: %08lx\n", rdusp());
}
/*
* Create a kernel thread
*/
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
int pid;
mm_segment_t fs;
fs = get_fs();
set_fs (KERNEL_DS);
{
register long retval __asm__ ("d0");
register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
retval = __NR_clone;
__asm__ __volatile__
("clrl %%d2\n\t"
"trap #0\n\t" /* Linux/m68k system call */
"tstl %0\n\t" /* child or parent */
"jne 1f\n\t" /* parent - jump */
"lea %%sp@(%c7),%6\n\t" /* reload current */
"movel %6@,%6\n\t"
"movel %3,%%sp@-\n\t" /* push argument */
"jsr %4@\n\t" /* call fn */
"movel %0,%%d1\n\t" /* pass exit value */
"movel %2,%%d0\n\t" /* exit */
"trap #0\n"
"1:"
: "+d" (retval)
: "i" (__NR_clone), "i" (__NR_exit),
"r" (arg), "a" (fn), "d" (clone_arg), "r" (current),
"i" (-THREAD_SIZE)
: "d2");
pid = retval;
}
set_fs (fs);
return pid;
}
EXPORT_SYMBOL(kernel_thread);
void flush_thread(void)
{
unsigned long zero = 0;
set_fs(USER_DS);
current->thread.fs = __USER_DS;
if (!FPU_IS_EMU)
asm volatile (".chip 68k/68881\n\t"
"frestore %0@\n\t"
".chip 68k" : : "a" (&zero));
}
/*
* "m68k_fork()".. By the time we get here, the
* non-volatile registers have also been saved on the
* stack. We do some ugly pointer stuff here.. (see
* also copy_thread)
*/
asmlinkage int m68k_fork(struct pt_regs *regs)
{
return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL);
}
asmlinkage int m68k_vfork(struct pt_regs *regs)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0,
NULL, NULL);
}
asmlinkage int m68k_clone(struct pt_regs *regs)
{
unsigned long clone_flags;
unsigned long newsp;
int __user *parent_tidptr, *child_tidptr;
/* syscall2 puts clone_flags in d1 and usp in d2 */
clone_flags = regs->d1;
newsp = regs->d2;
parent_tidptr = (int __user *)regs->d3;
child_tidptr = (int __user *)regs->d4;
if (!newsp)
newsp = rdusp();
return do_fork(clone_flags, newsp, regs, 0,
parent_tidptr, child_tidptr);
}
int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
struct switch_stack * childstack, *stack;
unsigned long *retp;
childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
*childregs = *regs;
childregs->d0 = 0;
retp = ((unsigned long *) regs);
stack = ((struct switch_stack *) retp) - 1;
childstack = ((struct switch_stack *) childregs) - 1;
*childstack = *stack;
childstack->retpc = (unsigned long)ret_from_fork;
p->thread.usp = usp;
p->thread.ksp = (unsigned long)childstack;
if (clone_flags & CLONE_SETTLS)
task_thread_info(p)->tp_value = regs->d5;
/*
* Must save the current SFC/DFC value, NOT the value when
* the parent was last descheduled - RGH 10-08-96
*/
p->thread.fs = get_fs().seg;
if (!FPU_IS_EMU) {
/* Copy the current fpu state */
asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");
if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2])
asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
"fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
: : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0])
: "memory");
/* Restore the state in case the fpu was busy */
asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
}
return 0;
}
/* Fill in the fpu structure for a core dump. */
int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
{
char fpustate[216];
if (FPU_IS_EMU) {
int i;
memcpy(fpu->fpcntl, current->thread.fpcntl, 12);
memcpy(fpu->fpregs, current->thread.fp, 96);
/* Convert internal fpu reg representation
* into long double format
*/
for (i = 0; i < 24; i += 3)
fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |
((fpu->fpregs[i] & 0x0000ffff) << 16);
return 1;
}
/* First dump the fpu context to avoid protocol violation. */
asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2])
return 0;
asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
:: "m" (fpu->fpcntl[0])
: "memory");
asm volatile ("fmovemx %/fp0-%/fp7,%0"
:: "m" (fpu->fpregs[0])
: "memory");
return 1;
}
EXPORT_SYMBOL(dump_fpu);
/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(const char __user *name,
const char __user *const __user *argv,
const char __user *const __user *envp)
{
int error;
char * filename;
struct pt_regs *regs = (struct pt_regs *) &name;
filename = getname(name);
error = PTR_ERR(filename);
if (IS_ERR(filename))
return error;
error = do_execve(filename, argv, envp, regs);
putname(filename);
return error;
}
unsigned long get_wchan(struct task_struct *p)
{
unsigned long fp, pc;
unsigned long stack_page;
int count = 0;
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
stack_page = (unsigned long)task_stack_page(p);
fp = ((struct switch_stack *)p->thread.ksp)->a6;
do {
if (fp < stack_page+sizeof(struct thread_info) ||
fp >= 8184+stack_page)
return 0;
pc = ((unsigned long *)fp)[1];
if (!in_sched_functions(pc))
return pc;
fp = *(unsigned long *) fp;
} while (count++ < 16);
return 0;
}
/* #ifdef CONFIG_MMU
* linux/arch/m68k/kernel/ptrace.c #include "ptrace_mm.c"
* #else
* Copyright (C) 1994 by Hamish Macdonald #include "ptrace_no.c"
* Taken from linux/kernel/ptrace.c and modified for M680x0. #endif
* linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/processor.h>
/*
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
*/
/* determines which bits in the SR the user has access to. */
/* 1 = access 0 = no access */
#define SR_MASK 0x001f
/* sets the trace bits. */
#define TRACE_BITS 0xC000
#define T1_BIT 0x8000
#define T0_BIT 0x4000
/* Find the stack offset for a register, relative to thread.esp0. */
#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
#define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \
- sizeof(struct switch_stack))
/* Mapping from PT_xxx to the stack offset at which the register is
saved. Notice that usp has no stack-slot and needs to be treated
specially (see get_reg/put_reg below). */
static const int regoff[] = {
[0] = PT_REG(d1),
[1] = PT_REG(d2),
[2] = PT_REG(d3),
[3] = PT_REG(d4),
[4] = PT_REG(d5),
[5] = SW_REG(d6),
[6] = SW_REG(d7),
[7] = PT_REG(a0),
[8] = PT_REG(a1),
[9] = PT_REG(a2),
[10] = SW_REG(a3),
[11] = SW_REG(a4),
[12] = SW_REG(a5),
[13] = SW_REG(a6),
[14] = PT_REG(d0),
[15] = -1,
[16] = PT_REG(orig_d0),
[17] = PT_REG(sr),
[18] = PT_REG(pc),
};
/*
* Get contents of register REGNO in task TASK.
*/
static inline long get_reg(struct task_struct *task, int regno)
{
unsigned long *addr;
if (regno == PT_USP)
addr = &task->thread.usp;
else if (regno < ARRAY_SIZE(regoff))
addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
else
return 0;
/* Need to take stkadj into account. */
if (regno == PT_SR || regno == PT_PC) {
long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
addr = (unsigned long *) ((unsigned long)addr + stkadj);
/* The sr is actually a 16 bit register. */
if (regno == PT_SR)
return *(unsigned short *)addr;
}
return *addr;
}
/*
* Write contents of register REGNO in task TASK.
*/
static inline int put_reg(struct task_struct *task, int regno,
unsigned long data)
{
unsigned long *addr;
if (regno == PT_USP)
addr = &task->thread.usp;
else if (regno < ARRAY_SIZE(regoff))
addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
else
return -1;
/* Need to take stkadj into account. */
if (regno == PT_SR || regno == PT_PC) {
long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
addr = (unsigned long *) ((unsigned long)addr + stkadj);
/* The sr is actually a 16 bit register. */
if (regno == PT_SR) {
*(unsigned short *)addr = data;
return 0;
}
}
*addr = data;
return 0;
}
/*
* Make sure the single step bit is not set.
*/
static inline void singlestep_disable(struct task_struct *child)
{
unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
put_reg(child, PT_SR, tmp);
clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
}
/*
* Called by kernel/ptrace.c when detaching..
*/
void ptrace_disable(struct task_struct *child)
{
singlestep_disable(child);
}
void user_enable_single_step(struct task_struct *child)
{
unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
put_reg(child, PT_SR, tmp | T1_BIT);
set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
}
void user_enable_block_step(struct task_struct *child)
{
unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
put_reg(child, PT_SR, tmp | T0_BIT);
}
void user_disable_single_step(struct task_struct *child)
{
singlestep_disable(child);
}
long arch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
unsigned long tmp;
int i, ret = 0;
int regno = addr >> 2; /* temporary hack. */
unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR:
if (addr & 3)
goto out_eio;
if (regno >= 0 && regno < 19) {
tmp = get_reg(child, regno);
} else if (regno >= 21 && regno < 49) {
tmp = child->thread.fp[regno - 21];
/* Convert internal fpu reg representation
* into long double format
*/
if (FPU_IS_EMU && (regno < 45) && !(regno % 3))
tmp = ((tmp & 0xffff0000) << 15) |
((tmp & 0x0000ffff) << 16);
} else
goto out_eio;
ret = put_user(tmp, datap);
break;
case PTRACE_POKEUSR:
/* write the word at location addr in the USER area */
if (addr & 3)
goto out_eio;
if (regno == PT_SR) {
data &= SR_MASK;
data |= get_reg(child, PT_SR) & ~SR_MASK;
}
if (regno >= 0 && regno < 19) {
if (put_reg(child, regno, data))
goto out_eio;
} else if (regno >= 21 && regno < 48) {
/* Convert long double format
* into internal fpu reg representation
*/
if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) {
data <<= 15;
data = (data & 0xffff0000) |
((data & 0x0000ffff) >> 1);
}
child->thread.fp[regno - 21] = data;
} else
goto out_eio;
break;
case PTRACE_GETREGS: /* Get all gp regs from the child. */
for (i = 0; i < 19; i++) {
tmp = get_reg(child, i);
ret = put_user(tmp, datap);
if (ret)
break;
datap++;
}
break;
case PTRACE_SETREGS: /* Set all gp regs in the child. */
for (i = 0; i < 19; i++) {
ret = get_user(tmp, datap);
if (ret)
break;
if (i == PT_SR) {
tmp &= SR_MASK;
tmp |= get_reg(child, PT_SR) & ~SR_MASK;
}
put_reg(child, i, tmp);
datap++;
}
break;
case PTRACE_GETFPREGS: /* Get the child FPU state. */
if (copy_to_user(datap, &child->thread.fp,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
break;
case PTRACE_SETFPREGS: /* Set the child FPU state. */
if (copy_from_user(&child->thread.fp, datap,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
break;
case PTRACE_GET_THREAD_AREA:
ret = put_user(task_thread_info(child)->tp_value, datap);
break;
default:
ret = ptrace_request(child, request, addr, data);
break;
}
return ret;
out_eio:
return -EIO;
}
asmlinkage void syscall_trace(void)
{
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 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 (current->exit_code) {
send_sig(current->exit_code, current, 1);
current->exit_code = 0;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* #ifdef CONFIG_MMU
* linux/arch/m68k/kernel/time.c #include "time_mm.c"
* #else
* Copyright (C) 1991, 1992, 1995 Linus Torvalds #include "time_no.c"
* #endif
* This file contains the m68k-specific time handling details.
* Most of the stuff is located in the machine specific files.
*
* 1997-09-10 Updated NTP code according to technical memorandum Jan '96
* "A Kernel Model for Precision Timekeeping" by Dave Mills
*/
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/rtc.h>
#include <linux/platform_device.h>
#include <asm/machdep.h>
#include <asm/io.h>
#include <asm/irq_regs.h>
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/profile.h>
static inline int set_rtc_mmss(unsigned long nowtime)
{
if (mach_set_clock_mmss)
return mach_set_clock_mmss (nowtime);
return -1;
}
/*
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "xtime_update()" routine every clocktick
*/
static irqreturn_t timer_interrupt(int irq, void *dummy)
{
xtime_update(1);
update_process_times(user_mode(get_irq_regs()));
profile_tick(CPU_PROFILING);
#ifdef CONFIG_HEARTBEAT
/* use power LED as a heartbeat instead -- much more useful
for debugging -- based on the version for PReP by Cort */
/* acts like an actual heart beat -- ie thump-thump-pause... */
if (mach_heartbeat) {
static unsigned cnt = 0, period = 0, dist = 0;
if (cnt == 0 || cnt == dist)
mach_heartbeat( 1 );
else if (cnt == 7 || cnt == dist+7)
mach_heartbeat( 0 );
if (++cnt > period) {
cnt = 0;
/* The hyperbolic function below modifies the heartbeat period
* length in dependency of the current (5min) load. It goes
* through the points f(0)=126, f(1)=86, f(5)=51,
* f(inf)->30. */
period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
dist = period / 4;
}
}
#endif /* CONFIG_HEARTBEAT */
return IRQ_HANDLED;
}
void read_persistent_clock(struct timespec *ts)
{
struct rtc_time time;
ts->tv_sec = 0;
ts->tv_nsec = 0;
if (mach_hwclk) {
mach_hwclk(0, &time);
if ((time.tm_year += 1900) < 1970)
time.tm_year += 100;
ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday,
time.tm_hour, time.tm_min, time.tm_sec);
}
}
void __init time_init(void)
{
mach_sched_init(timer_interrupt);
}
u32 arch_gettimeoffset(void)
{
return mach_gettimeoffset() * 1000;
}
static int __init rtc_init(void)
{
struct platform_device *pdev;
if (!mach_hwclk)
return -ENODEV;
pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
return 0;
}
module_init(rtc_init);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
PHDRS #ifdef CONFIG_MMU
{ #include "vmlinux.lds_mm.S"
text PT_LOAD FILEHDR PHDRS FLAGS (7);
data PT_LOAD FLAGS (7);
}
#ifdef CONFIG_SUN3
#include "vmlinux-sun3.lds"
#else #else
#include "vmlinux-std.lds" #include "vmlinux.lds_no.S"
#endif #endif
PHDRS
{
text PT_LOAD FILEHDR PHDRS FLAGS (7);
data PT_LOAD FLAGS (7);
}
#ifdef CONFIG_SUN3
#include "vmlinux-sun3.lds"
#else
#include "vmlinux-std.lds"
#endif
# ifdef CONFIG_MMU
# Makefile for m68k-specific library files.. include arch/m68k/lib/Makefile_mm
# else
include arch/m68k/lib/Makefile_no
lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ endif
checksum.o string.o uaccess.o
#
# Makefile for m68k-specific library files..
#
lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
checksum.o string.o uaccess.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# ifdef CONFIG_MMU
# Makefile for the linux m68k-specific parts of the memory manager. include arch/m68k/mm/Makefile_mm
# else
include arch/m68k/mm/Makefile_no
obj-y := cache.o init.o fault.o hwtest.o endif
obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o
obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o
#
# Makefile for the linux m68k-specific parts of the memory manager.
#
obj-y := cache.o init.o fault.o hwtest.o
obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o
obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment