mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
This commit is contained in:
commit
1da177e4c3
17291 changed files with 6718755 additions and 0 deletions
194
arch/h8300/Kconfig
Normal file
194
arch/h8300/Kconfig
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see Documentation/kbuild/config-language.txt.
|
||||
#
|
||||
|
||||
mainmenu "uClinux/h8300 (w/o MMU) Kernel Configuration"
|
||||
|
||||
config H8300
|
||||
bool
|
||||
default y
|
||||
|
||||
config MMU
|
||||
bool
|
||||
default n
|
||||
|
||||
config SWAP
|
||||
bool
|
||||
default n
|
||||
|
||||
config FPU
|
||||
bool
|
||||
default n
|
||||
|
||||
config UID16
|
||||
bool
|
||||
default y
|
||||
|
||||
config RWSEM_GENERIC_SPINLOCK
|
||||
bool
|
||||
default y
|
||||
|
||||
config RWSEM_XCHGADD_ALGORITHM
|
||||
bool
|
||||
default n
|
||||
|
||||
config GENERIC_CALIBRATE_DELAY
|
||||
bool
|
||||
default y
|
||||
|
||||
config ISA
|
||||
bool
|
||||
default y
|
||||
|
||||
config PCI
|
||||
bool
|
||||
default n
|
||||
|
||||
source "init/Kconfig"
|
||||
|
||||
source "arch/h8300/Kconfig.cpu"
|
||||
|
||||
menu "Executable file formats"
|
||||
|
||||
source "fs/Kconfig.binfmt"
|
||||
|
||||
endmenu
|
||||
|
||||
source "drivers/base/Kconfig"
|
||||
|
||||
source "drivers/mtd/Kconfig"
|
||||
|
||||
source "drivers/block/Kconfig"
|
||||
|
||||
source "drivers/ide/Kconfig"
|
||||
|
||||
source "arch/h8300/Kconfig.ide"
|
||||
|
||||
source "net/Kconfig"
|
||||
|
||||
#
|
||||
# input - input/joystick depends on it. As does USB.
|
||||
#
|
||||
source "drivers/input/Kconfig"
|
||||
|
||||
menu "Character devices"
|
||||
|
||||
config VT
|
||||
bool "Virtual terminal"
|
||||
---help---
|
||||
If you say Y here, you will get support for terminal devices with
|
||||
display and keyboard devices. These are called "virtual" because you
|
||||
can run several virtual terminals (also called virtual consoles) on
|
||||
one physical terminal. This is rather useful, for example one
|
||||
virtual terminal can collect system messages and warnings, another
|
||||
one can be used for a text-mode user session, and a third could run
|
||||
an X session, all in parallel. Switching between virtual terminals
|
||||
is done with certain key combinations, usually Alt-<function key>.
|
||||
|
||||
The setterm command ("man setterm") can be used to change the
|
||||
properties (such as colors or beeping) of a virtual terminal. The
|
||||
man page console_codes(4) ("man console_codes") contains the special
|
||||
character sequences that can be used to change those properties
|
||||
directly. The fonts used on virtual terminals can be changed with
|
||||
the setfont ("man setfont") command and the key bindings are defined
|
||||
with the loadkeys ("man loadkeys") command.
|
||||
|
||||
You need at least one virtual terminal device in order to make use
|
||||
of your keyboard and monitor. Therefore, only people configuring an
|
||||
embedded system would want to say N here in order to save some
|
||||
memory; the only way to log into such a system is then via a serial
|
||||
or network connection.
|
||||
|
||||
If unsure, say Y, or else you won't be able to do much with your new
|
||||
shiny Linux system :-)
|
||||
|
||||
config VT_CONSOLE
|
||||
bool "Support for console on virtual terminal"
|
||||
depends on VT
|
||||
---help---
|
||||
The system console is the device which receives all kernel messages
|
||||
and warnings and which allows logins in single user mode. If you
|
||||
answer Y here, a virtual terminal (the device used to interact with
|
||||
a physical terminal) can be used as system console. This is the most
|
||||
common mode of operations, so you should say Y here unless you want
|
||||
the kernel messages be output only to a serial port (in which case
|
||||
you should say Y to "Console on serial port", below).
|
||||
|
||||
If you do say Y here, by default the currently visible virtual
|
||||
terminal (/dev/tty0) will be used as system console. You can change
|
||||
that with a kernel command line option such as "console=tty3" which
|
||||
would use the third virtual terminal as system console. (Try "man
|
||||
bootparam" or see the documentation of your boot loader (lilo or
|
||||
loadlin) about how to pass options to the kernel at boot time.)
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config HW_CONSOLE
|
||||
bool
|
||||
depends on VT && !S390 && !UM
|
||||
default y
|
||||
|
||||
comment "Unix98 PTY support"
|
||||
|
||||
config UNIX98_PTYS
|
||||
bool "Unix98 PTY support"
|
||||
---help---
|
||||
A pseudo terminal (PTY) is a software device consisting of two
|
||||
halves: a master and a slave. The slave device behaves identical to
|
||||
a physical terminal; the master device is used by a process to
|
||||
read data from and write data to the slave, thereby emulating a
|
||||
terminal. Typical programs for the master side are telnet servers
|
||||
and xterms.
|
||||
|
||||
Linux has traditionally used the BSD-like names /dev/ptyxx for
|
||||
masters and /dev/ttyxx for slaves of pseudo terminals. This scheme
|
||||
has a number of problems. The GNU C library glibc 2.1 and later,
|
||||
however, supports the Unix98 naming standard: in order to acquire a
|
||||
pseudo terminal, a process opens /dev/ptmx; the number of the pseudo
|
||||
terminal is then made available to the process and the pseudo
|
||||
terminal slave can be accessed as /dev/pts/<number>. What was
|
||||
traditionally /dev/ttyp2 will then be /dev/pts/2, for example.
|
||||
|
||||
The entries in /dev/pts/ are created on the fly by a virtual
|
||||
file system; therefore, if you say Y here you should say Y to
|
||||
"/dev/pts file system for Unix98 PTYs" as well.
|
||||
|
||||
If you want to say Y here, you need to have the C library glibc 2.1
|
||||
or later (equal to libc-6.1, check with "ls -l /lib/libc.so.*").
|
||||
Read the instructions in <file:Documentation/Changes> pertaining to
|
||||
pseudo terminals. It's safe to say N.
|
||||
|
||||
config UNIX98_PTY_COUNT
|
||||
int "Maximum number of Unix98 PTYs in use (0-2048)"
|
||||
depends on UNIX98_PTYS
|
||||
default "256"
|
||||
help
|
||||
The maximum number of Unix98 PTYs that can be used at any one time.
|
||||
The default is 256, and should be enough for desktop systems. Server
|
||||
machines which support incoming telnet/rlogin/ssh connections and/or
|
||||
serve several X terminals may want to increase this: every incoming
|
||||
connection and every xterm uses up one PTY.
|
||||
|
||||
When not in use, each additional set of 256 PTYs occupy
|
||||
approximately 8 KB of kernel memory on 32-bit architectures.
|
||||
|
||||
source "drivers/char/pcmcia/Kconfig"
|
||||
|
||||
source "drivers/serial/Kconfig"
|
||||
|
||||
source "drivers/i2c/Kconfig"
|
||||
|
||||
source "drivers/usb/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
source "fs/Kconfig"
|
||||
|
||||
source "arch/h8300/Kconfig.debug"
|
||||
|
||||
source "security/Kconfig"
|
||||
|
||||
source "crypto/Kconfig"
|
||||
|
||||
source "lib/Kconfig"
|
||||
183
arch/h8300/Kconfig.cpu
Normal file
183
arch/h8300/Kconfig.cpu
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
menu "Processor type and features"
|
||||
|
||||
choice
|
||||
prompt "H8/300 platform"
|
||||
default H8300H_GENERIC
|
||||
|
||||
config H8300H_GENERIC
|
||||
bool "H8/300H Generic"
|
||||
help
|
||||
H8/300H CPU Generic Hardware Support
|
||||
|
||||
config H8300H_AKI3068NET
|
||||
bool "AE-3068/69"
|
||||
help
|
||||
AKI-H8/3068F / AKI-H8/3069F Flashmicom LAN Board Support
|
||||
More Information. (Japanese Only)
|
||||
<http://akizukidensi.com/catalog/h8.html>
|
||||
AE-3068/69 Evaluation Board Support
|
||||
More Information.
|
||||
<http://www.microtronique.com/ae3069lan.htm>
|
||||
|
||||
config H8300H_H8MAX
|
||||
bool "H8MAX"
|
||||
help
|
||||
H8MAX Evaluation Board Support
|
||||
More Information. (Japanese Only)
|
||||
<http://strawberry-linux.com/h8/index.html>
|
||||
|
||||
config H8300H_SIM
|
||||
bool "H8/300H Simulator"
|
||||
help
|
||||
GDB Simulator Support
|
||||
More Information.
|
||||
arch/h8300/Doc/simulator.txt
|
||||
|
||||
config H8S_GENERIC
|
||||
bool "H8S Generic"
|
||||
help
|
||||
H8S CPU Generic Hardware Support
|
||||
|
||||
config H8S_EDOSK2674
|
||||
bool "EDOSK-2674"
|
||||
help
|
||||
Renesas EDOSK-2674 Evaluation Board Support
|
||||
More Information.
|
||||
<http://www.azpower.com/H8-uClinux/index.html>
|
||||
<http://www.eu.renesas.com/tools/edk/support/edosk2674.html>
|
||||
|
||||
config H8S_SIM
|
||||
bool "H8S Simulator"
|
||||
help
|
||||
GDB Simulator Support
|
||||
More Information.
|
||||
arch/h8300/Doc/simulator.txt
|
||||
|
||||
endchoice
|
||||
|
||||
if (H8300H_GENERIC || H8S_GENERIC)
|
||||
menu "Detail Selection"
|
||||
if (H8300H_GENERIC)
|
||||
choice
|
||||
prompt "CPU Selection"
|
||||
|
||||
config H83002
|
||||
bool "H8/3001,3002,3003"
|
||||
|
||||
config H83007
|
||||
bool "H8/3006,3007"
|
||||
|
||||
config H83048
|
||||
bool "H8/3044,3045,3046,3047,3048,3052"
|
||||
|
||||
config H83068
|
||||
bool "H8/3065,3066,3067,3068,3069"
|
||||
endchoice
|
||||
endif
|
||||
|
||||
if (H8S_GENERIC)
|
||||
choice
|
||||
prompt "CPU Selection"
|
||||
|
||||
config H8S2678
|
||||
bool "H8S/2670,2673,2674R,2675,2676"
|
||||
endchoice
|
||||
endif
|
||||
|
||||
config CPU_CLOCK
|
||||
int "CPU Clock Frequency (/1KHz)"
|
||||
default "20000"
|
||||
help
|
||||
CPU Clock Frequency divide to 1000
|
||||
endmenu
|
||||
endif
|
||||
|
||||
if (H8300H_GENERIC || H8S_GENERIC || H8300H_SIM || H8S_SIM || H8S_EDOSK2674)
|
||||
choice
|
||||
prompt "Kernel executes from"
|
||||
---help---
|
||||
Choose the memory type that the kernel will be running in.
|
||||
|
||||
config RAMKERNEL
|
||||
bool "RAM"
|
||||
help
|
||||
The kernel will be resident in RAM when running.
|
||||
|
||||
config ROMKERNEL
|
||||
bool "ROM"
|
||||
help
|
||||
The kernel will be resident in FLASH/ROM when running.
|
||||
|
||||
endchoice
|
||||
endif
|
||||
|
||||
if (H8300H_AKI3068NET)
|
||||
config H83068
|
||||
bool
|
||||
default y
|
||||
|
||||
config CPU_CLOCK
|
||||
int
|
||||
default "20000"
|
||||
|
||||
config RAMKERNEL
|
||||
bool
|
||||
default y
|
||||
endif
|
||||
|
||||
if (H8300H_H8MAX)
|
||||
config H83068
|
||||
bool
|
||||
default y
|
||||
|
||||
config CPU_CLOCK
|
||||
int
|
||||
default 25000
|
||||
|
||||
config RAMKERNEL
|
||||
bool
|
||||
default y
|
||||
endif
|
||||
|
||||
if (H8300H_SIM)
|
||||
config H83007
|
||||
bool
|
||||
default y
|
||||
|
||||
config CPU_CLOCK
|
||||
int
|
||||
default "16000"
|
||||
endif
|
||||
|
||||
if (H8S_EDOSK2674)
|
||||
config H8S2678
|
||||
bool
|
||||
default y
|
||||
config CPU_CLOCK
|
||||
int
|
||||
default 33000
|
||||
endif
|
||||
|
||||
if (H8S_SIM)
|
||||
config H8S2678
|
||||
bool
|
||||
default y
|
||||
config CPU_CLOCK
|
||||
int
|
||||
default 33000
|
||||
endif
|
||||
|
||||
config CPU_H8300H
|
||||
bool
|
||||
depends on (H8002 || H83007 || H83048 || H83068)
|
||||
default y
|
||||
|
||||
config CPU_H8S
|
||||
bool
|
||||
depends on H8S2678
|
||||
default y
|
||||
|
||||
config PREEMPT
|
||||
bool "Preemptible Kernel"
|
||||
default n
|
||||
endmenu
|
||||
68
arch/h8300/Kconfig.debug
Normal file
68
arch/h8300/Kconfig.debug
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
menu "Kernel hacking"
|
||||
|
||||
source "lib/Kconfig.debug"
|
||||
|
||||
config FULLDEBUG
|
||||
bool "Full Symbolic/Source Debugging support"
|
||||
help
|
||||
Enable debugging symbols on kernel build.
|
||||
|
||||
config HIGHPROFILE
|
||||
bool "Use fast second timer for profiling"
|
||||
help
|
||||
Use a fast secondary clock to produce profiling information.
|
||||
|
||||
config NO_KERNEL_MSG
|
||||
bool "Suppress Kernel BUG Messages"
|
||||
help
|
||||
Do not output any debug BUG messages within the kernel.
|
||||
|
||||
config GDB_MAGICPRINT
|
||||
bool "Message Output for GDB MagicPrint service"
|
||||
depends on (H8300H_SIM || H8S_SIM)
|
||||
help
|
||||
kernel messages output useing MagicPrint service from GDB
|
||||
|
||||
config SYSCALL_PRINT
|
||||
bool "SystemCall trace print"
|
||||
help
|
||||
outout history of systemcall
|
||||
|
||||
config GDB_DEBUG
|
||||
bool "Use gdb stub"
|
||||
depends on (!H8300H_SIM && !H8S_SIM)
|
||||
help
|
||||
gdb stub exception support
|
||||
|
||||
config CONFIG_SH_STANDARD_BIOS
|
||||
bool "Use gdb protocol serial console"
|
||||
depends on (!H8300H_SIM && !H8S_SIM)
|
||||
help
|
||||
serial console output using GDB protocol.
|
||||
Require eCos/RedBoot
|
||||
|
||||
config DEFAULT_CMDLINE
|
||||
bool "Use buildin commandline"
|
||||
default n
|
||||
help
|
||||
buildin kernel commandline enabled.
|
||||
|
||||
config KERNEL_COMMAND
|
||||
string "Buildin commmand string"
|
||||
depends on DEFAULT_CMDLINE
|
||||
help
|
||||
buildin kernel commandline strings.
|
||||
|
||||
config BLKDEV_RESERVE
|
||||
bool "BLKDEV Reserved Memory"
|
||||
default n
|
||||
help
|
||||
Reserved BLKDEV area.
|
||||
|
||||
config CONFIG_BLKDEV_RESERVE_ADDRESS
|
||||
hex 'start address'
|
||||
depends on BLKDEV_RESERVE
|
||||
help
|
||||
BLKDEV start address.
|
||||
|
||||
endmenu
|
||||
44
arch/h8300/Kconfig.ide
Normal file
44
arch/h8300/Kconfig.ide
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# uClinux H8/300 Target Board Selection Menu (IDE)
|
||||
|
||||
if (H8300H_AKI3068NET)
|
||||
menu "IDE Extra configuration"
|
||||
|
||||
config H8300_IDE_BASE
|
||||
hex "IDE register base address"
|
||||
depends on IDE
|
||||
default 0
|
||||
help
|
||||
IDE registers base address
|
||||
|
||||
config H8300_IDE_ALT
|
||||
hex "IDE register alternate address"
|
||||
depends on IDE
|
||||
default 0
|
||||
help
|
||||
IDE alternate registers address
|
||||
|
||||
config H8300_IDE_IRQ
|
||||
int "IDE IRQ no"
|
||||
depends on IDE
|
||||
default 0
|
||||
help
|
||||
IDE use IRQ no
|
||||
endmenu
|
||||
endif
|
||||
|
||||
if (H8300H_H8MAX)
|
||||
config H8300_IDE_BASE
|
||||
hex
|
||||
depends on IDE
|
||||
default 0x200000
|
||||
|
||||
config H8300_IDE_ALT
|
||||
hex
|
||||
depends on IDE
|
||||
default 0x60000c
|
||||
|
||||
config H8300_IDE_IRQ
|
||||
int
|
||||
depends on IDE
|
||||
default 5
|
||||
endif
|
||||
78
arch/h8300/Makefile
Normal file
78
arch/h8300/Makefile
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#
|
||||
# arch/h8300/Makefile
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# (C) Copyright 2002,2003 Yoshinori Sato <[email protected]>
|
||||
#
|
||||
|
||||
platform-$(CONFIG_CPU_H8300H) := h8300h
|
||||
platform-$(CONFIG_CPU_H8S) := h8s
|
||||
PLATFORM := $(platform-y)
|
||||
|
||||
board-$(CONFIG_H8300H_GENERIC) := generic
|
||||
board-$(CONFIG_H8300H_AKI3068NET) := aki3068net
|
||||
board-$(CONFIG_H8300H_H8MAX) := h8max
|
||||
board-$(CONFIG_H8300H_SIM) := generic
|
||||
board-$(CONFIG_H8S_GENERIC) := generic
|
||||
board-$(CONFIG_H8S_EDOSK2674) := edosk2674
|
||||
board-$(CONFIG_H8S_SIM) := generic
|
||||
BOARD := $(board-y)
|
||||
|
||||
model-$(CONFIG_RAMKERNEL) := ram
|
||||
model-$(CONFIG_ROMKERNEL) := rom
|
||||
MODEL := $(model-y)
|
||||
|
||||
cflags-$(CONFIG_CPU_H8300H) := -mh
|
||||
ldflags-$(CONFIG_CPU_H8300H) := -mh8300helf
|
||||
cflags-$(CONFIG_CPU_H8S) := -ms
|
||||
ldflags-$(CONFIG_CPU_H8S) := -mh8300self
|
||||
|
||||
CFLAGS += $(cflags-y)
|
||||
CFLAGS += -mint32 -fno-builtin
|
||||
CFLAGS += -g
|
||||
CFLAGS += -D__linux__
|
||||
CFLAGS += -DUTS_SYSNAME=\"uClinux\"
|
||||
AFLAGS += -DPLATFORM=$(PLATFORM) -DMODEL=$(MODEL) $(cflags-y)
|
||||
LDFLAGS += $(ldflags-y)
|
||||
|
||||
CROSS_COMPILE = h8300-elf-
|
||||
LIBGCC := $(shell $(CROSS-COMPILE)$(CC) $(CFLAGS) -print-libgcc-file-name)
|
||||
|
||||
head-y := arch/$(ARCH)/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o
|
||||
|
||||
core-y += arch/$(ARCH)/kernel/ \
|
||||
arch/$(ARCH)/mm/
|
||||
ifdef PLATFORM
|
||||
core-y += arch/$(ARCH)/platform/$(PLATFORM)/ \
|
||||
arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/
|
||||
endif
|
||||
|
||||
libs-y += arch/$(ARCH)/lib/ $(LIBGCC)
|
||||
|
||||
boot := arch/h8300/boot
|
||||
|
||||
export MODEL PLATFORM BOARD
|
||||
|
||||
archmrproper:
|
||||
|
||||
archclean:
|
||||
$(Q)$(MAKE) $(clean)=$(boot)
|
||||
|
||||
prepare: include/asm-$(ARCH)/asm-offsets.h
|
||||
|
||||
include/asm-$(ARCH)/asm-offsets.h: arch/$(ARCH)/kernel/asm-offsets.s \
|
||||
include/asm include/linux/version.h
|
||||
$(call filechk,gen-asm-offsets)
|
||||
|
||||
vmlinux.srec vmlinux.bin: vmlinux
|
||||
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
||||
|
||||
define archhelp
|
||||
echo 'vmlinux.bin - Create raw binary'
|
||||
echo 'vmlinux.srec - Create srec binary'
|
||||
endef
|
||||
|
||||
CLEAN_FILES += include/asm-$(ARCH)/asm-offsets.h
|
||||
37
arch/h8300/README
Normal file
37
arch/h8300/README
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
linux-2.6 for H8/300 README
|
||||
Yoshinori Sato <[email protected]>
|
||||
|
||||
* Supported CPU
|
||||
H8/300H and H8S
|
||||
|
||||
* Supported Target
|
||||
1.simulator of GDB
|
||||
require patches.
|
||||
|
||||
2.AE 3068/AE 3069
|
||||
more information
|
||||
MICROTRONIQUE <http://www.microtronique.com/>
|
||||
Akizuki Denshi Tsusho Ltd. <http://www.akizuki.ne.jp> (Japanese Only)
|
||||
|
||||
3.H8MAX
|
||||
see http://ip-sol.jp/h8max/ (Japanese Only)
|
||||
|
||||
4.EDOSK2674
|
||||
see http://www.eu.renesas.com/products/mpumcu/tool/edk/support/edosk2674.html
|
||||
http://www.azpower.com/H8-uClinux/
|
||||
|
||||
* Toolchain Version
|
||||
gcc-3.1 or higher and patch
|
||||
see arch/h8300/tools_patch/README
|
||||
binutils-2.12 or higher
|
||||
gdb-5.2 or higher
|
||||
The environment that can compile a h8300-elf binary is necessary.
|
||||
|
||||
* Userland Develop environment
|
||||
used h8300-elf toolchains.
|
||||
see http://www.uclinux.org/pub/uClinux/ports/h8/
|
||||
|
||||
* A few words of thanks
|
||||
Porting to H8/300 serieses is support of Information-technology Promotion Agency, Japan.
|
||||
I thank support.
|
||||
and All developer/user.
|
||||
12
arch/h8300/boot/Makefile
Normal file
12
arch/h8300/boot/Makefile
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# arch/h8300/boot/Makefile
|
||||
|
||||
targets := vmlinux.srec vmlinux.bin
|
||||
|
||||
OBJCOPYFLAGS_vmlinux.srec := -Osrec
|
||||
OBJCOPYFLAGS_vmlinux.bin := -Obinary
|
||||
|
||||
$(obj)/vmlinux.srec $(obj)/vmlinux.bin: vmlinux FORCE
|
||||
$(call if_changed,objcopy)
|
||||
@echo ' Kernel: $@ is ready'
|
||||
|
||||
CLEAN_FILES += arch/$(ARCH)/vmlinux.bin arch/$(ARCH)/vmlinux.srec
|
||||
356
arch/h8300/defconfig
Normal file
356
arch/h8300/defconfig
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.11-rc1
|
||||
# Sun Jan 16 17:24:38 2005
|
||||
#
|
||||
CONFIG_H8300=y
|
||||
# CONFIG_MMU is not set
|
||||
# CONFIG_SWAP is not set
|
||||
# CONFIG_FPU is not set
|
||||
CONFIG_UID16=y
|
||||
CONFIG_RWSEM_GENERIC_SPINLOCK=y
|
||||
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
|
||||
CONFIG_GENERIC_CALIBRATE_DELAY=y
|
||||
CONFIG_ISA=y
|
||||
# CONFIG_PCI is not set
|
||||
|
||||
#
|
||||
# Code maturity level options
|
||||
#
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
CONFIG_CLEAN_COMPILE=y
|
||||
CONFIG_BROKEN_ON_SMP=y
|
||||
|
||||
#
|
||||
# General setup
|
||||
#
|
||||
CONFIG_LOCALVERSION=""
|
||||
# CONFIG_BSD_PROCESS_ACCT is not set
|
||||
# CONFIG_SYSCTL is not set
|
||||
# CONFIG_AUDIT is not set
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
# CONFIG_HOTPLUG is not set
|
||||
# CONFIG_IKCONFIG is not set
|
||||
CONFIG_EMBEDDED=y
|
||||
# CONFIG_KALLSYMS is not set
|
||||
# CONFIG_FUTEX is not set
|
||||
# CONFIG_EPOLL is not set
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
CONFIG_CC_ALIGN_FUNCTIONS=0
|
||||
CONFIG_CC_ALIGN_LABELS=0
|
||||
CONFIG_CC_ALIGN_LOOPS=0
|
||||
CONFIG_CC_ALIGN_JUMPS=0
|
||||
CONFIG_TINY_SHMEM=y
|
||||
|
||||
#
|
||||
# Loadable module support
|
||||
#
|
||||
# CONFIG_MODULES is not set
|
||||
|
||||
#
|
||||
# Processor type and features
|
||||
#
|
||||
CONFIG_H8300H_GENERIC=y
|
||||
# CONFIG_H8300H_AKI3068NET is not set
|
||||
# CONFIG_H8300H_H8MAX is not set
|
||||
# CONFIG_H8300H_SIM is not set
|
||||
# CONFIG_H8S_GENERIC is not set
|
||||
# CONFIG_H8S_EDOSK2674 is not set
|
||||
# CONFIG_H8S_SIM is not set
|
||||
|
||||
#
|
||||
# Detail Selection
|
||||
#
|
||||
# CONFIG_H83002 is not set
|
||||
# CONFIG_H83007 is not set
|
||||
# CONFIG_H83048 is not set
|
||||
CONFIG_H83068=y
|
||||
CONFIG_CPU_CLOCK=20000
|
||||
# CONFIG_RAMKERNEL is not set
|
||||
CONFIG_ROMKERNEL=y
|
||||
CONFIG_CPU_H8300H=y
|
||||
# CONFIG_PREEMPT is not set
|
||||
|
||||
#
|
||||
# Executable file formats
|
||||
#
|
||||
CONFIG_BINFMT_FLAT=y
|
||||
CONFIG_BINFMT_ZFLAT=y
|
||||
# CONFIG_BINFMT_SHARED_FLAT is not set
|
||||
# CONFIG_BINFMT_MISC is not set
|
||||
|
||||
#
|
||||
# Generic Driver Options
|
||||
#
|
||||
# CONFIG_STANDALONE is not set
|
||||
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
|
||||
# CONFIG_FW_LOADER is not set
|
||||
# CONFIG_DEBUG_DRIVER is not set
|
||||
|
||||
#
|
||||
# Memory Technology Devices (MTD)
|
||||
#
|
||||
CONFIG_MTD=y
|
||||
# CONFIG_MTD_DEBUG is not set
|
||||
CONFIG_MTD_PARTITIONS=y
|
||||
CONFIG_MTD_CONCAT=y
|
||||
# CONFIG_MTD_REDBOOT_PARTS is not set
|
||||
# CONFIG_MTD_CMDLINE_PARTS is not set
|
||||
|
||||
#
|
||||
# User Modules And Translation Layers
|
||||
#
|
||||
CONFIG_MTD_CHAR=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
# CONFIG_FTL is not set
|
||||
# CONFIG_NFTL is not set
|
||||
# CONFIG_INFTL is not set
|
||||
|
||||
#
|
||||
# RAM/ROM/Flash chip drivers
|
||||
#
|
||||
# CONFIG_MTD_CFI is not set
|
||||
# CONFIG_MTD_JEDECPROBE is not set
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_1=y
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_2=y
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_4=y
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
|
||||
CONFIG_MTD_CFI_I1=y
|
||||
CONFIG_MTD_CFI_I2=y
|
||||
# CONFIG_MTD_CFI_I4 is not set
|
||||
# CONFIG_MTD_CFI_I8 is not set
|
||||
CONFIG_MTD_RAM=y
|
||||
CONFIG_MTD_ROM=y
|
||||
# CONFIG_MTD_ABSENT is not set
|
||||
|
||||
#
|
||||
# Mapping drivers for chip access
|
||||
#
|
||||
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
|
||||
CONFIG_MTD_UCLINUX=y
|
||||
|
||||
#
|
||||
# Self-contained MTD device drivers
|
||||
#
|
||||
# CONFIG_MTD_SLRAM is not set
|
||||
# CONFIG_MTD_PHRAM is not set
|
||||
# CONFIG_MTD_MTDRAM is not set
|
||||
# CONFIG_MTD_BLKMTD is not set
|
||||
# CONFIG_MTD_BLOCK2MTD is not set
|
||||
|
||||
#
|
||||
# Disk-On-Chip Device Drivers
|
||||
#
|
||||
# CONFIG_MTD_DOC2000 is not set
|
||||
# CONFIG_MTD_DOC2001 is not set
|
||||
# CONFIG_MTD_DOC2001PLUS is not set
|
||||
|
||||
#
|
||||
# NAND Flash Device Drivers
|
||||
#
|
||||
# CONFIG_MTD_NAND is not set
|
||||
|
||||
#
|
||||
# Block devices
|
||||
#
|
||||
# CONFIG_BLK_DEV_FD is not set
|
||||
# CONFIG_BLK_DEV_XD is not set
|
||||
# CONFIG_BLK_DEV_LOOP is not set
|
||||
# CONFIG_BLK_DEV_RAM is not set
|
||||
CONFIG_BLK_DEV_RAM_COUNT=16
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
# CONFIG_CDROM_PKTCDVD is not set
|
||||
|
||||
#
|
||||
# IO Schedulers
|
||||
#
|
||||
CONFIG_IOSCHED_NOOP=y
|
||||
# CONFIG_IOSCHED_AS is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
|
||||
#
|
||||
# ATA/ATAPI/MFM/RLL support
|
||||
#
|
||||
# CONFIG_IDE is not set
|
||||
|
||||
#
|
||||
# Networking support
|
||||
#
|
||||
# CONFIG_NET is not set
|
||||
# CONFIG_NETPOLL is not set
|
||||
# CONFIG_NET_POLL_CONTROLLER is not set
|
||||
|
||||
#
|
||||
# Input device support
|
||||
#
|
||||
# CONFIG_INPUT is not set
|
||||
|
||||
#
|
||||
# Userland interfaces
|
||||
#
|
||||
|
||||
#
|
||||
# Input I/O drivers
|
||||
#
|
||||
# CONFIG_GAMEPORT is not set
|
||||
CONFIG_SOUND_GAMEPORT=y
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_SERIO_I8042 is not set
|
||||
|
||||
#
|
||||
# Input Device Drivers
|
||||
#
|
||||
|
||||
#
|
||||
# Character devices
|
||||
#
|
||||
# CONFIG_VT is not set
|
||||
|
||||
#
|
||||
# Unix98 PTY support
|
||||
#
|
||||
# CONFIG_UNIX98_PTYS is not set
|
||||
|
||||
#
|
||||
# Serial drivers
|
||||
#
|
||||
# CONFIG_SERIAL_8250 is not set
|
||||
|
||||
#
|
||||
# Non-8250 serial port support
|
||||
#
|
||||
CONFIG_SERIAL_SH_SCI=y
|
||||
CONFIG_SERIAL_SH_SCI_CONSOLE=y
|
||||
CONFIG_SERIAL_CORE=y
|
||||
CONFIG_SERIAL_CORE_CONSOLE=y
|
||||
|
||||
#
|
||||
# I2C support
|
||||
#
|
||||
# CONFIG_I2C is not set
|
||||
|
||||
#
|
||||
# USB support
|
||||
#
|
||||
# CONFIG_USB_ARCH_HAS_HCD is not set
|
||||
# CONFIG_USB_ARCH_HAS_OHCI is not set
|
||||
|
||||
#
|
||||
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
|
||||
#
|
||||
|
||||
#
|
||||
# USB Gadget Support
|
||||
#
|
||||
# CONFIG_USB_GADGET is not set
|
||||
|
||||
#
|
||||
# File systems
|
||||
#
|
||||
# CONFIG_EXT2_FS is not set
|
||||
# CONFIG_EXT3_FS is not set
|
||||
# CONFIG_JBD is not set
|
||||
# CONFIG_REISERFS_FS is not set
|
||||
# CONFIG_JFS_FS is not set
|
||||
# CONFIG_XFS_FS is not set
|
||||
# CONFIG_MINIX_FS is not set
|
||||
CONFIG_ROMFS_FS=y
|
||||
# CONFIG_QUOTA is not set
|
||||
# CONFIG_DNOTIFY is not set
|
||||
# CONFIG_AUTOFS_FS is not set
|
||||
# CONFIG_AUTOFS4_FS is not set
|
||||
|
||||
#
|
||||
# CD-ROM/DVD Filesystems
|
||||
#
|
||||
# CONFIG_ISO9660_FS is not set
|
||||
# CONFIG_UDF_FS is not set
|
||||
|
||||
#
|
||||
# DOS/FAT/NT Filesystems
|
||||
#
|
||||
# CONFIG_MSDOS_FS is not set
|
||||
# CONFIG_VFAT_FS is not set
|
||||
# CONFIG_NTFS_FS is not set
|
||||
|
||||
#
|
||||
# Pseudo filesystems
|
||||
#
|
||||
CONFIG_PROC_FS=y
|
||||
# CONFIG_SYSFS is not set
|
||||
# CONFIG_DEVFS_FS is not set
|
||||
# CONFIG_TMPFS is not set
|
||||
# CONFIG_HUGETLB_PAGE is not set
|
||||
CONFIG_RAMFS=y
|
||||
|
||||
#
|
||||
# Miscellaneous filesystems
|
||||
#
|
||||
# CONFIG_ADFS_FS is not set
|
||||
# CONFIG_AFFS_FS is not set
|
||||
# CONFIG_HFS_FS is not set
|
||||
# CONFIG_HFSPLUS_FS is not set
|
||||
# CONFIG_BEFS_FS is not set
|
||||
# CONFIG_BFS_FS is not set
|
||||
# CONFIG_EFS_FS is not set
|
||||
# CONFIG_JFFS_FS is not set
|
||||
# CONFIG_JFFS2_FS is not set
|
||||
# CONFIG_CRAMFS is not set
|
||||
# CONFIG_VXFS_FS is not set
|
||||
# CONFIG_HPFS_FS is not set
|
||||
# CONFIG_QNX4FS_FS is not set
|
||||
# CONFIG_SYSV_FS is not set
|
||||
# CONFIG_UFS_FS is not set
|
||||
|
||||
#
|
||||
# Partition Types
|
||||
#
|
||||
# CONFIG_PARTITION_ADVANCED is not set
|
||||
CONFIG_MSDOS_PARTITION=y
|
||||
|
||||
#
|
||||
# Native Language Support
|
||||
#
|
||||
# CONFIG_NLS is not set
|
||||
|
||||
#
|
||||
# Kernel hacking
|
||||
#
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
# CONFIG_SCHEDSTATS is not set
|
||||
# CONFIG_DEBUG_KOBJECT is not set
|
||||
# CONFIG_DEBUG_FS is not set
|
||||
CONFIG_FULLDEBUG=y
|
||||
# CONFIG_HIGHPROFILE is not set
|
||||
CONFIG_NO_KERNEL_MSG=y
|
||||
# CONFIG_SYSCALL_PRINT is not set
|
||||
# CONFIG_GDB_DEBUG is not set
|
||||
# CONFIG_CONFIG_SH_STANDARD_BIOS is not set
|
||||
# CONFIG_DEFAULT_CMDLINE is not set
|
||||
# CONFIG_BLKDEV_RESERVE is not set
|
||||
|
||||
#
|
||||
# Security options
|
||||
#
|
||||
# CONFIG_KEYS is not set
|
||||
# CONFIG_SECURITY is not set
|
||||
|
||||
#
|
||||
# Cryptographic options
|
||||
#
|
||||
# CONFIG_CRYPTO is not set
|
||||
|
||||
#
|
||||
# Hardware crypto devices
|
||||
#
|
||||
|
||||
#
|
||||
# Library routines
|
||||
#
|
||||
# CONFIG_CRC_CCITT is not set
|
||||
CONFIG_CRC32=y
|
||||
# CONFIG_LIBCRC32C is not set
|
||||
CONFIG_ZLIB_INFLATE=y
|
||||
11
arch/h8300/kernel/Makefile
Normal file
11
arch/h8300/kernel/Makefile
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
extra-y := vmlinux.lds
|
||||
|
||||
obj-y := process.o traps.o ptrace.o ints.o \
|
||||
sys_h8300.o time.o semaphore.o signal.o \
|
||||
setup.o gpio.o init_task.o syscalls.o
|
||||
|
||||
obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o
|
||||
65
arch/h8300/kernel/asm-offsets.c
Normal file
65
arch/h8300/kernel/asm-offsets.c
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
#define DEFINE(sym, val) \
|
||||
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
|
||||
|
||||
#define BLANK() asm volatile("\n->" : : )
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* offsets into the task struct */
|
||||
DEFINE(TASK_STATE, offsetof(struct task_struct, state));
|
||||
DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
|
||||
DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
|
||||
DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
|
||||
DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
|
||||
DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info));
|
||||
DEFINE(TASK_MM, offsetof(struct task_struct, mm));
|
||||
DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
|
||||
|
||||
/* offsets into the irq_cpustat_t struct */
|
||||
DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
|
||||
|
||||
/* offsets into the thread struct */
|
||||
DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
|
||||
DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
|
||||
DEFINE(THREAD_CCR, offsetof(struct thread_struct, ccr));
|
||||
|
||||
/* offsets into the pt_regs struct */
|
||||
DEFINE(LER0, offsetof(struct pt_regs, er0) - sizeof(long));
|
||||
DEFINE(LER1, offsetof(struct pt_regs, er1) - sizeof(long));
|
||||
DEFINE(LER2, offsetof(struct pt_regs, er2) - sizeof(long));
|
||||
DEFINE(LER3, offsetof(struct pt_regs, er3) - sizeof(long));
|
||||
DEFINE(LER4, offsetof(struct pt_regs, er4) - sizeof(long));
|
||||
DEFINE(LER5, offsetof(struct pt_regs, er5) - sizeof(long));
|
||||
DEFINE(LER6, offsetof(struct pt_regs, er6) - sizeof(long));
|
||||
DEFINE(LORIG, offsetof(struct pt_regs, orig_er0) - sizeof(long));
|
||||
DEFINE(LCCR, offsetof(struct pt_regs, ccr) - sizeof(long));
|
||||
DEFINE(LVEC, offsetof(struct pt_regs, vector) - sizeof(long));
|
||||
#if defined(__H8300S__)
|
||||
DEFINE(LEXR, offsetof(struct pt_regs, exr) - sizeof(long));
|
||||
#endif
|
||||
DEFINE(LRET, offsetof(struct pt_regs, pc) - sizeof(long));
|
||||
|
||||
DEFINE(PT_PTRACED, PT_PTRACED);
|
||||
DEFINE(PT_DTRACE, PT_DTRACE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
174
arch/h8300/kernel/gpio.c
Normal file
174
arch/h8300/kernel/gpio.c
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* linux/arch/h8300/kernel/gpio.c
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Internal I/O Port Management
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#define _(addr) (volatile unsigned char *)(addr)
|
||||
#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
|
||||
#include <asm/regs306x.h>
|
||||
static volatile unsigned char *ddrs[] = {
|
||||
_(P1DDR),_(P2DDR),_(P3DDR),_(P4DDR),_(P5DDR),_(P6DDR),
|
||||
NULL, _(P8DDR),_(P9DDR),_(PADDR),_(PBDDR),
|
||||
};
|
||||
#define MAX_PORT 11
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_H83002) || defined(CONFIG_H8048)
|
||||
/* Fix me!! */
|
||||
#include <asm/regs306x.h>
|
||||
static volatile unsigned char *ddrs[] = {
|
||||
_(P1DDR),_(P2DDR),_(P3DDR),_(P4DDR),_(P5DDR),_(P6DDR),
|
||||
NULL, _(P8DDR),_(P9DDR),_(PADDR),_(PBDDR),
|
||||
};
|
||||
#define MAX_PORT 11
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_H8S2678)
|
||||
#include <asm/regs267x.h>
|
||||
static volatile unsigned char *ddrs[] = {
|
||||
_(P1DDR),_(P2DDR),_(P3DDR),NULL ,_(P5DDR),_(P6DDR),
|
||||
_(P7DDR),_(P8DDR),NULL, _(PADDR),_(PBDDR),_(PCDDR),
|
||||
_(PDDDR),_(PEDDR),_(PFDDR),_(PGDDR),_(PHDDR),
|
||||
_(PADDR),_(PBDDR),_(PCDDR),_(PDDDR),_(PEDDR),_(PFDDR),
|
||||
_(PGDDR),_(PHDDR)
|
||||
};
|
||||
#define MAX_PORT 17
|
||||
#endif
|
||||
#undef _
|
||||
|
||||
#if !defined(P1DDR)
|
||||
#error Unsuppoted CPU Selection
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
unsigned char used;
|
||||
unsigned char ddr;
|
||||
} gpio_regs[MAX_PORT];
|
||||
|
||||
extern char *_platform_gpio_table(int length);
|
||||
|
||||
int h8300_reserved_gpio(int port, unsigned int bits)
|
||||
{
|
||||
unsigned char *used;
|
||||
|
||||
if (port < 0 || port >= MAX_PORT)
|
||||
return -1;
|
||||
used = &(gpio_regs[port].used);
|
||||
if ((*used & bits) != 0)
|
||||
return 0;
|
||||
*used |= bits;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int h8300_free_gpio(int port, unsigned int bits)
|
||||
{
|
||||
unsigned char *used;
|
||||
|
||||
if (port < 0 || port >= MAX_PORT)
|
||||
return -1;
|
||||
used = &(gpio_regs[port].used);
|
||||
if ((*used & bits) != bits)
|
||||
return 0;
|
||||
*used &= (~bits);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int h8300_set_gpio_dir(int port_bit,int dir)
|
||||
{
|
||||
int port = (port_bit >> 8) & 0xff;
|
||||
int bit = port_bit & 0xff;
|
||||
|
||||
if (ddrs[port] == NULL)
|
||||
return 0;
|
||||
if (gpio_regs[port].used & bit) {
|
||||
if (dir)
|
||||
gpio_regs[port].ddr |= bit;
|
||||
else
|
||||
gpio_regs[port].ddr &= ~bit;
|
||||
*ddrs[port] = gpio_regs[port].ddr;
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int h8300_get_gpio_dir(int port_bit)
|
||||
{
|
||||
int port = (port_bit >> 8) & 0xff;
|
||||
int bit = port_bit & 0xff;
|
||||
|
||||
if (ddrs[port] == NULL)
|
||||
return 0;
|
||||
if (gpio_regs[port].used & bit) {
|
||||
return (gpio_regs[port].ddr & bit) != 0;
|
||||
} else
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_PROC_FS)
|
||||
static char *port_status(int portno)
|
||||
{
|
||||
static char result[10];
|
||||
const static char io[2]={'I','O'};
|
||||
char *rp;
|
||||
int c;
|
||||
unsigned char used,ddr;
|
||||
|
||||
used = gpio_regs[portno].used;
|
||||
ddr = gpio_regs[portno].ddr;
|
||||
result[8]='\0';
|
||||
rp = result + 7;
|
||||
for (c = 8; c > 0; c--,rp--,used >>= 1, ddr >>= 1)
|
||||
if (used & 0x01)
|
||||
*rp = io[ ddr & 0x01];
|
||||
else
|
||||
*rp = '-';
|
||||
return result;
|
||||
}
|
||||
|
||||
static int gpio_proc_read(char *buf, char **start, off_t offset,
|
||||
int len, int *unused_i, void *unused_v)
|
||||
{
|
||||
int c,outlen;
|
||||
const static char port_name[]="123456789ABCDEFGH";
|
||||
outlen = 0;
|
||||
for (c = 0; c < MAX_PORT; c++) {
|
||||
if (ddrs[c] == NULL)
|
||||
continue ;
|
||||
len = sprintf(buf,"P%c: %s\n",port_name[c],port_status(c));
|
||||
buf += len;
|
||||
outlen += len;
|
||||
}
|
||||
return outlen;
|
||||
}
|
||||
|
||||
static __init int register_proc(void)
|
||||
{
|
||||
struct proc_dir_entry *proc_gpio;
|
||||
|
||||
proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL);
|
||||
if (proc_gpio)
|
||||
proc_gpio->read_proc = gpio_proc_read;
|
||||
return proc_gpio != NULL;
|
||||
}
|
||||
|
||||
__initcall(register_proc);
|
||||
#endif
|
||||
|
||||
void __init h8300_gpio_init(void)
|
||||
{
|
||||
memcpy(gpio_regs,_platform_gpio_table(sizeof(gpio_regs)),sizeof(gpio_regs));
|
||||
}
|
||||
112
arch/h8300/kernel/h8300_ksyms.c
Normal file
112
arch/h8300/kernel/h8300_ksyms.c
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/elfcore.h>
|
||||
#include <linux/in6.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/config.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <asm/checksum.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/gpio.h>
|
||||
|
||||
//asmlinkage long long __ashrdi3 (long long, int);
|
||||
//asmlinkage long long __lshrdi3 (long long, int);
|
||||
extern char h8300_debug_device[];
|
||||
|
||||
extern void dump_thread(struct pt_regs *, struct user *);
|
||||
|
||||
/* platform dependent support */
|
||||
|
||||
EXPORT_SYMBOL(dump_thread);
|
||||
EXPORT_SYMBOL(strnlen);
|
||||
EXPORT_SYMBOL(strrchr);
|
||||
EXPORT_SYMBOL(strstr);
|
||||
EXPORT_SYMBOL(strchr);
|
||||
EXPORT_SYMBOL(strcat);
|
||||
EXPORT_SYMBOL(strlen);
|
||||
EXPORT_SYMBOL(strcmp);
|
||||
EXPORT_SYMBOL(strncmp);
|
||||
|
||||
EXPORT_SYMBOL(ip_fast_csum);
|
||||
|
||||
EXPORT_SYMBOL(kernel_thread);
|
||||
EXPORT_SYMBOL(enable_irq);
|
||||
EXPORT_SYMBOL(disable_irq);
|
||||
|
||||
/* Networking helper routines. */
|
||||
EXPORT_SYMBOL(csum_partial_copy);
|
||||
|
||||
/* 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(__ashrdi3);
|
||||
//EXPORT_SYMBOL(__lshrdi3);
|
||||
EXPORT_SYMBOL(memcpy);
|
||||
EXPORT_SYMBOL(memset);
|
||||
EXPORT_SYMBOL(memcmp);
|
||||
EXPORT_SYMBOL(memscan);
|
||||
EXPORT_SYMBOL(memmove);
|
||||
|
||||
EXPORT_SYMBOL(get_wchan);
|
||||
|
||||
/*
|
||||
* libgcc functions - functions that are used internally by the
|
||||
* compiler... (prototypes are not correct though, but that
|
||||
* doesn't really matter since they're not versioned).
|
||||
*/
|
||||
extern void __gcc_bcmp(void);
|
||||
extern void __ashldi3(void);
|
||||
extern void __ashrdi3(void);
|
||||
extern void __cmpdi2(void);
|
||||
extern void __divdi3(void);
|
||||
extern void __divsi3(void);
|
||||
extern void __lshrdi3(void);
|
||||
extern void __moddi3(void);
|
||||
extern void __modsi3(void);
|
||||
extern void __muldi3(void);
|
||||
extern void __mulsi3(void);
|
||||
extern void __negdi2(void);
|
||||
extern void __ucmpdi2(void);
|
||||
extern void __udivdi3(void);
|
||||
extern void __udivmoddi4(void);
|
||||
extern void __udivsi3(void);
|
||||
extern void __umoddi3(void);
|
||||
extern void __umodsi3(void);
|
||||
|
||||
/* gcc lib functions */
|
||||
EXPORT_SYMBOL(__gcc_bcmp);
|
||||
EXPORT_SYMBOL(__ashldi3);
|
||||
EXPORT_SYMBOL(__ashrdi3);
|
||||
EXPORT_SYMBOL(__cmpdi2);
|
||||
EXPORT_SYMBOL(__divdi3);
|
||||
EXPORT_SYMBOL(__divsi3);
|
||||
EXPORT_SYMBOL(__lshrdi3);
|
||||
EXPORT_SYMBOL(__moddi3);
|
||||
EXPORT_SYMBOL(__modsi3);
|
||||
EXPORT_SYMBOL(__muldi3);
|
||||
EXPORT_SYMBOL(__mulsi3);
|
||||
EXPORT_SYMBOL(__negdi2);
|
||||
EXPORT_SYMBOL(__ucmpdi2);
|
||||
EXPORT_SYMBOL(__udivdi3);
|
||||
EXPORT_SYMBOL(__udivmoddi4);
|
||||
EXPORT_SYMBOL(__udivsi3);
|
||||
EXPORT_SYMBOL(__umoddi3);
|
||||
EXPORT_SYMBOL(__umodsi3);
|
||||
|
||||
#ifdef MAGIC_ROM_PTR
|
||||
EXPORT_SYMBOL(is_in_rom);
|
||||
#endif
|
||||
|
||||
EXPORT_SYMBOL(h8300_reserved_gpio);
|
||||
EXPORT_SYMBOL(h8300_free_gpio);
|
||||
EXPORT_SYMBOL(h8300_set_gpio_dir);
|
||||
43
arch/h8300/kernel/init_task.c
Normal file
43
arch/h8300/kernel/init_task.c
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* linux/arch/h8300/kernel/init_task.c
|
||||
*/
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/init_task.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mqueue.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
static struct fs_struct init_fs = INIT_FS;
|
||||
static struct files_struct init_files = INIT_FILES;
|
||||
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
|
||||
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
|
||||
struct mm_struct init_mm = INIT_MM(init_mm);
|
||||
|
||||
EXPORT_SYMBOL(init_mm);
|
||||
|
||||
/*
|
||||
* Initial task structure.
|
||||
*
|
||||
* All other task structs will be allocated on slabs in fork.c
|
||||
*/
|
||||
__asm__(".align 4");
|
||||
struct task_struct init_task = INIT_TASK(init_task);
|
||||
|
||||
EXPORT_SYMBOL(init_task);
|
||||
|
||||
/*
|
||||
* Initial thread structure.
|
||||
*
|
||||
* We need to make sure that this is 8192-byte aligned due to the
|
||||
* way process stacks are handled. This is done by having a special
|
||||
* "init_task" linker map entry..
|
||||
*/
|
||||
union thread_union init_thread_union
|
||||
__attribute__((__section__(".data.init_task"))) =
|
||||
{ INIT_THREAD_INFO(init_task) };
|
||||
|
||||
255
arch/h8300/kernel/ints.c
Normal file
255
arch/h8300/kernel/ints.c
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8300h/ints.c
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Based on linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
|
||||
*
|
||||
* 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 1996 Roman Zippel
|
||||
* Copyright 1999 D. Jeff Dionne <jeff@rt-control.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/hardirq.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/errno.h>
|
||||
|
||||
/*
|
||||
* This structure has only 4 elements for speed reasons
|
||||
*/
|
||||
typedef struct irq_handler {
|
||||
irqreturn_t (*handler)(int, void *, struct pt_regs *);
|
||||
int flags;
|
||||
int count;
|
||||
void *dev_id;
|
||||
const char *devname;
|
||||
} irq_handler_t;
|
||||
|
||||
static irq_handler_t *irq_list[NR_IRQS];
|
||||
static int use_kmalloc;
|
||||
|
||||
extern unsigned long *interrupt_redirect_table;
|
||||
extern const int h8300_saved_vectors[];
|
||||
extern const unsigned long h8300_trap_table[];
|
||||
int h8300_enable_irq_pin(unsigned int irq);
|
||||
void h8300_disable_irq_pin(unsigned int irq);
|
||||
|
||||
#define CPU_VECTOR ((unsigned long *)0x000000)
|
||||
#define ADDR_MASK (0xffffff)
|
||||
|
||||
#if defined(CONFIG_RAMKERNEL)
|
||||
static unsigned long __init *get_vector_address(void)
|
||||
{
|
||||
unsigned long *rom_vector = CPU_VECTOR;
|
||||
unsigned long base,tmp;
|
||||
int vec_no;
|
||||
|
||||
base = rom_vector[EXT_IRQ0] & ADDR_MASK;
|
||||
|
||||
/* check romvector format */
|
||||
for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ0+EXT_IRQS; vec_no++) {
|
||||
if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ramvector base address */
|
||||
base -= EXT_IRQ0*4;
|
||||
|
||||
/* writerble check */
|
||||
tmp = ~(*(volatile unsigned long *)base);
|
||||
(*(volatile unsigned long *)base) = tmp;
|
||||
if ((*(volatile unsigned long *)base) != tmp)
|
||||
return NULL;
|
||||
return (unsigned long *)base;
|
||||
}
|
||||
#endif
|
||||
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
#if defined(CONFIG_RAMKERNEL)
|
||||
int i;
|
||||
unsigned long *ramvec,*ramvec_p;
|
||||
const unsigned long *trap_entry;
|
||||
const int *saved_vector;
|
||||
|
||||
ramvec = get_vector_address();
|
||||
if (ramvec == NULL)
|
||||
panic("interrupt vector serup failed.");
|
||||
else
|
||||
printk(KERN_INFO "virtual vector at 0x%08lx\n",(unsigned long)ramvec);
|
||||
|
||||
/* create redirect table */
|
||||
ramvec_p = ramvec;
|
||||
trap_entry = h8300_trap_table;
|
||||
saved_vector = h8300_saved_vectors;
|
||||
for ( i = 0; i < NR_IRQS; i++) {
|
||||
if (i == *saved_vector) {
|
||||
ramvec_p++;
|
||||
saved_vector++;
|
||||
} else {
|
||||
if ( i < NR_TRAPS ) {
|
||||
if (*trap_entry)
|
||||
*ramvec_p = VECTOR(*trap_entry);
|
||||
ramvec_p++;
|
||||
trap_entry++;
|
||||
} else
|
||||
*ramvec_p++ = REDIRECT(interrupt_entry);
|
||||
}
|
||||
}
|
||||
interrupt_redirect_table = ramvec;
|
||||
#ifdef DUMP_VECTOR
|
||||
ramvec_p = ramvec;
|
||||
for (i = 0; i < NR_IRQS; i++) {
|
||||
if ((i % 8) == 0)
|
||||
printk(KERN_DEBUG "\n%p: ",ramvec_p);
|
||||
printk(KERN_DEBUG "%p ",*ramvec_p);
|
||||
ramvec_p++;
|
||||
}
|
||||
printk(KERN_DEBUG "\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
int request_irq(unsigned int irq,
|
||||
irqreturn_t (*handler)(int, void *, struct pt_regs *),
|
||||
unsigned long flags, const char *devname, void *dev_id)
|
||||
{
|
||||
irq_handler_t *irq_handle;
|
||||
if (irq < 0 || irq >= NR_IRQS) {
|
||||
printk(KERN_ERR "Incorrect IRQ %d from %s\n", irq, devname);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (irq_list[irq] || (h8300_enable_irq_pin(irq) == -EBUSY))
|
||||
return -EBUSY;
|
||||
|
||||
if (use_kmalloc)
|
||||
irq_handle = (irq_handler_t *)kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
|
||||
else {
|
||||
/* use bootmem allocater */
|
||||
irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t));
|
||||
irq_handle = (irq_handler_t *)((unsigned long)irq_handle | 0x80000000);
|
||||
}
|
||||
|
||||
if (irq_handle == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
irq_handle->handler = handler;
|
||||
irq_handle->flags = flags;
|
||||
irq_handle->count = 0;
|
||||
irq_handle->dev_id = dev_id;
|
||||
irq_handle->devname = devname;
|
||||
irq_list[irq] = irq_handle;
|
||||
|
||||
if (irq_handle->flags & SA_SAMPLE_RANDOM)
|
||||
rand_initialize_irq(irq);
|
||||
|
||||
enable_irq(irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(request_irq);
|
||||
|
||||
void free_irq(unsigned int irq, void *dev_id)
|
||||
{
|
||||
if (irq >= NR_IRQS)
|
||||
return;
|
||||
|
||||
if (!irq_list[irq] || irq_list[irq]->dev_id != dev_id)
|
||||
printk(KERN_WARNING "Removing probably wrong IRQ %d from %s\n",
|
||||
irq, irq_list[irq]->devname);
|
||||
disable_irq(irq);
|
||||
h8300_disable_irq_pin(irq);
|
||||
if (((unsigned long)irq_list[irq] & 0x80000000) == 0) {
|
||||
kfree(irq_list[irq]);
|
||||
irq_list[irq] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(free_irq);
|
||||
|
||||
/*
|
||||
* Do we need these probe functions on the m68k?
|
||||
*/
|
||||
unsigned long probe_irq_on (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(probe_irq_on);
|
||||
|
||||
int probe_irq_off (unsigned long irqs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(probe_irq_off);
|
||||
|
||||
void enable_irq(unsigned int irq)
|
||||
{
|
||||
if (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS))
|
||||
IER_REGS |= 1 << (irq - EXT_IRQ0);
|
||||
}
|
||||
|
||||
void disable_irq(unsigned int irq)
|
||||
{
|
||||
if (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS))
|
||||
IER_REGS &= ~(1 << (irq - EXT_IRQ0));
|
||||
}
|
||||
|
||||
asmlinkage void process_int(int irq, struct pt_regs *fp)
|
||||
{
|
||||
irq_enter();
|
||||
h8300_clear_isr(irq);
|
||||
if (irq >= NR_TRAPS && irq < NR_IRQS) {
|
||||
if (irq_list[irq]) {
|
||||
irq_list[irq]->handler(irq, irq_list[irq]->dev_id, fp);
|
||||
irq_list[irq]->count++;
|
||||
if (irq_list[irq]->flags & SA_SAMPLE_RANDOM)
|
||||
add_interrupt_randomness(irq);
|
||||
}
|
||||
} else {
|
||||
BUG();
|
||||
}
|
||||
irq_exit();
|
||||
}
|
||||
|
||||
int show_interrupts(struct seq_file *p, void *v)
|
||||
{
|
||||
int i = *(loff_t *) v;
|
||||
|
||||
if ((i < NR_IRQS) && (irq_list[i]!=NULL)) {
|
||||
seq_printf(p, "%3d: %10u ",i,irq_list[i]->count);
|
||||
seq_printf(p, "%s\n", irq_list[i]->devname);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_irq_proc(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int __init enable_kmalloc(void)
|
||||
{
|
||||
use_kmalloc = 1;
|
||||
return 0;
|
||||
}
|
||||
core_initcall(enable_kmalloc);
|
||||
122
arch/h8300/kernel/module.c
Normal file
122
arch/h8300/kernel/module.c
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
#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
|
||||
|
||||
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);
|
||||
/* FIXME: If module_region == mod->init_region, trim exception
|
||||
table entries. */
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
printk(KERN_ERR "module %s: RELOCATION unsupported\n",
|
||||
me->name);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
int apply_relocate_add(Elf32_Shdr *sechdrs,
|
||||
const char *strtab,
|
||||
unsigned int symindex,
|
||||
unsigned int relsec,
|
||||
struct module *me)
|
||||
{
|
||||
unsigned int i;
|
||||
Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
|
||||
|
||||
DEBUGP("Applying relocate section %u to %u\n", relsec,
|
||||
sechdrs[relsec].sh_info);
|
||||
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
|
||||
/* This is where to make the change */
|
||||
uint32_t *loc = (uint32_t *)(sechdrs[sechdrs[relsec].sh_info].sh_addr
|
||||
+ rela[i].r_offset);
|
||||
/* This is the symbol it is referring to. Note that all
|
||||
undefined symbols have been resolved. */
|
||||
Elf32_Sym *sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
|
||||
+ ELF32_R_SYM(rela[i].r_info);
|
||||
uint32_t v = sym->st_value + rela[i].r_addend;
|
||||
|
||||
switch (ELF32_R_TYPE(rela[i].r_info)) {
|
||||
case R_H8_DIR24R8:
|
||||
loc = (uint32_t *)((uint32_t)loc - 1);
|
||||
*loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v);
|
||||
break;
|
||||
case R_H8_DIR24A8:
|
||||
if (ELF32_R_SYM(rela[i].r_info))
|
||||
*loc += v;
|
||||
break;
|
||||
case R_H8_DIR32:
|
||||
case R_H8_DIR32A16:
|
||||
*loc += v;
|
||||
break;
|
||||
case R_H8_PCREL16:
|
||||
v -= (unsigned long)loc + 2;
|
||||
if ((Elf32_Sword)v > 0x7fff ||
|
||||
(Elf32_Sword)v < -(Elf32_Sword)0x8000)
|
||||
goto overflow;
|
||||
else
|
||||
*(unsigned short *)loc = v;
|
||||
break;
|
||||
case R_H8_PCREL8:
|
||||
v -= (unsigned long)loc + 1;
|
||||
if ((Elf32_Sword)v > 0x7f ||
|
||||
(Elf32_Sword)v < -(Elf32_Sword)0x80)
|
||||
goto overflow;
|
||||
else
|
||||
*(unsigned char *)loc = v;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "module %s: Unknown relocation: %u\n",
|
||||
me->name, ELF32_R_TYPE(rela[i].r_info));
|
||||
return -ENOEXEC;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
overflow:
|
||||
printk(KERN_ERR "module %s: relocation offset overflow: %08x\n",
|
||||
me->name, rela[i].r_offset);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
int module_finalize(const Elf_Ehdr *hdr,
|
||||
const Elf_Shdr *sechdrs,
|
||||
struct module *me)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void module_arch_cleanup(struct module *mod)
|
||||
{
|
||||
}
|
||||
288
arch/h8300/kernel/process.c
Normal file
288
arch/h8300/kernel/process.c
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* linux/arch/h8300/kernel/process.c
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Based on:
|
||||
*
|
||||
* linux/arch/m68knommu/kernel/process.c
|
||||
*
|
||||
* Copyright (C) 1998 D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
|
||||
* Kenneth Albanowski <kjahds@kjahds.com>,
|
||||
* The Silver Hammer Group, Ltd.
|
||||
*
|
||||
* 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/config.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/a.out.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
asmlinkage void ret_from_fork(void);
|
||||
|
||||
/*
|
||||
* The idle loop on an H8/300..
|
||||
*/
|
||||
#if !defined(CONFIG_H8300H_SIM) && !defined(CONFIG_H8S_SIM)
|
||||
void default_idle(void)
|
||||
{
|
||||
while(1) {
|
||||
if (need_resched()) {
|
||||
local_irq_enable();
|
||||
__asm__("sleep");
|
||||
local_irq_disable();
|
||||
}
|
||||
schedule();
|
||||
}
|
||||
}
|
||||
#else
|
||||
void default_idle(void)
|
||||
{
|
||||
while(1) {
|
||||
if (need_resched())
|
||||
schedule();
|
||||
}
|
||||
}
|
||||
#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)
|
||||
{
|
||||
idle();
|
||||
}
|
||||
|
||||
void machine_restart(char * __unused)
|
||||
{
|
||||
local_irq_disable();
|
||||
__asm__("jmp @@0");
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(machine_restart);
|
||||
|
||||
void machine_halt(void)
|
||||
{
|
||||
local_irq_disable();
|
||||
__asm__("sleep");
|
||||
for (;;);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(machine_halt);
|
||||
|
||||
void machine_power_off(void)
|
||||
{
|
||||
local_irq_disable();
|
||||
__asm__("sleep");
|
||||
for (;;);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(machine_power_off);
|
||||
|
||||
void show_regs(struct pt_regs * regs)
|
||||
{
|
||||
printk("\nPC: %08lx Status: %02x",
|
||||
regs->pc, regs->ccr);
|
||||
printk("\nORIG_ER0: %08lx ER0: %08lx ER1: %08lx",
|
||||
regs->orig_er0, regs->er0, regs->er1);
|
||||
printk("\nER2: %08lx ER3: %08lx ER4: %08lx ER5: %08lx",
|
||||
regs->er2, regs->er3, regs->er4, regs->er5);
|
||||
printk("\nER6' %08lx ",regs->er6);
|
||||
if (user_mode(regs))
|
||||
printk("USP: %08lx\n", rdusp());
|
||||
else
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a kernel thread
|
||||
*/
|
||||
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
|
||||
{
|
||||
long retval;
|
||||
long clone_arg;
|
||||
mm_segment_t fs;
|
||||
|
||||
fs = get_fs();
|
||||
set_fs (KERNEL_DS);
|
||||
clone_arg = flags | CLONE_VM;
|
||||
__asm__("mov.l sp,er3\n\t"
|
||||
"sub.l er2,er2\n\t"
|
||||
"mov.l %2,er1\n\t"
|
||||
"mov.l %1,er0\n\t"
|
||||
"trapa #0\n\t"
|
||||
"cmp.l sp,er3\n\t"
|
||||
"beq 1f\n\t"
|
||||
"mov.l %4,er0\n\t"
|
||||
"mov.l %3,er1\n\t"
|
||||
"jsr @er1\n\t"
|
||||
"mov.l %5,er0\n\t"
|
||||
"trapa #0\n"
|
||||
"1:\n\t"
|
||||
"mov.l er0,%0"
|
||||
:"=r"(retval)
|
||||
:"i"(__NR_clone),"g"(clone_arg),"g"(fn),"g"(arg),"i"(__NR_exit)
|
||||
:"er0","er1","er2","er3");
|
||||
set_fs (fs);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void flush_thread(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* "h8300_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 h8300_fork(struct pt_regs *regs)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
asmlinkage int h8300_vfork(struct pt_regs *regs)
|
||||
{
|
||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
asmlinkage int h8300_clone(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long clone_flags;
|
||||
unsigned long newsp;
|
||||
|
||||
/* syscall2 puts clone_flags in er1 and usp in er2 */
|
||||
clone_flags = regs->er1;
|
||||
newsp = regs->er2;
|
||||
if (!newsp)
|
||||
newsp = rdusp();
|
||||
return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
|
||||
|
||||
}
|
||||
|
||||
int copy_thread(int nr, unsigned long clone_flags,
|
||||
unsigned long usp, unsigned long topstk,
|
||||
struct task_struct * p, struct pt_regs * regs)
|
||||
{
|
||||
struct pt_regs * childregs;
|
||||
|
||||
childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
|
||||
|
||||
*childregs = *regs;
|
||||
childregs->retpc = (unsigned long) ret_from_fork;
|
||||
childregs->er0 = 0;
|
||||
|
||||
p->thread.usp = usp;
|
||||
p->thread.ksp = (unsigned long)childregs;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* fill in the user structure for a core dump..
|
||||
*/
|
||||
void dump_thread(struct pt_regs * regs, struct user * dump)
|
||||
{
|
||||
/* changed the size calculations - should hopefully work better. lbt */
|
||||
dump->magic = CMAGIC;
|
||||
dump->start_code = 0;
|
||||
dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
|
||||
dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
|
||||
dump->u_dsize = ((unsigned long) (current->mm->brk +
|
||||
(PAGE_SIZE-1))) >> PAGE_SHIFT;
|
||||
dump->u_dsize -= dump->u_tsize;
|
||||
dump->u_ssize = 0;
|
||||
|
||||
dump->u_ar0 = (struct user_regs_struct *)(((int)(&dump->regs)) -((int)(dump)));
|
||||
dump->regs.er0 = regs->er0;
|
||||
dump->regs.er1 = regs->er1;
|
||||
dump->regs.er2 = regs->er2;
|
||||
dump->regs.er3 = regs->er3;
|
||||
dump->regs.er4 = regs->er4;
|
||||
dump->regs.er5 = regs->er5;
|
||||
dump->regs.er6 = regs->er6;
|
||||
dump->regs.orig_er0 = regs->orig_er0;
|
||||
dump->regs.ccr = regs->ccr;
|
||||
dump->regs.pc = regs->pc;
|
||||
}
|
||||
|
||||
/*
|
||||
* sys_execve() executes a new program.
|
||||
*/
|
||||
asmlinkage int sys_execve(char *name, char **argv, char **envp,int dummy,...)
|
||||
{
|
||||
int error;
|
||||
char * filename;
|
||||
struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4);
|
||||
|
||||
lock_kernel();
|
||||
filename = getname(name);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
error = do_execve(filename, argv, envp, regs);
|
||||
putname(filename);
|
||||
out:
|
||||
unlock_kernel();
|
||||
return error;
|
||||
}
|
||||
|
||||
unsigned long thread_saved_pc(struct task_struct *tsk)
|
||||
{
|
||||
return ((struct pt_regs *)tsk->thread.esp0)->pc;
|
||||
}
|
||||
|
||||
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)p;
|
||||
fp = ((struct pt_regs *)p->thread.ksp)->er6;
|
||||
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;
|
||||
}
|
||||
277
arch/h8300/kernel/ptrace.c
Normal file
277
arch/h8300/kernel/ptrace.c
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* linux/arch/h8300/kernel/ptrace.c
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Based on:
|
||||
* linux/arch/m68k/kernel/ptrace.c
|
||||
*
|
||||
* Copyright (C) 1994 by Hamish Macdonald
|
||||
* Taken from linux/kernel/ptrace.c and modified for M680x0.
|
||||
* 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/smp_lock.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/config.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/signal.h>
|
||||
|
||||
/* cpu depend functions */
|
||||
extern long h8300_get_reg(struct task_struct *task, int regno);
|
||||
extern int h8300_put_reg(struct task_struct *task, int regno, unsigned long data);
|
||||
extern void h8300_disable_trace(struct task_struct *child);
|
||||
extern void h8300_enable_trace(struct task_struct *child);
|
||||
|
||||
/*
|
||||
* does not yet catch signals sent when the child dies.
|
||||
* in exit.c or in signal.c.
|
||||
*/
|
||||
|
||||
inline
|
||||
static int read_long(struct task_struct * tsk, unsigned long addr,
|
||||
unsigned long * result)
|
||||
{
|
||||
*result = *(unsigned long *)addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ptrace_disable(struct task_struct *child)
|
||||
{
|
||||
h8300_disable_trace(child);
|
||||
}
|
||||
|
||||
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
|
||||
{
|
||||
struct task_struct *child;
|
||||
int ret;
|
||||
|
||||
lock_kernel();
|
||||
ret = -EPERM;
|
||||
if (request == PTRACE_TRACEME) {
|
||||
/* are we already being traced? */
|
||||
if (current->ptrace & PT_PTRACED)
|
||||
goto out;
|
||||
/* set the ptrace bit in the process flags. */
|
||||
current->ptrace |= PT_PTRACED;
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
ret = -ESRCH;
|
||||
read_lock(&tasklist_lock);
|
||||
child = find_task_by_pid(pid);
|
||||
if (child)
|
||||
get_task_struct(child);
|
||||
read_unlock(&tasklist_lock);
|
||||
if (!child)
|
||||
goto out;
|
||||
|
||||
ret = -EPERM;
|
||||
if (pid == 1) /* you may not mess with init */
|
||||
goto out_tsk;
|
||||
|
||||
if (request == PTRACE_ATTACH) {
|
||||
ret = ptrace_attach(child);
|
||||
goto out_tsk;
|
||||
}
|
||||
ret = ptrace_check_attach(child, request == PTRACE_KILL);
|
||||
if (ret < 0)
|
||||
goto out_tsk;
|
||||
|
||||
switch (request) {
|
||||
case PTRACE_PEEKTEXT: /* read word at location addr. */
|
||||
case PTRACE_PEEKDATA: {
|
||||
unsigned long tmp;
|
||||
|
||||
ret = read_long(child, addr, &tmp);
|
||||
if (ret < 0)
|
||||
break ;
|
||||
ret = put_user(tmp, (unsigned long *) data);
|
||||
break ;
|
||||
}
|
||||
|
||||
/* read the word at location addr in the USER area. */
|
||||
case PTRACE_PEEKUSR: {
|
||||
unsigned long tmp = 0;
|
||||
|
||||
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) {
|
||||
ret = -EIO;
|
||||
break ;
|
||||
}
|
||||
|
||||
ret = 0; /* Default return condition */
|
||||
addr = addr >> 2; /* temporary hack. */
|
||||
|
||||
if (addr < H8300_REGS_NO)
|
||||
tmp = h8300_get_reg(child, addr);
|
||||
else {
|
||||
switch(addr) {
|
||||
case 49:
|
||||
tmp = child->mm->start_code;
|
||||
break ;
|
||||
case 50:
|
||||
tmp = child->mm->start_data;
|
||||
break ;
|
||||
case 51:
|
||||
tmp = child->mm->end_code;
|
||||
break ;
|
||||
case 52:
|
||||
tmp = child->mm->end_data;
|
||||
break ;
|
||||
default:
|
||||
ret = -EIO;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
ret = put_user(tmp,(unsigned 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 = 0;
|
||||
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
|
||||
break;
|
||||
ret = -EIO;
|
||||
break;
|
||||
|
||||
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
|
||||
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) {
|
||||
ret = -EIO;
|
||||
break ;
|
||||
}
|
||||
addr = addr >> 2; /* temporary hack. */
|
||||
|
||||
if (addr == PT_ORIG_ER0) {
|
||||
ret = -EIO;
|
||||
break ;
|
||||
}
|
||||
if (addr < H8300_REGS_NO) {
|
||||
ret = h8300_put_reg(child, addr, data);
|
||||
break ;
|
||||
}
|
||||
ret = -EIO;
|
||||
break ;
|
||||
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
|
||||
case PTRACE_CONT: { /* restart after signal. */
|
||||
ret = -EIO;
|
||||
if ((unsigned long) data >= _NSIG)
|
||||
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);
|
||||
/* make sure the single step bit is not set. */
|
||||
h8300_disable_trace(child);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
h8300_disable_trace(child);
|
||||
wake_up_process(child);
|
||||
break;
|
||||
}
|
||||
|
||||
case PTRACE_SINGLESTEP: { /* set the trap flag. */
|
||||
ret = -EIO;
|
||||
if ((unsigned long) data > _NSIG)
|
||||
break;
|
||||
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
|
||||
child->exit_code = data;
|
||||
h8300_enable_trace(child);
|
||||
wake_up_process(child);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case PTRACE_DETACH: /* detach a process that was attached. */
|
||||
ret = ptrace_detach(child, data);
|
||||
break;
|
||||
|
||||
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
|
||||
int i;
|
||||
unsigned long tmp;
|
||||
for (i = 0; i < H8300_REGS_NO; i++) {
|
||||
tmp = h8300_get_reg(child, i);
|
||||
if (put_user(tmp, (unsigned long *) data)) {
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
data += sizeof(long);
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case PTRACE_SETREGS: { /* Set all gp regs in the child. */
|
||||
int i;
|
||||
unsigned long tmp;
|
||||
for (i = 0; i < H8300_REGS_NO; i++) {
|
||||
if (get_user(tmp, (unsigned long *) data)) {
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
h8300_put_reg(child, i, tmp);
|
||||
data += sizeof(long);
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ret = -EIO;
|
||||
break;
|
||||
}
|
||||
out_tsk:
|
||||
put_task_struct(child);
|
||||
out:
|
||||
unlock_kernel();
|
||||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage void syscall_trace(void)
|
||||
{
|
||||
if (!test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
return;
|
||||
if (!(current->ptrace & PT_PTRACED))
|
||||
return;
|
||||
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;
|
||||
}
|
||||
}
|
||||
133
arch/h8300/kernel/semaphore.c
Normal file
133
arch/h8300/kernel/semaphore.c
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Generic semaphore code. Buyer beware. Do your own
|
||||
* specific changes in <asm/semaphore-helper.h>
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/semaphore-helper.h>
|
||||
|
||||
#ifndef CONFIG_RMW_INSNS
|
||||
spinlock_t semaphore_wake_lock;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Semaphores are implemented using a two-way counter:
|
||||
* The "count" variable is decremented for each process
|
||||
* that tries to sleep, while the "waking" variable is
|
||||
* incremented when the "up()" code goes to wake up waiting
|
||||
* processes.
|
||||
*
|
||||
* Notably, the inline "up()" and "down()" functions can
|
||||
* efficiently test if they need to do any extra work (up
|
||||
* needs to do something only if count was negative before
|
||||
* the increment operation.
|
||||
*
|
||||
* waking_non_zero() (from asm/semaphore.h) must execute
|
||||
* atomically.
|
||||
*
|
||||
* When __up() is called, the count was negative before
|
||||
* incrementing it, and we need to wake up somebody.
|
||||
*
|
||||
* This routine adds one to the count of processes that need to
|
||||
* wake up and exit. ALL waiting processes actually wake up but
|
||||
* only the one that gets to the "waking" field first will gate
|
||||
* through and acquire the semaphore. The others will go back
|
||||
* to sleep.
|
||||
*
|
||||
* Note that these functions are only called when there is
|
||||
* contention on the lock, and as such all this is the
|
||||
* "non-critical" part of the whole semaphore business. The
|
||||
* critical part is the inline stuff in <asm/semaphore.h>
|
||||
* where we want to avoid any extra jumps and calls.
|
||||
*/
|
||||
void __up(struct semaphore *sem)
|
||||
{
|
||||
wake_one_more(sem);
|
||||
wake_up(&sem->wait);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the "down" function. Return zero for semaphore acquired,
|
||||
* return negative for signalled out of the function.
|
||||
*
|
||||
* If called from __down, the return is ignored and the wait loop is
|
||||
* not interruptible. This means that a task waiting on a semaphore
|
||||
* using "down()" cannot be killed until someone does an "up()" on
|
||||
* the semaphore.
|
||||
*
|
||||
* If called from __down_interruptible, the return value gets checked
|
||||
* upon return. If the return value is negative then the task continues
|
||||
* with the negative value in the return register (it can be tested by
|
||||
* the caller).
|
||||
*
|
||||
* Either form may be used in conjunction with "up()".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define DOWN_HEAD(task_state) \
|
||||
\
|
||||
\
|
||||
current->state = (task_state); \
|
||||
add_wait_queue(&sem->wait, &wait); \
|
||||
\
|
||||
/* \
|
||||
* Ok, we're set up. sem->count is known to be less than zero \
|
||||
* so we must wait. \
|
||||
* \
|
||||
* We can let go the lock for purposes of waiting. \
|
||||
* We re-acquire it after awaking so as to protect \
|
||||
* all semaphore operations. \
|
||||
* \
|
||||
* If "up()" is called before we call waking_non_zero() then \
|
||||
* we will catch it right away. If it is called later then \
|
||||
* we will have to go through a wakeup cycle to catch it. \
|
||||
* \
|
||||
* Multiple waiters contend for the semaphore lock to see \
|
||||
* who gets to gate through and who has to wait some more. \
|
||||
*/ \
|
||||
for (;;) {
|
||||
|
||||
#define DOWN_TAIL(task_state) \
|
||||
current->state = (task_state); \
|
||||
} \
|
||||
current->state = TASK_RUNNING; \
|
||||
remove_wait_queue(&sem->wait, &wait);
|
||||
|
||||
void __sched __down(struct semaphore * sem)
|
||||
{
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
|
||||
DOWN_HEAD(TASK_UNINTERRUPTIBLE)
|
||||
if (waking_non_zero(sem))
|
||||
break;
|
||||
schedule();
|
||||
DOWN_TAIL(TASK_UNINTERRUPTIBLE)
|
||||
}
|
||||
|
||||
int __sched __down_interruptible(struct semaphore * sem)
|
||||
{
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
int ret = 0;
|
||||
|
||||
DOWN_HEAD(TASK_INTERRUPTIBLE)
|
||||
|
||||
ret = waking_non_zero_interruptible(sem, current);
|
||||
if (ret)
|
||||
{
|
||||
if (ret == 1)
|
||||
/* ret != 0 only if we get interrupted -arca */
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
schedule();
|
||||
DOWN_TAIL(TASK_INTERRUPTIBLE)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __down_trylock(struct semaphore * sem)
|
||||
{
|
||||
return waking_non_zero_trylock(sem);
|
||||
}
|
||||
248
arch/h8300/kernel/setup.c
Normal file
248
arch/h8300/kernel/setup.c
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* linux/arch/h8300/kernel/setup.c
|
||||
*
|
||||
* Copyleft ()) 2000 James D. Schettine {james@telos-systems.com}
|
||||
* Copyright (C) 1999,2000 Greg Ungerer (gerg@snapgear.com)
|
||||
* Copyright (C) 1998,1999 D. Jeff Dionne <jeff@lineo.ca>
|
||||
* Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>
|
||||
* Copyright (C) 1995 Hamish Macdonald
|
||||
* Copyright (C) 2000 Lineo Inc. (www.lineo.com)
|
||||
* Copyright (C) 2001 Lineo, Inc. <www.lineo.com>
|
||||
*
|
||||
* H8/300 porting Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file handles the architecture-dependent parts of system setup
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/genhd.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
#include <asm/pgtable.h>
|
||||
#endif
|
||||
|
||||
#if defined(__H8300H__)
|
||||
#define CPU "H8/300H"
|
||||
#include <asm/regs306x.h>
|
||||
#endif
|
||||
|
||||
#if defined(__H8300S__)
|
||||
#define CPU "H8S"
|
||||
#include <asm/regs267x.h>
|
||||
#endif
|
||||
|
||||
#define STUBSIZE 0xc000;
|
||||
|
||||
unsigned long rom_length;
|
||||
unsigned long memory_start;
|
||||
unsigned long memory_end;
|
||||
|
||||
char command_line[COMMAND_LINE_SIZE];
|
||||
|
||||
extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
|
||||
extern int _ramstart, _ramend;
|
||||
extern char _target_name[];
|
||||
extern void h8300_gpio_init(void);
|
||||
|
||||
#if (defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)) \
|
||||
&& defined(CONFIG_GDB_MAGICPRINT)
|
||||
/* printk with gdb service */
|
||||
static void gdb_console_output(struct console *c, const char *msg, unsigned len)
|
||||
{
|
||||
for (; len > 0; len--) {
|
||||
asm("mov.w %0,r2\n\t"
|
||||
"jsr @0xc4"::"r"(*msg++):"er2");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup initial baud/bits/parity. We do two things here:
|
||||
* - construct a cflag setting for the first rs_open()
|
||||
* - initialize the serial port
|
||||
* Return non-zero if we didn't find a serial port.
|
||||
*/
|
||||
static int __init gdb_console_setup(struct console *co, char *options)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct console gdb_console = {
|
||||
.name = "gdb_con",
|
||||
.write = gdb_console_output,
|
||||
.device = NULL,
|
||||
.setup = gdb_console_setup,
|
||||
.flags = CON_PRINTBUFFER,
|
||||
.index = -1,
|
||||
};
|
||||
#endif
|
||||
|
||||
void __init setup_arch(char **cmdline_p)
|
||||
{
|
||||
int bootmap_size;
|
||||
|
||||
memory_start = (unsigned long) &_ramstart;
|
||||
|
||||
/* allow for ROMFS on the end of the kernel */
|
||||
if (memcmp((void *)memory_start, "-rom1fs-", 8) == 0) {
|
||||
#if defined(CONFIG_BLK_DEV_INITRD)
|
||||
initrd_start = memory_start;
|
||||
initrd_end = memory_start += be32_to_cpu(((unsigned long *) (memory_start))[2]);
|
||||
#else
|
||||
memory_start += be32_to_cpu(((unsigned long *) memory_start)[2]);
|
||||
#endif
|
||||
}
|
||||
memory_start = PAGE_ALIGN(memory_start);
|
||||
#if !defined(CONFIG_BLKDEV_RESERVE)
|
||||
memory_end = (unsigned long) &_ramend; /* by now the stack is part of the init task */
|
||||
#if defined(CONFIG_GDB_DEBUG)
|
||||
memory_end -= STUBSIZE;
|
||||
#endif
|
||||
#else
|
||||
if ((memory_end < CONFIG_BLKDEV_RESERVE_ADDRESS) &&
|
||||
(memory_end > CONFIG_BLKDEV_RESERVE_ADDRESS)
|
||||
/* overlap userarea */
|
||||
memory_end = CONFIG_BLKDEV_RESERVE_ADDRESS;
|
||||
#endif
|
||||
|
||||
init_mm.start_code = (unsigned long) &_stext;
|
||||
init_mm.end_code = (unsigned long) &_etext;
|
||||
init_mm.end_data = (unsigned long) &_edata;
|
||||
init_mm.brk = (unsigned long) 0;
|
||||
|
||||
#if (defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)) && defined(CONFIG_GDB_MAGICPRINT)
|
||||
register_console((struct console *)&gdb_console);
|
||||
#endif
|
||||
|
||||
printk(KERN_INFO "\r\n\nuClinux " CPU "\n");
|
||||
printk(KERN_INFO "Target Hardware: %s\n",_target_name);
|
||||
printk(KERN_INFO "Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
|
||||
printk(KERN_INFO "H8/300 series support by Yoshinori Sato <[email protected]>\n");
|
||||
|
||||
#ifdef DEBUG
|
||||
printk(KERN_DEBUG "KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x "
|
||||
"BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext,
|
||||
(int) &_sdata, (int) &_edata,
|
||||
(int) &_sbss, (int) &_ebss);
|
||||
printk(KERN_DEBUG "KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x "
|
||||
"STACK=0x%06x-0x%06x\n",
|
||||
(int) &_ebss, (int) memory_start,
|
||||
(int) memory_start, (int) memory_end,
|
||||
(int) memory_end, (int) &_ramend);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEFAULT_CMDLINE
|
||||
/* set from default command line */
|
||||
if (*command_line == '\0')
|
||||
strcpy(command_line,CONFIG_KERNEL_COMMAND);
|
||||
#endif
|
||||
/* Keep a copy of command line */
|
||||
*cmdline_p = &command_line[0];
|
||||
memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
|
||||
saved_command_line[COMMAND_LINE_SIZE-1] = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (strlen(*cmdline_p))
|
||||
printk(KERN_DEBUG "Command line: '%s'\n", *cmdline_p);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* give all the memory to the bootmap allocator, tell it to put the
|
||||
* boot mem_map at the start of memory
|
||||
*/
|
||||
bootmap_size = init_bootmem_node(
|
||||
NODE_DATA(0),
|
||||
memory_start >> PAGE_SHIFT, /* map goes here */
|
||||
PAGE_OFFSET >> PAGE_SHIFT, /* 0 on coldfire */
|
||||
memory_end >> PAGE_SHIFT);
|
||||
/*
|
||||
* free the usable memory, we have to make sure we do not free
|
||||
* the bootmem bitmap so we then reserve it after freeing it :-)
|
||||
*/
|
||||
free_bootmem(memory_start, memory_end - memory_start);
|
||||
reserve_bootmem(memory_start, bootmap_size);
|
||||
/*
|
||||
* get kmalloc into gear
|
||||
*/
|
||||
paging_init();
|
||||
h8300_gpio_init();
|
||||
#if defined(CONFIG_H8300_AKI3068NET) && defined(CONFIG_IDE)
|
||||
{
|
||||
#define AREABIT(addr) (1 << (((addr) >> 21) & 7))
|
||||
/* setup BSC */
|
||||
volatile unsigned char *abwcr = (volatile unsigned char *)ABWCR;
|
||||
volatile unsigned char *cscr = (volatile unsigned char *)CSCR;
|
||||
*abwcr &= ~(AREABIT(CONFIG_H8300_IDE_BASE) | AREABIT(CONFIG_H8300_IDE_ALT));
|
||||
*cscr |= (AREABIT(CONFIG_H8300_IDE_BASE) | AREABIT(CONFIG_H8300_IDE_ALT)) | 0x0f;
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
printk(KERN_DEBUG "Done setup_arch\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Get CPU information for use by the procfs.
|
||||
*/
|
||||
|
||||
static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
{
|
||||
char *cpu;
|
||||
int mode;
|
||||
u_long clockfreq;
|
||||
|
||||
cpu = CPU;
|
||||
mode = *(volatile unsigned char *)MDCR & 0x07;
|
||||
|
||||
clockfreq = CONFIG_CPU_CLOCK;
|
||||
|
||||
seq_printf(m, "CPU:\t\t%s (mode:%d)\n"
|
||||
"Clock:\t\t%lu.%1luMHz\n"
|
||||
"BogoMips:\t%lu.%02lu\n"
|
||||
"Calibration:\t%lu loops\n",
|
||||
cpu,mode,
|
||||
clockfreq/1000,clockfreq%1000,
|
||||
(loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
|
||||
(loops_per_jiffy*HZ));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *c_start(struct seq_file *m, loff_t *pos)
|
||||
{
|
||||
return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
|
||||
}
|
||||
|
||||
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
|
||||
{
|
||||
++*pos;
|
||||
return c_start(m, pos);
|
||||
}
|
||||
|
||||
static void c_stop(struct seq_file *m, void *v)
|
||||
{
|
||||
}
|
||||
|
||||
struct seq_operations cpuinfo_op = {
|
||||
.start = c_start,
|
||||
.next = c_next,
|
||||
.stop = c_stop,
|
||||
.show = show_cpuinfo,
|
||||
};
|
||||
552
arch/h8300/kernel/signal.c
Normal file
552
arch/h8300/kernel/signal.c
Normal file
|
|
@ -0,0 +1,552 @@
|
|||
/*
|
||||
* linux/arch/h8300/kernel/signal.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* uClinux H8/300 support by Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
* and David McCullough <davidm@snapgear.com>
|
||||
*
|
||||
* Based on
|
||||
* Linux/m68k by Hamish Macdonald
|
||||
*/
|
||||
|
||||
/*
|
||||
* ++roman (07/09/96): implemented signal stacks (specially for tosemu on
|
||||
* Atari :-) Current limitation: Only one sigstack can be active at one time.
|
||||
* If a second signal with SA_ONSTACK set arrives while working on a sigstack,
|
||||
* SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
|
||||
* signal handlers!
|
||||
*/
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/highuid.h>
|
||||
#include <linux/personality.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/ucontext.h>
|
||||
|
||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||
|
||||
asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
|
||||
|
||||
/*
|
||||
* Atomically swap in the new signal mask, and wait for a signal.
|
||||
*/
|
||||
asmlinkage int do_sigsuspend(struct pt_regs *regs)
|
||||
{
|
||||
old_sigset_t mask = regs->er3;
|
||||
sigset_t saveset;
|
||||
|
||||
mask &= _BLOCKABLE;
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
saveset = current->blocked;
|
||||
siginitset(¤t->blocked, mask);
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
regs->er0 = -EINTR;
|
||||
while (1) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
if (do_signal(regs, &saveset))
|
||||
return -EINTR;
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage int
|
||||
do_rt_sigsuspend(struct pt_regs *regs)
|
||||
{
|
||||
sigset_t *unewset = (sigset_t *)regs->er1;
|
||||
size_t sigsetsize = (size_t)regs->er2;
|
||||
sigset_t saveset, newset;
|
||||
|
||||
/* XXX: Don't preclude handling different sized sigset_t's. */
|
||||
if (sigsetsize != sizeof(sigset_t))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(&newset, unewset, sizeof(newset)))
|
||||
return -EFAULT;
|
||||
sigdelsetmask(&newset, ~_BLOCKABLE);
|
||||
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
saveset = current->blocked;
|
||||
current->blocked = newset;
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
regs->er0 = -EINTR;
|
||||
while (1) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
if (do_signal(regs, &saveset))
|
||||
return -EINTR;
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage int
|
||||
sys_sigaction(int sig, const struct old_sigaction *act,
|
||||
struct old_sigaction *oact)
|
||||
{
|
||||
struct k_sigaction new_ka, old_ka;
|
||||
int ret;
|
||||
|
||||
if (act) {
|
||||
old_sigset_t mask;
|
||||
if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
|
||||
__get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
|
||||
__get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
|
||||
return -EFAULT;
|
||||
__get_user(new_ka.sa.sa_flags, &act->sa_flags);
|
||||
__get_user(mask, &act->sa_mask);
|
||||
siginitset(&new_ka.sa.sa_mask, mask);
|
||||
}
|
||||
|
||||
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
|
||||
|
||||
if (!ret && oact) {
|
||||
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
|
||||
__put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
|
||||
__put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
|
||||
return -EFAULT;
|
||||
__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
|
||||
__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage int
|
||||
sys_sigaltstack(const stack_t *uss, stack_t *uoss)
|
||||
{
|
||||
return do_sigaltstack(uss, uoss, rdusp());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Do a signal return; undo the signal stack.
|
||||
*
|
||||
* Keep the return code on the stack quadword aligned!
|
||||
* That makes the cache flush below easier.
|
||||
*/
|
||||
|
||||
struct sigframe
|
||||
{
|
||||
long dummy_er0;
|
||||
long dummy_vector;
|
||||
#if defined(CONFIG_CPU_H8S)
|
||||
short dummy_exr;
|
||||
#endif
|
||||
long dummy_pc;
|
||||
char *pretcode;
|
||||
unsigned char retcode[8];
|
||||
unsigned long extramask[_NSIG_WORDS-1];
|
||||
struct sigcontext sc;
|
||||
int sig;
|
||||
} __attribute__((aligned(2),packed));
|
||||
|
||||
struct rt_sigframe
|
||||
{
|
||||
long dummy_er0;
|
||||
long dummy_vector;
|
||||
#if defined(CONFIG_CPU_H8S)
|
||||
short dummy_exr;
|
||||
#endif
|
||||
long dummy_pc;
|
||||
char *pretcode;
|
||||
struct siginfo *pinfo;
|
||||
void *puc;
|
||||
unsigned char retcode[8];
|
||||
struct siginfo info;
|
||||
struct ucontext uc;
|
||||
int sig;
|
||||
} __attribute__((aligned(2),packed));
|
||||
|
||||
static inline int
|
||||
restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc,
|
||||
int *pd0)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int ccr;
|
||||
unsigned int usp;
|
||||
unsigned int er0;
|
||||
|
||||
/* Always make any pending restarted system calls return -EINTR */
|
||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
||||
|
||||
#define COPY(r) err |= __get_user(regs->r, &usc->sc_##r) /* restore passed registers */
|
||||
COPY(er1);
|
||||
COPY(er2);
|
||||
COPY(er3);
|
||||
COPY(er5);
|
||||
COPY(pc);
|
||||
ccr = regs->ccr & 0x10;
|
||||
COPY(ccr);
|
||||
#undef COPY
|
||||
regs->ccr &= 0xef;
|
||||
regs->ccr |= ccr;
|
||||
regs->orig_er0 = -1; /* disable syscall checks */
|
||||
err |= __get_user(usp, &usc->sc_usp);
|
||||
wrusp(usp);
|
||||
|
||||
err |= __get_user(er0, &usc->sc_er0);
|
||||
*pd0 = er0;
|
||||
return err;
|
||||
}
|
||||
|
||||
asmlinkage int do_sigreturn(unsigned long __unused,...)
|
||||
{
|
||||
struct pt_regs *regs = (struct pt_regs *) (&__unused - 1);
|
||||
unsigned long usp = rdusp();
|
||||
struct sigframe *frame = (struct sigframe *)(usp - 4);
|
||||
sigset_t set;
|
||||
int er0;
|
||||
|
||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
|
||||
(_NSIG_WORDS > 1 &&
|
||||
__copy_from_user(&set.sig[1], &frame->extramask,
|
||||
sizeof(frame->extramask))))
|
||||
goto badframe;
|
||||
|
||||
sigdelsetmask(&set, ~_BLOCKABLE);
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
current->blocked = set;
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
if (restore_sigcontext(regs, &frame->sc, &er0))
|
||||
goto badframe;
|
||||
return er0;
|
||||
|
||||
badframe:
|
||||
force_sig(SIGSEGV, current);
|
||||
return 0;
|
||||
}
|
||||
|
||||
asmlinkage int do_rt_sigreturn(unsigned long __unused,...)
|
||||
{
|
||||
struct pt_regs *regs = (struct pt_regs *) &__unused;
|
||||
unsigned long usp = rdusp();
|
||||
struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
|
||||
sigset_t set;
|
||||
int er0;
|
||||
|
||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
|
||||
goto badframe;
|
||||
|
||||
sigdelsetmask(&set, ~_BLOCKABLE);
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
current->blocked = set;
|
||||
recalc_sigpending();
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &er0))
|
||||
goto badframe;
|
||||
|
||||
if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT)
|
||||
goto badframe;
|
||||
|
||||
return er0;
|
||||
|
||||
badframe:
|
||||
force_sig(SIGSEGV, current);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
|
||||
unsigned long mask)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
err |= __put_user(regs->er0, &sc->sc_er0);
|
||||
err |= __put_user(regs->er1, &sc->sc_er1);
|
||||
err |= __put_user(regs->er2, &sc->sc_er2);
|
||||
err |= __put_user(regs->er3, &sc->sc_er3);
|
||||
err |= __put_user(regs->er4, &sc->sc_er4);
|
||||
err |= __put_user(regs->er5, &sc->sc_er5);
|
||||
err |= __put_user(regs->er6, &sc->sc_er6);
|
||||
err |= __put_user(rdusp(), &sc->sc_usp);
|
||||
err |= __put_user(regs->pc, &sc->sc_pc);
|
||||
err |= __put_user(regs->ccr, &sc->sc_ccr);
|
||||
err |= __put_user(mask, &sc->sc_mask);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
|
||||
{
|
||||
unsigned long usp;
|
||||
|
||||
/* Default to using normal stack. */
|
||||
usp = rdusp();
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
if (ka->sa.sa_flags & SA_ONSTACK) {
|
||||
if (!on_sig_stack(usp))
|
||||
usp = current->sas_ss_sp + current->sas_ss_size;
|
||||
}
|
||||
return (void *)((usp - frame_size) & -8UL);
|
||||
}
|
||||
|
||||
static void setup_frame (int sig, struct k_sigaction *ka,
|
||||
sigset_t *set, struct pt_regs *regs)
|
||||
{
|
||||
struct sigframe *frame;
|
||||
int err = 0;
|
||||
int usig;
|
||||
unsigned char *ret;
|
||||
|
||||
frame = get_sigframe(ka, regs, sizeof(*frame));
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
|
||||
goto give_sigsegv;
|
||||
|
||||
usig = current_thread_info()->exec_domain
|
||||
&& current_thread_info()->exec_domain->signal_invmap
|
||||
&& sig < 32
|
||||
? current_thread_info()->exec_domain->signal_invmap[sig]
|
||||
: sig;
|
||||
|
||||
err |= __put_user(usig, &frame->sig);
|
||||
if (err)
|
||||
goto give_sigsegv;
|
||||
|
||||
err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
|
||||
if (err)
|
||||
goto give_sigsegv;
|
||||
|
||||
if (_NSIG_WORDS > 1) {
|
||||
err |= copy_to_user(frame->extramask, &set->sig[1],
|
||||
sizeof(frame->extramask));
|
||||
if (err)
|
||||
goto give_sigsegv;
|
||||
}
|
||||
|
||||
ret = frame->retcode;
|
||||
if (ka->sa.sa_flags & SA_RESTORER)
|
||||
ret = (unsigned char *)(ka->sa.sa_restorer);
|
||||
else {
|
||||
/* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
|
||||
err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
|
||||
(unsigned long *)(frame->retcode + 0));
|
||||
err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4));
|
||||
}
|
||||
|
||||
/* Set up to return from userspace. */
|
||||
err |= __put_user(ret, &frame->pretcode);
|
||||
|
||||
if (err)
|
||||
goto give_sigsegv;
|
||||
|
||||
/* Set up registers for signal handler */
|
||||
wrusp ((unsigned long) frame);
|
||||
regs->pc = (unsigned long) ka->sa.sa_handler;
|
||||
regs->er0 = (current_thread_info()->exec_domain
|
||||
&& current_thread_info()->exec_domain->signal_invmap
|
||||
&& sig < 32
|
||||
? current_thread_info()->exec_domain->signal_invmap[sig]
|
||||
: sig);
|
||||
regs->er1 = (unsigned long)&(frame->sc);
|
||||
regs->er5 = current->mm->start_data; /* GOT base */
|
||||
|
||||
return;
|
||||
|
||||
give_sigsegv:
|
||||
force_sigsegv(sig, current);
|
||||
}
|
||||
|
||||
static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
sigset_t *set, struct pt_regs *regs)
|
||||
{
|
||||
struct rt_sigframe *frame;
|
||||
int err = 0;
|
||||
int usig;
|
||||
unsigned char *ret;
|
||||
|
||||
frame = get_sigframe(ka, regs, sizeof(*frame));
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
|
||||
goto give_sigsegv;
|
||||
|
||||
usig = current_thread_info()->exec_domain
|
||||
&& current_thread_info()->exec_domain->signal_invmap
|
||||
&& sig < 32
|
||||
? current_thread_info()->exec_domain->signal_invmap[sig]
|
||||
: sig;
|
||||
|
||||
err |= __put_user(usig, &frame->sig);
|
||||
if (err)
|
||||
goto give_sigsegv;
|
||||
|
||||
err |= __put_user(&frame->info, &frame->pinfo);
|
||||
err |= __put_user(&frame->uc, &frame->puc);
|
||||
err |= copy_siginfo_to_user(&frame->info, info);
|
||||
if (err)
|
||||
goto give_sigsegv;
|
||||
|
||||
/* Create the ucontext. */
|
||||
err |= __put_user(0, &frame->uc.uc_flags);
|
||||
err |= __put_user(0, &frame->uc.uc_link);
|
||||
err |= __put_user((void *)current->sas_ss_sp,
|
||||
&frame->uc.uc_stack.ss_sp);
|
||||
err |= __put_user(sas_ss_flags(rdusp()),
|
||||
&frame->uc.uc_stack.ss_flags);
|
||||
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
|
||||
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
|
||||
err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
|
||||
if (err)
|
||||
goto give_sigsegv;
|
||||
|
||||
/* Set up to return from userspace. */
|
||||
ret = frame->retcode;
|
||||
if (ka->sa.sa_flags & SA_RESTORER)
|
||||
ret = (unsigned char *)(ka->sa.sa_restorer);
|
||||
else {
|
||||
/* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
|
||||
err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
|
||||
(unsigned long *)(frame->retcode + 0));
|
||||
err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4));
|
||||
}
|
||||
err |= __put_user(ret, &frame->pretcode);
|
||||
|
||||
if (err)
|
||||
goto give_sigsegv;
|
||||
|
||||
/* Set up registers for signal handler */
|
||||
wrusp ((unsigned long) frame);
|
||||
regs->pc = (unsigned long) ka->sa.sa_handler;
|
||||
regs->er0 = (current_thread_info()->exec_domain
|
||||
&& current_thread_info()->exec_domain->signal_invmap
|
||||
&& sig < 32
|
||||
? current_thread_info()->exec_domain->signal_invmap[sig]
|
||||
: sig);
|
||||
regs->er1 = (unsigned long)&(frame->info);
|
||||
regs->er2 = (unsigned long)&frame->uc;
|
||||
regs->er5 = current->mm->start_data; /* GOT base */
|
||||
|
||||
return;
|
||||
|
||||
give_sigsegv:
|
||||
force_sigsegv(sig, current);
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, we're invoking a handler
|
||||
*/
|
||||
static void
|
||||
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
||||
sigset_t *oldset, struct pt_regs * regs)
|
||||
{
|
||||
/* are we from a system call? */
|
||||
if (regs->orig_er0 >= 0) {
|
||||
switch (regs->er0) {
|
||||
case -ERESTART_RESTARTBLOCK:
|
||||
case -ERESTARTNOHAND:
|
||||
regs->er0 = -EINTR;
|
||||
break;
|
||||
|
||||
case -ERESTARTSYS:
|
||||
if (!(ka->sa.sa_flags & SA_RESTART)) {
|
||||
regs->er0 = -EINTR;
|
||||
break;
|
||||
}
|
||||
/* fallthrough */
|
||||
case -ERESTARTNOINTR:
|
||||
regs->er0 = regs->orig_er0;
|
||||
regs->pc -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* set up the stack frame */
|
||||
if (ka->sa.sa_flags & SA_SIGINFO)
|
||||
setup_rt_frame(sig, ka, info, oldset, regs);
|
||||
else
|
||||
setup_frame(sig, ka, oldset, regs);
|
||||
|
||||
if (!(ka->sa.sa_flags & SA_NODEFER)) {
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
|
||||
sigaddset(¤t->blocked,sig);
|
||||
recalc_sigpending();
|
||||
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.
|
||||
*/
|
||||
asmlinkage 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 ((regs->ccr & 0x10))
|
||||
return 1;
|
||||
|
||||
if (current->flags & PF_FREEZE) {
|
||||
refrigerator(0);
|
||||
goto no_signal;
|
||||
}
|
||||
|
||||
current->thread.esp0 = (unsigned long) regs;
|
||||
|
||||
if (!oldset)
|
||||
oldset = ¤t->blocked;
|
||||
|
||||
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
|
||||
if (signr > 0) {
|
||||
/* Whee! Actually deliver the signal. */
|
||||
handle_signal(signr, &info, &ka, oldset, regs);
|
||||
return 1;
|
||||
}
|
||||
no_signal:
|
||||
/* Did we come from a system call? */
|
||||
if (regs->orig_er0 >= 0) {
|
||||
/* Restart the system call - no handlers present */
|
||||
if (regs->er0 == -ERESTARTNOHAND ||
|
||||
regs->er0 == -ERESTARTSYS ||
|
||||
regs->er0 == -ERESTARTNOINTR) {
|
||||
regs->er0 = regs->orig_er0;
|
||||
regs->pc -= 2;
|
||||
}
|
||||
if (regs->er0 == -ERESTART_RESTARTBLOCK){
|
||||
regs->er0 = __NR_restart_syscall;
|
||||
regs->pc -= 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
282
arch/h8300/kernel/sys_h8300.c
Normal file
282
arch/h8300/kernel/sys_h8300.c
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* linux/arch/h8300/kernel/sys_h8300.c
|
||||
*
|
||||
* This file contains various random system calls that
|
||||
* have a non-standard calling sequence on the H8/300
|
||||
* platform.
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/sem.h>
|
||||
#include <linux/msg.h>
|
||||
#include <linux/shm.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/utsname.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/cachectl.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/ipc.h>
|
||||
|
||||
/*
|
||||
* sys_pipe() is the normal C calling standard for creating
|
||||
* a pipe. It's not the way unix traditionally does this, though.
|
||||
*/
|
||||
asmlinkage int sys_pipe(unsigned long * fildes)
|
||||
{
|
||||
int fd[2];
|
||||
int error;
|
||||
|
||||
error = do_pipe(fd);
|
||||
if (!error) {
|
||||
if (copy_to_user(fildes, fd, 2*sizeof(int)))
|
||||
error = -EFAULT;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/* common code for old and new mmaps */
|
||||
static inline long do_mmap2(
|
||||
unsigned long addr, unsigned long len,
|
||||
unsigned long prot, unsigned long flags,
|
||||
unsigned long fd, unsigned long pgoff)
|
||||
{
|
||||
int error = -EBADF;
|
||||
struct file * file = NULL;
|
||||
|
||||
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
|
||||
if (!(flags & MAP_ANONYMOUS)) {
|
||||
file = fget(fd);
|
||||
if (!file)
|
||||
goto out;
|
||||
}
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
|
||||
if (file)
|
||||
fput(file);
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
|
||||
unsigned long prot, unsigned long flags,
|
||||
unsigned long fd, unsigned long pgoff)
|
||||
{
|
||||
return do_mmap2(addr, len, prot, flags, fd, pgoff);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the select(nd, in, out, ex, tv) and mmap() system
|
||||
* calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
|
||||
* handle more than 4 system call parameters, so these system calls
|
||||
* used a memory block for parameter passing..
|
||||
*/
|
||||
|
||||
struct mmap_arg_struct {
|
||||
unsigned long addr;
|
||||
unsigned long len;
|
||||
unsigned long prot;
|
||||
unsigned long flags;
|
||||
unsigned long fd;
|
||||
unsigned long offset;
|
||||
};
|
||||
|
||||
asmlinkage int old_mmap(struct mmap_arg_struct *arg)
|
||||
{
|
||||
struct mmap_arg_struct a;
|
||||
int error = -EFAULT;
|
||||
|
||||
if (copy_from_user(&a, arg, sizeof(a)))
|
||||
goto out;
|
||||
|
||||
error = -EINVAL;
|
||||
if (a.offset & ~PAGE_MASK)
|
||||
goto out;
|
||||
|
||||
a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
|
||||
|
||||
error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if 0 /* DAVIDM - do we want this */
|
||||
struct mmap_arg_struct64 {
|
||||
__u32 addr;
|
||||
__u32 len;
|
||||
__u32 prot;
|
||||
__u32 flags;
|
||||
__u64 offset; /* 64 bits */
|
||||
__u32 fd;
|
||||
};
|
||||
|
||||
asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
|
||||
{
|
||||
int error = -EFAULT;
|
||||
struct file * file = NULL;
|
||||
struct mmap_arg_struct64 a;
|
||||
unsigned long pgoff;
|
||||
|
||||
if (copy_from_user(&a, arg, sizeof(a)))
|
||||
return -EFAULT;
|
||||
|
||||
if ((long)a.offset & ~PAGE_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
pgoff = a.offset >> PAGE_SHIFT;
|
||||
if ((a.offset >> PAGE_SHIFT) != pgoff)
|
||||
return -EINVAL;
|
||||
|
||||
if (!(a.flags & MAP_ANONYMOUS)) {
|
||||
error = -EBADF;
|
||||
file = fget(a.fd);
|
||||
if (!file)
|
||||
goto out;
|
||||
}
|
||||
a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
if (file)
|
||||
fput(file);
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct sel_arg_struct {
|
||||
unsigned long n;
|
||||
fd_set *inp, *outp, *exp;
|
||||
struct timeval *tvp;
|
||||
};
|
||||
|
||||
asmlinkage int old_select(struct sel_arg_struct *arg)
|
||||
{
|
||||
struct sel_arg_struct a;
|
||||
|
||||
if (copy_from_user(&a, arg, sizeof(a)))
|
||||
return -EFAULT;
|
||||
/* sys_select() does the appropriate kernel locking */
|
||||
return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
|
||||
}
|
||||
|
||||
/*
|
||||
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
|
||||
*
|
||||
* This is really horribly ugly.
|
||||
*/
|
||||
asmlinkage int sys_ipc (uint call, int first, int second,
|
||||
int third, void *ptr, long fifth)
|
||||
{
|
||||
int version, ret;
|
||||
|
||||
version = call >> 16; /* hack for backward compatibility */
|
||||
call &= 0xffff;
|
||||
|
||||
if (call <= SEMCTL)
|
||||
switch (call) {
|
||||
case SEMOP:
|
||||
return sys_semop (first, (struct sembuf *)ptr, second);
|
||||
case SEMGET:
|
||||
return sys_semget (first, second, third);
|
||||
case SEMCTL: {
|
||||
union semun fourth;
|
||||
if (!ptr)
|
||||
return -EINVAL;
|
||||
if (get_user(fourth.__pad, (void **) ptr))
|
||||
return -EFAULT;
|
||||
return sys_semctl (first, second, third, fourth);
|
||||
}
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
if (call <= MSGCTL)
|
||||
switch (call) {
|
||||
case MSGSND:
|
||||
return sys_msgsnd (first, (struct msgbuf *) ptr,
|
||||
second, third);
|
||||
case MSGRCV:
|
||||
switch (version) {
|
||||
case 0: {
|
||||
struct ipc_kludge tmp;
|
||||
if (!ptr)
|
||||
return -EINVAL;
|
||||
if (copy_from_user (&tmp,
|
||||
(struct ipc_kludge *)ptr,
|
||||
sizeof (tmp)))
|
||||
return -EFAULT;
|
||||
return sys_msgrcv (first, tmp.msgp, second,
|
||||
tmp.msgtyp, third);
|
||||
}
|
||||
default:
|
||||
return sys_msgrcv (first,
|
||||
(struct msgbuf *) ptr,
|
||||
second, fifth, third);
|
||||
}
|
||||
case MSGGET:
|
||||
return sys_msgget ((key_t) first, second);
|
||||
case MSGCTL:
|
||||
return sys_msgctl (first, second,
|
||||
(struct msqid_ds *) ptr);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
if (call <= SHMCTL)
|
||||
switch (call) {
|
||||
case SHMAT:
|
||||
switch (version) {
|
||||
default: {
|
||||
ulong raddr;
|
||||
ret = do_shmat (first, (char *) ptr,
|
||||
second, &raddr);
|
||||
if (ret)
|
||||
return ret;
|
||||
return put_user (raddr, (ulong *) third);
|
||||
}
|
||||
}
|
||||
case SHMDT:
|
||||
return sys_shmdt ((char *)ptr);
|
||||
case SHMGET:
|
||||
return sys_shmget (first, second, third);
|
||||
case SHMCTL:
|
||||
return sys_shmctl (first, second,
|
||||
(struct shmid_ds *) ptr);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* sys_cacheflush -- no support. */
|
||||
asmlinkage int
|
||||
sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
asmlinkage int sys_getpagesize(void)
|
||||
{
|
||||
return PAGE_SIZE;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SYSCALL_PRINT)
|
||||
asmlinkage void syscall_print(void *dummy,...)
|
||||
{
|
||||
struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4);
|
||||
printk("call %06lx:%ld 1:%08lx,2:%08lx,3:%08lx,ret:%08lx\n",
|
||||
((regs->pc)&0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0);
|
||||
}
|
||||
#endif
|
||||
340
arch/h8300/kernel/syscalls.S
Normal file
340
arch/h8300/kernel/syscalls.S
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
/* Systemcall Entry Table */
|
||||
#include <linux/config.h>
|
||||
#include <linux/sys.h>
|
||||
#include <asm/linkage.h>
|
||||
#include <asm/unistd.h>
|
||||
|
||||
.globl SYMBOL_NAME(sys_call_table)
|
||||
|
||||
#if defined(CONFIG_CPU_H8300H)
|
||||
.h8300h
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_H8S)
|
||||
.h8300s
|
||||
#endif
|
||||
.section .text
|
||||
.align 2
|
||||
SYMBOL_NAME_LABEL(sys_call_table)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/
|
||||
.long SYMBOL_NAME(sys_exit)
|
||||
.long SYMBOL_NAME(sys_fork)
|
||||
.long SYMBOL_NAME(sys_read)
|
||||
.long SYMBOL_NAME(sys_write)
|
||||
.long SYMBOL_NAME(sys_open) /* 5 */
|
||||
.long SYMBOL_NAME(sys_close)
|
||||
.long SYMBOL_NAME(sys_waitpid)
|
||||
.long SYMBOL_NAME(sys_creat)
|
||||
.long SYMBOL_NAME(sys_link)
|
||||
.long SYMBOL_NAME(sys_unlink) /* 10 */
|
||||
.long SYMBOL_NAME(sys_execve)
|
||||
.long SYMBOL_NAME(sys_chdir)
|
||||
.long SYMBOL_NAME(sys_time)
|
||||
.long SYMBOL_NAME(sys_mknod)
|
||||
.long SYMBOL_NAME(sys_chmod) /* 15 */
|
||||
.long SYMBOL_NAME(sys_chown16)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* old break syscall holder */
|
||||
.long SYMBOL_NAME(sys_stat)
|
||||
.long SYMBOL_NAME(sys_lseek)
|
||||
.long SYMBOL_NAME(sys_getpid) /* 20 */
|
||||
.long SYMBOL_NAME(sys_mount)
|
||||
.long SYMBOL_NAME(sys_oldumount)
|
||||
.long SYMBOL_NAME(sys_setuid16)
|
||||
.long SYMBOL_NAME(sys_getuid16)
|
||||
.long SYMBOL_NAME(sys_stime) /* 25 */
|
||||
.long SYMBOL_NAME(sys_ptrace)
|
||||
.long SYMBOL_NAME(sys_alarm)
|
||||
.long SYMBOL_NAME(sys_fstat)
|
||||
.long SYMBOL_NAME(sys_pause)
|
||||
.long SYMBOL_NAME(sys_utime) /* 30 */
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* old stty syscall holder */
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* old gtty syscall holder */
|
||||
.long SYMBOL_NAME(sys_access)
|
||||
.long SYMBOL_NAME(sys_nice)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* 35 */ /* old ftime syscall holder */
|
||||
.long SYMBOL_NAME(sys_sync)
|
||||
.long SYMBOL_NAME(sys_kill)
|
||||
.long SYMBOL_NAME(sys_rename)
|
||||
.long SYMBOL_NAME(sys_mkdir)
|
||||
.long SYMBOL_NAME(sys_rmdir) /* 40 */
|
||||
.long SYMBOL_NAME(sys_dup)
|
||||
.long SYMBOL_NAME(sys_pipe)
|
||||
.long SYMBOL_NAME(sys_times)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* old prof syscall holder */
|
||||
.long SYMBOL_NAME(sys_brk) /* 45 */
|
||||
.long SYMBOL_NAME(sys_setgid16)
|
||||
.long SYMBOL_NAME(sys_getgid16)
|
||||
.long SYMBOL_NAME(sys_signal)
|
||||
.long SYMBOL_NAME(sys_geteuid16)
|
||||
.long SYMBOL_NAME(sys_getegid16) /* 50 */
|
||||
.long SYMBOL_NAME(sys_acct)
|
||||
.long SYMBOL_NAME(sys_umount) /* recycled never used phys() */
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* old lock syscall holder */
|
||||
.long SYMBOL_NAME(sys_ioctl)
|
||||
.long SYMBOL_NAME(sys_fcntl) /* 55 */
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* old mpx syscall holder */
|
||||
.long SYMBOL_NAME(sys_setpgid)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* old ulimit syscall holder */
|
||||
.long SYMBOL_NAME(sys_ni_syscall)
|
||||
.long SYMBOL_NAME(sys_umask) /* 60 */
|
||||
.long SYMBOL_NAME(sys_chroot)
|
||||
.long SYMBOL_NAME(sys_ustat)
|
||||
.long SYMBOL_NAME(sys_dup2)
|
||||
.long SYMBOL_NAME(sys_getppid)
|
||||
.long SYMBOL_NAME(sys_getpgrp) /* 65 */
|
||||
.long SYMBOL_NAME(sys_setsid)
|
||||
.long SYMBOL_NAME(sys_sigaction)
|
||||
.long SYMBOL_NAME(sys_sgetmask)
|
||||
.long SYMBOL_NAME(sys_ssetmask)
|
||||
.long SYMBOL_NAME(sys_setreuid16) /* 70 */
|
||||
.long SYMBOL_NAME(sys_setregid16)
|
||||
.long SYMBOL_NAME(sys_sigsuspend)
|
||||
.long SYMBOL_NAME(sys_sigpending)
|
||||
.long SYMBOL_NAME(sys_sethostname)
|
||||
.long SYMBOL_NAME(sys_setrlimit) /* 75 */
|
||||
.long SYMBOL_NAME(sys_old_getrlimit)
|
||||
.long SYMBOL_NAME(sys_getrusage)
|
||||
.long SYMBOL_NAME(sys_gettimeofday)
|
||||
.long SYMBOL_NAME(sys_settimeofday)
|
||||
.long SYMBOL_NAME(sys_getgroups16) /* 80 */
|
||||
.long SYMBOL_NAME(sys_setgroups16)
|
||||
.long SYMBOL_NAME(old_select)
|
||||
.long SYMBOL_NAME(sys_symlink)
|
||||
.long SYMBOL_NAME(sys_lstat)
|
||||
.long SYMBOL_NAME(sys_readlink) /* 85 */
|
||||
.long SYMBOL_NAME(sys_uselib)
|
||||
.long SYMBOL_NAME(sys_swapon)
|
||||
.long SYMBOL_NAME(sys_reboot)
|
||||
.long SYMBOL_NAME(old_readdir)
|
||||
.long SYMBOL_NAME(old_mmap) /* 90 */
|
||||
.long SYMBOL_NAME(sys_munmap)
|
||||
.long SYMBOL_NAME(sys_truncate)
|
||||
.long SYMBOL_NAME(sys_ftruncate)
|
||||
.long SYMBOL_NAME(sys_fchmod)
|
||||
.long SYMBOL_NAME(sys_fchown16) /* 95 */
|
||||
.long SYMBOL_NAME(sys_getpriority)
|
||||
.long SYMBOL_NAME(sys_setpriority)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* old profil syscall holder */
|
||||
.long SYMBOL_NAME(sys_statfs)
|
||||
.long SYMBOL_NAME(sys_fstatfs) /* 100 */
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* ioperm for i386 */
|
||||
.long SYMBOL_NAME(sys_socketcall)
|
||||
.long SYMBOL_NAME(sys_syslog)
|
||||
.long SYMBOL_NAME(sys_setitimer)
|
||||
.long SYMBOL_NAME(sys_getitimer) /* 105 */
|
||||
.long SYMBOL_NAME(sys_newstat)
|
||||
.long SYMBOL_NAME(sys_newlstat)
|
||||
.long SYMBOL_NAME(sys_newfstat)
|
||||
.long SYMBOL_NAME(sys_ni_syscall)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* iopl for i386 */ /* 110 */
|
||||
.long SYMBOL_NAME(sys_vhangup)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* obsolete idle() syscall */
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* vm86old for i386 */
|
||||
.long SYMBOL_NAME(sys_wait4)
|
||||
.long SYMBOL_NAME(sys_swapoff) /* 115 */
|
||||
.long SYMBOL_NAME(sys_sysinfo)
|
||||
.long SYMBOL_NAME(sys_ipc)
|
||||
.long SYMBOL_NAME(sys_fsync)
|
||||
.long SYMBOL_NAME(sys_sigreturn)
|
||||
.long SYMBOL_NAME(sys_clone) /* 120 */
|
||||
.long SYMBOL_NAME(sys_setdomainname)
|
||||
.long SYMBOL_NAME(sys_newuname)
|
||||
.long SYMBOL_NAME(sys_cacheflush) /* modify_ldt for i386 */
|
||||
.long SYMBOL_NAME(sys_adjtimex)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* 125 sys_mprotect */
|
||||
.long SYMBOL_NAME(sys_sigprocmask)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* sys_create_module */
|
||||
.long SYMBOL_NAME(sys_init_module)
|
||||
.long SYMBOL_NAME(sys_delete_module)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* 130 sys_get_kernel_syms */
|
||||
.long SYMBOL_NAME(sys_quotactl)
|
||||
.long SYMBOL_NAME(sys_getpgid)
|
||||
.long SYMBOL_NAME(sys_fchdir)
|
||||
.long SYMBOL_NAME(sys_bdflush)
|
||||
.long SYMBOL_NAME(sys_sysfs) /* 135 */
|
||||
.long SYMBOL_NAME(sys_personality)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* for afs_syscall */
|
||||
.long SYMBOL_NAME(sys_setfsuid16)
|
||||
.long SYMBOL_NAME(sys_setfsgid16)
|
||||
.long SYMBOL_NAME(sys_llseek) /* 140 */
|
||||
.long SYMBOL_NAME(sys_getdents)
|
||||
.long SYMBOL_NAME(sys_select)
|
||||
.long SYMBOL_NAME(sys_flock)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* sys_msync */
|
||||
.long SYMBOL_NAME(sys_readv) /* 145 */
|
||||
.long SYMBOL_NAME(sys_writev)
|
||||
.long SYMBOL_NAME(sys_getsid)
|
||||
.long SYMBOL_NAME(sys_fdatasync)
|
||||
.long SYMBOL_NAME(sys_sysctl)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* 150 sys_mlock */
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* sys_munlock */
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* sys_mlockall */
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* sys_munlockall */
|
||||
.long SYMBOL_NAME(sys_sched_setparam)
|
||||
.long SYMBOL_NAME(sys_sched_getparam) /* 155 */
|
||||
.long SYMBOL_NAME(sys_sched_setscheduler)
|
||||
.long SYMBOL_NAME(sys_sched_getscheduler)
|
||||
.long SYMBOL_NAME(sys_sched_yield)
|
||||
.long SYMBOL_NAME(sys_sched_get_priority_max)
|
||||
.long SYMBOL_NAME(sys_sched_get_priority_min) /* 160 */
|
||||
.long SYMBOL_NAME(sys_sched_rr_get_interval)
|
||||
.long SYMBOL_NAME(sys_nanosleep)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* sys_mremap */
|
||||
.long SYMBOL_NAME(sys_setresuid16)
|
||||
.long SYMBOL_NAME(sys_getresuid16) /* 165 */
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* for vm86 */
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* sys_query_module */
|
||||
.long SYMBOL_NAME(sys_poll)
|
||||
.long SYMBOL_NAME(sys_nfsservctl)
|
||||
.long SYMBOL_NAME(sys_setresgid16) /* 170 */
|
||||
.long SYMBOL_NAME(sys_getresgid16)
|
||||
.long SYMBOL_NAME(sys_prctl)
|
||||
.long SYMBOL_NAME(sys_rt_sigreturn)
|
||||
.long SYMBOL_NAME(sys_rt_sigaction)
|
||||
.long SYMBOL_NAME(sys_rt_sigprocmask) /* 175 */
|
||||
.long SYMBOL_NAME(sys_rt_sigpending)
|
||||
.long SYMBOL_NAME(sys_rt_sigtimedwait)
|
||||
.long SYMBOL_NAME(sys_rt_sigqueueinfo)
|
||||
.long SYMBOL_NAME(sys_rt_sigsuspend)
|
||||
.long SYMBOL_NAME(sys_pread64) /* 180 */
|
||||
.long SYMBOL_NAME(sys_pwrite64)
|
||||
.long SYMBOL_NAME(sys_lchown16);
|
||||
.long SYMBOL_NAME(sys_getcwd)
|
||||
.long SYMBOL_NAME(sys_capget)
|
||||
.long SYMBOL_NAME(sys_capset) /* 185 */
|
||||
.long SYMBOL_NAME(sys_sigaltstack)
|
||||
.long SYMBOL_NAME(sys_sendfile)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
|
||||
.long SYMBOL_NAME(sys_vfork) /* 190 */
|
||||
.long SYMBOL_NAME(sys_getrlimit)
|
||||
.long SYMBOL_NAME(sys_mmap2)
|
||||
.long SYMBOL_NAME(sys_truncate64)
|
||||
.long SYMBOL_NAME(sys_ftruncate64)
|
||||
.long SYMBOL_NAME(sys_stat64) /* 195 */
|
||||
.long SYMBOL_NAME(sys_lstat64)
|
||||
.long SYMBOL_NAME(sys_fstat64)
|
||||
.long SYMBOL_NAME(sys_chown)
|
||||
.long SYMBOL_NAME(sys_getuid)
|
||||
.long SYMBOL_NAME(sys_getgid) /* 200 */
|
||||
.long SYMBOL_NAME(sys_geteuid)
|
||||
.long SYMBOL_NAME(sys_getegid)
|
||||
.long SYMBOL_NAME(sys_setreuid)
|
||||
.long SYMBOL_NAME(sys_setregid)
|
||||
.long SYMBOL_NAME(sys_getgroups) /* 205 */
|
||||
.long SYMBOL_NAME(sys_setgroups)
|
||||
.long SYMBOL_NAME(sys_fchown)
|
||||
.long SYMBOL_NAME(sys_setresuid)
|
||||
.long SYMBOL_NAME(sys_getresuid)
|
||||
.long SYMBOL_NAME(sys_setresgid) /* 210 */
|
||||
.long SYMBOL_NAME(sys_getresgid)
|
||||
.long SYMBOL_NAME(sys_lchown)
|
||||
.long SYMBOL_NAME(sys_setuid)
|
||||
.long SYMBOL_NAME(sys_setgid)
|
||||
.long SYMBOL_NAME(sys_setfsuid) /* 215 */
|
||||
.long SYMBOL_NAME(sys_setfsgid)
|
||||
.long SYMBOL_NAME(sys_pivot_root)
|
||||
.long SYMBOL_NAME(sys_ni_syscall)
|
||||
.long SYMBOL_NAME(sys_ni_syscall)
|
||||
.long SYMBOL_NAME(sys_getdents64) /* 220 */
|
||||
.long SYMBOL_NAME(sys_fcntl64)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* reserved for TUX */
|
||||
.long SYMBOL_NAME(sys_ni_syscall)
|
||||
.long SYMBOL_NAME(sys_gettid)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* 225 */ /* sys_readahead */
|
||||
.long SYMBOL_NAME(sys_setxattr)
|
||||
.long SYMBOL_NAME(sys_lsetxattr)
|
||||
.long SYMBOL_NAME(sys_fsetxattr)
|
||||
.long SYMBOL_NAME(sys_getxattr)
|
||||
.long SYMBOL_NAME(sys_lgetxattr) /* 230 */
|
||||
.long SYMBOL_NAME(sys_fgetxattr)
|
||||
.long SYMBOL_NAME(sys_listxattr)
|
||||
.long SYMBOL_NAME(sys_llistxattr)
|
||||
.long SYMBOL_NAME(sys_flistxattr)
|
||||
.long SYMBOL_NAME(sys_removexattr) /* 235 */
|
||||
.long SYMBOL_NAME(sys_lremovexattr)
|
||||
.long SYMBOL_NAME(sys_fremovexattr)
|
||||
.long SYMBOL_NAME(sys_tkill)
|
||||
.long SYMBOL_NAME(sys_sendfile64)
|
||||
.long SYMBOL_NAME(sys_futex) /* 240 */
|
||||
.long SYMBOL_NAME(sys_sched_setaffinity)
|
||||
.long SYMBOL_NAME(sys_sched_getaffinity)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* sys_set_thread_area */
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* sys_get_thread_area */
|
||||
.long SYMBOL_NAME(sys_io_setup) /* 245 */
|
||||
.long SYMBOL_NAME(sys_io_destroy)
|
||||
.long SYMBOL_NAME(sys_io_getevents)
|
||||
.long SYMBOL_NAME(sys_io_submit)
|
||||
.long SYMBOL_NAME(sys_io_cancel)
|
||||
.long SYMBOL_NAME(sys_fadvise64) /* 250 */
|
||||
.long SYMBOL_NAME(sys_ni_syscall)
|
||||
.long SYMBOL_NAME(sys_exit_group)
|
||||
.long SYMBOL_NAME(sys_lookup_dcookie)
|
||||
.long SYMBOL_NAME(sys_epoll_create)
|
||||
.long SYMBOL_NAME(sys_epoll_ctl) /* 255 */
|
||||
.long SYMBOL_NAME(sys_epoll_wait)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* sys_remap_file_pages */
|
||||
.long SYMBOL_NAME(sys_set_tid_address)
|
||||
.long SYMBOL_NAME(sys_timer_create)
|
||||
.long SYMBOL_NAME(sys_timer_settime) /* 260 */
|
||||
.long SYMBOL_NAME(sys_timer_gettime)
|
||||
.long SYMBOL_NAME(sys_timer_getoverrun)
|
||||
.long SYMBOL_NAME(sys_timer_delete)
|
||||
.long SYMBOL_NAME(sys_clock_settime)
|
||||
.long SYMBOL_NAME(sys_clock_gettime) /* 265 */
|
||||
.long SYMBOL_NAME(sys_clock_getres)
|
||||
.long SYMBOL_NAME(sys_clock_nanosleep)
|
||||
.long SYMBOL_NAME(sys_statfs64)
|
||||
.long SYMBOL_NAME(sys_fstatfs64)
|
||||
.long SYMBOL_NAME(sys_tgkill) /* 270 */
|
||||
.long SYMBOL_NAME(sys_utimes)
|
||||
.long SYMBOL_NAME(sys_fadvise64_64)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* sys_vserver */
|
||||
.long SYMBOL_NAME(sys_mbind)
|
||||
.long SYMBOL_NAME(sys_get_mempolicy)
|
||||
.long SYMBOL_NAME(sys_set_mempolicy)
|
||||
.long SYMBOL_NAME(sys_mq_open)
|
||||
.long SYMBOL_NAME(sys_mq_unlink)
|
||||
.long SYMBOL_NAME(sys_mq_timedsend)
|
||||
.long SYMBOL_NAME(sys_mq_timedreceive) /* 280 */
|
||||
.long SYMBOL_NAME(sys_mq_notify)
|
||||
.long SYMBOL_NAME(sys_mq_getsetattr)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* reserved for kexec */
|
||||
.long SYMBOL_NAME(sys_waitid)
|
||||
.long SYMBOL_NAME(sys_ni_syscall) /* 285 */ /* available */
|
||||
.long SYMBOL_NAME(sys_add_key)
|
||||
.long SYMBOL_NAME(sys_request_key)
|
||||
.long SYMBOL_NAME(sys_keyctl)
|
||||
|
||||
.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
|
||||
.long SYMBOL_NAME(sys_ni_syscall)
|
||||
.endr
|
||||
|
||||
.macro call_sp addr
|
||||
mov.l #SYMBOL_NAME(\addr),er6
|
||||
bra SYMBOL_NAME(syscall_trampoline):8
|
||||
.endm
|
||||
|
||||
SYMBOL_NAME_LABEL(sys_clone)
|
||||
call_sp h8300_clone
|
||||
|
||||
SYMBOL_NAME_LABEL(sys_sigsuspend)
|
||||
call_sp do_sigsuspend
|
||||
|
||||
SYMBOL_NAME_LABEL(sys_rt_sigsuspend)
|
||||
call_sp do_rt_sigsuspend
|
||||
|
||||
SYMBOL_NAME_LABEL(sys_sigreturn)
|
||||
call_sp do_sigreturn
|
||||
|
||||
SYMBOL_NAME_LABEL(sys_rt_sigreturn)
|
||||
call_sp do_rt_sigreturn
|
||||
|
||||
SYMBOL_NAME_LABEL(sys_fork)
|
||||
call_sp h8300_fork
|
||||
|
||||
SYMBOL_NAME_LABEL(sys_vfork)
|
||||
call_sp h8300_vfork
|
||||
|
||||
SYMBOL_NAME_LABEL(syscall_trampoline)
|
||||
mov.l sp,er0
|
||||
jmp @er6
|
||||
134
arch/h8300/kernel/time.c
Normal file
134
arch/h8300/kernel/time.c
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* linux/arch/h8300/kernel/time.c
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Copied/hacked from:
|
||||
*
|
||||
* linux/arch/m68k/kernel/time.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
|
||||
*
|
||||
* 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/config.h> /* CONFIG_HEARTBEAT */
|
||||
#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/timex.h>
|
||||
#include <linux/profile.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/target_time.h>
|
||||
|
||||
#define TICK_SIZE (tick_nsec / 1000)
|
||||
|
||||
u64 jiffies_64;
|
||||
|
||||
EXPORT_SYMBOL(jiffies_64);
|
||||
|
||||
/*
|
||||
* timer_interrupt() needs to keep up the real-time clock,
|
||||
* as well as call the "do_timer()" routine every clocktick
|
||||
*/
|
||||
static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
|
||||
{
|
||||
/* may need to kick the hardware timer */
|
||||
platform_timer_eoi();
|
||||
|
||||
do_timer(regs);
|
||||
#ifndef CONFIG_SMP
|
||||
update_process_times(user_mode(regs));
|
||||
#endif
|
||||
profile_tick(CPU_PROFILING, regs);
|
||||
}
|
||||
|
||||
void time_init(void)
|
||||
{
|
||||
unsigned int year, mon, day, hour, min, sec;
|
||||
|
||||
/* FIX by dqg : Set to zero for platforms that don't have tod */
|
||||
/* without this time is undefined and can overflow time_t, causing */
|
||||
/* very stange errors */
|
||||
year = 1980;
|
||||
mon = day = 1;
|
||||
hour = min = sec = 0;
|
||||
platform_gettod (&year, &mon, &day, &hour, &min, &sec);
|
||||
|
||||
if ((year += 1900) < 1970)
|
||||
year += 100;
|
||||
xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
|
||||
xtime.tv_nsec = 0;
|
||||
|
||||
platform_timer_setup(timer_interrupt);
|
||||
}
|
||||
|
||||
/*
|
||||
* This version of gettimeofday has near microsecond resolution.
|
||||
*/
|
||||
void do_gettimeofday(struct timeval *tv)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long usec, sec;
|
||||
|
||||
read_lock_irqsave(&xtime_lock, flags);
|
||||
usec = 0;
|
||||
sec = xtime.tv_sec;
|
||||
usec += (xtime.tv_nsec / 1000);
|
||||
read_unlock_irqrestore(&xtime_lock, flags);
|
||||
|
||||
while (usec >= 1000000) {
|
||||
usec -= 1000000;
|
||||
sec++;
|
||||
}
|
||||
|
||||
tv->tv_sec = sec;
|
||||
tv->tv_usec = usec;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(do_gettimeofday);
|
||||
|
||||
int do_settimeofday(struct timespec *tv)
|
||||
{
|
||||
if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
|
||||
return -EINVAL;
|
||||
|
||||
write_lock_irq(&xtime_lock);
|
||||
/* This is revolting. We need to set the xtime.tv_usec
|
||||
* correctly. However, the value in this location is
|
||||
* is value at the last tick.
|
||||
* Discover what correction gettimeofday
|
||||
* would have done, and then undo it!
|
||||
*/
|
||||
while (tv->tv_nsec < 0) {
|
||||
tv->tv_nsec += NSEC_PER_SEC;
|
||||
tv->tv_sec--;
|
||||
}
|
||||
|
||||
xtime.tv_sec = tv->tv_sec;
|
||||
xtime.tv_nsec = tv->tv_nsec;
|
||||
time_adjust = 0; /* stop active adjtime() */
|
||||
time_status |= STA_UNSYNC;
|
||||
time_maxerror = NTP_PHASE_LIMIT;
|
||||
time_esterror = NTP_PHASE_LIMIT;
|
||||
write_sequnlock_irq(&xtime_lock);
|
||||
clock_was_set();
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(do_settimeofday);
|
||||
|
||||
unsigned long long sched_clock(void)
|
||||
{
|
||||
return (unsigned long long)jiffies * (1000000000 / HZ);
|
||||
|
||||
}
|
||||
169
arch/h8300/kernel/traps.c
Normal file
169
arch/h8300/kernel/traps.c
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* linux/arch/h8300/boot/traps.c -- general exception handling code
|
||||
* H8/300 support Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Cloned from Linux/m68k.
|
||||
*
|
||||
* No original Copyright holder listed,
|
||||
* Probabily original (C) Roman Zippel (assigned DJD, 1999)
|
||||
*
|
||||
* Copyright 1999-2000 D. Jeff Dionne, <jeff@rt-control.com>
|
||||
*
|
||||
* 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/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/gpio.h>
|
||||
|
||||
/*
|
||||
* this must be called very early as the kernel might
|
||||
* use some instruction that are emulated on the 060
|
||||
*/
|
||||
|
||||
void __init base_trap_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void __init trap_init (void)
|
||||
{
|
||||
}
|
||||
|
||||
asmlinkage void set_esp0 (unsigned long ssp)
|
||||
{
|
||||
current->thread.esp0 = ssp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic dumping code. Used for panic and debug.
|
||||
*/
|
||||
|
||||
static void dump(struct pt_regs *fp)
|
||||
{
|
||||
unsigned long *sp;
|
||||
unsigned char *tp;
|
||||
int i;
|
||||
|
||||
printk("\nCURRENT PROCESS:\n\n");
|
||||
printk("COMM=%s PID=%d\n", current->comm, current->pid);
|
||||
if (current->mm) {
|
||||
printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
|
||||
(int) current->mm->start_code,
|
||||
(int) current->mm->end_code,
|
||||
(int) current->mm->start_data,
|
||||
(int) current->mm->end_data,
|
||||
(int) current->mm->end_data,
|
||||
(int) current->mm->brk);
|
||||
printk("USER-STACK=%08x KERNEL-STACK=%08lx\n\n",
|
||||
(int) current->mm->start_stack,
|
||||
(int) PAGE_SIZE+(unsigned long)current);
|
||||
}
|
||||
|
||||
show_regs(fp);
|
||||
printk("\nCODE:");
|
||||
tp = ((unsigned char *) fp->pc) - 0x20;
|
||||
for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) {
|
||||
if ((i % 0x10) == 0)
|
||||
printk("\n%08x: ", (int) (tp + i));
|
||||
printk("%08x ", (int) *sp++);
|
||||
}
|
||||
printk("\n");
|
||||
|
||||
printk("\nKERNEL STACK:");
|
||||
tp = ((unsigned char *) fp) - 0x40;
|
||||
for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
|
||||
if ((i % 0x10) == 0)
|
||||
printk("\n%08x: ", (int) (tp + i));
|
||||
printk("%08x ", (int) *sp++);
|
||||
}
|
||||
printk("\n");
|
||||
if (STACK_MAGIC != *(unsigned long *)((unsigned long)current+PAGE_SIZE))
|
||||
printk("(Possibly corrupted stack page??)\n");
|
||||
|
||||
printk("\n\n");
|
||||
}
|
||||
|
||||
void die_if_kernel (char *str, struct pt_regs *fp, int nr)
|
||||
{
|
||||
extern int console_loglevel;
|
||||
|
||||
if (!(fp->ccr & PS_S))
|
||||
return;
|
||||
|
||||
console_loglevel = 15;
|
||||
dump(fp);
|
||||
|
||||
do_exit(SIGSEGV);
|
||||
}
|
||||
|
||||
extern char _start, _etext;
|
||||
#define check_kernel_text(addr) \
|
||||
((addr >= (unsigned long)(&_start)) && \
|
||||
(addr < (unsigned long)(&_etext)))
|
||||
|
||||
static int kstack_depth_to_print = 24;
|
||||
|
||||
void show_stack(struct task_struct *task, unsigned long *esp)
|
||||
{
|
||||
unsigned long *stack, addr;
|
||||
int i;
|
||||
|
||||
if (esp == NULL)
|
||||
esp = (unsigned long *) &esp;
|
||||
|
||||
stack = esp;
|
||||
|
||||
printk("Stack from %08lx:", (unsigned long)stack);
|
||||
for (i = 0; i < kstack_depth_to_print; i++) {
|
||||
if (((unsigned long)stack & (THREAD_SIZE - 1)) == 0)
|
||||
break;
|
||||
if (i % 8 == 0)
|
||||
printk("\n ");
|
||||
printk(" %08lx", *stack++);
|
||||
}
|
||||
|
||||
printk("\nCall Trace:");
|
||||
i = 0;
|
||||
stack = esp;
|
||||
while (((unsigned long)stack & (THREAD_SIZE - 1)) == 0) {
|
||||
addr = *stack++;
|
||||
/*
|
||||
* If the address is either in the text segment of the
|
||||
* kernel, or in the region which contains vmalloc'ed
|
||||
* memory, it *may* be the address of a calling
|
||||
* routine; if so, print it so that someone tracing
|
||||
* down the cause of the crash will be able to figure
|
||||
* out the call path that was taken.
|
||||
*/
|
||||
if (check_kernel_text(addr)) {
|
||||
if (i % 4 == 0)
|
||||
printk("\n ");
|
||||
printk(" [<%08lx>]", addr);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
void show_trace_task(struct task_struct *tsk)
|
||||
{
|
||||
show_stack(tsk,(unsigned long *)tsk->thread.esp0);
|
||||
}
|
||||
|
||||
void dump_stack(void)
|
||||
{
|
||||
show_stack(NULL,NULL);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dump_stack);
|
||||
172
arch/h8300/kernel/vmlinux.lds.S
Normal file
172
arch/h8300/kernel/vmlinux.lds.S
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
#define VMLINUX_SYMBOL(_sym_) _##_sym_
|
||||
#include <asm-generic/vmlinux.lds.h>
|
||||
#include <linux/config.h>
|
||||
|
||||
/* target memory map */
|
||||
#ifdef CONFIG_H8300H_GENERIC
|
||||
#define ROMTOP 0x000000
|
||||
#define ROMSIZE 0x400000
|
||||
#define RAMTOP 0x400000
|
||||
#define RAMSIZE 0x400000
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_H8300H_AKI3068NET
|
||||
#define ROMTOP 0x000000
|
||||
#define ROMSIZE 0x080000
|
||||
#define RAMTOP 0x400000
|
||||
#define RAMSIZE 0x200000
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_H8300H_H8MAX
|
||||
#define ROMTOP 0x000000
|
||||
#define ROMSIZE 0x080000
|
||||
#define RAMTOP 0x400000
|
||||
#define RAMSIZE 0x200000
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_H8300H_SIM
|
||||
#define ROMTOP 0x000000
|
||||
#define ROMSIZE 0x400000
|
||||
#define RAMTOP 0x400000
|
||||
#define RAMSIZE 0x400000
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_H8S_SIM
|
||||
#define ROMTOP 0x000000
|
||||
#define ROMSIZE 0x400000
|
||||
#define RAMTOP 0x400000
|
||||
#define RAMSIZE 0x800000
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_H8S_EDOSK2674
|
||||
#define ROMTOP 0x000000
|
||||
#define ROMSIZE 0x400000
|
||||
#define RAMTOP 0x400000
|
||||
#define RAMSIZE 0x800000
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)
|
||||
INPUT(romfs.o)
|
||||
#endif
|
||||
|
||||
_jiffies = _jiffies_64 + 4;
|
||||
|
||||
ENTRY(__start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
#if defined(CONFIG_ROMKERNEL)
|
||||
. = ROMTOP;
|
||||
.vectors :
|
||||
{
|
||||
__vector = . ;
|
||||
*(.vectors*)
|
||||
}
|
||||
#else
|
||||
. = RAMTOP;
|
||||
.bootvec :
|
||||
{
|
||||
*(.bootvec)
|
||||
}
|
||||
#endif
|
||||
.text :
|
||||
{
|
||||
#if defined(CONFIG_ROMKERNEL)
|
||||
*(.int_redirect)
|
||||
#endif
|
||||
__stext = . ;
|
||||
*(.text)
|
||||
SCHED_TEXT
|
||||
LOCK_TEXT
|
||||
__etext = . ;
|
||||
. = ALIGN(16); /* Exception table */
|
||||
___start___ex_table = .;
|
||||
*(__ex_table)
|
||||
___stop___ex_table = .;
|
||||
}
|
||||
|
||||
RODATA
|
||||
#if defined(CONFIG_ROMKERNEL)
|
||||
SECURITY_INIT
|
||||
#endif
|
||||
ROEND = .;
|
||||
#if defined(CONFIG_ROMKERNEL)
|
||||
. = RAMTOP;
|
||||
.data : AT(ROEND)
|
||||
#else
|
||||
.data :
|
||||
#endif
|
||||
{
|
||||
__sdata = . ;
|
||||
___data_start = . ;
|
||||
|
||||
. = ALIGN(0x2000) ;
|
||||
*(.data.init_task)
|
||||
. = ALIGN(0x4) ;
|
||||
*(.data)
|
||||
. = ALIGN(0x4) ;
|
||||
*(.data.*)
|
||||
|
||||
. = ALIGN(0x4) ;
|
||||
___init_begin = .;
|
||||
__sinittext = .;
|
||||
*(.init.text)
|
||||
__einittext = .;
|
||||
*(.init.data)
|
||||
. = ALIGN(0x4) ;
|
||||
___setup_start = .;
|
||||
*(.init.setup)
|
||||
. = ALIGN(0x4) ;
|
||||
___setup_end = .;
|
||||
___initcall_start = .;
|
||||
*(.initcall1.init)
|
||||
*(.initcall2.init)
|
||||
*(.initcall3.init)
|
||||
*(.initcall4.init)
|
||||
*(.initcall5.init)
|
||||
*(.initcall6.init)
|
||||
*(.initcall7.init)
|
||||
___initcall_end = .;
|
||||
___con_initcall_start = .;
|
||||
*(.con_initcall.init)
|
||||
___con_initcall_end = .;
|
||||
*(.exit.text)
|
||||
*(.exit.data)
|
||||
. = ALIGN(4);
|
||||
___initramfs_start = .;
|
||||
*(.init.ramfs)
|
||||
___initramfs_end = .;
|
||||
. = ALIGN(0x4) ;
|
||||
___init_end = .;
|
||||
__edata = . ;
|
||||
}
|
||||
#if defined(CONFIG_RAMKERNEL)
|
||||
SECURITY_INIT
|
||||
#endif
|
||||
__begin_data = LOADADDR(.data);
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(0x4) ;
|
||||
__sbss = . ;
|
||||
*(.bss*)
|
||||
. = ALIGN(0x4) ;
|
||||
*(COMMON)
|
||||
. = ALIGN(0x4) ;
|
||||
__ebss = . ;
|
||||
__end = . ;
|
||||
__ramstart = .;
|
||||
}
|
||||
/DISCARD/ : {
|
||||
*(.exitcall.exit)
|
||||
}
|
||||
.romfs :
|
||||
{
|
||||
*(.romfs*)
|
||||
}
|
||||
. = RAMTOP+RAMSIZE;
|
||||
.dummy :
|
||||
{
|
||||
COMMAND_START = . - 0x200 ;
|
||||
__ramend = . ;
|
||||
}
|
||||
}
|
||||
8
arch/h8300/lib/Makefile
Normal file
8
arch/h8300/lib/Makefile
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#
|
||||
# Makefile for H8/300-specific library files..
|
||||
#
|
||||
|
||||
.S.o:
|
||||
$(CC) $(AFLAGS) -D__ASSEMBLY__ -c $< -o $@
|
||||
|
||||
lib-y = ashrdi3.o checksum.o memcpy.o memset.o abs.o romfs.o
|
||||
21
arch/h8300/lib/abs.S
Normal file
21
arch/h8300/lib/abs.S
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
;;; abs.S
|
||||
|
||||
#include <asm/linkage.h>
|
||||
|
||||
#if defined(__H8300H__)
|
||||
.h8300h
|
||||
#endif
|
||||
#if defined(__H8300S__)
|
||||
.h8300s
|
||||
#endif
|
||||
.text
|
||||
.global SYMBOL_NAME(abs)
|
||||
|
||||
;;; int abs(int n)
|
||||
SYMBOL_NAME_LABEL(abs)
|
||||
mov.l er0,er0
|
||||
bpl 1f
|
||||
neg.l er0
|
||||
1:
|
||||
rts
|
||||
|
||||
63
arch/h8300/lib/ashrdi3.c
Normal file
63
arch/h8300/lib/ashrdi3.c
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
|
||||
/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define BITS_PER_UNIT 8
|
||||
|
||||
typedef int SItype __attribute__ ((mode (SI)));
|
||||
typedef unsigned int USItype __attribute__ ((mode (SI)));
|
||||
typedef int DItype __attribute__ ((mode (DI)));
|
||||
typedef int word_type __attribute__ ((mode (__word__)));
|
||||
|
||||
struct DIstruct {SItype high, low;};
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct DIstruct s;
|
||||
DItype ll;
|
||||
} DIunion;
|
||||
|
||||
DItype
|
||||
__ashrdi3 (DItype u, word_type b)
|
||||
{
|
||||
DIunion w;
|
||||
word_type bm;
|
||||
DIunion uu;
|
||||
|
||||
if (b == 0)
|
||||
return u;
|
||||
|
||||
uu.ll = u;
|
||||
|
||||
bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
|
||||
if (bm <= 0)
|
||||
{
|
||||
/* w.s.high = 1..1 or 0..0 */
|
||||
w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
|
||||
w.s.low = uu.s.high >> -bm;
|
||||
}
|
||||
else
|
||||
{
|
||||
USItype carries = (USItype)uu.s.high << bm;
|
||||
w.s.high = uu.s.high >> b;
|
||||
w.s.low = ((USItype)uu.s.low >> b) | carries;
|
||||
}
|
||||
|
||||
return w.ll;
|
||||
}
|
||||
159
arch/h8300/lib/checksum.c
Normal file
159
arch/h8300/lib/checksum.c
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* INET An implementation of the TCP/IP protocol suite for the LINUX
|
||||
* operating system. INET is implemented using the BSD Socket
|
||||
* interface as the means of communication with the user level.
|
||||
*
|
||||
* IP/TCP/UDP checksumming routines
|
||||
*
|
||||
* Authors: Jorge Cwik, <jorge@laser.satlink.net>
|
||||
* Arnt Gulbrandsen, <agulbra@nvg.unit.no>
|
||||
* Tom May, <ftom@netcom.com>
|
||||
* Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
|
||||
* Lots of code moved from tcp.c and ip.c; see those files
|
||||
* for more names.
|
||||
*
|
||||
* 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek:
|
||||
* Fixed some nasty bugs, causing some horrible crashes.
|
||||
* A: At some points, the sum (%0) was used as
|
||||
* length-counter instead of the length counter
|
||||
* (%1). Thanks to Roman Hodek for pointing this out.
|
||||
* B: GCC seems to mess up if one uses too many
|
||||
* data-registers to hold input values and one tries to
|
||||
* specify d0 and d1 as scratch registers. Letting gcc choose these
|
||||
* registers itself solves the problem.
|
||||
*
|
||||
* 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 the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
|
||||
of the assembly has to go. */
|
||||
|
||||
#include <net/checksum.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static inline unsigned short from32to16(unsigned long x)
|
||||
{
|
||||
/* add up 16-bit and 16-bit for 16+c bit */
|
||||
x = (x & 0xffff) + (x >> 16);
|
||||
/* add up carry.. */
|
||||
x = (x & 0xffff) + (x >> 16);
|
||||
return x;
|
||||
}
|
||||
|
||||
static unsigned long do_csum(const unsigned char * buff, int len)
|
||||
{
|
||||
int odd, count;
|
||||
unsigned long result = 0;
|
||||
|
||||
if (len <= 0)
|
||||
goto out;
|
||||
odd = 1 & (unsigned long) buff;
|
||||
if (odd) {
|
||||
result = *buff;
|
||||
len--;
|
||||
buff++;
|
||||
}
|
||||
count = len >> 1; /* nr of 16-bit words.. */
|
||||
if (count) {
|
||||
if (2 & (unsigned long) buff) {
|
||||
result += *(unsigned short *) buff;
|
||||
count--;
|
||||
len -= 2;
|
||||
buff += 2;
|
||||
}
|
||||
count >>= 1; /* nr of 32-bit words.. */
|
||||
if (count) {
|
||||
unsigned long carry = 0;
|
||||
do {
|
||||
unsigned long w = *(unsigned long *) buff;
|
||||
count--;
|
||||
buff += 4;
|
||||
result += carry;
|
||||
result += w;
|
||||
carry = (w > result);
|
||||
} while (count);
|
||||
result += carry;
|
||||
result = (result & 0xffff) + (result >> 16);
|
||||
}
|
||||
if (len & 2) {
|
||||
result += *(unsigned short *) buff;
|
||||
buff += 2;
|
||||
}
|
||||
}
|
||||
if (len & 1)
|
||||
result += (*buff << 8);
|
||||
result = from32to16(result);
|
||||
if (odd)
|
||||
result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a version of ip_compute_csum() optimized for IP headers,
|
||||
* which always checksum on 4 octet boundaries.
|
||||
*/
|
||||
unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
|
||||
{
|
||||
return ~do_csum(iph,ihl*4);
|
||||
}
|
||||
|
||||
/*
|
||||
* computes the checksum of a memory block at buff, length len,
|
||||
* and adds in "sum" (32-bit)
|
||||
*
|
||||
* returns a 32-bit number suitable for feeding into itself
|
||||
* or csum_tcpudp_magic
|
||||
*
|
||||
* this function must be called with even lengths, except
|
||||
* for the last fragment, which may be odd
|
||||
*
|
||||
* it's best to have buff aligned on a 32-bit boundary
|
||||
*/
|
||||
unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
|
||||
{
|
||||
unsigned int result = do_csum(buff, len);
|
||||
|
||||
/* add in old sum, and carry.. */
|
||||
result += sum;
|
||||
/* 16+c bits -> 16 bits */
|
||||
result = (result & 0xffff) + (result >> 16);
|
||||
return result;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(csum_partial);
|
||||
|
||||
/*
|
||||
* this routine is used for miscellaneous IP-like checksums, mainly
|
||||
* in icmp.c
|
||||
*/
|
||||
unsigned short ip_compute_csum(const unsigned char * buff, int len)
|
||||
{
|
||||
return ~do_csum(buff,len);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy from fs while checksumming, otherwise like csum_partial
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err)
|
||||
{
|
||||
if (csum_err) *csum_err = 0;
|
||||
memcpy(dst, src, len);
|
||||
return csum_partial(dst, len, sum);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy from ds while checksumming, otherwise like csum_partial
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
csum_partial_copy(const char *src, char *dst, int len, int sum)
|
||||
{
|
||||
memcpy(dst, src, len);
|
||||
return csum_partial(dst, len, sum);
|
||||
}
|
||||
84
arch/h8300/lib/memcpy.S
Normal file
84
arch/h8300/lib/memcpy.S
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
;;; memcpy.S
|
||||
|
||||
#include <asm/linkage.h>
|
||||
|
||||
#if defined(__H8300H__)
|
||||
.h8300h
|
||||
#endif
|
||||
#if defined(__H8300S__)
|
||||
.h8300s
|
||||
#endif
|
||||
|
||||
.text
|
||||
.global SYMBOL_NAME(memcpy)
|
||||
|
||||
;;; void *memcpy(void *to, void *from, size_t n)
|
||||
SYMBOL_NAME_LABEL(memcpy)
|
||||
mov.l er2,er2
|
||||
bne 1f
|
||||
rts
|
||||
1:
|
||||
;; address check
|
||||
bld #0,r0l
|
||||
bxor #0,r1l
|
||||
bcs 4f
|
||||
mov.l er4,@-sp
|
||||
mov.l er0,@-sp
|
||||
btst #0,r0l
|
||||
beq 1f
|
||||
;; (aligned even) odd address
|
||||
mov.b @er1,r3l
|
||||
mov.b r3l,@er0
|
||||
adds #1,er1
|
||||
adds #1,er0
|
||||
dec.l #1,er2
|
||||
beq 3f
|
||||
1:
|
||||
;; n < sizeof(unsigned long) check
|
||||
sub.l er4,er4
|
||||
adds #4,er4 ; loop count check value
|
||||
cmp.l er4,er2
|
||||
blo 2f
|
||||
;; unsigned long copy
|
||||
1:
|
||||
mov.l @er1,er3
|
||||
mov.l er3,@er0
|
||||
adds #4,er0
|
||||
adds #4,er1
|
||||
subs #4,er2
|
||||
cmp.l er4,er2
|
||||
bcc 1b
|
||||
;; rest
|
||||
2:
|
||||
mov.l er2,er2
|
||||
beq 3f
|
||||
1:
|
||||
mov.b @er1,r3l
|
||||
mov.b r3l,@er0
|
||||
adds #1,er1
|
||||
adds #1,er0
|
||||
dec.l #1,er2
|
||||
bne 1b
|
||||
3:
|
||||
mov.l @sp+,er0
|
||||
mov.l @sp+,er4
|
||||
rts
|
||||
|
||||
;; odd <- even / even <- odd
|
||||
4:
|
||||
mov.l er4,er3
|
||||
mov.l er2,er4
|
||||
mov.l er5,er2
|
||||
mov.l er1,er5
|
||||
mov.l er6,er1
|
||||
mov.l er0,er6
|
||||
1:
|
||||
eepmov.w
|
||||
mov.w r4,r4
|
||||
bne 1b
|
||||
dec.w #1,e4
|
||||
bpl 1b
|
||||
mov.l er1,er6
|
||||
mov.l er2,er5
|
||||
mov.l er3,er4
|
||||
rts
|
||||
61
arch/h8300/lib/memset.S
Normal file
61
arch/h8300/lib/memset.S
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/* memset.S */
|
||||
|
||||
#include <asm/linkage.h>
|
||||
|
||||
#if defined(__H8300H__)
|
||||
.h8300h
|
||||
#endif
|
||||
#if defined(__H8300S__)
|
||||
.h8300s
|
||||
#endif
|
||||
.text
|
||||
|
||||
.global SYMBOL_NAME(memset)
|
||||
|
||||
;;void *memset(*ptr, int c, size_t count)
|
||||
;; ptr = er0
|
||||
;; c = er1(r1l)
|
||||
;; count = er2
|
||||
SYMBOL_NAME_LABEL(memset)
|
||||
btst #0,r0l
|
||||
beq 2f
|
||||
|
||||
;; odd address
|
||||
1:
|
||||
mov.b r1l,@er0
|
||||
adds #1,er0
|
||||
dec.l #1,er2
|
||||
beq 6f
|
||||
|
||||
;; even address
|
||||
2:
|
||||
mov.l er2,er3
|
||||
cmp.l #4,er2
|
||||
blo 4f
|
||||
;; count>=4 -> count/4
|
||||
#if defined(__H8300H__)
|
||||
shlr.l er2
|
||||
shlr.l er2
|
||||
#endif
|
||||
#if defined(__H8300S__)
|
||||
shlr.l #2,er2
|
||||
#endif
|
||||
;; byte -> long
|
||||
mov.b r1l,r1h
|
||||
mov.w r1,e1
|
||||
3:
|
||||
mov.l er1,@er0
|
||||
adds #4,er0
|
||||
dec.l #1,er2
|
||||
bne 3b
|
||||
4:
|
||||
;; count % 4
|
||||
and.b #3,r3l
|
||||
beq 6f
|
||||
5:
|
||||
mov.b r1l,@er0
|
||||
adds #1,er0
|
||||
dec.b r3l
|
||||
bne 5b
|
||||
6:
|
||||
rts
|
||||
58
arch/h8300/lib/romfs.S
Normal file
58
arch/h8300/lib/romfs.S
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/* romfs move to __ebss */
|
||||
|
||||
#include <asm/linkage.h>
|
||||
#include <linux/config.h>
|
||||
|
||||
#if defined(__H8300H__)
|
||||
.h8300h
|
||||
#endif
|
||||
#if defined(__H8300S__)
|
||||
.h8300s
|
||||
#endif
|
||||
|
||||
#define BLKOFFSET 512
|
||||
|
||||
.text
|
||||
.globl __move_romfs
|
||||
_romfs_sig_len = 8
|
||||
|
||||
__move_romfs:
|
||||
mov.l #__sbss,er0
|
||||
mov.l #_romfs_sig,er1
|
||||
mov.b #_romfs_sig_len,r3l
|
||||
1: /* check romfs image */
|
||||
mov.b @er0+,r2l
|
||||
mov.b @er1+,r2h
|
||||
cmp.b r2l,r2h
|
||||
bne 2f
|
||||
dec.b r3l
|
||||
bne 1b
|
||||
|
||||
/* find romfs image */
|
||||
mov.l @__sbss+8,er0 /* romfs length(be) */
|
||||
mov.l #__sbss,er1
|
||||
add.l er0,er1 /* romfs image end */
|
||||
mov.l #__ebss,er2
|
||||
add.l er0,er2 /* distination address */
|
||||
#if defined(CONFIG_INTELFLASH)
|
||||
add.l #BLKOFFSET,er2
|
||||
#endif
|
||||
adds #2,er0
|
||||
adds #1,er0
|
||||
shlr er0
|
||||
shlr er0 /* transfer length */
|
||||
1:
|
||||
mov.l @er1,er3 /* copy image */
|
||||
mov.l er3,@er2
|
||||
subs #4,er1
|
||||
subs #4,er2
|
||||
dec.l #1,er0
|
||||
bpl 1b
|
||||
2:
|
||||
rts
|
||||
|
||||
.section .rodata
|
||||
_romfs_sig:
|
||||
.ascii "-rom1fs-"
|
||||
|
||||
.end
|
||||
5
arch/h8300/mm/Makefile
Normal file
5
arch/h8300/mm/Makefile
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#
|
||||
# Makefile for the linux m68k-specific parts of the memory manager.
|
||||
#
|
||||
|
||||
obj-y := init.o fault.o memory.o kmap.o
|
||||
58
arch/h8300/mm/fault.c
Normal file
58
arch/h8300/mm/fault.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* linux/arch/h8300/mm/fault.c
|
||||
*
|
||||
* Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>,
|
||||
* Copyright (C) 2000 Lineo, Inc. (www.lineo.com)
|
||||
*
|
||||
* Based on:
|
||||
*
|
||||
* linux/arch/m68knommu/mm/fault.c
|
||||
* linux/arch/m68k/mm/fault.c
|
||||
*
|
||||
* Copyright (C) 1995 Hamish Macdonald
|
||||
*/
|
||||
|
||||
#include <linux/mman.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/ptrace.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
extern void die_if_kernel(char *, struct pt_regs *, long);
|
||||
|
||||
/*
|
||||
* This routine handles page faults. It determines the problem, and
|
||||
* then passes it off to one of the appropriate routines.
|
||||
*
|
||||
* error_code:
|
||||
* bit 0 == 0 means no page found, 1 means protection fault
|
||||
* bit 1 == 0 means read, 1 means write
|
||||
*
|
||||
* If this routine detects a bad access, it returns 1, otherwise it
|
||||
* returns 0.
|
||||
*/
|
||||
asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
|
||||
unsigned long error_code)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printk ("regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n",
|
||||
regs->sr, regs->pc, address, error_code);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Oops. The kernel tried to access some bad page. We'll have to
|
||||
* terminate things with extreme prejudice.
|
||||
*/
|
||||
if ((unsigned long) address < PAGE_SIZE) {
|
||||
printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
|
||||
} else
|
||||
printk(KERN_ALERT "Unable to handle kernel access");
|
||||
printk(" at virtual address %08lx\n",address);
|
||||
die_if_kernel("Oops", regs, error_code);
|
||||
do_exit(SIGKILL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
232
arch/h8300/mm/init.c
Normal file
232
arch/h8300/mm/init.c
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* linux/arch/h8300/mm/init.c
|
||||
*
|
||||
* Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>,
|
||||
* Kenneth Albanowski <kjahds@kjahds.com>,
|
||||
* Copyright (C) 2000 Lineo, Inc. (www.lineo.com)
|
||||
*
|
||||
* Based on:
|
||||
*
|
||||
* linux/arch/m68knommu/mm/init.c
|
||||
* linux/arch/m68k/mm/init.c
|
||||
*
|
||||
* Copyright (C) 1995 Hamish Macdonald
|
||||
*
|
||||
* JAN/1999 -- hacked to support ColdFire (gerg@snapgear.com)
|
||||
* DEC/2000 -- linux 2.4 support <davidm@snapgear.com>
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/swap.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
extern void die_if_kernel(char *,struct pt_regs *,long);
|
||||
extern void free_initmem(void);
|
||||
|
||||
/*
|
||||
* BAD_PAGE is the page that is used for page faults when linux
|
||||
* is out-of-memory. Older versions of linux just did a
|
||||
* do_exit(), but using this instead means there is less risk
|
||||
* for a process dying in kernel mode, possibly leaving a inode
|
||||
* unused etc..
|
||||
*
|
||||
* BAD_PAGETABLE is the accompanying page-table: it is initialized
|
||||
* to point to BAD_PAGE entries.
|
||||
*
|
||||
* ZERO_PAGE is a special page that is used for zero-initialized
|
||||
* data and COW.
|
||||
*/
|
||||
static unsigned long empty_bad_page_table;
|
||||
|
||||
static unsigned long empty_bad_page;
|
||||
|
||||
unsigned long empty_zero_page;
|
||||
|
||||
extern unsigned long rom_length;
|
||||
|
||||
void show_mem(void)
|
||||
{
|
||||
unsigned long i;
|
||||
int free = 0, total = 0, reserved = 0, shared = 0;
|
||||
int cached = 0;
|
||||
|
||||
printk("\nMem-info:\n");
|
||||
show_free_areas();
|
||||
i = max_mapnr;
|
||||
while (i-- > 0) {
|
||||
total++;
|
||||
if (PageReserved(mem_map+i))
|
||||
reserved++;
|
||||
else if (PageSwapCache(mem_map+i))
|
||||
cached++;
|
||||
else if (!page_count(mem_map+i))
|
||||
free++;
|
||||
else
|
||||
shared += page_count(mem_map+i) - 1;
|
||||
}
|
||||
printk("%d pages of RAM\n",total);
|
||||
printk("%d free pages\n",free);
|
||||
printk("%d reserved pages\n",reserved);
|
||||
printk("%d pages shared\n",shared);
|
||||
printk("%d pages swap cached\n",cached);
|
||||
}
|
||||
|
||||
extern unsigned long memory_start;
|
||||
extern unsigned long memory_end;
|
||||
|
||||
/*
|
||||
* paging_init() continues the virtual memory environment setup which
|
||||
* was begun by the code in arch/head.S.
|
||||
* The parameters are pointers to where to stick the starting and ending
|
||||
* addresses of available kernel virtual memory.
|
||||
*/
|
||||
void paging_init(void)
|
||||
{
|
||||
/*
|
||||
* Make sure start_mem is page aligned, otherwise bootmem and
|
||||
* page_alloc get different views og the world.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
unsigned long start_mem = PAGE_ALIGN(memory_start);
|
||||
#endif
|
||||
unsigned long end_mem = memory_end & PAGE_MASK;
|
||||
|
||||
#ifdef DEBUG
|
||||
printk ("start_mem is %#lx\nvirtual_end is %#lx\n",
|
||||
start_mem, end_mem);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize the bad page table and bad page to point
|
||||
* to a couple of allocated pages.
|
||||
*/
|
||||
empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
|
||||
empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
|
||||
empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
|
||||
memset((void *)empty_zero_page, 0, PAGE_SIZE);
|
||||
|
||||
/*
|
||||
* Set up SFC/DFC registers (user data space).
|
||||
*/
|
||||
set_fs (USER_DS);
|
||||
|
||||
#ifdef DEBUG
|
||||
printk ("before free_area_init\n");
|
||||
|
||||
printk ("free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
|
||||
start_mem, end_mem);
|
||||
#endif
|
||||
|
||||
{
|
||||
unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
|
||||
|
||||
zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT;
|
||||
zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
zones_size[ZONE_HIGHMEM] = 0;
|
||||
#endif
|
||||
free_area_init(zones_size);
|
||||
}
|
||||
}
|
||||
|
||||
void mem_init(void)
|
||||
{
|
||||
int codek = 0, datak = 0, initk = 0;
|
||||
/* DAVIDM look at setup memory map generically with reserved area */
|
||||
unsigned long tmp;
|
||||
extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end;
|
||||
extern unsigned long _ramend, _ramstart;
|
||||
unsigned long len = &_ramend - &_ramstart;
|
||||
unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */
|
||||
unsigned long end_mem = memory_end; /* DAVIDM - this must not include kernel stack at top */
|
||||
|
||||
#ifdef DEBUG
|
||||
printk(KERN_DEBUG "Mem_init: start=%lx, end=%lx\n", start_mem, end_mem);
|
||||
#endif
|
||||
|
||||
end_mem &= PAGE_MASK;
|
||||
high_memory = (void *) end_mem;
|
||||
|
||||
start_mem = PAGE_ALIGN(start_mem);
|
||||
max_mapnr = num_physpages = MAP_NR(high_memory);
|
||||
|
||||
/* this will put all memory onto the freelists */
|
||||
totalram_pages = free_all_bootmem();
|
||||
|
||||
codek = (&_etext - &_stext) >> 10;
|
||||
datak = (&_ebss - &_sdata) >> 10;
|
||||
initk = (&__init_begin - &__init_end) >> 10;
|
||||
|
||||
tmp = nr_free_pages() << PAGE_SHIFT;
|
||||
printk(KERN_INFO "Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n",
|
||||
tmp >> 10,
|
||||
len >> 10,
|
||||
(rom_length > 0) ? ((rom_length >> 10) - codek) : 0,
|
||||
rom_length >> 10,
|
||||
codek,
|
||||
datak
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
{
|
||||
int pages = 0;
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
free_page(start);
|
||||
totalram_pages++;
|
||||
pages++;
|
||||
}
|
||||
printk ("Freeing initrd memory: %dk freed\n", pages);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
free_initmem()
|
||||
{
|
||||
#ifdef CONFIG_RAMKERNEL
|
||||
unsigned long addr;
|
||||
extern char __init_begin, __init_end;
|
||||
/*
|
||||
* the following code should be cool even if these sections
|
||||
* are not page aligned.
|
||||
*/
|
||||
addr = PAGE_ALIGN((unsigned long)(&__init_begin));
|
||||
/* next to check that the page we free is not a partial page */
|
||||
for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
}
|
||||
printk(KERN_INFO "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n",
|
||||
(addr - PAGE_ALIGN((long) &__init_begin)) >> 10,
|
||||
(int)(PAGE_ALIGN((unsigned long)(&__init_begin))),
|
||||
(int)(addr - PAGE_SIZE));
|
||||
#endif
|
||||
}
|
||||
|
||||
59
arch/h8300/mm/kmap.c
Normal file
59
arch/h8300/mm/kmap.c
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* linux/arch/h8300/mm/kmap.c
|
||||
*
|
||||
* Based on
|
||||
* linux/arch/m68knommu/mm/kmap.c
|
||||
*
|
||||
* Copyright (C) 2000 Lineo, <davidm@snapgear.com>
|
||||
* Copyright (C) 2000-2002 David McCullough <davidm@snapgear.com>
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
/*
|
||||
* Map some physical address range into the kernel address space.
|
||||
*/
|
||||
void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
|
||||
{
|
||||
return (void *)physaddr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unmap a ioremap()ed region again.
|
||||
*/
|
||||
void iounmap(void *addr)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* __iounmap unmaps nearly everything, so be careful
|
||||
* it doesn't free currently pointer/page tables anymore but it
|
||||
* wans't used anyway and might be added later.
|
||||
*/
|
||||
void __iounmap(void *addr, unsigned long size)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Set new cache mode for some kernel address space.
|
||||
* The caller must push data for that range itself, if such data may already
|
||||
* be in the cache.
|
||||
*/
|
||||
void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
|
||||
{
|
||||
}
|
||||
70
arch/h8300/mm/memory.c
Normal file
70
arch/h8300/mm/memory.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* linux/arch/h8300/mm/memory.c
|
||||
*
|
||||
* Copyright (C) 2002 Yoshinori Sato <ysato@users.sourceforge.jp>,
|
||||
*
|
||||
* Based on:
|
||||
*
|
||||
* linux/arch/m68knommu/mm/memory.c
|
||||
*
|
||||
* Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
|
||||
* Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
|
||||
*
|
||||
* Based on:
|
||||
*
|
||||
* linux/arch/m68k/mm/memory.c
|
||||
*
|
||||
* Copyright (C) 1995 Hamish Macdonald
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
void cache_clear (unsigned long paddr, int len)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void cache_push (unsigned long paddr, int len)
|
||||
{
|
||||
}
|
||||
|
||||
void cache_push_v (unsigned long vaddr, int len)
|
||||
{
|
||||
}
|
||||
|
||||
/* Map some physical address range into the kernel address space. The
|
||||
* code is copied and adapted from map_chunk().
|
||||
*/
|
||||
|
||||
unsigned long kernel_map(unsigned long paddr, unsigned long size,
|
||||
int nocacheflag, unsigned long *memavailp )
|
||||
{
|
||||
return paddr;
|
||||
}
|
||||
|
||||
#ifdef MAGIC_ROM_PTR
|
||||
|
||||
int is_in_rom(unsigned long addr)
|
||||
{
|
||||
/* Anything not in operational RAM is returned as in rom! */
|
||||
if (addr < _ramstart || addr >= _ramend)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
7
arch/h8300/platform/h8300h/Makefile
Normal file
7
arch/h8300/platform/h8300h/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
# Reuse any files we can from the H8/300H
|
||||
#
|
||||
|
||||
obj-y := entry.o ints_h8300h.o ptrace_h8300h.o
|
||||
6
arch/h8300/platform/h8300h/aki3068net/Makefile
Normal file
6
arch/h8300/platform/h8300h/aki3068net/Makefile
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
extra-y := crt0_ram.o
|
||||
obj-y := timer.o
|
||||
111
arch/h8300/platform/h8300h/aki3068net/crt0_ram.S
Normal file
111
arch/h8300/platform/h8300h/aki3068net/crt0_ram.S
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Platform depend startup
|
||||
* Target Archtecture: AE-3068 (aka. aki3068net)
|
||||
* Memory Layout : RAM
|
||||
*/
|
||||
|
||||
#define ASSEMBLY
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <asm/linkage.h>
|
||||
|
||||
#if !defined(CONFIG_BLKDEV_RESERVE)
|
||||
#if defined(CONFIG_GDB_DEBUG)
|
||||
#define RAMEND (__ramend - 0xc000)
|
||||
#else
|
||||
#define RAMEND __ramend
|
||||
#endif
|
||||
#else
|
||||
#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
|
||||
#endif
|
||||
|
||||
.global SYMBOL_NAME(_start)
|
||||
.global SYMBOL_NAME(command_line)
|
||||
.global SYMBOL_NAME(_platform_gpio_table)
|
||||
.global SYMBOL_NAME(_target_name)
|
||||
|
||||
.h8300h
|
||||
|
||||
.section .text
|
||||
.file "crt0_ram.S"
|
||||
|
||||
/* CPU Reset entry */
|
||||
SYMBOL_NAME_LABEL(_start)
|
||||
mov.l #RAMEND,sp
|
||||
ldc #0x80,ccr
|
||||
|
||||
/* Peripheral Setup */
|
||||
|
||||
#if defined(CONFIG_MTD_UCLINUX)
|
||||
/* move romfs image */
|
||||
jsr @__move_romfs
|
||||
#endif
|
||||
|
||||
/* .bss clear */
|
||||
mov.l #__sbss,er5
|
||||
mov.l #__ebss,er4
|
||||
sub.l er5,er4
|
||||
shlr er4
|
||||
shlr er4
|
||||
sub.l er0,er0
|
||||
1:
|
||||
mov.l er0,@er5
|
||||
adds #4,er5
|
||||
dec.l #1,er4
|
||||
bne 1b
|
||||
|
||||
/* copy kernel commandline */
|
||||
mov.l #COMMAND_START,er5
|
||||
mov.l #SYMBOL_NAME(command_line),er6
|
||||
mov.w #512,r4
|
||||
eepmov.w
|
||||
|
||||
/* uClinux kernel start */
|
||||
ldc #0x90,ccr /* running kernel */
|
||||
mov.l #SYMBOL_NAME(init_thread_union),sp
|
||||
add.l #0x2000,sp
|
||||
jsr @_start_kernel
|
||||
_exit:
|
||||
|
||||
jmp _exit
|
||||
|
||||
rts
|
||||
|
||||
/* I/O port assign information */
|
||||
__platform_gpio_table:
|
||||
mov.l #gpio_table,er0
|
||||
rts
|
||||
|
||||
gpio_table:
|
||||
;; P1DDR
|
||||
.byte 0xff,0xff
|
||||
;; P2DDR
|
||||
.byte 0xff,0xff
|
||||
;; P3DDR
|
||||
.byte 0xff,0x00
|
||||
;; P4DDR
|
||||
.byte 0x00,0x00
|
||||
;; P5DDR
|
||||
.byte 0x01,0x01
|
||||
;; P6DDR
|
||||
.byte 0x00,0x00
|
||||
;; dummy
|
||||
.byte 0x00,0x00
|
||||
;; P8DDR
|
||||
.byte 0x0c,0x0c
|
||||
;; P9DDR
|
||||
.byte 0x00,0x00
|
||||
;; PADDR
|
||||
.byte 0x00,0x00
|
||||
;; PBDDR
|
||||
.byte 0x30,0x30
|
||||
|
||||
__target_name:
|
||||
.asciz "AE-3068"
|
||||
|
||||
.section .bootvec,"ax"
|
||||
jmp @SYMBOL_NAME(_start)
|
||||
52
arch/h8300/platform/h8300h/aki3068net/timer.c
Normal file
52
arch/h8300/platform/h8300h/aki3068net/timer.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8300h/aki3068net/timer.c
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourcefoge.jp>
|
||||
*
|
||||
* Platform depend Timer Handler
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/timex.h>
|
||||
|
||||
#include <asm/segment.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/regs306x.h>
|
||||
|
||||
#define CMFA 6
|
||||
|
||||
#define CMIEA 0x40
|
||||
#define CCLR_CMA 0x08
|
||||
#define CLK_DIV8192 0x03
|
||||
|
||||
#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
|
||||
|
||||
void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
|
||||
{
|
||||
/* setup 8bit timer ch2 */
|
||||
ctrl_outb(H8300_TIMER_FREQ / HZ, TCORA2); /* set interval */
|
||||
ctrl_outb(0x00, _8TCSR2); /* no output */
|
||||
request_irq(40, timer_int, 0, "timer", 0);
|
||||
ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR2); /* start count */
|
||||
}
|
||||
|
||||
void platform_timer_eoi(void)
|
||||
{
|
||||
*(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA);
|
||||
}
|
||||
|
||||
void platform_gettod(int *year, int *mon, int *day, int *hour,
|
||||
int *min, int *sec)
|
||||
{
|
||||
*year = *mon = *day = *hour = *min = *sec = 0;
|
||||
}
|
||||
333
arch/h8300/platform/h8300h/entry.S
Normal file
333
arch/h8300/platform/h8300h/entry.S
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
/* -*- mode: asm -*-
|
||||
*
|
||||
* linux/arch/h8300/platform/h8300h/entry.S
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
* David McCullough <davidm@snapgear.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* entry.S
|
||||
* include exception/interrupt gateway
|
||||
* system call entry
|
||||
*/
|
||||
|
||||
#include <linux/sys.h>
|
||||
#include <linux/config.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/linkage.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/errno.h>
|
||||
|
||||
.h8300h
|
||||
|
||||
/* CPU context save/restore macros. */
|
||||
|
||||
.macro SAVE_ALL
|
||||
mov.l er0,@-sp
|
||||
|
||||
stc ccr,r0l /* check kernel mode */
|
||||
orc #0x10,ccr
|
||||
btst #4,r0l
|
||||
bne 5f
|
||||
|
||||
mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */
|
||||
mov.l @sp,er0
|
||||
mov.l @SYMBOL_NAME(sw_ksp),sp
|
||||
sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */
|
||||
mov.l er0,@-sp
|
||||
mov.l er1,@-sp
|
||||
mov.l @SYMBOL_NAME(sw_usp),er0
|
||||
mov.l @(8:16,er0),er1 /* copy the RET addr */
|
||||
mov.l er1,@(LRET-LER1:16,sp)
|
||||
|
||||
mov.w e1,r1 /* e1 highbyte = ccr */
|
||||
and #0xef,r1h /* mask mode? flag */
|
||||
sub.w r0,r0
|
||||
mov.b r1h,r0l
|
||||
mov.w r0,@(LCCR-LER1:16,sp) /* copy ccr */
|
||||
mov.l @(LORIG-LER1:16,sp),er0
|
||||
mov.l er0,@(LER0-LER1:16,sp) /* copy ER0 */
|
||||
bra 6f
|
||||
5:
|
||||
mov.l @sp,er0 /* kernel mode */
|
||||
subs #2,sp /* dummy ccr */
|
||||
mov.l er0,@-sp
|
||||
mov.l er1,@-sp
|
||||
mov.w @(LRET-LER1:16,sp),r1 /* copy old ccr */
|
||||
mov.b r1h,r1l
|
||||
mov.b #0,r1h
|
||||
mov.w r1,@(LCCR-LER1:16,sp) /* set ccr */
|
||||
6:
|
||||
mov.l er2,@-sp
|
||||
mov.l er3,@-sp
|
||||
mov.l er6,@-sp /* syscall arg #6 */
|
||||
mov.l er5,@-sp /* syscall arg #5 */
|
||||
mov.l er4,@-sp /* syscall arg #4 */
|
||||
.endm
|
||||
|
||||
.macro RESTORE_ALL
|
||||
mov.l @sp+,er4
|
||||
mov.l @sp+,er5
|
||||
mov.l @sp+,er6
|
||||
mov.l @sp+,er3
|
||||
mov.l @sp+,er2
|
||||
mov.w @(LCCR-LER1:16,sp),r0 /* check kernel mode */
|
||||
btst #4,r0l
|
||||
bne 7f
|
||||
|
||||
orc #0x80,ccr
|
||||
mov.l @SYMBOL_NAME(sw_usp),er0
|
||||
mov.l @(LER0-LER1:16,sp),er1 /* restore ER0 */
|
||||
mov.l er1,@er0
|
||||
mov.w @(LCCR-LER1:16,sp),r1 /* restore the RET addr */
|
||||
mov.b r1l,r1h
|
||||
mov.b @(LRET+1-LER1:16,sp),r1l
|
||||
mov.w r1,e1
|
||||
mov.w @(LRET+2-LER1:16,sp),r1
|
||||
mov.l er1,@(8:16,er0)
|
||||
|
||||
mov.l @sp+,er1
|
||||
add.l #(LRET-LER1),sp /* remove LORIG - LRET */
|
||||
mov.l sp,@SYMBOL_NAME(sw_ksp)
|
||||
mov.l er0,sp
|
||||
bra 8f
|
||||
7:
|
||||
mov.l @sp+,er1
|
||||
adds #4,sp
|
||||
adds #2,sp
|
||||
8:
|
||||
mov.l @sp+,er0
|
||||
adds #4,sp /* remove the sw created LVEC */
|
||||
rte
|
||||
.endm
|
||||
|
||||
.globl SYMBOL_NAME(system_call)
|
||||
.globl SYMBOL_NAME(ret_from_exception)
|
||||
.globl SYMBOL_NAME(ret_from_fork)
|
||||
.globl SYMBOL_NAME(ret_from_interrupt)
|
||||
.globl SYMBOL_NAME(interrupt_redirect_table)
|
||||
.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
|
||||
.globl SYMBOL_NAME(resume)
|
||||
.globl SYMBOL_NAME(interrupt_redirect_table)
|
||||
.globl SYMBOL_NAME(interrupt_entry)
|
||||
.globl SYMBOL_NAME(system_call)
|
||||
.globl SYMBOL_NAME(trace_break)
|
||||
|
||||
#if defined(CONFIG_ROMKERNEL)
|
||||
INTERRUPTS = 64
|
||||
.section .int_redirect,"ax"
|
||||
SYMBOL_NAME_LABEL(interrupt_redirect_table)
|
||||
.rept 7
|
||||
.long 0
|
||||
.endr
|
||||
jsr @SYMBOL_NAME(interrupt_entry) /* NMI */
|
||||
jmp @SYMBOL_NAME(system_call) /* TRAPA #0 (System call) */
|
||||
.long 0
|
||||
.long 0
|
||||
jmp @SYMBOL_NAME(trace_break) /* TRAPA #3 (breakpoint) */
|
||||
.rept INTERRUPTS-12
|
||||
jsr @SYMBOL_NAME(interrupt_entry)
|
||||
.endr
|
||||
#endif
|
||||
#if defined(CONFIG_RAMKERNEL)
|
||||
.globl SYMBOL_NAME(interrupt_redirect_table)
|
||||
.section .bss
|
||||
SYMBOL_NAME_LABEL(interrupt_redirect_table)
|
||||
.space 4
|
||||
#endif
|
||||
|
||||
.section .text
|
||||
.align 2
|
||||
SYMBOL_NAME_LABEL(interrupt_entry)
|
||||
SAVE_ALL
|
||||
mov.w @(LCCR,sp),r0
|
||||
btst #4,r0l
|
||||
bne 1f
|
||||
mov.l @SYMBOL_NAME(sw_usp),er0
|
||||
mov.l @(4:16,er0),er0
|
||||
bra 2f
|
||||
1:
|
||||
mov.l @(LVEC,sp),er0
|
||||
2:
|
||||
#if defined(CONFIG_ROMKERNEL)
|
||||
sub.l #SYMBOL_NAME(interrupt_redirect_table),er0
|
||||
#endif
|
||||
#if defined(CONFIG_RAMKERNEL)
|
||||
mov.l @SYMBOL_NAME(interrupt_redirect_table),er1
|
||||
sub.l er1,er0
|
||||
#endif
|
||||
shlr.l er0
|
||||
shlr.l er0
|
||||
dec.l #1,er0
|
||||
mov.l sp,er1
|
||||
subs #4,er1 /* adjust ret_pc */
|
||||
jsr @SYMBOL_NAME(process_int)
|
||||
mov.l @SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,er0
|
||||
beq 1f
|
||||
jsr @SYMBOL_NAME(do_softirq)
|
||||
1:
|
||||
jmp @SYMBOL_NAME(ret_from_interrupt)
|
||||
|
||||
SYMBOL_NAME_LABEL(system_call)
|
||||
subs #4,sp /* dummy LVEC */
|
||||
SAVE_ALL
|
||||
mov.w @(LCCR:16,sp),r1
|
||||
bset #4,r1l
|
||||
ldc r1l,ccr
|
||||
mov.l er0,er4
|
||||
mov.l #-ENOSYS,er0
|
||||
mov.l er0,@(LER0:16,sp)
|
||||
|
||||
/* save top of frame */
|
||||
mov.l sp,er0
|
||||
jsr @SYMBOL_NAME(set_esp0)
|
||||
cmp.l #NR_syscalls,er4
|
||||
bcc SYMBOL_NAME(ret_from_exception):16
|
||||
shll.l er4
|
||||
shll.l er4
|
||||
mov.l #SYMBOL_NAME(sys_call_table),er0
|
||||
add.l er4,er0
|
||||
mov.l @er0,er4
|
||||
beq SYMBOL_NAME(ret_from_exception):16
|
||||
mov.l sp,er2
|
||||
and.w #0xe000,r2
|
||||
mov.b @((TASK_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
|
||||
btst #(TIF_SYSCALL_TRACE & 7),r2l
|
||||
bne 1f
|
||||
mov.l @(LER1:16,sp),er0
|
||||
mov.l @(LER2:16,sp),er1
|
||||
mov.l @(LER3:16,sp),er2
|
||||
jsr @er4
|
||||
mov.l er0,@(LER0:16,sp) /* save the return value */
|
||||
#if defined(CONFIG_SYSCALL_PRINT)
|
||||
jsr @SYMBOL_NAME(syscall_print)
|
||||
#endif
|
||||
bra SYMBOL_NAME(ret_from_exception):8
|
||||
1:
|
||||
jsr SYMBOL_NAME(syscall_trace)
|
||||
mov.l @(LER1:16,sp),er0
|
||||
mov.l @(LER2:16,sp),er1
|
||||
mov.l @(LER3:16,sp),er2
|
||||
jsr @er4
|
||||
mov.l er0,@(LER0:16,sp) /* save the return value */
|
||||
jsr @SYMBOL_NAME(syscall_trace)
|
||||
bra SYMBOL_NAME(ret_from_exception):8
|
||||
|
||||
SYMBOL_NAME_LABEL(ret_from_fork)
|
||||
mov.l er2,er0
|
||||
jsr @SYMBOL_NAME(schedule_tail)
|
||||
bra SYMBOL_NAME(ret_from_exception):8
|
||||
|
||||
SYMBOL_NAME_LABEL(reschedule)
|
||||
/* save top of frame */
|
||||
mov.l sp,er0
|
||||
jsr @SYMBOL_NAME(set_esp0)
|
||||
jsr @SYMBOL_NAME(schedule)
|
||||
|
||||
SYMBOL_NAME_LABEL(ret_from_exception)
|
||||
#if defined(CONFIG_PREEMPT)
|
||||
orc #0x80,ccr
|
||||
#endif
|
||||
SYMBOL_NAME_LABEL(ret_from_interrupt)
|
||||
mov.b @(LCCR+1:16,sp),r0l
|
||||
btst #4,r0l /* check if returning to kernel */
|
||||
bne done:8 /* if so, skip resched, signals */
|
||||
andc #0x7f,ccr
|
||||
mov.l sp,er4
|
||||
and.w #0xe000,r4
|
||||
mov.l @(TI_FLAGS:16,er4),er1
|
||||
and.l #_TIF_WORK_MASK,er1
|
||||
beq done:8
|
||||
1:
|
||||
mov.l @(TI_FLAGS:16,er4),er1
|
||||
btst #TIF_NEED_RESCHED,r1l
|
||||
bne SYMBOL_NAME(reschedule):16
|
||||
mov.l sp,er0
|
||||
subs #4,er0 /* adjust retpc */
|
||||
mov.l er2,er1
|
||||
jsr @SYMBOL_NAME(do_signal)
|
||||
#if defined(CONFIG_PREEMPT)
|
||||
bra done:8 /* userspace thoru */
|
||||
3:
|
||||
btst #4,r0l
|
||||
beq done:8 /* userspace thoru */
|
||||
4:
|
||||
mov.l @(TI_PRE_COUNT:16,er4),er1
|
||||
bne done:8
|
||||
mov.l @(TI_FLAGS:16,er4),er1
|
||||
btst #TIF_NEED_RESCHED,r1l
|
||||
beq done:8
|
||||
mov.b r0l,r0l
|
||||
bpl done:8 /* interrupt off (exception path?) */
|
||||
mov.l #PREEMPT_ACTIVE,er1
|
||||
mov.l er1,@(TI_PRE_COUNT:16,er4)
|
||||
andc #0x7f,ccr
|
||||
jsr @SYMBOL_NAME(schedule)
|
||||
sub.l er1,er1
|
||||
mov.l er1,@(TI_PRE_COUNT:16,er4)
|
||||
orc #0x80,ccr
|
||||
bra 4b:8
|
||||
#endif
|
||||
done:
|
||||
RESTORE_ALL /* Does RTE */
|
||||
|
||||
SYMBOL_NAME_LABEL(resume)
|
||||
/*
|
||||
* Beware - when entering resume, offset of tss is in d1,
|
||||
* prev (the current task) is in a0, next (the new task)
|
||||
* is in a1 and d2.b is non-zero if the mm structure is
|
||||
* shared between the tasks, so don't change these
|
||||
* registers until their contents are no longer needed.
|
||||
*/
|
||||
|
||||
/* save sr */
|
||||
sub.w r3,r3
|
||||
stc ccr,r3l
|
||||
mov.w r3,@(THREAD_CCR+2:16,er0)
|
||||
|
||||
/* disable interrupts */
|
||||
orc #0x80,ccr
|
||||
mov.l @SYMBOL_NAME(sw_usp),er3
|
||||
mov.l er3,@(THREAD_USP:16,er0)
|
||||
mov.l sp,@(THREAD_KSP:16,er0)
|
||||
|
||||
/* Skip address space switching if they are the same. */
|
||||
/* FIXME: what did we hack out of here, this does nothing! */
|
||||
|
||||
mov.l @(THREAD_USP:16,er1),er0
|
||||
mov.l er0,@SYMBOL_NAME(sw_usp)
|
||||
mov.l @(THREAD_KSP:16,er1),sp
|
||||
|
||||
/* restore status register */
|
||||
mov.w @(THREAD_CCR+2:16,er1),r3
|
||||
|
||||
ldc r3l,ccr
|
||||
rts
|
||||
|
||||
SYMBOL_NAME_LABEL(trace_break)
|
||||
subs #4,sp
|
||||
SAVE_ALL
|
||||
sub.l er1,er1
|
||||
dec.l #1,er1
|
||||
mov.l er1,@(LORIG,sp)
|
||||
mov.l sp,er0
|
||||
jsr @SYMBOL_NAME(set_esp0)
|
||||
mov.l @SYMBOL_NAME(sw_usp),er0
|
||||
mov.l @er0,er1
|
||||
subs #2,er1
|
||||
mov.l er1,@er0
|
||||
and.w #0xff,e1
|
||||
mov.l er1,er0
|
||||
jsr @SYMBOL_NAME(trace_trap)
|
||||
jmp @SYMBOL_NAME(ret_from_exception)
|
||||
|
||||
.section .bss
|
||||
SYMBOL_NAME_LABEL(sw_ksp)
|
||||
.space 4
|
||||
SYMBOL_NAME_LABEL(sw_usp)
|
||||
.space 4
|
||||
6
arch/h8300/platform/h8300h/generic/Makefile
Normal file
6
arch/h8300/platform/h8300h/generic/Makefile
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
obj-y := timer.o
|
||||
extra-y = crt0_$(MODEL).o
|
||||
108
arch/h8300/platform/h8300h/generic/crt0_ram.S
Normal file
108
arch/h8300/platform/h8300h/generic/crt0_ram.S
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8300h/generic/crt0_ram.S
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Platform depend startup
|
||||
* Target Archtecture: AE-3068 (aka. aki3068net)
|
||||
* Memory Layout : RAM
|
||||
*/
|
||||
|
||||
#define ASSEMBLY
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <asm/linkage.h>
|
||||
|
||||
#if !defined(CONFIG_BLKDEV_RESERVE)
|
||||
#if defined(CONFIG_GDB_DEBUG)
|
||||
#define RAMEND (__ramend - 0xc000)
|
||||
#else
|
||||
#define RAMEND __ramend
|
||||
#endif
|
||||
#else
|
||||
#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
|
||||
#endif
|
||||
|
||||
.global SYMBOL_NAME(_start)
|
||||
.global SYMBOL_NAME(command_line)
|
||||
.global SYMBOL_NAME(_platform_gpio_table)
|
||||
.global SYMBOL_NAME(_target_name)
|
||||
|
||||
.h8300h
|
||||
|
||||
.section .text
|
||||
.file "crt0_ram.S"
|
||||
|
||||
/* CPU Reset entry */
|
||||
SYMBOL_NAME_LABEL(_start)
|
||||
mov.l #RAMEND,sp
|
||||
ldc #0x80,ccr
|
||||
|
||||
/* Peripheral Setup */
|
||||
|
||||
#if defined(CONFIG_BLK_DEV_BLKMEM)
|
||||
/* move romfs image */
|
||||
jsr @__move_romfs
|
||||
#endif
|
||||
|
||||
/* .bss clear */
|
||||
mov.l #__sbss,er5
|
||||
mov.l #__ebss,er4
|
||||
sub.l er5,er4
|
||||
shlr er4
|
||||
shlr er4
|
||||
sub.l er0,er0
|
||||
1:
|
||||
mov.l er0,@er5
|
||||
adds #4,er5
|
||||
dec.l #1,er4
|
||||
bne 1b
|
||||
|
||||
/* copy kernel commandline */
|
||||
mov.l #COMMAND_START,er5
|
||||
mov.l #SYMBOL_NAME(command_line),er6
|
||||
mov.w #512,r4
|
||||
eepmov.w
|
||||
|
||||
/* uClinux kernel start */
|
||||
ldc #0x90,ccr /* running kernel */
|
||||
mov.l #SYMBOL_NAME(init_thread_union),sp
|
||||
add.l #0x2000,sp
|
||||
jsr @_start_kernel
|
||||
_exit:
|
||||
|
||||
jmp _exit
|
||||
|
||||
rts
|
||||
|
||||
/* I/O port assign information */
|
||||
__platform_gpio_table:
|
||||
mov.l #gpio_table,er0
|
||||
rts
|
||||
|
||||
gpio_table:
|
||||
;; P1DDR
|
||||
.byte 0x00,0x00
|
||||
;; P2DDR
|
||||
.byte 0x00,0x00
|
||||
;; P3DDR
|
||||
.byte 0x00,0x00
|
||||
;; P4DDR
|
||||
.byte 0x00,0x00
|
||||
;; P5DDR
|
||||
.byte 0x00,0x00
|
||||
;; P6DDR
|
||||
.byte 0x00,0x00
|
||||
;; dummy
|
||||
.byte 0x00,0x00
|
||||
;; P8DDR
|
||||
.byte 0x00,0x00
|
||||
;; P9DDR
|
||||
.byte 0x00,0x00
|
||||
;; PADDR
|
||||
.byte 0x00,0x00
|
||||
;; PBDDR
|
||||
.byte 0x00,0x00
|
||||
|
||||
__target_name:
|
||||
.asciz "generic"
|
||||
123
arch/h8300/platform/h8300h/generic/crt0_rom.S
Normal file
123
arch/h8300/platform/h8300h/generic/crt0_rom.S
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8300h/generic/crt0_rom.S
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Platform depend startup
|
||||
* Target Archtecture: generic
|
||||
* Memory Layout : ROM
|
||||
*/
|
||||
|
||||
#define ASSEMBLY
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <asm/linkage.h>
|
||||
|
||||
.global SYMBOL_NAME(_start)
|
||||
.global SYMBOL_NAME(_command_line)
|
||||
.global SYMBOL_NAME(_platform_gpio_table)
|
||||
.global SYMBOL_NAME(_target_name)
|
||||
|
||||
.h8300h
|
||||
.section .text
|
||||
.file "crt0_rom.S"
|
||||
|
||||
/* CPU Reset entry */
|
||||
SYMBOL_NAME_LABEL(_start)
|
||||
mov.l #__ramend,sp
|
||||
ldc #0x80,ccr
|
||||
|
||||
/* Peripheral Setup */
|
||||
|
||||
/* .bss clear */
|
||||
mov.l #__sbss,er5
|
||||
mov.l #__ebss,er4
|
||||
sub.l er5,er4
|
||||
shlr er4
|
||||
shlr er4
|
||||
sub.l er0,er0
|
||||
1:
|
||||
mov.l er0,@er5
|
||||
adds #4,er5
|
||||
dec.l #1,er4
|
||||
bne 1b
|
||||
|
||||
/* copy .data */
|
||||
#if !defined(CONFIG_H8300H_SIM)
|
||||
/* copy .data */
|
||||
mov.l #__begin_data,er5
|
||||
mov.l #__sdata,er6
|
||||
mov.l #__edata,er4
|
||||
sub.l er6,er4
|
||||
shlr.l er4
|
||||
shlr.l er4
|
||||
1:
|
||||
mov.l @er5+,er0
|
||||
mov.l er0,@er6
|
||||
adds #4,er6
|
||||
dec.l #1,er4
|
||||
bne 1b
|
||||
#endif
|
||||
|
||||
/* copy kernel commandline */
|
||||
mov.l #COMMAND_START,er5
|
||||
mov.l #SYMBOL_NAME(_command_line),er6
|
||||
mov.w #512,r4
|
||||
eepmov.w
|
||||
|
||||
/* linux kernel start */
|
||||
ldc #0x90,ccr /* running kernel */
|
||||
mov.l #SYMBOL_NAME(init_thread_union),sp
|
||||
add.l #0x2000,sp
|
||||
jsr @_start_kernel
|
||||
_exit:
|
||||
|
||||
jmp _exit
|
||||
|
||||
rts
|
||||
|
||||
/* I/O port assign information */
|
||||
__platform_gpio_table:
|
||||
mov.l #gpio_table,er0
|
||||
rts
|
||||
|
||||
gpio_table:
|
||||
;; P1DDR
|
||||
.byte 0x00,0x00
|
||||
;; P2DDR
|
||||
.byte 0x00,0x00
|
||||
;; P3DDR
|
||||
.byte 0x00,0x00
|
||||
;; P4DDR
|
||||
.byte 0x00,0x00
|
||||
;; P5DDR
|
||||
.byte 0x00,0x00
|
||||
;; P6DDR
|
||||
.byte 0x00,0x00
|
||||
;; dummy
|
||||
.byte 0x00,0x00
|
||||
;; P8DDR
|
||||
.byte 0x00,0x00
|
||||
;; P9DDR
|
||||
.byte 0x00,0x00
|
||||
;; PADDR
|
||||
.byte 0x00,0x00
|
||||
;; PBDDR
|
||||
.byte 0x00,0x00
|
||||
|
||||
.section .rodata
|
||||
__target_name:
|
||||
.asciz "generic"
|
||||
|
||||
.section .bss
|
||||
__command_line:
|
||||
.space 512
|
||||
|
||||
/* interrupt vector */
|
||||
.section .vectors,"ax"
|
||||
.long __start
|
||||
vector = 1
|
||||
.rept 64-1
|
||||
.long _interrupt_redirect_table+vector*4
|
||||
vector = vector + 1
|
||||
.endr
|
||||
96
arch/h8300/platform/h8300h/generic/timer.c
Normal file
96
arch/h8300/platform/h8300h/generic/timer.c
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8300h/generic/timer.c
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Platform depend Timer Handler
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <asm/segment.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <linux/timex.h>
|
||||
|
||||
#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
|
||||
#include <asm/regs306x.h>
|
||||
#define CMFA 6
|
||||
|
||||
#define CMIEA 0x40
|
||||
#define CCLR_CMA 0x08
|
||||
#define CLK_DIV8192 0x03
|
||||
|
||||
#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
|
||||
|
||||
void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
|
||||
{
|
||||
/* setup 8bit timer ch2 */
|
||||
ctrl_outb(H8300_TIMER_FREQ / HZ, TCORA2); /* set interval */
|
||||
ctrl_outb(0x00, _8TCSR2); /* no output */
|
||||
request_irq(40, timer_int, 0, "timer", 0);
|
||||
ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR2); /* start count */
|
||||
}
|
||||
|
||||
void platform_timer_eoi(void)
|
||||
{
|
||||
*(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_H83002) || defined(CONFIG_H83048)
|
||||
/* FIXME! */
|
||||
#define TSTR 0x00ffff60
|
||||
#define TSNC 0x00ffff61
|
||||
#define TMDR 0x00ffff62
|
||||
#define TFCR 0x00ffff63
|
||||
#define TOER 0x00ffff90
|
||||
#define TOCR 0x00ffff91
|
||||
/* ITU0 */
|
||||
#define TCR 0x00ffff64
|
||||
#define TIOR 0x00ffff65
|
||||
#define TIER 0x00ffff66
|
||||
#define TSR 0x00ffff67
|
||||
#define TCNT 0x00ffff68
|
||||
#define GRA 0x00ffff6a
|
||||
#define GRB 0x00ffff6c
|
||||
|
||||
#define CCLR_CMGRA 0x20
|
||||
#define CLK_DIV8 0x03
|
||||
|
||||
#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8 /* Timer input freq. */
|
||||
|
||||
void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
|
||||
{
|
||||
*(unsigned short *)GRA= H8300_TIMER_FREQ / HZ; /* set interval */
|
||||
*(unsigned short *)TCNT=0; /* clear counter */
|
||||
ctrl_outb(0x80|CCLR_CMGRA|CLK_DIV8, TCR); /* set ITU0 clock */
|
||||
ctrl_outb(0x88, TIOR); /* no output */
|
||||
request_irq(26, timer_int, 0, "timer", 0);
|
||||
ctrl_outb(0xf9, TIER); /* compare match GRA interrupt */
|
||||
ctrl_outb(ctrl_inb(TSNC) & ~0x01, TSNC); /* ITU0 async */
|
||||
ctrl_outb(ctrl_inb(TMDR) & ~0x01, TMDR); /* ITU0 normal mode */
|
||||
ctrl_outb(ctrl_inb(TSTR) | 0x01, TSTR); /* ITU0 Start */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void platform_timer_eoi(void)
|
||||
{
|
||||
ctrl_outb(ctrl_inb(TSR) & ~0x01,TSR);
|
||||
}
|
||||
#endif
|
||||
|
||||
void platform_gettod(int *year, int *mon, int *day, int *hour,
|
||||
int *min, int *sec)
|
||||
{
|
||||
*year = *mon = *day = *hour = *min = *sec = 0;
|
||||
}
|
||||
6
arch/h8300/platform/h8300h/h8max/Makefile
Normal file
6
arch/h8300/platform/h8300h/h8max/Makefile
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
extra-y := crt0_ram.o
|
||||
obj-y := timer.o
|
||||
111
arch/h8300/platform/h8300h/h8max/crt0_ram.S
Normal file
111
arch/h8300/platform/h8300h/h8max/crt0_ram.S
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8300h/h8max/crt0_ram.S
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Platform depend startup
|
||||
* Target Archtecture: H8MAX
|
||||
* Memory Layout : RAM
|
||||
*/
|
||||
|
||||
#define ASSEMBLY
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <asm/linkage.h>
|
||||
|
||||
#if !defined(CONFIG_BLKDEV_RESERVE)
|
||||
#if defined(CONFIG_GDB_DEBUG)
|
||||
#define RAMEND (__ramend - 0xc000)
|
||||
#else
|
||||
#define RAMEND __ramend
|
||||
#endif
|
||||
#else
|
||||
#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
|
||||
#endif
|
||||
|
||||
.global SYMBOL_NAME(_start)
|
||||
.global SYMBOL_NAME(command_line)
|
||||
.global SYMBOL_NAME(_platform_gpio_table)
|
||||
.global SYMBOL_NAME(_target_name)
|
||||
|
||||
.h8300h
|
||||
|
||||
.section .text
|
||||
.file "crt0_ram.S"
|
||||
|
||||
/* CPU Reset entry */
|
||||
SYMBOL_NAME_LABEL(_start)
|
||||
mov.l #RAMEND,sp
|
||||
ldc #0x80,ccr
|
||||
|
||||
/* Peripheral Setup */
|
||||
|
||||
#if defined(CONFIG_MTD_UCLINUX)
|
||||
/* move romfs image */
|
||||
jsr @__move_romfs
|
||||
#endif
|
||||
|
||||
/* .bss clear */
|
||||
mov.l #__sbss,er5
|
||||
mov.l #__ebss,er4
|
||||
sub.l er5,er4
|
||||
shlr er4
|
||||
shlr er4
|
||||
sub.l er0,er0
|
||||
1:
|
||||
mov.l er0,@er5
|
||||
adds #4,er5
|
||||
dec.l #1,er4
|
||||
bne 1b
|
||||
|
||||
/* copy kernel commandline */
|
||||
mov.l #COMMAND_START,er5
|
||||
mov.l #SYMBOL_NAME(command_line),er6
|
||||
mov.w #512,r4
|
||||
eepmov.w
|
||||
|
||||
/* uClinux kernel start */
|
||||
ldc #0x90,ccr /* running kernel */
|
||||
mov.l #SYMBOL_NAME(init_thread_union),sp
|
||||
add.l #0x2000,sp
|
||||
jsr @_start_kernel
|
||||
_exit:
|
||||
|
||||
jmp _exit
|
||||
|
||||
rts
|
||||
|
||||
/* I/O port assign information */
|
||||
__platform_gpio_table:
|
||||
mov.l #gpio_table,er0
|
||||
rts
|
||||
|
||||
gpio_table:
|
||||
;; P1DDR
|
||||
.byte 0xff,0xff
|
||||
;; P2DDR
|
||||
.byte 0xff,0xff
|
||||
;; P3DDR
|
||||
.byte 0x00,0x00
|
||||
;; P4DDR
|
||||
.byte 0x00,0x00
|
||||
;; P5DDR
|
||||
.byte 0x01,0x01
|
||||
;; P6DDR
|
||||
.byte 0xf6,0xf6
|
||||
;; dummy
|
||||
.byte 0x00,0x00
|
||||
;; P8DDR
|
||||
.byte 0xee,0xee
|
||||
;; P9DDR
|
||||
.byte 0x00,0x00
|
||||
;; PADDR
|
||||
.byte 0x00,0x00
|
||||
;; PBDDR
|
||||
.byte 0x30,0x30
|
||||
|
||||
__target_name:
|
||||
.asciz "H8MAX"
|
||||
|
||||
.section .bootvec,"ax"
|
||||
jmp @SYMBOL_NAME(_start)
|
||||
53
arch/h8300/platform/h8300h/h8max/timer.c
Normal file
53
arch/h8300/platform/h8300h/h8max/timer.c
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8300h/h8max/timer.c
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourcefoge.jp>
|
||||
*
|
||||
* Platform depend Timer Handler
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/timex.h>
|
||||
|
||||
#include <asm/segment.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/regs306x.h>
|
||||
|
||||
#define CMFA 6
|
||||
|
||||
#define CMIEA 0x40
|
||||
#define CCLR_CMA 0x08
|
||||
#define CLK_DIV8192 0x03
|
||||
|
||||
#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
|
||||
|
||||
void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
|
||||
{
|
||||
/* setup 8bit timer ch2 */
|
||||
ctrl_outb(H8300_TIMER_FREQ / HZ, TCORA2); /* set interval */
|
||||
ctrl_outb(0x00, _8TCSR2); /* no output */
|
||||
request_irq(40, timer_int, 0, "timer", 0);
|
||||
ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR2); /* start count */
|
||||
}
|
||||
|
||||
void platform_timer_eoi(void)
|
||||
{
|
||||
*(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA);
|
||||
}
|
||||
|
||||
void platform_gettod(int *year, int *mon, int *day, int *hour,
|
||||
int *min, int *sec)
|
||||
{
|
||||
*year = *mon = *day = *hour = *min = *sec = 0;
|
||||
}
|
||||
|
||||
86
arch/h8300/platform/h8300h/ints_h8300h.c
Normal file
86
arch/h8300/platform/h8300h/ints_h8300h.c
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8300h/ints_h8300h.c
|
||||
* Interrupt handling CPU variants
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/regs306x.h>
|
||||
|
||||
/* saved vector list */
|
||||
const int __initdata h8300_saved_vectors[]={
|
||||
#if defined(CONFIG_GDB_DEBUG)
|
||||
TRAP3_VEC,
|
||||
#endif
|
||||
-1
|
||||
};
|
||||
|
||||
/* trap entry table */
|
||||
const unsigned long __initdata h8300_trap_table[NR_TRAPS]={
|
||||
0,0,0,0,0,0,0,0,
|
||||
(unsigned long)system_call, /* TRAPA #0 */
|
||||
0,0,
|
||||
(unsigned long)trace_break, /* TRAPA #3 */
|
||||
};
|
||||
|
||||
int h8300_enable_irq_pin(unsigned int irq)
|
||||
{
|
||||
int bitmask;
|
||||
if (irq < EXT_IRQ0 || irq > EXT_IRQ5)
|
||||
return 0;
|
||||
|
||||
/* initialize IRQ pin */
|
||||
bitmask = 1 << (irq - EXT_IRQ0);
|
||||
switch(irq) {
|
||||
case EXT_IRQ0:
|
||||
case EXT_IRQ1:
|
||||
case EXT_IRQ2:
|
||||
case EXT_IRQ3:
|
||||
if (H8300_GPIO_RESERVE(H8300_GPIO_P8, bitmask) == 0)
|
||||
return -EBUSY;
|
||||
H8300_GPIO_DDR(H8300_GPIO_P8, bitmask, H8300_GPIO_INPUT);
|
||||
break;
|
||||
case EXT_IRQ4:
|
||||
case EXT_IRQ5:
|
||||
if (H8300_GPIO_RESERVE(H8300_GPIO_P9, bitmask) == 0)
|
||||
return -EBUSY;
|
||||
H8300_GPIO_DDR(H8300_GPIO_P9, bitmask, H8300_GPIO_INPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void h8300_disable_irq_pin(unsigned int irq)
|
||||
{
|
||||
int bitmask;
|
||||
if (irq < EXT_IRQ0 || irq > EXT_IRQ5)
|
||||
return;
|
||||
|
||||
/* disable interrupt & release IRQ pin */
|
||||
bitmask = 1 << (irq - EXT_IRQ0);
|
||||
switch(irq) {
|
||||
case EXT_IRQ0:
|
||||
case EXT_IRQ1:
|
||||
case EXT_IRQ2:
|
||||
case EXT_IRQ3:
|
||||
*(volatile unsigned char *)IER &= ~bitmask;
|
||||
H8300_GPIO_FREE(H8300_GPIO_P8, bitmask);
|
||||
break ;
|
||||
case EXT_IRQ4:
|
||||
case EXT_IRQ5:
|
||||
*(volatile unsigned char *)IER &= ~bitmask;
|
||||
H8300_GPIO_FREE(H8300_GPIO_P9, bitmask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
284
arch/h8300/platform/h8300h/ptrace_h8300h.c
Normal file
284
arch/h8300/platform/h8300h/ptrace_h8300h.c
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8300h/ptrace_h8300h.c
|
||||
* ptrace cpu depend helper functions
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* 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/linkage.h>
|
||||
#include <linux/sched.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
#define CCR_MASK 0x6f /* mode/imask not set */
|
||||
#define BREAKINST 0x5730 /* trapa #3 */
|
||||
|
||||
/* 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 h8300_register_offset[] = {
|
||||
PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4),
|
||||
PT_REG(er5), PT_REG(er6), PT_REG(er0), PT_REG(orig_er0),
|
||||
PT_REG(ccr), PT_REG(pc)
|
||||
};
|
||||
|
||||
/* read register */
|
||||
long h8300_get_reg(struct task_struct *task, int regno)
|
||||
{
|
||||
switch (regno) {
|
||||
case PT_USP:
|
||||
return task->thread.usp + sizeof(long)*2;
|
||||
case PT_CCR:
|
||||
return *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]);
|
||||
default:
|
||||
return *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]);
|
||||
}
|
||||
}
|
||||
|
||||
/* write register */
|
||||
int h8300_put_reg(struct task_struct *task, int regno, unsigned long data)
|
||||
{
|
||||
unsigned short oldccr;
|
||||
switch (regno) {
|
||||
case PT_USP:
|
||||
task->thread.usp = data - sizeof(long)*2;
|
||||
case PT_CCR:
|
||||
oldccr = *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]);
|
||||
oldccr &= ~CCR_MASK;
|
||||
data &= CCR_MASK;
|
||||
data |= oldccr;
|
||||
*(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]) = data;
|
||||
break;
|
||||
default:
|
||||
*(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]) = data;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* disable singlestep */
|
||||
void h8300_disable_trace(struct task_struct *child)
|
||||
{
|
||||
if((long)child->thread.breakinfo.addr != -1L) {
|
||||
*child->thread.breakinfo.addr = child->thread.breakinfo.inst;
|
||||
child->thread.breakinfo.addr = (unsigned short *)-1L;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate next pc */
|
||||
enum jump_type {none, /* normal instruction */
|
||||
jabs, /* absolute address jump */
|
||||
ind, /* indirect address jump */
|
||||
ret, /* return to subrutine */
|
||||
reg, /* register indexed jump */
|
||||
relb, /* pc relative jump (byte offset) */
|
||||
relw, /* pc relative jump (word offset) */
|
||||
};
|
||||
|
||||
/* opcode decode table define
|
||||
ptn: opcode pattern
|
||||
msk: opcode bitmask
|
||||
len: instruction length (<0 next table index)
|
||||
jmp: jump operation mode */
|
||||
struct optable {
|
||||
unsigned char bitpattern;
|
||||
unsigned char bitmask;
|
||||
signed char length;
|
||||
signed char type;
|
||||
} __attribute__((aligned(1),packed));
|
||||
|
||||
#define OPTABLE(ptn,msk,len,jmp) \
|
||||
{ \
|
||||
.bitpattern = ptn, \
|
||||
.bitmask = msk, \
|
||||
.length = len, \
|
||||
.type = jmp, \
|
||||
}
|
||||
|
||||
const static struct optable optable_0[] = {
|
||||
OPTABLE(0x00,0xff, 1,none), /* 0x00 */
|
||||
OPTABLE(0x01,0xff,-1,none), /* 0x01 */
|
||||
OPTABLE(0x02,0xfe, 1,none), /* 0x02-0x03 */
|
||||
OPTABLE(0x04,0xee, 1,none), /* 0x04-0x05/0x14-0x15 */
|
||||
OPTABLE(0x06,0xfe, 1,none), /* 0x06-0x07 */
|
||||
OPTABLE(0x08,0xea, 1,none), /* 0x08-0x09/0x0c-0x0d/0x18-0x19/0x1c-0x1d */
|
||||
OPTABLE(0x0a,0xee, 1,none), /* 0x0a-0x0b/0x1a-0x1b */
|
||||
OPTABLE(0x0e,0xee, 1,none), /* 0x0e-0x0f/0x1e-0x1f */
|
||||
OPTABLE(0x10,0xfc, 1,none), /* 0x10-0x13 */
|
||||
OPTABLE(0x16,0xfe, 1,none), /* 0x16-0x17 */
|
||||
OPTABLE(0x20,0xe0, 1,none), /* 0x20-0x3f */
|
||||
OPTABLE(0x40,0xf0, 1,relb), /* 0x40-0x4f */
|
||||
OPTABLE(0x50,0xfc, 1,none), /* 0x50-0x53 */
|
||||
OPTABLE(0x54,0xfd, 1,ret ), /* 0x54/0x56 */
|
||||
OPTABLE(0x55,0xff, 1,relb), /* 0x55 */
|
||||
OPTABLE(0x57,0xff, 1,none), /* 0x57 */
|
||||
OPTABLE(0x58,0xfb, 2,relw), /* 0x58/0x5c */
|
||||
OPTABLE(0x59,0xfb, 1,reg ), /* 0x59/0x5b */
|
||||
OPTABLE(0x5a,0xfb, 2,jabs), /* 0x5a/0x5e */
|
||||
OPTABLE(0x5b,0xfb, 2,ind ), /* 0x5b/0x5f */
|
||||
OPTABLE(0x60,0xe8, 1,none), /* 0x60-0x67/0x70-0x77 */
|
||||
OPTABLE(0x68,0xfa, 1,none), /* 0x68-0x69/0x6c-0x6d */
|
||||
OPTABLE(0x6a,0xfe,-2,none), /* 0x6a-0x6b */
|
||||
OPTABLE(0x6e,0xfe, 2,none), /* 0x6e-0x6f */
|
||||
OPTABLE(0x78,0xff, 4,none), /* 0x78 */
|
||||
OPTABLE(0x79,0xff, 2,none), /* 0x79 */
|
||||
OPTABLE(0x7a,0xff, 3,none), /* 0x7a */
|
||||
OPTABLE(0x7b,0xff, 2,none), /* 0x7b */
|
||||
OPTABLE(0x7c,0xfc, 2,none), /* 0x7c-0x7f */
|
||||
OPTABLE(0x80,0x80, 1,none), /* 0x80-0xff */
|
||||
};
|
||||
|
||||
const static struct optable optable_1[] = {
|
||||
OPTABLE(0x00,0xff,-3,none), /* 0x0100 */
|
||||
OPTABLE(0x40,0xf0,-3,none), /* 0x0140-0x14f */
|
||||
OPTABLE(0x80,0xf0, 1,none), /* 0x0180-0x018f */
|
||||
OPTABLE(0xc0,0xc0, 2,none), /* 0x01c0-0x01ff */
|
||||
};
|
||||
|
||||
const static struct optable optable_2[] = {
|
||||
OPTABLE(0x00,0x20, 2,none), /* 0x6a0?/0x6a8?/0x6b0?/0x6b8? */
|
||||
OPTABLE(0x20,0x20, 3,none), /* 0x6a2?/0x6aa?/0x6b2?/0x6ba? */
|
||||
};
|
||||
|
||||
const static struct optable optable_3[] = {
|
||||
OPTABLE(0x69,0xfb, 2,none), /* 0x010069/0x01006d/014069/0x01406d */
|
||||
OPTABLE(0x6b,0xff,-4,none), /* 0x01006b/0x01406b */
|
||||
OPTABLE(0x6f,0xff, 3,none), /* 0x01006f/0x01406f */
|
||||
OPTABLE(0x78,0xff, 5,none), /* 0x010078/0x014078 */
|
||||
};
|
||||
|
||||
const static struct optable optable_4[] = {
|
||||
OPTABLE(0x00,0x78, 3,none), /* 0x0100690?/0x01006d0?/0140690/0x01406d0?/0x0100698?/0x01006d8?/0140698?/0x01406d8? */
|
||||
OPTABLE(0x20,0x78, 4,none), /* 0x0100692?/0x01006d2?/0140692/0x01406d2?/0x010069a?/0x01006da?/014069a?/0x01406da? */
|
||||
};
|
||||
|
||||
const static struct optables_list {
|
||||
const struct optable *ptr;
|
||||
int size;
|
||||
} optables[] = {
|
||||
#define OPTABLES(no) \
|
||||
{ \
|
||||
.ptr = optable_##no, \
|
||||
.size = sizeof(optable_##no) / sizeof(struct optable), \
|
||||
}
|
||||
OPTABLES(0),
|
||||
OPTABLES(1),
|
||||
OPTABLES(2),
|
||||
OPTABLES(3),
|
||||
OPTABLES(4),
|
||||
|
||||
};
|
||||
|
||||
const unsigned char condmask[] = {
|
||||
0x00,0x40,0x01,0x04,0x02,0x08,0x10,0x20
|
||||
};
|
||||
|
||||
static int isbranch(struct task_struct *task,int reson)
|
||||
{
|
||||
unsigned char cond = h8300_get_reg(task, PT_CCR);
|
||||
/* encode complex conditions */
|
||||
/* B4: N^V
|
||||
B5: Z|(N^V)
|
||||
B6: C|Z */
|
||||
__asm__("bld #3,%w0\n\t"
|
||||
"bxor #1,%w0\n\t"
|
||||
"bst #4,%w0\n\t"
|
||||
"bor #2,%w0\n\t"
|
||||
"bst #5,%w0\n\t"
|
||||
"bld #2,%w0\n\t"
|
||||
"bor #0,%w0\n\t"
|
||||
"bst #6,%w0\n\t"
|
||||
:"=&r"(cond)::"cc");
|
||||
cond &= condmask[reson >> 1];
|
||||
if (!(reson & 1))
|
||||
return cond == 0;
|
||||
else
|
||||
return cond != 0;
|
||||
}
|
||||
|
||||
static unsigned short *getnextpc(struct task_struct *child, unsigned short *pc)
|
||||
{
|
||||
const struct optable *op;
|
||||
unsigned char *fetch_p;
|
||||
unsigned char inst;
|
||||
unsigned long addr;
|
||||
unsigned long *sp;
|
||||
int op_len,regno;
|
||||
op = optables[0].ptr;
|
||||
op_len = optables[0].size;
|
||||
fetch_p = (unsigned char *)pc;
|
||||
inst = *fetch_p++;
|
||||
do {
|
||||
if ((inst & op->bitmask) == op->bitpattern) {
|
||||
if (op->length < 0) {
|
||||
op = optables[-op->length].ptr;
|
||||
op_len = optables[-op->length].size + 1;
|
||||
inst = *fetch_p++;
|
||||
} else {
|
||||
switch (op->type) {
|
||||
case none:
|
||||
return pc + op->length;
|
||||
case jabs:
|
||||
addr = *(unsigned long *)pc;
|
||||
return (unsigned short *)(addr & 0x00ffffff);
|
||||
case ind:
|
||||
addr = *pc & 0xff;
|
||||
return (unsigned short *)(*(unsigned long *)addr);
|
||||
case ret:
|
||||
sp = (unsigned long *)h8300_get_reg(child, PT_USP);
|
||||
/* user stack frames
|
||||
| er0 | temporary saved
|
||||
+--------+
|
||||
| exp | exception stack frames
|
||||
+--------+
|
||||
| ret pc | userspace return address
|
||||
*/
|
||||
return (unsigned short *)(*(sp+2) & 0x00ffffff);
|
||||
case reg:
|
||||
regno = (*pc >> 4) & 0x07;
|
||||
if (regno == 0)
|
||||
addr = h8300_get_reg(child, PT_ER0);
|
||||
else
|
||||
addr = h8300_get_reg(child, regno-1+PT_ER1);
|
||||
return (unsigned short *)addr;
|
||||
case relb:
|
||||
if ((inst = 0x55) || isbranch(child,inst & 0x0f))
|
||||
pc = (unsigned short *)((unsigned long)pc +
|
||||
((signed char)(*fetch_p)));
|
||||
return pc+1; /* skip myself */
|
||||
case relw:
|
||||
if ((inst = 0x5c) || isbranch(child,(*fetch_p & 0xf0) >> 4))
|
||||
pc = (unsigned short *)((unsigned long)pc +
|
||||
((signed short)(*(pc+1))));
|
||||
return pc+2; /* skip myself */
|
||||
}
|
||||
}
|
||||
} else
|
||||
op++;
|
||||
} while(--op_len > 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set breakpoint(s) to simulate a single step from the current PC. */
|
||||
|
||||
void h8300_enable_trace(struct task_struct *child)
|
||||
{
|
||||
unsigned short *nextpc;
|
||||
nextpc = getnextpc(child,(unsigned short *)h8300_get_reg(child, PT_PC));
|
||||
child->thread.breakinfo.addr = nextpc;
|
||||
child->thread.breakinfo.inst = *nextpc;
|
||||
*nextpc = BREAKINST;
|
||||
}
|
||||
|
||||
asmlinkage void trace_trap(unsigned long bp)
|
||||
{
|
||||
if ((unsigned long)current->thread.breakinfo.addr == bp) {
|
||||
h8300_disable_trace(current);
|
||||
force_sig(SIGTRAP,current);
|
||||
} else
|
||||
force_sig(SIGILL,current);
|
||||
}
|
||||
|
||||
7
arch/h8300/platform/h8s/Makefile
Normal file
7
arch/h8300/platform/h8s/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
# Reuse any files we can from the H8S
|
||||
#
|
||||
|
||||
obj-y := entry.o ints_h8s.o ptrace_h8s.o
|
||||
6
arch/h8300/platform/h8s/edosk2674/Makefile
Normal file
6
arch/h8300/platform/h8s/edosk2674/Makefile
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
extra-y := crt0_$(MODEL).o
|
||||
obj-y := timer.o
|
||||
131
arch/h8300/platform/h8s/edosk2674/crt0_ram.S
Normal file
131
arch/h8300/platform/h8s/edosk2674/crt0_ram.S
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8s/edosk2674/crt0_ram.S
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Platform depend startup
|
||||
* Target Archtecture: EDOSK-2674
|
||||
* Memory Layout : RAM
|
||||
*/
|
||||
|
||||
#define ASSEMBLY
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <asm/linkage.h>
|
||||
#include <asm/regs267x.h>
|
||||
|
||||
#if !defined(CONFIG_BLKDEV_RESERVE)
|
||||
#if defined(CONFIG_GDB_DEBUG)
|
||||
#define RAMEND (__ramend - 0xc000)
|
||||
#else
|
||||
#define RAMEND __ramend
|
||||
#endif
|
||||
#else
|
||||
#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
|
||||
#endif
|
||||
|
||||
.global SYMBOL_NAME(_start)
|
||||
.global SYMBOL_NAME(_command_line)
|
||||
.global SYMBOL_NAME(_platform_gpio_table)
|
||||
.global SYMBOL_NAME(_target_name)
|
||||
|
||||
.h8300s
|
||||
|
||||
.section .text
|
||||
.file "crt0_ram.S"
|
||||
|
||||
/* CPU Reset entry */
|
||||
SYMBOL_NAME_LABEL(_start)
|
||||
mov.l #RAMEND,sp
|
||||
ldc #0x80,ccr
|
||||
ldc #0x00,exr
|
||||
|
||||
/* Peripheral Setup */
|
||||
bclr #4,@INTCR:8 /* interrupt mode 2 */
|
||||
bset #5,@INTCR:8
|
||||
bclr #0,@IER+1:16
|
||||
bset #1,@ISCRL+1:16 /* IRQ0 Positive Edge */
|
||||
bclr #0,@ISCRL+1:16
|
||||
|
||||
#if defined(CONFIG_MTD_UCLINUX)
|
||||
/* move romfs image */
|
||||
jsr @__move_romfs
|
||||
#endif
|
||||
|
||||
/* .bss clear */
|
||||
mov.l #__sbss,er5
|
||||
mov.l er5,er6
|
||||
mov.l #__ebss,er4
|
||||
sub.l er5,er4
|
||||
shlr #2,er4
|
||||
sub.l er0,er0
|
||||
1:
|
||||
mov.l er0,@er5
|
||||
adds #4,er5
|
||||
dec.l #1,er4
|
||||
bne 1b
|
||||
|
||||
/* copy kernel commandline */
|
||||
mov.l #COMMAND_START,er5
|
||||
mov.l #SYMBOL_NAME(command_line),er6
|
||||
mov.w #512,r4
|
||||
eepmov.w
|
||||
|
||||
/* uClinux kernel start */
|
||||
ldc #0x90,ccr /* running kernel */
|
||||
mov.l #SYMBOL_NAME(init_thread_union),sp
|
||||
add.l #0x2000,sp
|
||||
jsr @_start_kernel
|
||||
_exit:
|
||||
|
||||
jmp _exit
|
||||
|
||||
rts
|
||||
|
||||
/* I/O port assign information */
|
||||
__platform_gpio_table:
|
||||
mov.l #gpio_table,er0
|
||||
rts
|
||||
|
||||
gpio_table:
|
||||
;; P1DDR
|
||||
;; used,ddr
|
||||
.byte 0x00,0x00
|
||||
;; P2DDR
|
||||
.byte 0x00,0x00
|
||||
;; P3DDR
|
||||
.byte 0x3f,0x3a
|
||||
;; dummy
|
||||
.byte 0x00,0x00
|
||||
;; P5DDR
|
||||
.byte 0x00,0x00
|
||||
;; P6DDR
|
||||
.byte 0x00,0x00
|
||||
;; P7DDR
|
||||
.byte 0x00,0x00
|
||||
;; P8DDR
|
||||
.byte 0x00,0x00
|
||||
;; dummy
|
||||
.byte 0x00,0x00
|
||||
;; PADDR
|
||||
.byte 0xff,0xff
|
||||
;; PBDDR
|
||||
.byte 0xff,0x00
|
||||
;; PCDDR
|
||||
.byte 0xff,0x00
|
||||
;; PDDDR
|
||||
.byte 0xff,0x00
|
||||
;; PEDDR
|
||||
.byte 0xff,0x00
|
||||
;; PFDDR
|
||||
.byte 0xff,0xff
|
||||
;; PGDDR
|
||||
.byte 0x0f,0x0f
|
||||
;; PHDDR
|
||||
.byte 0x0f,0x0f
|
||||
|
||||
__target_name:
|
||||
.asciz "EDOSK-2674"
|
||||
|
||||
.section .bootvec,"ax"
|
||||
jmp @SYMBOL_NAME(_start)
|
||||
187
arch/h8300/platform/h8s/edosk2674/crt0_rom.S
Normal file
187
arch/h8300/platform/h8s/edosk2674/crt0_rom.S
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8s/edosk2674/crt0_rom.S
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Platform depend startup
|
||||
* Target Archtecture: EDOSK-2674
|
||||
* Memory Layout : ROM
|
||||
*/
|
||||
|
||||
#define ASSEMBLY
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <asm/linkage.h>
|
||||
#include <asm/regs267x.h>
|
||||
|
||||
.global SYMBOL_NAME(_start)
|
||||
.global SYMBOL_NAME(_command_line)
|
||||
.global SYMBOL_NAME(_platform_gpio_table)
|
||||
.global SYMBOL_NAME(_target_name)
|
||||
|
||||
.h8300s
|
||||
.section .text
|
||||
.file "crt0_rom.S"
|
||||
|
||||
/* CPU Reset entry */
|
||||
SYMBOL_NAME_LABEL(_start)
|
||||
mov.l #__ramend,sp
|
||||
ldc #0x80,ccr
|
||||
ldc #0,exr
|
||||
|
||||
/* Peripheral Setup */
|
||||
;BSC/GPIO setup
|
||||
mov.l #init_regs,er0
|
||||
mov.w #0xffff,e2
|
||||
1:
|
||||
mov.w @er0+,r2
|
||||
beq 2f
|
||||
mov.w @er0+,r1
|
||||
mov.b r1l,@er2
|
||||
bra 1b
|
||||
|
||||
2:
|
||||
;SDRAM setup
|
||||
#define SDRAM_SMR 0x400040
|
||||
|
||||
mov.b #0,r0l
|
||||
mov.b r0l,@DRACCR:16
|
||||
mov.w #0x188,r0
|
||||
mov.w r0,@REFCR:16
|
||||
mov.w #0x85b4,r0
|
||||
mov.w r0,@DRAMCR:16
|
||||
mov.b #0,r1l
|
||||
mov.b r1l,@SDRAM_SMR
|
||||
mov.w #0x84b4,r0
|
||||
mov.w r0,@DRAMCR:16
|
||||
;special thanks to Arizona Cooperative Power
|
||||
|
||||
/* copy .data */
|
||||
mov.l #__begin_data,er5
|
||||
mov.l #__sdata,er6
|
||||
mov.l #__edata,er4
|
||||
sub.l er6,er4
|
||||
shlr.l #2,er4
|
||||
1:
|
||||
mov.l @er5+,er0
|
||||
mov.l er0,@er6
|
||||
adds #4,er6
|
||||
dec.l #1,er4
|
||||
bne 1b
|
||||
|
||||
/* .bss clear */
|
||||
mov.l #__sbss,er5
|
||||
mov.l #__ebss,er4
|
||||
sub.l er5,er4
|
||||
shlr.l #2,er4
|
||||
sub.l er0,er0
|
||||
1:
|
||||
mov.l er0,@er5
|
||||
adds #4,er5
|
||||
dec.l #1,er4
|
||||
bne 1b
|
||||
|
||||
/* copy kernel commandline */
|
||||
mov.l #COMMAND_START,er5
|
||||
mov.l #SYMBOL_NAME(_command_line),er6
|
||||
mov.w #512,r4
|
||||
eepmov.w
|
||||
|
||||
/* linux kernel start */
|
||||
ldc #0x90,ccr /* running kernel */
|
||||
mov.l #SYMBOL_NAME(init_thread_union),sp
|
||||
add.l #0x2000,sp
|
||||
jsr @_start_kernel
|
||||
_exit:
|
||||
|
||||
jmp _exit
|
||||
|
||||
rts
|
||||
|
||||
/* I/O port assign information */
|
||||
__platform_gpio_table:
|
||||
mov.l #gpio_table,er0
|
||||
rts
|
||||
|
||||
#define INIT_REGS_DATA(REGS,DATA) \
|
||||
.word ((REGS) & 0xffff),DATA
|
||||
|
||||
init_regs:
|
||||
INIT_REGS_DATA(ASTCR,0xff)
|
||||
INIT_REGS_DATA(RDNCR,0x00)
|
||||
INIT_REGS_DATA(ABWCR,0x80)
|
||||
INIT_REGS_DATA(WTCRAH,0x27)
|
||||
INIT_REGS_DATA(WTCRAL,0x77)
|
||||
INIT_REGS_DATA(WTCRBH,0x71)
|
||||
INIT_REGS_DATA(WTCRBL,0x22)
|
||||
INIT_REGS_DATA(CSACRH,0x80)
|
||||
INIT_REGS_DATA(CSACRL,0x80)
|
||||
INIT_REGS_DATA(BROMCRH,0xa0)
|
||||
INIT_REGS_DATA(BROMCRL,0xa0)
|
||||
INIT_REGS_DATA(P3DDR,0x3a)
|
||||
INIT_REGS_DATA(P3ODR,0x06)
|
||||
INIT_REGS_DATA(PADDR,0xff)
|
||||
INIT_REGS_DATA(PFDDR,0xfe)
|
||||
INIT_REGS_DATA(PGDDR,0x0f)
|
||||
INIT_REGS_DATA(PHDDR,0x0f)
|
||||
INIT_REGS_DATA(PFCR0,0xff)
|
||||
INIT_REGS_DATA(PFCR2,0x0d)
|
||||
INIT_REGS_DATA(ITSR, 0x00)
|
||||
INIT_REGS_DATA(ITSR+1,0x3f)
|
||||
INIT_REGS_DATA(INTCR,0x20)
|
||||
|
||||
.word 0
|
||||
|
||||
gpio_table:
|
||||
;; P1DDR
|
||||
.byte 0x00,0x00
|
||||
;; P2DDR
|
||||
.byte 0x00,0x00
|
||||
;; P3DDR
|
||||
.byte 0x00,0x00
|
||||
;; dummy
|
||||
.byte 0x00,0x00
|
||||
;; P5DDR
|
||||
.byte 0x00,0x00
|
||||
;; P6DDR
|
||||
.byte 0x00,0x00
|
||||
;; P7DDR
|
||||
.byte 0x00,0x00
|
||||
;; P8DDR
|
||||
.byte 0x00,0x00
|
||||
;; dummy
|
||||
.byte 0x00,0x00
|
||||
;; PADDR
|
||||
.byte 0x00,0x00
|
||||
;; PBDDR
|
||||
.byte 0x00,0x00
|
||||
;; PCDDR
|
||||
.byte 0x00,0x00
|
||||
;; PDDDR
|
||||
.byte 0x00,0x00
|
||||
;; PEDDR
|
||||
.byte 0x00,0x00
|
||||
;; PFDDR
|
||||
.byte 0x00,0x00
|
||||
;; PGDDR
|
||||
.byte 0x00,0x00
|
||||
;; PHDDR
|
||||
.byte 0x00,0x00
|
||||
|
||||
.section .rodata
|
||||
__target_name:
|
||||
.asciz "EDOSK-2674"
|
||||
|
||||
.section .bss
|
||||
__command_line:
|
||||
.space 512
|
||||
|
||||
/* interrupt vector */
|
||||
.section .vectors,"ax"
|
||||
.long __start
|
||||
.long __start
|
||||
vector = 2
|
||||
.rept 126
|
||||
.long _interrupt_redirect_table+vector*4
|
||||
vector = vector + 1
|
||||
.endr
|
||||
55
arch/h8300/platform/h8s/edosk2674/timer.c
Normal file
55
arch/h8300/platform/h8s/edosk2674/timer.c
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8s/edosk2674/timer.c
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Platform depend Timer Handler
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/timex.h>
|
||||
|
||||
#include <asm/segment.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/regs267x.h>
|
||||
|
||||
#define CMFA 6
|
||||
|
||||
#define CMIEA 0x40
|
||||
#define CCLR_CMA 0x08
|
||||
#define CLK_DIV8192 0x03
|
||||
|
||||
#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
|
||||
|
||||
void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
|
||||
{
|
||||
/* 8bit timer module enabled */
|
||||
ctrl_outb(ctrl_inb(MSTPCRL) & ~0x01, MSTPCRL);
|
||||
/* setup 8bit timer ch1 */
|
||||
ctrl_outb(H8300_TIMER_FREQ / HZ, _8TCORA1); /* set interval */
|
||||
ctrl_outb(0x00, _8TCSR1); /* no output */
|
||||
request_irq(76, timer_int, 0, "timer" ,0);
|
||||
ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR1); /* start count */
|
||||
}
|
||||
|
||||
void platform_timer_eoi(void)
|
||||
{
|
||||
*(volatile unsigned char *)_8TCSR1 &= ~(1 << CMFA);
|
||||
}
|
||||
|
||||
void platform_gettod(int *year, int *mon, int *day, int *hour,
|
||||
int *min, int *sec)
|
||||
{
|
||||
/* FIXME! not RTC support */
|
||||
*year = *mon = *day = *hour = *min = *sec = 0;
|
||||
}
|
||||
331
arch/h8300/platform/h8s/entry.S
Normal file
331
arch/h8300/platform/h8s/entry.S
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
/* -*- mode: asm -*-
|
||||
*
|
||||
* linux/arch/h8300/platform/h8s/entry.S
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* fairly heavy changes to fix syscall args and signal processing
|
||||
* by David McCullough <davidm@snapgear.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* entry.S
|
||||
* include exception/interrupt gateway
|
||||
* system call entry
|
||||
*/
|
||||
|
||||
#include <linux/sys.h>
|
||||
#include <linux/config.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/linkage.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/errno.h>
|
||||
|
||||
.h8300s
|
||||
|
||||
/* CPU context save/restore macros. */
|
||||
|
||||
.macro SAVE_ALL
|
||||
mov.l er0,@-sp
|
||||
|
||||
stc ccr,r0l /* check kernel mode */
|
||||
orc #0x10,ccr
|
||||
btst #4,r0l
|
||||
bne 5f
|
||||
|
||||
mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */
|
||||
mov.l @sp,er0
|
||||
mov.l @SYMBOL_NAME(sw_ksp),sp
|
||||
sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */
|
||||
stm.l er0-er3,@-sp
|
||||
mov.l @SYMBOL_NAME(sw_usp),er0
|
||||
mov.l @(10:16,er0),er1 /* copy the RET addr */
|
||||
mov.l er1,@(LRET-LER3:16,sp)
|
||||
mov.w @(8:16,er0),r1
|
||||
mov.w r1,@(LEXR-LER3:16,sp) /* copy EXR */
|
||||
|
||||
mov.w e1,r1 /* e1 highbyte = ccr */
|
||||
and #0xef,r1h /* mask mode? flag */
|
||||
sub.w r0,r0
|
||||
mov.b r1h,r0l
|
||||
mov.w r0,@(LCCR-LER3:16,sp) /* copy ccr */
|
||||
mov.l @(LORIG-LER3:16,sp),er0
|
||||
mov.l er0,@(LER0-LER3:16,sp) /* copy ER0 */
|
||||
bra 6f
|
||||
5:
|
||||
mov.l @sp,er0 /* kernel mode */
|
||||
subs #2,sp /* dummy ccr */
|
||||
stm.l er0-er3,@-sp
|
||||
mov.w @(LRET-LER3:16,sp),r1 /* copy old ccr */
|
||||
mov.b r1h,r1l
|
||||
mov.b #0,r1h
|
||||
mov.w r1,@(LCCR-LER3:16,sp)
|
||||
6:
|
||||
mov.l er6,@-sp /* syscall arg #6 */
|
||||
mov.l er5,@-sp /* syscall arg #5 */
|
||||
mov.l er4,@-sp /* syscall arg #4 */
|
||||
.endm
|
||||
|
||||
.macro RESTORE_ALL
|
||||
mov.l @sp+,er4
|
||||
mov.l @sp+,er5
|
||||
mov.l @sp+,er6
|
||||
ldm.l @sp+,er2-er3
|
||||
mov.w @(LCCR-LER1:16,sp),r0 /* check kernel mode */
|
||||
btst #4,r0l
|
||||
bne 7f
|
||||
|
||||
orc #0x80,ccr
|
||||
mov.l @SYMBOL_NAME(sw_usp),er0
|
||||
mov.l @(LER0-LER1:16,sp),er1 /* restore ER0 */
|
||||
mov.l er1,@er0
|
||||
mov.w @(LEXR-LER1:16,sp),r1 /* restore EXR */
|
||||
mov.b r1l,r1h
|
||||
mov.w r1,@(8:16,er0)
|
||||
mov.w @(LCCR-LER1:16,sp),r1 /* restore the RET addr */
|
||||
mov.b r1l,r1h
|
||||
mov.b @(LRET+1-LER1:16,sp),r1l
|
||||
mov.w r1,e1
|
||||
mov.w @(LRET+2-LER1:16,sp),r1
|
||||
mov.l er1,@(10:16,er0)
|
||||
|
||||
mov.l @sp+,er1
|
||||
add.l #(LRET-LER1),sp /* remove LORIG - LRET */
|
||||
mov.l sp,@SYMBOL_NAME(sw_ksp)
|
||||
mov.l er0,sp
|
||||
bra 8f
|
||||
7:
|
||||
mov.l @sp+,er1
|
||||
adds #4,sp
|
||||
adds #2,sp
|
||||
8:
|
||||
mov.l @sp+,er0
|
||||
adds #4,sp /* remove the sw created LVEC */
|
||||
rte
|
||||
.endm
|
||||
|
||||
.globl SYMBOL_NAME(system_call)
|
||||
.globl SYMBOL_NAME(ret_from_exception)
|
||||
.globl SYMBOL_NAME(ret_from_fork)
|
||||
.globl SYMBOL_NAME(ret_from_interrupt)
|
||||
.globl SYMBOL_NAME(interrupt_redirect_table)
|
||||
.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
|
||||
.globl SYMBOL_NAME(resume)
|
||||
.globl SYMBOL_NAME(trace_break)
|
||||
.globl SYMBOL_NAME(interrupt_entry)
|
||||
|
||||
INTERRUPTS = 128
|
||||
#if defined(CONFIG_ROMKERNEL)
|
||||
.section .int_redirect,"ax"
|
||||
SYMBOL_NAME_LABEL(interrupt_redirect_table)
|
||||
.rept 7
|
||||
.long 0
|
||||
.endr
|
||||
jsr @SYMBOL_NAME(interrupt_entry) /* NMI */
|
||||
jmp @SYMBOL_NAME(system_call) /* TRAPA #0 (System call) */
|
||||
.long 0
|
||||
.long 0
|
||||
jmp @SYMBOL_NAME(trace_break) /* TRAPA #3 (breakpoint) */
|
||||
.rept INTERRUPTS-12
|
||||
jsr @SYMBOL_NAME(interrupt_entry)
|
||||
.endr
|
||||
#endif
|
||||
#if defined(CONFIG_RAMKERNEL)
|
||||
.globl SYMBOL_NAME(interrupt_redirect_table)
|
||||
.section .bss
|
||||
SYMBOL_NAME_LABEL(interrupt_redirect_table)
|
||||
.space 4
|
||||
#endif
|
||||
|
||||
.section .text
|
||||
.align 2
|
||||
SYMBOL_NAME_LABEL(interrupt_entry)
|
||||
SAVE_ALL
|
||||
mov.w @(LCCR,sp),r0
|
||||
btst #4,r0l
|
||||
bne 1f
|
||||
mov.l @SYMBOL_NAME(sw_usp),er0
|
||||
mov.l @(4:16,er0),er0
|
||||
bra 2f
|
||||
1:
|
||||
mov.l @(LVEC:16,sp),er0
|
||||
2:
|
||||
#if defined(CONFIG_ROMKERNEL)
|
||||
sub.l #SYMBOL_NAME(interrupt_redirect_table),er0
|
||||
#endif
|
||||
#if defined(CONFIG_RAMKERNEL)
|
||||
mov.l @SYMBOL_NAME(interrupt_redirect_table),er1
|
||||
sub.l er1,er0
|
||||
#endif
|
||||
shlr.l #2,er0
|
||||
dec.l #1,er0
|
||||
mov.l sp,er1
|
||||
subs #4,er1 /* adjust ret_pc */
|
||||
jsr @SYMBOL_NAME(process_int)
|
||||
mov.l @SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,er0
|
||||
beq 1f
|
||||
jsr @SYMBOL_NAME(do_softirq)
|
||||
1:
|
||||
jmp @SYMBOL_NAME(ret_from_exception)
|
||||
|
||||
SYMBOL_NAME_LABEL(system_call)
|
||||
subs #4,sp /* dummy LVEC */
|
||||
SAVE_ALL
|
||||
mov.w @(LCCR:16,sp),r1
|
||||
bset #4,r1l
|
||||
ldc r1l,ccr /* restore ccr */
|
||||
mov.l er0,er4
|
||||
mov.l #-ENOSYS,er0
|
||||
mov.l er0,@(LER0:16,sp)
|
||||
|
||||
/* save top of frame */
|
||||
mov.l sp,er0
|
||||
jsr @SYMBOL_NAME(set_esp0)
|
||||
cmp.l #NR_syscalls,er4
|
||||
bcc SYMBOL_NAME(ret_from_exception):16
|
||||
shll.l #2,er4
|
||||
mov.l #SYMBOL_NAME(sys_call_table),er0
|
||||
add.l er4,er0
|
||||
mov.l @er0,er0
|
||||
mov.l er0,er4
|
||||
beq SYMBOL_NAME(ret_from_exception):16
|
||||
mov.l sp,er2
|
||||
and.w #0xe000,r2
|
||||
mov.b @((TASK_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
|
||||
btst #(TIF_SYSCALL_TRACE & 7),r2l
|
||||
mov.l @(LER1:16,sp),er0
|
||||
mov.l @(LER2:16,sp),er1
|
||||
mov.l @(LER3:16,sp),er2
|
||||
jsr @er4
|
||||
mov.l er0,@(LER0:16,sp) /* save the return value */
|
||||
#if defined(CONFIG_SYSCALL_PRINT)
|
||||
jsr @SYMBOL_NAME(syscall_print)
|
||||
#endif
|
||||
bra SYMBOL_NAME(ret_from_exception):8
|
||||
1:
|
||||
jsr SYMBOL_NAME(syscall_trace)
|
||||
mov.l @(LER1:16,sp),er0
|
||||
mov.l @(LER2:16,sp),er1
|
||||
mov.l @(LER3:16,sp),er2
|
||||
jsr @er4
|
||||
mov.l er0,@(LER0:16,sp) /* save the return value */
|
||||
jsr @SYMBOL_NAME(syscall_trace)
|
||||
bra SYMBOL_NAME(ret_from_exception):8
|
||||
|
||||
SYMBOL_NAME_LABEL(ret_from_fork)
|
||||
mov.l er2,er0
|
||||
jsr @SYMBOL_NAME(schedule_tail)
|
||||
bra SYMBOL_NAME(ret_from_exception):8
|
||||
|
||||
SYMBOL_NAME_LABEL(reschedule)
|
||||
/* save top of frame */
|
||||
mov.l sp,er0
|
||||
jsr @SYMBOL_NAME(set_esp0)
|
||||
jsr @SYMBOL_NAME(schedule)
|
||||
|
||||
SYMBOL_NAME_LABEL(ret_from_exception)
|
||||
#if defined(CONFIG_PREEMPT)
|
||||
orc #0x80,ccr
|
||||
#endif
|
||||
SYMBOL_NAME_LABEL(ret_from_interrupt)
|
||||
mov.b @(LCCR+1:16,sp),r0l
|
||||
btst #4,r0l /* check if returning to kernel */
|
||||
bne done:8 /* if so, skip resched, signals */
|
||||
andc #0x7f,ccr
|
||||
mov.l sp,er4
|
||||
and.w #0xe000,r4
|
||||
mov.l @(TI_FLAGS:16,er4),er1
|
||||
and.l #_TIF_WORK_MASK,er1
|
||||
beq done:8
|
||||
1:
|
||||
mov.l @(TI_FLAGS:16,er4),er1
|
||||
btst #TIF_NEED_RESCHED,r1l
|
||||
bne SYMBOL_NAME(reschedule):16
|
||||
mov.l sp,er0
|
||||
subs #4,er0 /* adjust retpc */
|
||||
mov.l er2,er1
|
||||
jsr @SYMBOL_NAME(do_signal)
|
||||
#if defined(CONFIG_PREEMPT)
|
||||
bra done:8 /* userspace thoru */
|
||||
3:
|
||||
btst #4,r0l
|
||||
beq done:8 /* userspace thoru */
|
||||
4:
|
||||
mov.l @(TI_PRE_COUNT:16,er4),er1
|
||||
bne done:8
|
||||
mov.l @(TI_FLAGS:16,er4),er1
|
||||
btst #TIF_NEED_RESCHED,r1l
|
||||
beq done:8
|
||||
mov.b r0l,r0l
|
||||
bpl done:8 /* interrupt off (exception path?) */
|
||||
mov.l #PREEMPT_ACTIVE,er1
|
||||
mov.l er1,@(TI_PRE_COUNT:16,er4)
|
||||
andc #0x7f,ccr
|
||||
jsr @SYMBOL_NAME(schedule)
|
||||
sub.l er1,er1
|
||||
mov.l er1,@(TI_PRE_COUNT:16,er4)
|
||||
orc #0x80,ccr
|
||||
bra 4b:8
|
||||
#endif
|
||||
done:
|
||||
RESTORE_ALL /* Does RTE */
|
||||
|
||||
SYMBOL_NAME_LABEL(resume)
|
||||
/*
|
||||
* er0 = prev
|
||||
* er1 = next
|
||||
* return last in er2
|
||||
*/
|
||||
|
||||
/* save sr */
|
||||
sub.w r3,r3
|
||||
stc ccr,r3l
|
||||
stc exr,r3h
|
||||
mov.w r3,@(THREAD_CCR+2:16,er0)
|
||||
|
||||
/* disable interrupts */
|
||||
orc #0x80,ccr
|
||||
mov.l @SYMBOL_NAME(sw_usp),er3
|
||||
mov.l er3,@(THREAD_USP:16,er0)
|
||||
mov.l sp,@(THREAD_KSP:16,er0)
|
||||
|
||||
/* Skip address space switching if they are the same. */
|
||||
/* FIXME: what did we hack out of here, this does nothing! */
|
||||
|
||||
mov.l @(THREAD_USP:16,er1),er0
|
||||
mov.l er0,@SYMBOL_NAME(sw_usp)
|
||||
mov.l @(THREAD_KSP:16,er1),sp
|
||||
|
||||
/* restore status register */
|
||||
mov.w @(THREAD_CCR+2:16,er1),r3
|
||||
|
||||
ldc r3l,ccr
|
||||
ldc r3h,exr
|
||||
|
||||
rts
|
||||
|
||||
SYMBOL_NAME_LABEL(trace_break)
|
||||
subs #4,sp /* dummy LVEC */
|
||||
SAVE_ALL
|
||||
sub.l er1,er1
|
||||
dec.l #1,er1
|
||||
mov.l er1,@(LORIG,sp)
|
||||
mov.l sp,er0
|
||||
jsr @SYMBOL_NAME(set_esp0)
|
||||
mov.l @SYMBOL_NAME(sw_usp),er0
|
||||
mov.l @er0,er1
|
||||
subs #2,er1
|
||||
mov.l er1,@er0
|
||||
and.w #0xff,e1
|
||||
mov.l er1,er0
|
||||
jsr @SYMBOL_NAME(trace_trap)
|
||||
jmp @SYMBOL_NAME(ret_from_exception)
|
||||
|
||||
.section .bss
|
||||
SYMBOL_NAME_LABEL(sw_ksp)
|
||||
.space 4
|
||||
SYMBOL_NAME_LABEL(sw_usp)
|
||||
.space 4
|
||||
6
arch/h8300/platform/h8s/generic/Makefile
Normal file
6
arch/h8300/platform/h8s/generic/Makefile
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
extra-y = crt0_$(MODEL).o
|
||||
obj-y := timer.o
|
||||
128
arch/h8300/platform/h8s/generic/crt0_ram.S
Normal file
128
arch/h8300/platform/h8s/generic/crt0_ram.S
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8s/edosk2674/crt0_ram.S
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Platform depend startup
|
||||
* Target Archtecture: generic
|
||||
* Memory Layout : RAM
|
||||
*/
|
||||
|
||||
#define ASSEMBLY
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <asm/linkage.h>
|
||||
#include <asm/regs267x.h>
|
||||
|
||||
#if !defined(CONFIG_BLKDEV_RESERVE)
|
||||
#if defined(CONFIG_GDB_DEBUG)
|
||||
#define RAMEND (__ramend - 0xc000)
|
||||
#else
|
||||
#define RAMEND __ramend
|
||||
#endif
|
||||
#else
|
||||
#define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
|
||||
#endif
|
||||
|
||||
.global SYMBOL_NAME(_start)
|
||||
.global SYMBOL_NAME(_command_line)
|
||||
.global SYMBOL_NAME(_platform_gpio_table)
|
||||
.global SYMBOL_NAME(_target_name)
|
||||
|
||||
.h8300s
|
||||
|
||||
.section .text
|
||||
.file "crt0_ram.S"
|
||||
|
||||
/* CPU Reset entry */
|
||||
SYMBOL_NAME_LABEL(_start)
|
||||
mov.l #RAMEND,sp
|
||||
ldc #0x80,ccr
|
||||
ldc #0x00,exr
|
||||
|
||||
/* Peripheral Setup */
|
||||
bclr #4,@INTCR:8 /* interrupt mode 2 */
|
||||
bset #5,@INTCR:8
|
||||
|
||||
#if defined(CONFIG_MTD_UCLINUX)
|
||||
/* move romfs image */
|
||||
jsr @__move_romfs
|
||||
#endif
|
||||
|
||||
/* .bss clear */
|
||||
mov.l #__sbss,er5
|
||||
mov.l er5,er6
|
||||
mov.l #__ebss,er4
|
||||
sub.l er5,er4
|
||||
shlr #2,er4
|
||||
sub.l er0,er0
|
||||
1:
|
||||
mov.l er0,@er5
|
||||
adds #4,er5
|
||||
dec.l #1,er4
|
||||
bne 1b
|
||||
|
||||
/* copy kernel commandline */
|
||||
mov.l #COMMAND_START,er5
|
||||
mov.l #SYMBOL_NAME(command_line),er6
|
||||
mov.w #512,r4
|
||||
eepmov.w
|
||||
|
||||
/* uClinux kernel start */
|
||||
ldc #0x90,ccr /* running kernel */
|
||||
mov.l #SYMBOL_NAME(init_thread_union),sp
|
||||
add.l #0x2000,sp
|
||||
jsr @_start_kernel
|
||||
_exit:
|
||||
|
||||
jmp _exit
|
||||
|
||||
rts
|
||||
|
||||
/* I/O port assign information */
|
||||
__platform_gpio_table:
|
||||
mov.l #gpio_table,er0
|
||||
rts
|
||||
|
||||
gpio_table:
|
||||
;; P1DDR
|
||||
;; used,ddr
|
||||
.byte 0x00,0x00
|
||||
;; P2DDR
|
||||
.byte 0x00,0x00
|
||||
;; P3DDR
|
||||
.byte 0x00,0x00
|
||||
;; dummy
|
||||
.byte 0x00,0x00
|
||||
;; P5DDR
|
||||
.byte 0x00,0x00
|
||||
;; P6DDR
|
||||
.byte 0x00,0x00
|
||||
;; P7DDR
|
||||
.byte 0x00,0x00
|
||||
;; P8DDR
|
||||
.byte 0x00,0x00
|
||||
;; dummy
|
||||
.byte 0x00,0x00
|
||||
;; PADDR
|
||||
.byte 0x00,0x00
|
||||
;; PBDDR
|
||||
.byte 0x00,0x00
|
||||
;; PCDDR
|
||||
.byte 0x00,0x00
|
||||
;; PDDDR
|
||||
.byte 0x00,0x00
|
||||
;; PEDDR
|
||||
.byte 0x00,0x00
|
||||
;; PFDDR
|
||||
.byte 0x00,0x00
|
||||
;; PGDDR
|
||||
.byte 0x00,0x00
|
||||
;; PHDDR
|
||||
.byte 0x00,0x00
|
||||
|
||||
__target_name:
|
||||
.asciz "generic"
|
||||
|
||||
.section .bootvec,"ax"
|
||||
jmp @SYMBOL_NAME(_start)
|
||||
129
arch/h8300/platform/h8s/generic/crt0_rom.S
Normal file
129
arch/h8300/platform/h8s/generic/crt0_rom.S
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8s/generic/crt0_rom.S
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Platform depend startup
|
||||
* Target Archtecture: generic
|
||||
* Memory Layout : ROM
|
||||
*/
|
||||
|
||||
#define ASSEMBLY
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <asm/linkage.h>
|
||||
#include <asm/regs267x.h>
|
||||
|
||||
.global SYMBOL_NAME(_start)
|
||||
.global SYMBOL_NAME(_command_line)
|
||||
.global SYMBOL_NAME(_platform_gpio_table)
|
||||
.global SYMBOL_NAME(_target_name)
|
||||
|
||||
.h8300s
|
||||
.section .text
|
||||
.file "crt0_rom.S"
|
||||
|
||||
/* CPU Reset entry */
|
||||
SYMBOL_NAME_LABEL(_start)
|
||||
mov.l #__ramend,sp
|
||||
ldc #0x80,ccr
|
||||
ldc #0,exr
|
||||
bclr #4,@INTCR:8
|
||||
bset #5,@INTCR:8 /* Interrupt mode 2 */
|
||||
|
||||
/* Peripheral Setup */
|
||||
|
||||
/* copy .data */
|
||||
#if !defined(CONFIG_H8S_SIM)
|
||||
mov.l #__begin_data,er5
|
||||
mov.l #__sdata,er6
|
||||
mov.l #__edata,er4
|
||||
sub.l er6,er4
|
||||
shlr.l #2,er4
|
||||
1:
|
||||
mov.l @er5+,er0
|
||||
mov.l er0,@er6
|
||||
adds #4,er6
|
||||
dec.l #1,er4
|
||||
bne 1b
|
||||
#endif
|
||||
|
||||
/* .bss clear */
|
||||
mov.l #__sbss,er5
|
||||
mov.l #__ebss,er4
|
||||
sub.l er5,er4
|
||||
shlr.l #2,er4
|
||||
sub.l er0,er0
|
||||
1:
|
||||
mov.l er0,@er5
|
||||
adds #4,er5
|
||||
dec.l #1,er4
|
||||
bne 1b
|
||||
|
||||
/* linux kernel start */
|
||||
ldc #0x90,ccr /* running kernel */
|
||||
mov.l #SYMBOL_NAME(init_thread_union),sp
|
||||
add.l #0x2000,sp
|
||||
jsr @_start_kernel
|
||||
_exit:
|
||||
|
||||
jmp _exit
|
||||
|
||||
rts
|
||||
|
||||
/* I/O port assign information */
|
||||
__platform_gpio_table:
|
||||
mov.l #gpio_table,er0
|
||||
rts
|
||||
|
||||
gpio_table:
|
||||
;; P1DDR
|
||||
.byte 0x00,0x00
|
||||
;; P2DDR
|
||||
.byte 0x00,0x00
|
||||
;; P3DDR
|
||||
.byte 0x00,0x00
|
||||
;; P4DDR
|
||||
.byte 0x00,0x00
|
||||
;; P5DDR
|
||||
.byte 0x00,0x00
|
||||
;; P6DDR
|
||||
.byte 0x00,0x00
|
||||
;; dummy
|
||||
.byte 0x00,0x00
|
||||
;; P8DDR
|
||||
.byte 0x00,0x00
|
||||
;; PADDR
|
||||
.byte 0x00,0x00
|
||||
;; PBDDR
|
||||
.byte 0x00,0x00
|
||||
;; PCDDR
|
||||
.byte 0x00,0x00
|
||||
;; PDDDR
|
||||
.byte 0x00,0x00
|
||||
;; PEDDR
|
||||
.byte 0x00,0x00
|
||||
;; PFDDR
|
||||
.byte 0x00,0x00
|
||||
;; PGDDR
|
||||
.byte 0x00,0x00
|
||||
;; PHDDR
|
||||
.byte 0x00,0x00
|
||||
|
||||
.section .rodata
|
||||
__target_name:
|
||||
.asciz "generic"
|
||||
|
||||
.section .bss
|
||||
__command_line:
|
||||
.space 512
|
||||
|
||||
/* interrupt vector */
|
||||
.section .vectors,"ax"
|
||||
.long __start
|
||||
.long __start
|
||||
vector = 2
|
||||
.rept 126-1
|
||||
.long _interrupt_redirect_table+vector*4
|
||||
vector = vector + 1
|
||||
.endr
|
||||
54
arch/h8300/platform/h8s/generic/timer.c
Normal file
54
arch/h8300/platform/h8s/generic/timer.c
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8s/generic/timer.c
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Platform depend Timer Handler
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/timex.h>
|
||||
|
||||
#include <asm/segment.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/regs267x.h>
|
||||
|
||||
#define CMFA 6
|
||||
|
||||
#define CMIEA 0x40
|
||||
#define CCLR_CMA 0x08
|
||||
#define CLK_DIV8192 0x03
|
||||
|
||||
#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
|
||||
|
||||
void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
|
||||
{
|
||||
/* 8bit timer module enabled */
|
||||
ctrl_outb(ctrl_inb(MSTPCRL) & ~0x01, MSTPCRL);
|
||||
/* setup 8bit timer ch1 */
|
||||
ctrl_outb(H8300_TIMER_FREQ / HZ, _8TCORA1); /* set interval */
|
||||
ctrl_outb(0x00, _8TCSR1); /* no output */
|
||||
request_irq(76, timer_int, 0, "timer" ,0);
|
||||
ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR1); /* start count */
|
||||
}
|
||||
|
||||
void platform_timer_eoi(void)
|
||||
{
|
||||
*(volatile unsigned char *)_8TCSR1 &= ~(1 << CMFA);
|
||||
}
|
||||
|
||||
void platform_gettod(int *year, int *mon, int *day, int *hour,
|
||||
int *min, int *sec)
|
||||
{
|
||||
*year = *mon = *day = *hour = *min = *sec = 0;
|
||||
}
|
||||
303
arch/h8300/platform/h8s/ints.c
Normal file
303
arch/h8300/platform/h8s/ints.c
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8s/ints.c
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* Based on linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
|
||||
*
|
||||
* 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 1996 Roman Zippel
|
||||
* Copyright 1999 D. Jeff Dionne <jeff@rt-control.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/hardirq.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/regs267x.h>
|
||||
#include <asm/errno.h>
|
||||
|
||||
/*
|
||||
* This structure has only 4 elements for speed reasons
|
||||
*/
|
||||
typedef struct irq_handler {
|
||||
irqreturn_t (*handler)(int, void *, struct pt_regs *);
|
||||
int flags;
|
||||
int count;
|
||||
void *dev_id;
|
||||
const char *devname;
|
||||
} irq_handler_t;
|
||||
|
||||
static irq_handler_t *irq_list[NR_IRQS];
|
||||
|
||||
/* IRQ pin assignment */
|
||||
struct irq_pins {
|
||||
unsigned char port_no;
|
||||
unsigned char bit_no;
|
||||
};
|
||||
/* ISTR = 0 */
|
||||
const static struct irq_pins irq_assign_table0[16]={
|
||||
{H8300_GPIO_P5,H8300_GPIO_B0},{H8300_GPIO_P5,H8300_GPIO_B1},
|
||||
{H8300_GPIO_P5,H8300_GPIO_B2},{H8300_GPIO_P5,H8300_GPIO_B3},
|
||||
{H8300_GPIO_P5,H8300_GPIO_B4},{H8300_GPIO_P5,H8300_GPIO_B5},
|
||||
{H8300_GPIO_P5,H8300_GPIO_B6},{H8300_GPIO_P5,H8300_GPIO_B7},
|
||||
{H8300_GPIO_P6,H8300_GPIO_B0},{H8300_GPIO_P6,H8300_GPIO_B1},
|
||||
{H8300_GPIO_P6,H8300_GPIO_B2},{H8300_GPIO_P6,H8300_GPIO_B3},
|
||||
{H8300_GPIO_P6,H8300_GPIO_B4},{H8300_GPIO_P6,H8300_GPIO_B5},
|
||||
{H8300_GPIO_PF,H8300_GPIO_B1},{H8300_GPIO_PF,H8300_GPIO_B2},
|
||||
};
|
||||
/* ISTR = 1 */
|
||||
const static struct irq_pins irq_assign_table1[16]={
|
||||
{H8300_GPIO_P8,H8300_GPIO_B0},{H8300_GPIO_P8,H8300_GPIO_B1},
|
||||
{H8300_GPIO_P8,H8300_GPIO_B2},{H8300_GPIO_P8,H8300_GPIO_B3},
|
||||
{H8300_GPIO_P8,H8300_GPIO_B4},{H8300_GPIO_P8,H8300_GPIO_B5},
|
||||
{H8300_GPIO_PH,H8300_GPIO_B2},{H8300_GPIO_PH,H8300_GPIO_B3},
|
||||
{H8300_GPIO_P2,H8300_GPIO_B0},{H8300_GPIO_P2,H8300_GPIO_B1},
|
||||
{H8300_GPIO_P2,H8300_GPIO_B2},{H8300_GPIO_P2,H8300_GPIO_B3},
|
||||
{H8300_GPIO_P2,H8300_GPIO_B4},{H8300_GPIO_P2,H8300_GPIO_B5},
|
||||
{H8300_GPIO_P2,H8300_GPIO_B6},{H8300_GPIO_P2,H8300_GPIO_B7},
|
||||
};
|
||||
|
||||
static short use_kmalloc = 0;
|
||||
|
||||
extern unsigned long *interrupt_redirect_table;
|
||||
|
||||
#define CPU_VECTOR ((unsigned long *)0x000000)
|
||||
#define ADDR_MASK (0xffffff)
|
||||
|
||||
static inline unsigned long *get_vector_address(void)
|
||||
{
|
||||
volatile unsigned long *rom_vector = CPU_VECTOR;
|
||||
unsigned long base,tmp;
|
||||
int vec_no;
|
||||
|
||||
base = rom_vector[EXT_IRQ0] & ADDR_MASK;
|
||||
|
||||
/* check romvector format */
|
||||
for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ15; vec_no++) {
|
||||
if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ramvector base address */
|
||||
base -= EXT_IRQ0*4;
|
||||
|
||||
/* writerble check */
|
||||
tmp = ~(*(unsigned long *)base);
|
||||
(*(unsigned long *)base) = tmp;
|
||||
if ((*(unsigned long *)base) != tmp)
|
||||
return NULL;
|
||||
return (unsigned long *)base;
|
||||
}
|
||||
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
#if defined(CONFIG_RAMKERNEL)
|
||||
int i;
|
||||
unsigned long *ramvec,*ramvec_p;
|
||||
unsigned long break_vec;
|
||||
|
||||
ramvec = get_vector_address();
|
||||
if (ramvec == NULL)
|
||||
panic("interrupt vector serup failed.");
|
||||
else
|
||||
printk("virtual vector at 0x%08lx\n",(unsigned long)ramvec);
|
||||
|
||||
#if defined(CONFIG_GDB_DEBUG)
|
||||
/* save orignal break vector */
|
||||
break_vec = ramvec[TRAP3_VEC];
|
||||
#else
|
||||
break_vec = VECTOR(trace_break);
|
||||
#endif
|
||||
|
||||
/* create redirect table */
|
||||
for (ramvec_p = ramvec, i = 0; i < NR_IRQS; i++)
|
||||
*ramvec_p++ = REDIRECT(interrupt_entry);
|
||||
|
||||
/* set special vector */
|
||||
ramvec[TRAP0_VEC] = VECTOR(system_call);
|
||||
ramvec[TRAP3_VEC] = break_vec;
|
||||
interrupt_redirect_table = ramvec;
|
||||
#ifdef DUMP_VECTOR
|
||||
ramvec_p = ramvec;
|
||||
for (i = 0; i < NR_IRQS; i++) {
|
||||
if ((i % 8) == 0)
|
||||
printk("\n%p: ",ramvec_p);
|
||||
printk("%p ",*ramvec_p);
|
||||
ramvec_p++;
|
||||
}
|
||||
printk("\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
int request_irq(unsigned int irq,
|
||||
irqreturn_t (*handler)(int, void *, struct pt_regs *),
|
||||
unsigned long flags, const char *devname, void *dev_id)
|
||||
{
|
||||
unsigned short ptn = 1 << (irq - EXT_IRQ0);
|
||||
irq_handler_t *irq_handle;
|
||||
if (irq < 0 || irq >= NR_IRQS) {
|
||||
printk("Incorrect IRQ %d from %s\n", irq, devname);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (irq_list[irq])
|
||||
return -EBUSY; /* already used */
|
||||
if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) {
|
||||
/* initialize IRQ pin */
|
||||
unsigned int port_no,bit_no;
|
||||
if (*(volatile unsigned short *)ITSR & ptn) {
|
||||
port_no = irq_assign_table1[irq - EXT_IRQ0].port_no;
|
||||
bit_no = irq_assign_table1[irq - EXT_IRQ0].bit_no;
|
||||
} else {
|
||||
port_no = irq_assign_table0[irq - EXT_IRQ0].port_no;
|
||||
bit_no = irq_assign_table0[irq - EXT_IRQ0].bit_no;
|
||||
}
|
||||
if (H8300_GPIO_RESERVE(port_no, bit_no) == 0)
|
||||
return -EBUSY; /* pin already use */
|
||||
H8300_GPIO_DDR(port_no, bit_no, H8300_GPIO_INPUT);
|
||||
*(volatile unsigned short *)ISR &= ~ptn; /* ISR clear */
|
||||
}
|
||||
|
||||
if (use_kmalloc)
|
||||
irq_handle = (irq_handler_t *)kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
|
||||
else {
|
||||
/* use bootmem allocater */
|
||||
irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t));
|
||||
irq_handle = (irq_handler_t *)((unsigned long)irq_handle | 0x80000000);
|
||||
}
|
||||
|
||||
if (irq_handle == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
irq_handle->handler = handler;
|
||||
irq_handle->flags = flags;
|
||||
irq_handle->count = 0;
|
||||
irq_handle->dev_id = dev_id;
|
||||
irq_handle->devname = devname;
|
||||
irq_list[irq] = irq_handle;
|
||||
if (irq_handle->flags & SA_SAMPLE_RANDOM)
|
||||
rand_initialize_irq(irq);
|
||||
|
||||
/* enable interrupt */
|
||||
/* compatible i386 */
|
||||
if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15)
|
||||
*(volatile unsigned short *)IER |= ptn;
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(request_irq);
|
||||
|
||||
void free_irq(unsigned int irq, void *dev_id)
|
||||
{
|
||||
if (irq >= NR_IRQS)
|
||||
return;
|
||||
if (irq_list[irq]->dev_id != dev_id)
|
||||
printk("%s: Removing probably wrong IRQ %d from %s\n",
|
||||
__FUNCTION__, irq, irq_list[irq]->devname);
|
||||
if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) {
|
||||
/* disable interrupt & release IRQ pin */
|
||||
unsigned short port_no,bit_no;
|
||||
*(volatile unsigned short *)ISR &= ~(1 << (irq - EXT_IRQ0));
|
||||
*(volatile unsigned short *)IER |= 1 << (irq - EXT_IRQ0);
|
||||
if (*(volatile unsigned short *)ITSR & (1 << (irq - EXT_IRQ0))) {
|
||||
port_no = irq_assign_table1[irq - EXT_IRQ0].port_no;
|
||||
bit_no = irq_assign_table1[irq - EXT_IRQ0].bit_no;
|
||||
} else {
|
||||
port_no = irq_assign_table0[irq - EXT_IRQ0].port_no;
|
||||
bit_no = irq_assign_table0[irq - EXT_IRQ0].bit_no;
|
||||
}
|
||||
H8300_GPIO_FREE(port_no, bit_no);
|
||||
}
|
||||
if (((unsigned long)irq_list[irq] & 0x80000000) == 0) {
|
||||
kfree(irq_list[irq]);
|
||||
irq_list[irq] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(free_irq);
|
||||
|
||||
unsigned long probe_irq_on (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(probe_irq_on);
|
||||
|
||||
int probe_irq_off (unsigned long irqs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(probe_irq_off);
|
||||
|
||||
void enable_irq(unsigned int irq)
|
||||
{
|
||||
if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15)
|
||||
*(volatile unsigned short *)IER |= 1 << (irq - EXT_IRQ0);
|
||||
}
|
||||
|
||||
void disable_irq(unsigned int irq)
|
||||
{
|
||||
if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15)
|
||||
*(volatile unsigned short *)IER &= ~(1 << (irq - EXT_IRQ0));
|
||||
}
|
||||
|
||||
asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
|
||||
{
|
||||
irq_enter();
|
||||
/* ISR clear */
|
||||
/* compatible i386 */
|
||||
if (vec >= EXT_IRQ0 && vec <= EXT_IRQ15)
|
||||
*(volatile unsigned short *)ISR &= ~(1 << (vec - EXT_IRQ0));
|
||||
if (vec < NR_IRQS) {
|
||||
if (irq_list[vec]) {
|
||||
irq_list[vec]->handler(vec, irq_list[vec]->dev_id, fp);
|
||||
irq_list[vec]->count++;
|
||||
if (irq_list[vec]->flags & SA_SAMPLE_RANDOM)
|
||||
add_interrupt_randomness(vec);
|
||||
}
|
||||
} else {
|
||||
BUG();
|
||||
}
|
||||
irq_exit();
|
||||
}
|
||||
|
||||
int show_interrupts(struct seq_file *p, void *v)
|
||||
{
|
||||
int i = *(loff_t *) v;
|
||||
|
||||
if ((i < NR_IRQS) && (irq_list[i] !=NULL)) {
|
||||
seq_printf(p, "%3d: %10u ",i,irq_list[i]->count);
|
||||
seq_printf(p, "%s\n", irq_list[i]->devname);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_irq_proc(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int __init enable_kmalloc(void)
|
||||
{
|
||||
use_kmalloc = 1;
|
||||
return 0;
|
||||
}
|
||||
core_initcall(enable_kmalloc);
|
||||
105
arch/h8300/platform/h8s/ints_h8s.c
Normal file
105
arch/h8300/platform/h8s/ints_h8s.c
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8s/ints_h8s.c
|
||||
* Interrupt handling CPU variants
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/regs267x.h>
|
||||
|
||||
/* saved vector list */
|
||||
const int __initdata h8300_saved_vectors[]={
|
||||
#if defined(CONFIG_GDB_DEBUG)
|
||||
TRACE_VEC,
|
||||
TRAP3_VEC,
|
||||
#endif
|
||||
-1
|
||||
};
|
||||
|
||||
/* trap entry table */
|
||||
const unsigned long __initdata h8300_trap_table[NR_TRAPS]={
|
||||
0,0,0,0,0,
|
||||
(unsigned long)trace_break, /* TRACE */
|
||||
0,0,
|
||||
(unsigned long)system_call, /* TRAPA #0 */
|
||||
0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
/* IRQ pin assignment */
|
||||
struct irq_pins {
|
||||
unsigned char port_no;
|
||||
unsigned char bit_no;
|
||||
} __attribute__((aligned(1),packed));
|
||||
/* ISTR = 0 */
|
||||
const static struct irq_pins irq_assign_table0[16]={
|
||||
{H8300_GPIO_P5,H8300_GPIO_B0},{H8300_GPIO_P5,H8300_GPIO_B1},
|
||||
{H8300_GPIO_P5,H8300_GPIO_B2},{H8300_GPIO_P5,H8300_GPIO_B3},
|
||||
{H8300_GPIO_P5,H8300_GPIO_B4},{H8300_GPIO_P5,H8300_GPIO_B5},
|
||||
{H8300_GPIO_P5,H8300_GPIO_B6},{H8300_GPIO_P5,H8300_GPIO_B7},
|
||||
{H8300_GPIO_P6,H8300_GPIO_B0},{H8300_GPIO_P6,H8300_GPIO_B1},
|
||||
{H8300_GPIO_P6,H8300_GPIO_B2},{H8300_GPIO_P6,H8300_GPIO_B3},
|
||||
{H8300_GPIO_P6,H8300_GPIO_B4},{H8300_GPIO_P6,H8300_GPIO_B5},
|
||||
{H8300_GPIO_PF,H8300_GPIO_B1},{H8300_GPIO_PF,H8300_GPIO_B2},
|
||||
};
|
||||
/* ISTR = 1 */
|
||||
const static struct irq_pins irq_assign_table1[16]={
|
||||
{H8300_GPIO_P8,H8300_GPIO_B0},{H8300_GPIO_P8,H8300_GPIO_B1},
|
||||
{H8300_GPIO_P8,H8300_GPIO_B2},{H8300_GPIO_P8,H8300_GPIO_B3},
|
||||
{H8300_GPIO_P8,H8300_GPIO_B4},{H8300_GPIO_P8,H8300_GPIO_B5},
|
||||
{H8300_GPIO_PH,H8300_GPIO_B2},{H8300_GPIO_PH,H8300_GPIO_B3},
|
||||
{H8300_GPIO_P2,H8300_GPIO_B0},{H8300_GPIO_P2,H8300_GPIO_B1},
|
||||
{H8300_GPIO_P2,H8300_GPIO_B2},{H8300_GPIO_P2,H8300_GPIO_B3},
|
||||
{H8300_GPIO_P2,H8300_GPIO_B4},{H8300_GPIO_P2,H8300_GPIO_B5},
|
||||
{H8300_GPIO_P2,H8300_GPIO_B6},{H8300_GPIO_P2,H8300_GPIO_B7},
|
||||
};
|
||||
|
||||
/* IRQ to GPIO pinno transrate */
|
||||
#define IRQ_GPIO_MAP(irqbit,irq,port,bit) \
|
||||
do { \
|
||||
if (*(volatile unsigned short *)ITSR & irqbit) { \
|
||||
port = irq_assign_table1[irq - EXT_IRQ0].port_no; \
|
||||
bit = irq_assign_table1[irq - EXT_IRQ0].bit_no; \
|
||||
} else { \
|
||||
port = irq_assign_table0[irq - EXT_IRQ0].port_no; \
|
||||
bit = irq_assign_table0[irq - EXT_IRQ0].bit_no; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
int h8300_enable_irq_pin(unsigned int irq)
|
||||
{
|
||||
if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) {
|
||||
unsigned short ptn = 1 << (irq - EXT_IRQ0);
|
||||
unsigned int port_no,bit_no;
|
||||
IRQ_GPIO_MAP(ptn, irq, port_no, bit_no);
|
||||
if (H8300_GPIO_RESERVE(port_no, bit_no) == 0)
|
||||
return -EBUSY; /* pin already use */
|
||||
H8300_GPIO_DDR(port_no, bit_no, H8300_GPIO_INPUT);
|
||||
*(volatile unsigned short *)ISR &= ~ptn; /* ISR clear */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void h8300_disable_irq_pin(unsigned int irq)
|
||||
{
|
||||
if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) {
|
||||
/* disable interrupt & release IRQ pin */
|
||||
unsigned short ptn = 1 << (irq - EXT_IRQ0);
|
||||
unsigned short port_no,bit_no;
|
||||
*(volatile unsigned short *)ISR &= ~ptn;
|
||||
*(volatile unsigned short *)IER &= ~ptn;
|
||||
IRQ_GPIO_MAP(ptn, irq, port_no, bit_no);
|
||||
H8300_GPIO_FREE(port_no, bit_no);
|
||||
}
|
||||
}
|
||||
84
arch/h8300/platform/h8s/ptrace_h8s.c
Normal file
84
arch/h8300/platform/h8s/ptrace_h8s.c
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* linux/arch/h8300/platform/h8s/ptrace_h8s.c
|
||||
* ptrace cpu depend helper functions
|
||||
*
|
||||
* Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
*
|
||||
* 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/linkage.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
#define CCR_MASK 0x6f
|
||||
#define EXR_TRACE 0x80
|
||||
|
||||
/* 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 h8300_register_offset[] = {
|
||||
PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4),
|
||||
PT_REG(er5), PT_REG(er6), PT_REG(er0), PT_REG(orig_er0),
|
||||
PT_REG(ccr), PT_REG(pc), 0, PT_REG(exr)
|
||||
};
|
||||
|
||||
/* read register */
|
||||
long h8300_get_reg(struct task_struct *task, int regno)
|
||||
{
|
||||
switch (regno) {
|
||||
case PT_USP:
|
||||
return task->thread.usp + sizeof(long)*2 + 2;
|
||||
case PT_CCR:
|
||||
case PT_EXR:
|
||||
return *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]);
|
||||
default:
|
||||
return *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]);
|
||||
}
|
||||
}
|
||||
|
||||
/* write register */
|
||||
int h8300_put_reg(struct task_struct *task, int regno, unsigned long data)
|
||||
{
|
||||
unsigned short oldccr;
|
||||
switch (regno) {
|
||||
case PT_USP:
|
||||
task->thread.usp = data - sizeof(long)*2 - 2;
|
||||
case PT_CCR:
|
||||
oldccr = *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]);
|
||||
oldccr &= ~CCR_MASK;
|
||||
data &= CCR_MASK;
|
||||
data |= oldccr;
|
||||
*(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]) = data;
|
||||
break;
|
||||
case PT_EXR:
|
||||
/* exr modify not support */
|
||||
return -EIO;
|
||||
default:
|
||||
*(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]) = data;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* disable singlestep */
|
||||
void h8300_disable_trace(struct task_struct *child)
|
||||
{
|
||||
*(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) &= ~EXR_TRACE;
|
||||
}
|
||||
|
||||
/* enable singlestep */
|
||||
void h8300_enable_trace(struct task_struct *child)
|
||||
{
|
||||
*(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) |= EXR_TRACE;
|
||||
}
|
||||
|
||||
asmlinkage void trace_trap(unsigned long bp)
|
||||
{
|
||||
(void)bp;
|
||||
force_sig(SIGTRAP,current);
|
||||
}
|
||||
|
||||
Loading…
Reference in a new issue