Commit e3f197f5 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] H8300 support

parent 7e56be3a
#
# 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 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
source "init/Kconfig"
menu "Processor type and features"
choice
prompt "H8/300 platform"
default H8300H_GENERIC
config H8300H_GENERIC
bool "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 Suppot
More Information. (Japanese Only)
<http://akizukidensi.com/catalog/h8.html>
AE-3068/69 Evalution Board Support
More Information.
<http://www.microtronique.com/ae3069lan.htm>
config H8300H_H8MAX
bool "H8MAX"
help
H8MAX Evalution Board Suooprt
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
endchoice
choice
prompt "CPU Selection"
config H83002
bool "H8/3001,3002,3003"
depends on H8300H_GENERIC
config H83007
bool "H8/3006,3007"
depends on (H8300H_GENERIC || H8300H_SIM)
config H83048
bool "H8/3044,3045,3046,3047,3048,3052"
depends on H8300H_GENERIC
config H83068
bool "H8/3065,3066,3067,3068,3069"
depends on (H8300H_GENERIC || H8300H_AKI3068NET || H8300H_H8MAX)
endchoice
config CPU_H8300H
bool
depends on (H8300H_GENERIC || H8300H_AKI3068NET || H8300H_H8MAX || H8300H_SIM)
default y
config CPU_CLOCK
int "CPU Clock Frequency (/1KHz)"
default "20000" if H8300H_AKI3068NET
default "25000" if H8300H_H8MAX
default "16000" if H8300H_SIM
default "16000" if H8300H_GENERIC
help
CPU Clock Frequency divide to 1000
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
config DEFAULT_CMDLINE
bool
help
buildin kernel commandline enabled.
config KERNEL_COMMAND
string
help
buildin kernel commandline strings.
endmenu
menu "Executable file formats"
config KCORE_AOUT
bool
default y
config KCORE_ELF
default y
config BINFMT_FLAT
tristate "Kernel support for flat binaries"
help
Support uClinux FLAT format binaries.
endmenu
source "drivers/block/Kconfig"
menu "ATA/IDE/MFM/RLL support"
config IDE
tristate "ATA/ATAPI/MFM/RLL device support"
---help---
If you say Y here, your kernel will be able to manage low cost mass
storage units such as ATA/(E)IDE and ATAPI units. The most common
cases are IDE hard drives and ATAPI CD-ROM drives.
It only makes sense to choose this option if your board actually
has an IDE interface. If unsure, say N.
source "drivers/ide/Kconfig"
endmenu
source "net/Kconfig"
menu "Network device support"
depends on NET
config NETDEVICES
bool "Network device support"
---help---
You can say N here if you don't intend to connect your Linux box to
any other computer at all or if all your connections will be over a
telephone line with a modem either via UUCP (UUCP is a protocol to
forward mail and news between unix hosts over telephone lines; read
the UUCP-HOWTO, available from
<http://www.linuxdoc.org/docs.html#howto>) or dialing up a shell
account or a BBS, even using term (term is a program which gives you
almost full Internet connectivity if you have a regular dial up
shell account on some Internet connected Unix computer. Read
<http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html>).
You'll have to say Y if your computer contains a network card that
you want to use under Linux (make sure you know its name because you
will be asked for it and read the Ethernet-HOWTO (especially if you
plan to use more than one network card under Linux)) or if you want
to use SLIP (Serial Line Internet Protocol is the protocol used to
send Internet traffic over telephone lines or null modem cables) or
CSLIP (compressed SLIP) or PPP (Point to Point Protocol, a better
and newer replacement for SLIP) or PLIP (Parallel Line Internet
Protocol is mainly used to create a mini network by connecting the
parallel ports of two local machines) or AX.25/KISS (protocol for
sending Internet traffic over amateur radio links).
Make sure to read the NET-3-HOWTO. Eventually, you will have to read
Olaf Kirch's excellent and free book "Network Administrator's
Guide", to be found in <http://www.linuxdoc.org/docs.html#guide>. If
unsure, say Y.
endmenu
source "net/ax25/Kconfig"
source "net/irda/Kconfig"
source "drivers/isdn/Kconfig"
source "drivers/telephony/Kconfig"
#
# input before char - char/joystick depends on it. As does USB.
#
source "drivers/input/Kconfig"
#
# Character device configuration
#
menu "Character devices"
config VT
bool "Virtual terminal"
requires INPUT=y
---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
config SH_SCI
tristate "Serial (SCI) support"
help
Selecting this option will allow the Linux kernel to transfer data
over SCI (Serial Communication Interface) and/or SCIF (Serial
Communication Interface with FIFO) which are built into the Hitachi
SuperH processor. The option provides 1 to 3 (depending
on the CPU model) standard Linux tty devices, /dev/ttySC[012]; one
of these is normally used as the system console.
If in doubt, press "y".
config SERIAL_CONSOLE
bool "Support for console on serial port"
depends on SERIAL=y || SH_SCI=y
---help---
If you say Y here, it will be possible to use a serial port as the
system console (the system console is the device which receives all
kernel messages and warnings and which allows logins in single user
mode). This could be useful if some terminal or printer is connected
to that serial port.
Even if you say Y here, the currently visible virtual console
(/dev/tty0) will still be used as the system console by default, but
you can alter that using a kernel command line option such as
"console=ttyS1". (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 you don't have a VGA card installed and you say Y here, the
kernel will automatically use the first serial line, /dev/ttyS0, as
system console.
If unsure, say N.
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.
endmenu
#source drivers/misc/Config.in
source "drivers/media/Kconfig"
source "fs/Kconfig"
source "drivers/usb/Kconfig"
source "net/bluetooth/Kconfig"
menu "Kernel hacking"
config FULLDEBUG
bool "Full Symbolic/Source Debugging support"
help
Enable debugging symbols on kernel build.
config MAGIC_SYSRQ
bool "Magic SysRq key"
help
Enables console device to interprent special characters as
commands to dump state information.
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
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
help
gdb stub exception support
config CONFIG_SH_STANDARD_BIOS
bool "Use gdb protocol serial console"
depends on !H8300H_SIM
help
serial console output using GDB protocol.
Require eCos/RedBoot
endmenu
source "security/Kconfig"
source "crypto/Kconfig"
source "lib/Kconfig"
#
# 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, Yoshinori Sato <ysato@users.sourceforge.jp>
#
ifndef include-config
-include $(TOPDIR)/.config
endif
platform-$(CONFIG_CPU_H8300H) := h8300h
PLATFORM := $(platform-y)
board-$(CONFIG_H8300H_GENERIC) := generic
board-$(CONFIG_H8300H_AKI3068NET) := ucsimm
board-$(CONFIG_H8300H_H8MAX) := ucdimm
board-$(CONFIG_H8300H_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 += $(cflags-y)
CFLAGS += -mint32 -fno-builtin
CFLAGS += -O2 -g
CFLAGS += -D__linux__
CFLAGS += -DUTS_SYSNAME=\"uClinux\" -DTARGET=$(BOARD)
AFLAGS += -DPLATFORM=$(PLATFORM) -DTARGET=$(BOARD) -DMODEL=$(MODEL) $(cflags-y)
LDFLAGS += $(ldflags-y)
LDFLAGS_BLOB := --format binary --oformat elf32-h8300
CROSS_COMPILE = h8300-elf-
#HEAD := arch/$(ARCH)/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o
LIBGCC := $(shell $(CROSS-COMPILE)$(CC) $(CFLAGS) -print-libgcc-file-name)
core-y += arch/$(ARCH)/kernel/ \
arch/$(ARCH)/mm/ \
arch/$(ARCH)/platform/$(PLATFORM)/ \
arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/
libs-y += arch/$(ARCH)/lib/ $(LIBGCC)
export MODEL
archmrproper:
archclean:
$(call descend arch/$(ARCH), subdirclean)
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)
uClinux-2.4 for H8/300 README
Yoshinori Sato <ysato@users.sourceforge.jp>
* Supported CPU
H8/300H
H8S is planning.
* 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
Under development
see http://www.strawbelly-linux.com (Japanese Only)
* 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
Tempolary used h8300-hms(h8300-coff) Toolchain.
I prepare toolchain corresponding to h8300-elf.
* A few words of thanks
Porting to H8/300H is support of Information-technology Promotion Agency, Japan.
I thank support.
and All developer/user.
#
# Automatically generated make config: don't edit
#
# 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
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
#
# General setup
#
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_SYSCTL is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_IKCONFIG is not set
#
# Loadable module support
#
# CONFIG_MODULES is not set
#
# Processor type and features
#
# CONFIG_H8300H_GENERIC is not set
# CONFIG_H8300H_AKI3068NET is not set
# CONFIG_H8300H_H8MAX is not set
CONFIG_H8300H_SIM=y
# CONFIG_H83002 is not set
CONFIG_H83007=y
# CONFIG_H83048 is not set
# CONFIG_H83068 is not set
CONFIG_CPU_H8300H=y
CONFIG_CPU_CLOCK=16000
# CONFIG_RAMKERNEL is not set
CONFIG_ROMKERNEL=y
#
# Executable file formats
#
CONFIG_KCORE_AOUT=y
CONFIG_BINFMT_FLAT=y
#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_RAM is not set
#
# ATA/IDE/MFM/RLL support
#
# CONFIG_IDE is not set
#
# Networking support
#
# CONFIG_NET is not set
#
# Amateur Radio support
#
# CONFIG_HAMRADIO is not set
#
# ISDN subsystem
#
#
# Telephony Support
#
# CONFIG_PHONE 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
#
# Input Device Drivers
#
#
# Character devices
#
CONFIG_SH_SCI=y
CONFIG_SERIAL_CONSOLE=y
# CONFIG_UNIX98_PTYS is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV 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_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_FAT_FS is not set
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_TMPFS 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_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_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
#
# USB support
#
#
# Kernel hacking
#
CONFIG_FULLDEBUG=y
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_HIGHPROFILE is not set
CONFIG_NO_KERNEL_MSG=y
# CONFIG_GDB_MAGICPRINT is not set
# CONFIG_SYSCALL_PRINT is not set
#
# Security options
#
# CONFIG_SECURITY is not set
#
# Cryptographic options
#
# CONFIG_CRYPTO is not set
#
# Library routines
#
# CONFIG_CRC32 is not set
#
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definitions are now in the main makefile...
obj-y := process.o traps.o ptrace.o \
sys_h8300.o time.o semaphore.o signal.o \
setup.o h8300_ksyms.o gpio.o init_task.o \
syscalls.o
/*
* 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 <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/hardirq.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));
DEFINE(THREAD_VFORK, offsetof(struct thread_struct, vfork_ret));
DEFINE(PT_PTRACED, PT_PTRACED);
DEFINE(PT_DTRACE, PT_DTRACE);
return 0;
}
/*
* linux/arch/h8300/kernel/gpio.c
*
* Yoshinori Sato <ysato@users.sourceforge.jp>
*
*/
/*
* H8/300H 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>
#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
#define P1DDR (unsigned char *)0xfee000
#define P2DDR (unsigned char *)0xfee001
#define P3DDR (unsigned char *)0xfee002
#define P4DDR (unsigned char *)0xfee003
#define P5DDR (unsigned char *)0xfee004
#define P6DDR (unsigned char *)0xfee005
#define P8DDR (unsigned char *)0xfee007
#define P9DDR (unsigned char *)0xfee008
#define PADDR (unsigned char *)0xfee009
#define PBDDR (unsigned char *)0xfee00A
#endif
#if defined(CONFIG_H83002) || defined(CONFIG_H8048)
#define P1DDR (unsigned char *)0xffffc0
#define P2DDR (unsigned char *)0xffffc1
#define P3DDR (unsigned char *)0xffffc4
#define P4DDR (unsigned char *)0xffffc5
#define P5DDR (unsigned char *)0xffffc8
#define P6DDR (unsigned char *)0xffffc9
#define P8DDR (unsigned char *)0xffffcd
#define P9DDR (unsigned char *)0xffffd0
#define PADDR (unsigned char *)0xffffd1
#define PBDDR (unsigned char *)0xffffd4
#endif
#if defined(P1DDR)
#define MAX_PORT 11
static struct {
unsigned char used;
unsigned char ddr;
} gpio_regs[MAX_PORT];
static volatile unsigned char *ddrs[] = {
P1DDR,P2DDR,P3DDR,P4DDR,P5DDR,P6DDR,NULL,P8DDR,P9DDR,PADDR,PBDDR,
};
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)
{
const unsigned char mask[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
int port = (port_bit >> 8) & 0xff;
int bit = port_bit & 0x07;
if (ddrs[port] == NULL)
return 0;
if (gpio_regs[port].used & mask[bit]) {
if (dir)
gpio_regs[port].ddr |= mask[bit];
else
gpio_regs[port].ddr &= ~mask[bit];
*ddrs[port] = gpio_regs[port].ddr;
return 1;
} else
return 0;
}
int h8300_get_gpio_dir(int port_bit)
{
const unsigned char mask[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
int port = (port_bit >> 8) & 0xff;
int bit = port_bit & 0x07;
if (ddrs[port] == NULL)
return 0;
if (gpio_regs[port].used & mask[bit]) {
return (gpio_regs[port].ddr & mask[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)
{
int c,outlen;
const static char port_name[]="123456789AB";
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 const struct proc_dir_entry proc_gpio = {
0, 4,"gpio",S_IFREG | S_IRUGO, 1, 0, 0, 0, NULL, gpio_proc_read,
};
#endif
int h8300_gpio_init(void)
{
memcpy(gpio_regs,_platform_gpio_table(sizeof(gpio_regs)),sizeof(gpio_regs));
#if 0 && defined(CONFIG_PROC_FS)
proc_register(&proc_root,&proc_gpio);
#endif
return 0;
}
#else
#error Unsuppoted CPU Selection
#endif
#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/hardirq.h>
#include <asm/softirq.h>
#include <asm/current.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(mach_enable_irq);
EXPORT_SYMBOL(mach_disable_irq);
EXPORT_SYMBOL(kernel_thread);
/* 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_NOVERS(__ashrdi3);
//EXPORT_SYMBOL_NOVERS(__lshrdi3);
EXPORT_SYMBOL_NOVERS(memcpy);
EXPORT_SYMBOL_NOVERS(memset);
EXPORT_SYMBOL_NOVERS(memcmp);
EXPORT_SYMBOL_NOVERS(memscan);
EXPORT_SYMBOL_NOVERS(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_NOVERS(__gcc_bcmp);
EXPORT_SYMBOL_NOVERS(__ashldi3);
EXPORT_SYMBOL_NOVERS(__ashrdi3);
EXPORT_SYMBOL_NOVERS(__cmpdi2);
EXPORT_SYMBOL_NOVERS(__divdi3);
EXPORT_SYMBOL_NOVERS(__divsi3);
EXPORT_SYMBOL_NOVERS(__lshrdi3);
EXPORT_SYMBOL_NOVERS(__moddi3);
EXPORT_SYMBOL_NOVERS(__modsi3);
EXPORT_SYMBOL_NOVERS(__muldi3);
EXPORT_SYMBOL_NOVERS(__mulsi3);
EXPORT_SYMBOL_NOVERS(__negdi2);
EXPORT_SYMBOL_NOVERS(__ucmpdi2);
EXPORT_SYMBOL_NOVERS(__udivdi3);
EXPORT_SYMBOL_NOVERS(__udivmoddi4);
EXPORT_SYMBOL_NOVERS(__udivsi3);
EXPORT_SYMBOL_NOVERS(__umoddi3);
EXPORT_SYMBOL_NOVERS(__umodsi3);
EXPORT_SYMBOL_NOVERS(_current_task);
EXPORT_SYMBOL_NOVERS(is_in_rom);
EXPORT_SYMBOL_NOVERS(h8300_reserved_gpio)
EXPORT_SYMBOL_NOVERS(h8300_free_gpio)
EXPORT_SYMBOL_NOVERS(h8300_set_gpio_dir)
/*
* linux/arch/h8300/kernel/init_task.c
*/
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/init_task.h>
#include <linux/fs.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);
/*
* 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);
/*
* 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) };
/*
* 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/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_exception(void);
/*
* The idle loop on an H8/300..
*/
#if !defined(CONFIG_H8300H_SIM)
void default_idle(void)
{
while(1) {
if (need_resched()) {
sti();
__asm__("sleep");
cli();
}
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)
{
cli();
__asm__("jmp @@0");
}
void machine_halt(void)
{
cli();
__asm__("sleep");
for (;;);
}
void machine_power_off(void)
{
cli();
__asm__("sleep");
for (;;);
}
void show_regs(struct pt_regs * regs)
{
printk("\n");
printk("PC: %08lx Status: %02x\n",
regs->pc, regs->ccr);
printk("ORIG_ER0: %08lx ER0: %08lx ER1: %08lx\n",
regs->orig_er0, regs->er0, regs->er1);
printk("ER2: %08lx ER3: %08lx\n",
regs->er2, regs->er3);
if (!(regs->ccr & 0x10))
printk("USP: %08lx\n", rdusp());
}
/*
* Create a kernel thread
*/
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
long retval;
register long clone_arg asm("er1");
mm_segment_t fs;
fs = get_fs();
set_fs (KERNEL_DS);
clone_arg = flags | CLONE_VM;
__asm__ __volatile__ (
"mov.l sp, er2\n\t"
"mov.l %1,er0\n\t"
"mov.l %5,er1\n\t"
"trapa #0\n\t"
"cmp.l sp, er2\n\t"
"beq 1f\n\t"
"mov.l %3, er0\n\t"
"jsr @%4\n\t"
"mov.l %2, er0\n\t"
"trapa #0\n"
"1:\n\t"
"mov.l er0,%0"
: "=r" (retval)
: "i" (__NR_clone),
"i" (__NR_exit),
"r" (arg),
"r" (fn),
"r" (clone_arg)
: "cc", "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)
{
struct task_struct *p;
p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL);
return IS_ERR(p) ? PTR_ERR(p) : p->pid;
}
asmlinkage int h8300_clone(struct pt_regs *regs)
{
unsigned long clone_flags;
unsigned long newsp;
struct task_struct *p;
/* syscall2 puts clone_flags in er1 and usp in er2 */
clone_flags = regs->er1;
newsp = regs->er2;
if (!newsp)
newsp = rdusp();
p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0, NULL, NULL);
return IS_ERR(p) ? PTR_ERR(p) : p->pid;
}
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;
struct switch_stack * childstack, *stack;
unsigned long stack_offset, *retp;
stack_offset = KTHREAD_SIZE - sizeof(struct pt_regs);
childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
*childregs = *regs;
retp = (unsigned long *) regs-2;
stack = ((struct switch_stack *) retp) - 1;
childstack = ((struct switch_stack *) childregs) - 1;
*childstack = *stack;
childregs->er0 = 0;
childstack->retpc = (unsigned long) ret_from_exception;
p->thread.usp = usp;
p->thread.ksp = (unsigned long)childstack;
p->thread.vfork_ret = 0;
return 0;
}
/*
* fill in the user structure for a core dump..
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
struct switch_stack *sw;
/* 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)));
sw = ((struct switch_stack *)regs) - 1;
dump->regs.er0 = regs->er0;
dump->regs.er1 = regs->er1;
dump->regs.er2 = regs->er2;
dump->regs.er3 = regs->er3;
dump->regs.er4 = sw->er4;
dump->regs.er5 = sw->er5;
dump->regs.er6 = sw->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;
}
/*
* These bracket the sleeping functions..
*/
extern void scheduling_functions_start_here(void);
extern void scheduling_functions_end_here(void);
#define first_sched ((unsigned long) scheduling_functions_start_here)
#define last_sched ((unsigned long) scheduling_functions_end_here)
unsigned long thread_saved_pc(struct task_struct *tsk)
{
struct switch_stack *sw = (struct switch_stack *)(tsk->thread.ksp);
/* Check whether the thread is blocked in resume() */
if (sw->retpc > (unsigned long)scheduling_functions_start_here &&
sw->retpc < (unsigned long)scheduling_functions_end_here)
return ((unsigned long *)sw->er6)[1];
else
return sw->retpc;
}
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 switch_stack *)p->thread.ksp)->er6;
do {
if (fp < stack_page+sizeof(struct task_struct) ||
fp >= 8184+stack_page)
return 0;
pc = ((unsigned long *)fp)[1];
/* FIXME: This depends on the order of these functions. */
if (pc < first_sched || pc >= last_sched)
return pc;
fp = *(unsigned long *) fp;
} while (count++ < 16);
return 0;
}
/*
* linux/arch/h8300/kernel/ptrace.c
*
* Yoshinori Sato <qzb04471@nifty.ne.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>
/*
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
*/
/* determines which bits in the SR the user has access to. */
/* 1 = access 0 = no access */
#define SR_MASK 0x001f
/* sets the trace bits. */
#define TRACE_BITS 0x8000
/* Find the stack offset for a register, relative to thread.esp0. */
#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
#define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \
- sizeof(struct switch_stack))
/* Mapping from PT_xxx to the stack offset at which the register is
saved. Notice that usp has no stack-slot and needs to be treated
specially (see get_reg/put_reg below). */
static const int regoff[] = {
PT_REG(er1), PT_REG(er2), PT_REG(er3), SW_REG(er4),
SW_REG(er5), SW_REG(er6), PT_REG(er0), PT_REG(orig_er0),
PT_REG(ccr), PT_REG(pc)
};
/*
* Get contents of register REGNO in task TASK.
*/
static inline long get_reg(struct task_struct *task, int regno)
{
unsigned long *addr;
if (regno == PT_USP)
addr = &task->thread.usp;
else if (regno < sizeof(regoff)/sizeof(regoff[0]))
addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
else
return 0;
return *addr;
}
/*
* Write contents of register REGNO in task TASK.
*/
static inline int put_reg(struct task_struct *task, int regno,
unsigned long data)
{
unsigned long *addr;
if (regno == PT_USP)
addr = &task->thread.usp;
else if (regno < sizeof(regoff)/sizeof(regoff[0]))
addr = (unsigned long *) (task->thread.esp0 + regoff[regno]);
else
return -1;
*addr = data;
return 0;
}
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure the single step bit is not set.
*/
int ptrace_cancel_bpt(struct task_struct *child)
{
int i,r=0;
for(i=0; i<4; i++) {
if (child->thread.debugreg[i]) {
if (child->thread.debugreg[i] != ~0)
put_user(child->thread.debugreg[i+4],
(unsigned short *)child->thread.debugreg[i]);
r = 1;
child->thread.debugreg[i] = 0;
}
}
return r;
}
const static unsigned char opcode0[]={
0x04,0x02,0x04,0x02,0x04,0x02,0x04,0x02, /* 0x58 */
0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, /* 0x60 */
0x02,0x02,0x11,0x11,0x02,0x02,0x04,0x04, /* 0x68 */
0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, /* 0x70 */
0x08,0x04,0x06,0x04,0x04,0x04,0x04,0x04}; /* 0x78 */
const static int table_parser01(unsigned char *pc);
const static int table_parser02(unsigned char *pc);
const static int table_parser100(unsigned char *pc);
const static int table_parser101(unsigned char *pc);
const static int (*parsers[])(unsigned char *pc)={table_parser01,table_parser02};
static int insn_length(unsigned char *pc)
{
if (*pc == 0x01)
return table_parser01(pc+1);
if (*pc < 0x58 || *pc>=0x80)
return 2;
else
if (opcode0[*pc-0x58]<0x10)
return opcode0[*pc-0x58];
else
return (*parsers[opcode0[*pc-0x58]-0x10])(pc+1);
}
const static int table_parser01(unsigned char *pc)
{
const unsigned char codelen[]={0x10,0x00,0x00,0x00,0x11,0x00,0x00,0x00,
0x02,0x00,0x00,0x00,0x04,0x04,0x00,0x04};
const static int (*parsers[])(unsigned char *)={table_parser100,table_parser101};
unsigned char second_index;
second_index = (*pc) >> 4;
if (codelen[second_index]<0x10)
return codelen[second_index];
else
return parsers[codelen[second_index]-0x10](pc);
}
const static int table_parser02(unsigned char *pc)
{
return (*pc & 0x20)?0x06:0x04;
}
const static int table_parser100(unsigned char *pc)
{
return (*(pc+2) & 0x02)?0x08:0x06;
}
const static int table_parser101(unsigned char *pc)
{
return (*(pc+2) & 0x02)?0x08:0x06;
}
#define BREAK_INST 0x5730 /* TRAPA #3 */
int ptrace_set_bpt(struct task_struct *child)
{
unsigned long pc,next;
unsigned short insn;
pc = get_reg(child,PT_PC);
next = insn_length((unsigned char *)pc) + pc;
get_user(insn,(unsigned short *)pc);
if (insn == 0x5470) {
/* rts */
unsigned long sp;
sp = get_reg(child,PT_USP);
get_user(next,(unsigned long *)sp);
} else if ((insn & 0xfb00) != 0x5800) {
/* jmp / jsr */
int regs;
const short reg_tbl[]={PT_ER0,PT_ER1,PT_ER2,PT_ER3,
PT_ER4,PT_ER5,PT_ER6,PT_USP};
switch(insn & 0xfb00) {
case 0x5900:
regs = (insn & 0x0070) >> 8;
next = get_reg(child,reg_tbl[regs]);
break;
case 0x5a00:
get_user(next,(unsigned long *)(pc+2));
next &= 0x00ffffff;
break;
case 0x5b00:
/* unneccessary? */
next = *(unsigned long *)(insn & 0xff);
break;
}
} else if (((insn & 0xf000) == 0x4000) || ((insn &0xff00) == 0x5500)) {
/* b**:8 */
unsigned long dsp;
dsp = (long)(insn && 0xff)+pc+2;
child->thread.debugreg[1] = dsp;
get_user(child->thread.debugreg[5],(unsigned short *)dsp);
put_user(BREAK_INST,(unsigned short *)dsp);
} else if (((insn & 0xff00) == 0x5800) || ((insn &0xff00) == 0x5c00)) {
/* b**:16 */
unsigned long dsp;
get_user(dsp,(unsigned short *)(pc+2));
dsp = (long)dsp+pc+4;
child->thread.debugreg[1] = dsp;
get_user(child->thread.debugreg[5],(unsigned short *)dsp);
put_user(BREAK_INST,(unsigned short *)dsp);
}
child->thread.debugreg[0] = next;
get_user(child->thread.debugreg[4],(unsigned short *)next);
put_user(BREAK_INST,(unsigned short *)next);
return 0;
}
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)
{
ptrace_cancel_bpt(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 = -ESRCH;
if (!(child->ptrace & PT_PTRACED))
goto out_tsk;
if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL)
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 = verify_area(VERIFY_WRITE, (void *) data, sizeof(long));
if (!ret)
put_user(tmp, (unsigned long *) data);
break ;
}
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
unsigned long tmp;
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
ret = -EIO;
ret = verify_area(VERIFY_WRITE, (void *) data,
sizeof(long));
if (ret)
break ;
tmp = 0; /* Default return condition */
addr = addr >> 2; /* temporary hack. */
if (addr < 10)
tmp = get_reg(child, addr);
else {
ret = -EIO;
break ;
}
put_user(tmp,(unsigned long *) data);
ret = 0;
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 == PT_CCR) {
data &= SR_MASK;
}
if (addr < 10) {
if (put_reg(child, addr, data))
ret = -EIO;
else
ret = 0;
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. */
ptrace_cancel_bpt(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->state == TASK_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
ptrace_cancel_bpt(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->thread.debugreg[0]=-1;
child->exit_code = data;
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 < 19; i++) {
tmp = 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 < 10; i++) {
if (get_user(tmp, (unsigned long *) data)) {
ret = -EFAULT;
break;
}
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;
current->exit_code = SIGTRAP;
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
schedule();
/*
* 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;
}
}
asmlinkage void trace_trap(unsigned long bp)
{
if (current->thread.debugreg[0] == bp ||
current->thread.debugreg[1] == bp) {
ptrace_cancel_bpt(current);
force_sig(SIGTRAP,current);
} else
force_sig(SIGILL,current);
}
/*
* Generic semaphore code. Buyer beware. Do your own
* specific changes in <asm/semaphore-helper.h>
*/
#include <linux/config.h>
#include <linux/sched.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 __down(struct semaphore * sem)
{
DECLARE_WAITQUEUE(wait, current);
DOWN_HEAD(TASK_UNINTERRUPTIBLE)
if (waking_non_zero(sem))
break;
schedule();
DOWN_TAIL(TASK_UNINTERRUPTIBLE)
}
int __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);
}
/*
* linux/arch/h8300h/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/300H 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 <asm/setup.h>
#include <asm/irq.h>
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h>
#include <asm/pgtable.h>
#endif
#if defined(CONFIG_CPU_H8300H)
#define CPU "H8/300H"
#endif
unsigned long rom_length;
unsigned long memory_start;
unsigned long memory_end;
struct task_struct *_current_task;
char command_line[512];
char saved_command_line[512];
extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
extern int _ramstart, _ramend;
extern char _target_name[];
#if defined(CONFIG_H8300H_SIM) && defined(CONFIG_GDB_MAGICPRINT)
/* printk with gdb service */
static void gdb_console_output(struct console *c, 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",
write: gdb_console_output,
device: NULL,
setup: gdb_console_setup,
flags: CON_PRINTBUFFER,
index: -1,
};
#endif
void setup_arch(char **cmdline_p)
{
int bootmap_size;
memory_start = PAGE_ALIGN((unsigned long)(&_ramstart));
memory_end = &_ramend; /* by now the stack is part of the init task */
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_GDB_MAGICPRINT)
register_console(&gdb_console);
#endif
printk("\x0F\r\n\nuClinux " CPU "\n");
printk("Target Hardware: %s\n",_target_name);
printk("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
printk("H8/300H support by Yoshinori Sato <ysato@users.sourceforge.jp>\n");
#ifdef DEBUG
printk("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("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_BLK_DEV_BLKMEM
ROOT_DEV = MKDEV(BLKMEM_MAJOR,0);
#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, sizeof(saved_command_line));
saved_command_line[sizeof(saved_command_line)-1] = 0;
#ifdef DEBUG
if (strlen(*cmdline_p))
printk("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();
#ifdef DEBUG
printk("Done setup_arch\n");
#endif
}
int get_cpuinfo(char * buffer)
{
char *cpu;
u_long clockfreq;
cpu = CPU;
clockfreq = CONFIG_CPU_CLOCK;
return(sprintf(buffer, "CPU:\t\t%s\n"
"Clock:\t%lu.%1luMHz\n"
"BogoMips:\t%lu.%02lu\n"
"Calibration:\t%lu loops\n",
cpu,
clockfreq/100,clockfreq%100,
(loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
(loops_per_jiffy*HZ)));
}
/*
* Get CPU information for use by the procfs.
*/
static int show_cpuinfo(struct seq_file *m, void *v)
{
char *cpu;
u_long clockfreq;
cpu = CPU;
clockfreq = CONFIG_CPU_CLOCK;
seq_printf(m, "CPU:\t\t%s\n"
"Clock:\t%lu.%1luMHz\n"
"BogoMips:\t%lu.%02lu\n"
"Calibration:\t%lu loops\n",
cpu,
clockfreq/100,clockfreq%100,
(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,
};
/*
* 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
*
* 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/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 <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 long sys_wait4(pid_t pid, unsigned int * stat_addr, int options,
struct rusage * ru);
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
/*
* 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(&current->sighand->siglock);
saveset = current->blocked;
siginitset(&current->blocked, mask);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
regs->er0 = -EINTR;
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
if (do_signal(&saveset, regs))
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(&current->sighand->siglock);
saveset = current->blocked;
current->blocked = newset;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
regs->er0 = -EINTR;
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
if (do_signal(&saveset, regs))
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 (verify_area(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 (verify_area(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
{
char *pretcode;
int sig;
int code;
struct sigcontext *psc;
char retcode[6];
unsigned long extramask[_NSIG_WORDS-1];
struct sigcontext sc;
};
struct rt_sigframe
{
char *pretcode;
int sig;
struct siginfo *pinfo;
void *puc;
char retcode[6];
struct siginfo info;
struct ucontext uc;
};
static inline int
restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp,
int *pd0)
{
struct sigcontext context;
int err = 0;
/* get previous context */
if (copy_from_user(&context, usc, sizeof(context)))
goto badframe;
/* restore passed registers */
regs->er1 = context.sc_er1;
regs->er2 = context.sc_er2;
regs->er3 = context.sc_er3;
regs->ccr = (regs->ccr & 0x10)|(context.sc_ccr & 0xef);
regs->pc = context.sc_pc;
regs->orig_er0 = -1; /* disable syscall checks */
wrusp(context.sc_usp);
*pd0 = context.sc_er0;
return err;
badframe:
return 1;
}
static inline int
rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
struct ucontext *uc, int *pd0)
{
int temp;
greg_t *gregs = uc->uc_mcontext.gregs;
unsigned long usp;
int err;
err = __get_user(temp, &uc->uc_mcontext.version);
if (temp != MCONTEXT_VERSION)
goto badframe;
/* restore passed registers */
err |= __get_user(regs->er0, &gregs[0]);
err |= __get_user(regs->er1, &gregs[1]);
err |= __get_user(regs->er2, &gregs[2]);
err |= __get_user(regs->er3, &gregs[3]);
err |= __get_user(sw->er4, &gregs[4]);
err |= __get_user(sw->er5, &gregs[5]);
err |= __get_user(sw->er6, &gregs[6]);
err |= __get_user(usp, &gregs[7]);
wrusp(usp);
err |= __get_user(regs->pc, &gregs[8]);
err |= __get_user(temp, &gregs[9]);
regs->ccr = (regs->ccr & 0x10) | (temp & 0xef);
regs->orig_er0 = -1; /* disable syscall checks */
if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
goto badframe;
*pd0 = regs->er0;
return err;
badframe:
return 1;
}
asmlinkage int do_sigreturn(unsigned long __unused,...)
{
struct switch_stack *sw = (struct switch_stack *) &__unused;
struct pt_regs *regs = (struct pt_regs *) (sw + 1);
unsigned long usp = rdusp();
struct sigframe *frame = (struct sigframe *)(usp - 4);
sigset_t set;
int er0;
if (verify_area(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(&current->sighand->siglock);
current->blocked = set;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
if (restore_sigcontext(regs, &frame->sc, frame + 1, &er0))
goto badframe;
return er0;
badframe:
force_sig(SIGSEGV, current);
return 0;
}
asmlinkage int do_rt_sigreturn(unsigned long __unused,...)
{
struct switch_stack *sw = (struct switch_stack *) &__unused;
struct pt_regs *regs = (struct pt_regs *) (sw + 1);
unsigned long usp = rdusp();
struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
sigset_t set;
int er0;
if (verify_area(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(&current->sighand->siglock);
current->blocked = set;
recalc_sigpending();
spin_lock_irq(&current->sighand->siglock);
if (rt_restore_ucontext(regs, sw, &frame->uc, &er0))
goto badframe;
return er0;
badframe:
force_sig(SIGSEGV, current);
return 0;
}
static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
unsigned long mask)
{
sc->sc_mask = mask;
sc->sc_usp = rdusp();
sc->sc_er0 = regs->er0;
sc->sc_er1 = regs->er1;
sc->sc_er2 = regs->er2;
sc->sc_er3 = regs->er3;
sc->sc_ccr = regs->ccr;
sc->sc_pc = regs->pc;
}
static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
{
struct switch_stack *sw = (struct switch_stack *)regs - 1;
greg_t *gregs = uc->uc_mcontext.gregs;
int err = 0;
err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
err |= __put_user(regs->er0, &gregs[0]);
err |= __put_user(regs->er1, &gregs[1]);
err |= __put_user(regs->er2, &gregs[2]);
err |= __put_user(regs->er3, &gregs[3]);
err |= __put_user(sw->er4, &gregs[4]);
err |= __put_user(sw->er5, &gregs[5]);
err |= __put_user(sw->er6, &gregs[6]);
err |= __put_user(rdusp(), &gregs[7]);
err |= __put_user(regs->pc, &gregs[8]);
err |= __put_user(regs->ccr, &gregs[9]);
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;
struct sigcontext context;
int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame));
err |= __put_user((current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
&& sig < 32
? current_thread_info()->exec_domain->signal_invmap[sig]
: sig),
&frame->sig);
err |= __put_user(&frame->sc, &frame->psc);
if (_NSIG_WORDS > 1)
err |= copy_to_user(frame->extramask, &set->sig[1],
sizeof(frame->extramask));
setup_sigcontext(&context, regs, set->sig[0]);
err |= copy_to_user (&frame->sc, &context, sizeof(context));
/* Set up to return from userspace. */
err |= __put_user(frame->retcode, &frame->pretcode);
/* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
(long *)(frame->retcode + 0));
err |= __put_user(0x5700, (short *)(frame->retcode + 4));
if (err)
goto give_sigsegv;
/* Set up registers for signal handler */
wrusp ((unsigned long) frame);
regs->pc = (unsigned long) ka->sa.sa_handler;
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, 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;
frame = get_sigframe(ka, regs, sizeof(*frame));
err |= __put_user((current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
&& sig < 32
? current_thread_info()->exec_domain->signal_invmap[sig]
: sig),
&frame->sig);
err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc);
err |= copy_siginfo_to_user(&frame->info, info);
/* 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 |= rt_setup_ucontext(&frame->uc, regs);
err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
/* Set up to return from userspace. */
err |= __put_user(frame->retcode, &frame->pretcode);
/* moveq #,d0; notb d0; movea.l #,a5; trap #0 */
/* sub.l er0,er0; mov.b #__NR_rt_sigreturn,r0l; trapa #0 */
err != __put_user(0x1a80f800 + (__NR_rt_sigreturn & 0xff),
(long *)(frame->retcode + 0));
err |= __put_user(0x5700, (short *)(frame->retcode + 4));
if (err)
goto give_sigsegv;
/* Set up registers for signal handler */
wrusp ((unsigned long) frame);
regs->pc = (unsigned long) ka->sa.sa_handler;
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
}
static inline void
handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
{
switch (regs->er0) {
case -ERESTARTNOHAND:
if (!has_handler)
goto do_restart;
regs->er0 = -EINTR;
break;
case -ERESTARTSYS:
if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
regs->er0 = -EINTR;
break;
}
/* fallthrough */
case -ERESTARTNOINTR:
do_restart:
regs->er0 = regs->orig_er0;
regs->pc -= 2;
break;
}
}
/*
* OK, we're invoking a handler
*/
static void
handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
{
/* are we from a system call? */
if (regs->orig_er0 >= 0)
/* If so, check system call restarting.. */
handle_restart(regs, ka, 1);
/* 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_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
if (!(ka->sa.sa_flags & SA_NODEFER)) {
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
sigaddset(&current->blocked,sig);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
}
}
/*
* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
*
* Note that we go through the signals twice: once to check the signals
* that the kernel can handle, and then we build all the user-level signal
* handling stack-frames in one go after that.
*/
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
{
siginfo_t info;
struct k_sigaction *ka;
current->thread.esp0 = (unsigned long) regs;
if (!oldset)
oldset = &current->blocked;
for (;;) {
int signr;
signr = get_signal_to_deliver(&info, regs, NULL);
if (!signr)
break;
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
current->exit_code = signr;
current->state = TASK_STOPPED;
/* Did we come from a system call? */
if (regs->orig_er0 >= 0) {
/* Restart the system call the same way as
if the process were not traced. */
struct k_sigaction *ka =
&current->sighand->action[signr-1];
int has_handler =
(ka->sa.sa_handler != SIG_IGN &&
ka->sa.sa_handler != SIG_DFL);
handle_restart(regs, ka, has_handler);
}
notify_parent(current, SIGCHLD);
schedule();
/* We're back. Did the debugger cancel the sig? */
if (!(signr = current->exit_code)) {
discard_frame:
continue;
}
current->exit_code = 0;
/* The debugger continued. Ignore SIGSTOP. */
if (signr == SIGSTOP)
goto discard_frame;
/* Update the siginfo structure. Is this good? */
if (signr != info.si_signo) {
info.si_signo = signr;
info.si_errno = 0;
info.si_code = SI_USER;
info.si_pid = current->parent->pid;
info.si_uid = current->parent->uid;
}
/* If the (new) signal is now blocked, requeue it. */
if (sigismember(&current->blocked, signr)) {
send_sig_info(signr, &info, current);
continue;
}
}
ka = &current->sighand->action[signr-1];
if (ka->sa.sa_handler == SIG_IGN) {
if (signr != SIGCHLD)
continue;
/* Check for SIGCHLD: it's special. */
while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
/* nothing */;
continue;
}
if (ka->sa.sa_handler == SIG_DFL) {
int exit_code = signr;
if (current->pid == 1)
continue;
switch (signr) {
case SIGCONT: case SIGCHLD:
case SIGWINCH: case SIGURG:
continue;
case SIGTSTP: case SIGTTIN: case SIGTTOU:
if (is_orphaned_pgrp(current->pgrp))
continue;
/* FALLTHRU */
case SIGSTOP: {
struct sighand_struct *sig;
current->state = TASK_STOPPED;
current->exit_code = signr;
sig = current->parent->sighand;
if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags
& SA_NOCLDSTOP))
notify_parent(current, SIGCHLD);
schedule();
continue;
}
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGIOT: case SIGFPE: case SIGSEGV:
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, exit_code, regs))
exit_code |= 0x80;
/* FALLTHRU */
default:
sigaddset(&current->pending.signal, signr);
recalc_sigpending();
current->flags |= PF_SIGNALED;
do_exit(exit_code);
/* NOTREACHED */
}
}
/* Whee! Actually deliver the signal. */
handle_signal(signr, ka, &info, oldset, regs);
return 1;
}
/* Did we come from a system call? */
if (regs->orig_er0 >= 0)
/* Restart the system call - no handlers present */
handle_restart(regs, NULL, 0);
return 0;
}
/*
* 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/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(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(&current->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(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
up_write(&current->mm->mmap_sem);
if (file)
fput(file);
out:
return error;
}
#endif
extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
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 = sys_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;
}
asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
{
return -ENOSYS;
}
/* 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);
unsigned long *usp=rdusp()+8;
printk("call %06x:%d 1:%08x,2:%08x,3:%08x,ret:%08x\n",
((*usp) & 0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0);
}
#endif
/* 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_ioperm)
.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_ni_syscall) /* 250 */ /* sys_alloc_hugepages */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_freec_hugepages */
.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)
.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
.long SYMBOL_NAME(sys_ni_syscall)
.endr
SYMBOL_NAME_LABEL(sys_clone)
mov.l #SYMBOL_NAME(h8300_clone),er0
jmp @SYMBOL_NAME(syscall_trampoline)
SYMBOL_NAME_LABEL(sys_sigsuspend)
mov.l #SYMBOL_NAME(do_sigsuspend),er0
jmp @SYMBOL_NAME(syscall_trampoline)
SYMBOL_NAME_LABEL(sys_rt_sigsuspend)
mov.l #SYMBOL_NAME(do_rt_sigsuspend),er0
jmp @SYMBOL_NAME(syscall_trampoline)
SYMBOL_NAME_LABEL(sys_sigreturn)
mov.l #SYMBOL_NAME(do_sigreturn),er0
jmp @SYMBOL_NAME(syscall_trampoline)
SYMBOL_NAME_LABEL(sys_rt_sigreturn)
mov.l #SYMBOL_NAME(do_rt_sigreturn),er0
jmp @SYMBOL_NAME(syscall_trampoline)
SYMBOL_NAME_LABEL(sys_fork)
mov.l #SYMBOL_NAME(h8300_fork),er0
jmp @SYMBOL_NAME(syscall_trampoline)
/*
* 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/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;
static inline void do_profile (unsigned long pc)
{
if (prof_buffer && current->pid) {
extern int _stext;
pc -= (unsigned long) &_stext;
pc >>= prof_shift;
if (pc < prof_len)
++prof_buffer[pc];
else
/*
* Don't ignore out-of-bounds PC values silently,
* put them into the last histogram slot, so if
* present, they will show up as a sharp peak.
*/
++prof_buffer[prof_len-1];
}
}
/*
* 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);
if (!user_mode(regs))
do_profile(regs->pc);
}
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;
}
void do_settimeofday(struct timeval *tv)
{
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_usec < 0) {
tv->tv_usec += 1000000;
tv->tv_sec--;
}
xtime.tv_sec = tv->tv_sec;
xtime.tv_nsec = (tv->tv_usec * 1000);
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT;
write_unlock_irq(&xtime_lock);
}
/*
* 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_stat.h>
#include <linux/errno.h>
#include <linux/init.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");
#if 0
{
extern int swt_lastjiffies, swt_reference;
printk("WATCHDOG: jiffies=%d lastjiffies=%d [%d] reference=%d\n",
jiffies, swt_lastjiffies, (swt_lastjiffies - jiffies),
swt_reference);
}
#endif
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=%08x\n\n",
(int) current->mm->start_stack,
(int) PAGE_SIZE+(unsigned long)current);
}
printk("PC: %08lx\n", (long)fp->pc);
printk("CCR: %08lx SP: %08lx\n", fp->ccr, (long) fp);
printk("ER0: %08lx ER1: %08lx ER2: %08lx ER3: %08lx\n",
fp->er0, fp->er1, fp->er2, fp->er3);
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 show_trace_task(struct task_struct *tsk)
{
/* DAVIDM: we can do better, need a proper stack dump */
printk("STACK ksp=0x%lx, usp=0x%lx\n", tsk->thread.ksp, tsk->thread.usp);
}
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);
}
#
# Makefile for H8/300-specific library files..
#
.S.o:
$(CC) $(AFLAGS) -D__ASSEMBLY__ -c $< -o $@
L_TARGET = lib.a
obj-y = ashrdi3.o checksum.o memcpy.o memset.o abs.o
;;; memcpy.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
/* 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;
}
/*
* 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>
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;
}
/*
* 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);
}
;;; 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
/* 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)
mov.l er2,er2
beq 7f
mov.l er0,@-sp
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
shlr.l er2
shlr.l er2
;; 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:
mov.l @sp+,er0
7:
rts
\ No newline at end of file
#
# Makefile for the linux m68k-specific parts of the memory manager.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definition is now in the main makefile...
obj-y := init.o fault.o memory.o kmap.o extable.o
/*
* linux/arch/h8300/mm/extable.c
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
/* Simple binary search */
const struct exception_table_entry *
search_extable(const struct exception_table_entry *first,
const struct exception_table_entry *last,
unsigned long value)
{
while (first <= last) {
const struct exception_table_entry *mid;
long diff;
mid = (last - first) / 2 + first;
diff = mid->insn - value;
if (diff == 0)
return mid;
else if (diff < 0)
first = mid+1;
else
last = mid-1;
}
return NULL;
}
/*
* 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;
}
/*
* 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>
#ifdef CONFIG_BLK_DEV_RAM
#include <linux/blk.h>
#endif
#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 char _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("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("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("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
}
/*
* 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)
{
}
/*
* 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
#
# Makefile for the linux kernel.
#
# Reuse any files we can from the H8/300H
#
#VPATH := $(VPATH):$(BOARD)
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
.S.o:
$(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o
obj-y := entry.o ints.o
$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S
entry.o: entry.S
ints.o: ints.c
#
# h8300h/Makefile
#
# This file is included by the global makefile so that you can add your own
# platform-specific flags and dependencies.
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (c) 2001 Lineo, Inc, <www.lineo.com>
# Copyright (c) 2000,2001 D. Jeff Dionne <jeff@lineo.ca>
# Copyright (c) 1998,1999 D. Jeff Dionne <jeff@uclinux.org>
# Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>
# Copyright (C) 1994 Hamish Macdonald
#
# 68VZ328 Fixes By Evan Stawnyczy <e@lineo.ca>
# H8/300H Modify By Yoshinori Sato <ysato@users.sourceforge.jp>
CROSS_COMPILE = h8300-elf-
GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./')
INCGCC = $(GCC_DIR)/include
LIBGCC = $(GCC_DIR)/h8300h/int32/libgcc.a
CFLAGS := -fno-builtin -DNO_CACHE $(CFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -mh -mint32 -malign-300 -D__ELF__ -DNO_FORGET -DUTS_SYSNAME=\"uClinux\" -D__linux__ -DTARGET=$(BOARD)
AFLAGS := $(AFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -mh -D__ELF__ -DUTS_SYSNAME=\"uClinux\"
LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld
LDFLAGS := $(LDFLAGS) -mh8300helf
HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \
arch/$(ARCH)/platform/$(PLATFORM) \
arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD) \
$(SUBDIRS)
CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
arch/$(ARCH)/platform/$(PLATFORM)/platform.o \
arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(BOARD).o \
$(CORE_FILES)
LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC)
linux.bin: linux
$(OBJCOPY) -O binary linux linux.bin
archclean:
rm -f linux
#
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
all: $(BOARD).o
O_TARGET := $(BOARD).o
obj-y := timer.o
timer.o: timer.c
clean:
rm -f *.[oa]
/*
* linux/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S
*
* Yoshinori Sato <ysato@users.sourceforge.jp>
*
* Platform depend startup for uClinux-2.4.x
* Target Archtecture: AE-3068 (aka. aki3068net)
* Memory Layout : RAM
*/
#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_ram.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 er5,er6
inc.l #1,er6
mov.l #__ebss,er4
sub.l er5,er4
sub.w r0,r0
mov.b r0l,@er5
1:
eepmov.w
dec.w #1,e4
bpl 1b
/* copy kernel commandline */
mov.l #COMMAND_START,er5
mov.l #SYMBOL_NAME(command_line),er6
mov.w #512,r4
eepmov.w
/* RAM Interrupt Vector Table Setup */
#if defined(CONFIG_GDB_DEBUG)
mov.l @SYMBOL_NAME(interrupt_redirect_table)+11*4,er0
#endif
mov.l #SYMBOL_NAME(_vector_lma),er5
mov.l #SYMBOL_NAME(interrupt_redirect_table),er6
mov.w #0x100,r4
eepmov.w
#if defined(CONFIG_GDB_DEBUG)
mov.l er0,@SYMBOL_NAME(interrupt_redirect_table)+11*4
#endif
/* uClinux kernel start */
ldc #0x90,ccr /* running kernel */
mov.l #SYMBOL_NAME(init_task_union),sp
mov.l sp,@SYMBOL_NAME(_current_task)
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)
/* AE-3068 (aka. aki3068net) RAM */
OUTPUT_ARCH(h8300h)
ENTRY("__start")
MEMORY
{
ram : ORIGIN = 0x400000, LENGTH = 0x600000-0x400000-0x80000
disk : ORIGIN = 0x600000-0x80000, LENGTH = 0x60000
eram : ORIGIN = 0x600000, LENGTH = 0
iram : ORIGIN = 0xffbf20, LENGTH = 0x4000
}
SECTIONS
{
.bootvec :
{
*(.bootvec)
} > ram
.text :
{
__stext = . ;
*(.text)
. = ALIGN(0x4) ;
*(.text.*)
. = ALIGN(0x4) ;
*(.kstrtab)
. = ALIGN(0x4) ;
*(.rodata*)
. = ALIGN(16); /* Exception table */
___start___ex_table = .;
*(__ex_table)
___stop___ex_table = .;
___start___ksymtab = .; /* Kernel symbol table */
*(__ksymtab)
___stop___ksymtab = .;
. = ALIGN(0x4) ;
__etext = . ;
} > ram
.data :
{
__sdata = . ;
___data_start = . ;
*(.data)
*(.data.*)
*(.exitcall.exit)
. = ALIGN(0x2000) ;
*(.data.init_task)
. = ALIGN(0x2000) ;
___init_begin = .;
*(.text.init)
*(.data.init)
. = ALIGN(16);
___setup_start = .;
*(.setup.init)
___setup_end = .;
___initcall_start = .;
*(.initcall.init)
. = ALIGN(4) ;
___initcall_end = .;
___init_end = .;
__edata = . ;
. = ALIGN(0x4) ;
__sbss = . ;
*(.bss)
. = ALIGN(0x4) ;
*(COMMON)
. = ALIGN(0x4) ;
__ebss = . ;
__end = . ;
__ramstart = .;
} > ram
.blkimg :
{
__ramend = . ;
__blkimg = . ;
} > disk
.ram_vec : AT(ADDR(.data) + SIZEOF(.data))
{
*(.int_redirect)
} > iram
__vector_lma = LOADADDR(.ram_vec);
.dummy2 :
{
COMMAND_START = . - 0x200 ;
} > eram
}
/*
* 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 <asm/segment.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <linux/timex.h>
#define TMR8CMA2 0x00ffff94
#define TMR8TCSR2 0x00ffff92
#define TMR8TCNT2 0x00ffff90
#define CMFA 6
int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *))
{
outb(CONFIG_CLK_FREQ*10/8192,TMR8CMA2);
outb(0x00,TMR8TCSR2);
request_irq(40,timer_int,0,"timer",0);
outb(0x40|0x08|0x03,TMR8TCNT2);
}
void platform_timer_eoi(void)
{
*(unsigned char *)TMR8TCSR2 &= ~(1 << CMFA);
}
void platform_gettod(int *year, int *mon, int *day, int *hour,
int *min, int *sec)
{
*year = *mon = *day = *hour = *min = *sec = 0;
}
/* -*- mode: asm -*-
*
* linux/arch/h8300/platform/h8300h/entry.S
*
* Yoshinori Sato <ysato@users.sourceforge.jp>
*
*/
/*
* 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>
ENOSYS = 38
LSIGTRAP = 5
SOFTIRQ_PENDING = 0
/* the following macro is used when enabling interrupts */
LER3 = 0
LER2 = 4
LER1 = 8
LORIG = 12
LCCR = 16
LER0 = 18
LVEC = 22
LRET = 24
.h8300h
/* CPU context save/restore macros. */
.macro SAVE_ALL
mov.l er0,@-sp
stc ccr,r0l
orc #0x10,ccr
btst #4,r0l
bne 1f
mov.l sp,@SYMBOL_NAME(sw_usp)
mov.l @sp,er0
mov.l @SYMBOL_NAME(sw_ksp),sp
mov.l er0,@-sp
stc ccr,r0l
and #0xef,r0l
mov.w r0,@-sp
mov.l @(2:16,sp),er0
bra 2f
1:
mov.l @sp,er0
stc ccr,@-sp
2:
mov.l er0,@-sp
mov.l er1,@-sp
mov.l er2,@-sp
mov.l er3,@-sp
.endm
.macro RESTORE_REGS
mov.w @(LCCR:16,sp),r0
btst #4,r0l
bne 1f
mov.l @SYMBOL_NAME(sw_usp),er0
mov.l @(LER0:16,sp),er1
mov.l er1,@er0
mov.l @sp+,er3
mov.l @sp+,er2
mov.l @sp+,er1
add.l #10,sp
mov.l sp,@SYMBOL_NAME(sw_ksp)
mov.l er0,sp
bra 2f
1:
mov.l @sp+,er3
mov.l @sp+,er2
mov.l @sp+,er1
adds #4,sp
adds #2,sp
2:
mov.l @sp+,er0
adds #4,sp
.endm
.macro RESTORE_ALL
RESTORE_REGS
rte
.endm
#define SWITCH_STACK_SIZE (3*4+12) /* includes return address */
.macro SAVE_SWITCH_STACK
mov.l er4,@-sp
mov.l er5,@-sp
mov.l er6,@-sp
.endm
.macro RESTORE_SWITCH_STACK
mov.l @sp+,er6
mov.l @sp+,er5
mov.l @sp+,er4
.endm
.globl SYMBOL_NAME(system_call)
.globl SYMBOL_NAME(ret_from_exception)
.globl SYMBOL_NAME(ret_from_signal)
.globl SYMBOL_NAME(ret_from_interrupt), SYMBOL_NAME(bad_interrupt)
.globl SYMBOL_NAME(interrupt_redirect_table)
.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
.globl SYMBOL_NAME(resume)
.globl SYMBOL_NAME(sys_vfork)
.globl SYMBOL_NAME(syscall_trampoline)
.section .int_redirect,"ax"
SYMBOL_NAME_LABEL(interrupt_redirect_table)
.rept 7
.long 0
.endr
jsr @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 64-12
jsr @interrupt_entry
.endr
.section .text
.align 2
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:
sub.l #SYMBOL_NAME(interrupt_redirect_table),er0
shlr.l er0
shlr.l er0
dec.l #1,er0
mov.l sp,er1
jsr @SYMBOL_NAME(process_int)
mov.l @SYMBOL_NAME(irq_stat)+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
SAVE_ALL
mov.l er0,er3
mov.l #-ENOSYS,er0
mov.l er0,@(LER0:16,sp)
/* save top of frame */
mov.l sp,er0
mov.l er3,@-sp
jsr @SYMBOL_NAME(set_esp0)
mov.l @sp+,er3
cmp.l #NR_syscalls,er3
bcc SYMBOL_NAME(ret_from_exception):16
shll.l er3
shll.l er3
mov.l #SYMBOL_NAME(sys_call_table),er0
add.l er3,er0
mov.l @er0,er0
mov.l er0,er3
beq SYMBOL_NAME(ret_from_exception):16
mov.l @SYMBOL_NAME(_current_task),er2
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
mov.l er5,@-sp
mov.l er4,@-sp
jsr @er3
adds #4,sp
adds #4,sp
mov.l er0,@(LER0,sp) /* save the return value */
#if defined(CONFIG_SYSCALL_PRINT)
jsr @SYMBOL_NAME(syscall_print)
#endif
jmp @SYMBOL_NAME(ret_from_exception)
1:
SAVE_SWITCH_STACK
mov.l er3,er5 /* save syscall entry */
jsr SYMBOL_NAME(syscall_trace)
mov.l er5,er3
RESTORE_SWITCH_STACK
mov.l @(LER1:16,sp),er0
mov.l @(LER2:16,sp),er1
mov.l @(LER3:16,sp),er2
mov.l er5,@-sp
mov.l er4,@-sp
jsr @er3
adds #4,sp
adds #4,sp
mov.l er0,@(LER0:16,sp) /* save the return value */
SAVE_SWITCH_STACK
jsr SYMBOL_NAME(syscall_trace)
SYMBOL_NAME_LABEL(ret_from_signal)
RESTORE_SWITCH_STACK
SYMBOL_NAME_LABEL(ret_from_exception)
mov.b @(LCCR+1:16,sp),r0l
btst #4,r0l /* check if returning to kernel */
bne 3f /* if so, skip resched, signals */
andc #0x7f,ccr
mov.l @SYMBOL_NAME(_current_task),er0
mov.l @(TI_FLAGS:16,er2),er1
and.l #_TIF_WORK_MASK,er1
bne 1f
mov.l @((TASK_THREAD+THREAD_VFORK):16,er0),er1
bne Lvfork_return
3:
RESTORE_ALL /* Does RTE */
1:
mov.l @(TI_FLAGS:16,er2),er1
btst #TIF_NEED_RESCHED,r1l
bne @SYMBOL_NAME(reschedule):16
Lsignal_return:
SAVE_SWITCH_STACK
mov.l sp,er1
add #12,er1
mov.l er2,er0
jsr @SYMBOL_NAME(do_signal)
RESTORE_SWITCH_STACK
mov.l @SYMBOL_NAME(_current_task),er0
mov.l @((TASK_THREAD+THREAD_VFORK):16,er0),er1
bne Lvfork_return
RESTORE_ALL
Lvfork_return:
sub.l er2,er2
mov.l er2,@((TASK_THREAD+THREAD_VFORK):16,er0)
mov.l @SYMBOL_NAME(sw_usp),er0
mov.l er1,@(8:16,er0)
RESTORE_ALL
SYMBOL_NAME_LABEL(reschedule)
/* save top of frame */
mov.l sp,er0
jsr @SYMBOL_NAME(set_esp0)
mov.l #SYMBOL_NAME(ret_from_exception),er0
mov.l er0,@-sp
jmp @SYMBOL_NAME(schedule)
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:16,er0)
SAVE_SWITCH_STACK
/* 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)
/* get pointer to tss struct (a1 contains new task) */
mov.l er1,@SYMBOL_NAME(_current_task)
/* 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_SWITCH_STACK
/* restore status register */
mov.w @(THREAD_CCR:16,er1),r3
ldc r3l,ccr
rts
/* Handler for uninitialized and spurious interrupts */
SYMBOL_NAME_LABEL(bad_interrupt)
mov.l @SYMBOL_NAME(num_spurious),er0
inc.l #1,er0
mov.l er0,@SYMBOL_NAME(num_spurious)
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)
SYMBOL_NAME_LABEL(sys_vfork)
SAVE_SWITCH_STACK
mov.l @SYMBOL_NAME(sw_usp),er6
mov.l @(8:16,er6),er6
mov.l sp,er0
add.l #SWITCH_STACK_SIZE,er0
jsr @SYMBOL_NAME(h8300_vfork)
mov.l @SYMBOL_NAME(_current_task),er5
mov.l er6,@((TASK_THREAD+THREAD_VFORK):16,er5)
RESTORE_SWITCH_STACK
rts
SYMBOL_NAME_LABEL(syscall_trampoline)
SAVE_SWITCH_STACK
mov.l er0,er6
mov.l sp,er0
add.l #SWITCH_STACK_SIZE,er0
jsr @er6
RESTORE_SWITCH_STACK
rts
.section .bss
SYMBOL_NAME_LABEL(sw_ksp)
.space 4
SYMBOL_NAME_LABEL(sw_usp)
.space 4
#
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y := timer.o crt0_$(MODEL).o
clean:
rm -f *.[oa]
/*
* linux/arch/h8300/platform/h8300h/generic/crt0_rom.S
*
* Yoshinori Sato <ysato@users.sourceforge.jp>
*
* Platform depend startup for uClinux-2.4.x
* 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 er5,er6
inc.l #1,er6
mov.l #__ebss,er4
sub.l er5,er4
sub.w r0,r0
mov.b r0l,@er5
1:
eepmov.w
dec.w #1,e4
bpl 1b
/* copy .data */
#if !defined(CONFIG_H8300H_SIM)
mov.l #__begin_data,er5
mov.l #__sdata,er6
mov.l #__edata,er4
sub.l er6,er4
1:
eepmov.w
dec.w #1,e4
bpl 1b
#endif
/* 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
mov.l sp,@SYMBOL_NAME(_current_task)
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"
.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
/* AKI3068NET RAM */
OUTPUT_ARCH(h8300h)
ENTRY("__start")
MEMORY
{
ram : ORIGIN = 0x400000, LENGTH = 0xA0000
/* rdisk : ORIGIN = 0x4A0000, LENGTH = 0x70000 */
/* uram : ORIGIN = 0x510000, LENGTH = 0xF0000 */
uram : ORIGIN = 0x4A0000, LENGTH = 0x160000
eram : ORIGIN = 0x600000, LENGTH = 0
iram : ORIGIN = 0xffbf20, LENGTH = 0x4000
}
SECTIONS
{
.bootvec :
{
*(.bootvec)
} > ram
.text :
{
__stext = . ;
*(.text)
__etext = . ;
} > ram
.rodata :
{
___data_rom_start = ALIGN ( 4 ) ;
} > ram
.erom :
{
__erom = . ;
} > ram
.data :
{
__ramstart = . ;
__sdata = . ;
___data_start = . ;
*(.data)
__edata = . ;
edata = ALIGN( 0x10 ) ;
___data_end = ALIGN( 0x10 ) ;
} > ram
.bss :
{
__sbss = . ;
___bss_start = . ;
*(.bss)
*(COMMON)
__ebss = . ;
___bss_end = . ;
} > ram
/*
.rootimg :
{
__rootimage = . ;
} > rdisk
*/
.dummy1 :
{
end = ALIGN( 0x10 ) ;
__end = ALIGN( 0x10 ) ;
} > uram
.ram_vec : AT(___bss_end)
{
__ram_vector = . ;
} > iram
__ram_vector_image = LOADADDR(.ram_vec) ;
.dummy2 :
{
_COMMAND_START = . - 0x200 ;
__ramend = . ;
} > eram
}
OUTPUT_ARCH(h8300h)
ENTRY("__start")
/*INPUT(rootimage.o)*/
_jiffies = _jiffies_64 + 4;
MEMORY
{
vector : ORIGIN = 0x000000, LENGTH = 0x000100
rom : ORIGIN = 0x000100, LENGTH = 0x200000-0x000100
erom : ORIGIN = 0x200000, LENGTH = 1
ram : ORIGIN = 0x200000, LENGTH = 0x100000
eram : ORIGIN = 0x2fa000, LENGTH = 1
}
SECTIONS
{
.vectors :
{
__vector = . ;
*(.vectors*)
} > vector
.text :
{
*(.int_redirect)
__stext = . ;
*(.text)
. = ALIGN(0x4) ;
*(.exit.text)
*(.text.*)
. = ALIGN(0x4) ;
*(.exitcall.exit)
. = ALIGN(0x4) ;
*(.kstrtab)
. = ALIGN(0x4) ;
*(.rodata*)
. = ALIGN(16); /* Exception table */
___start___ex_table = .;
*(__ex_table)
___stop___ex_table = .;
___start___ksymtab = .; /* Kernel symbol table */
*(__ksymtab)
___stop___ksymtab = .;
. = ALIGN(0x4) ;
__etext = . ;
} > rom
.data : AT( ADDR(.text)+SIZEOF(.text))
{
__sdata = . ;
___data_start = . ;
. = ALIGN(0x2000) ;
*(.data.init_task)
. = ALIGN(0x4) ;
*(.data)
. = ALIGN(0x4) ;
*(.data.*)
. = ALIGN(0x4) ;
___init_begin = .;
*(.init.text)
*(.init.data)
. = ALIGN(0x4) ;
___setup_start = .;
*(.init.setup)
. = ALIGN(0x4) ;
___setup_end = .;
___start___param = .;
*(__param)
___stop___param = .;
___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 = .;
. = ALIGN(4);
___initramfs_start = .;
*(.init.ramfs)
___initramfs_end = .;
. = ALIGN(0x4) ;
___init_end = .;
__edata = . ;
} > ram
__begin_data = LOADADDR(.data) ;
.blkimg : AT( LOADADDR(.data) + SIZEOF(.data))
{
__blkimg = . ;
*(.rootimg*)
} > rom
.erom :
{
__erom = . ;
} > erom
.bss :
{
. = ALIGN(0x4) ;
__sbss = . ;
*(.bss)
. = ALIGN(0x4) ;
*(COMMON)
. = ALIGN(0x4) ;
__ebss = . ;
__end = . ;
__ramstart = .;
} > ram
.dummy :
{
COMMAND_START = . - 0x200 ;
__ramend = . ;
} > eram
}
/*
* linux/arch/h8300/platform/h8300h/generic/timer.c
*
* Yoshinori Sato <qzb04471@nifty.ne.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)
#define TMR8CMA2 0x00ffff94
#define TMR8TCSR2 0x00ffff92
#define TMR8TCNT2 0x00ffff90
int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *))
{
outb(H8300_TIMER_COUNT_DATA,TMR8CMA2);
outb(0x00,TMR8TCSR2);
request_irq(40,timer_int,0,"timer",0);
outb(0x40|0x08|0x03,TMR8TCNT2);
return 0;
}
void platform_timer_eoi(void)
{
__asm__("bclr #6,@0xffff92:8");
}
#endif
#if defined(H8_3002) || defined(CONFIG_H83048)
#define TSTR 0x00ffff60
#define TSNC 0x00ffff61
#define TMDR 0x00ffff62
#define TFCR 0x00ffff63
#define TOER 0x00ffff90
#define TOCR 0x00ffff91
#define TCR 0x00ffff64
#define TIOR 0x00ffff65
#define TIER 0x00ffff66
#define TSR 0x00ffff67
#define TCNT 0x00ffff68
#define GRA 0x00ffff6a
#define GRB 0x00ffff6c
int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *))
{
*(unsigned short *)GRA= H8300_TIMER_COUNT_DATA;
*(unsigned short *)TCNT=0;
outb(0x23,TCR);
outb(0x00,TIOR);
request_irq(26,timer_int,0,"timer",0);
outb(inb(TIER) | 0x01,TIER);
outb(inb(TSNC) & ~0x01,TSNC);
outb(inb(TMDR) & ~0x01,TMDR);
outb(inb(TSTR) | 0x01,TSTR);
return 0;
}
void platform_timer_eoi(void)
{
outb(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;
}
#
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
all: $(BOARD).o
O_TARGET := $(BOARD).o
obj-y := timer.o
timer.o: timer.c
clean:
rm -f *.[oa]
/*
* linux/arch/h8300/platform/h8300h/h8max/crt0_ram.S
*
* Yoshinori Sato <ysato@users.sourceforge.jp>
*
* Platform depend startup for uClinux-2.4.x
* Target Archtecture: H8MAX
* Memory Layout : RAM
*/
#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_ram.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 er5,er6
inc.l #1,er6
mov.l #__ebss,er4
sub.l er5,er4
sub.w r0,r0
mov.b r0l,@er5
1:
eepmov.w
dec.w #1,e4
bpl 1b
/* copy kernel commandline */
mov.l #COMMAND_START,er5
mov.l #SYMBOL_NAME(command_line),er6
mov.w #512,r4
eepmov.w
/* RAM Interrupt Vector Table Setup */
#if defined(CONFIG_GDB_DEBUG)
mov.l @SYMBOL_NAME(interrupt_redirect_table)+11*4,er0
#endif
mov.l #SYMBOL_NAME(_vector_lma),er5
mov.l #SYMBOL_NAME(interrupt_redirect_table),er6
mov.w #0x100,r4
eepmov.w
#if defined(CONFIG_GDB_DEBUG)
mov.l er0,@SYMBOL_NAME(interrupt_redirect_table)+11*4
#endif
/* uClinux kernel start */
ldc #0x90,ccr /* running kernel */
mov.l #SYMBOL_NAME(init_task_union),sp
mov.l sp,@SYMBOL_NAME(_current_task)
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)
/* H8MAX RAM */
OUTPUT_ARCH(h8300h)
ENTRY("__start")
MEMORY
{
ram : ORIGIN = 0x400000, LENGTH = 0x600000-0x400000-0xc000
disk : ORIGIN = 0x600000-0xc000, LENGTH = 0xc000
eram : ORIGIN = 0x600000, LENGTH = 0
iram : ORIGIN = 0xfffd20, LENGTH = 0x100
}
SECTIONS
{
.bootvec :
{
*(.bootvec)
} > ram
.text :
{
__stext = . ;
*(.text)
. = ALIGN(0x4) ;
*(.text.*)
. = ALIGN(0x4) ;
*(.kstrtab)
. = ALIGN(0x4) ;
*(.rodata*)
. = ALIGN(16); /* Exception table */
___start___ex_table = .;
*(__ex_table)
___stop___ex_table = .;
___start___ksymtab = .; /* Kernel symbol table */
*(__ksymtab)
___stop___ksymtab = .;
. = ALIGN(0x4) ;
__etext = . ;
} > ram
.data :
{
__sdata = . ;
___data_start = . ;
*(.data)
*(.data.*)
*(.exitcall.exit)
. = ALIGN(0x2000) ;
*(.data.init_task)
. = ALIGN(0x2000) ;
___init_begin = .;
*(.text.init)
*(.data.init)
. = ALIGN(16);
___setup_start = .;
*(.setup.init)
___setup_end = .;
___initcall_start = .;
*(.initcall.init)
. = ALIGN(4) ;
___initcall_end = .;
___init_end = .;
__edata = . ;
. = ALIGN(0x4) ;
__sbss = . ;
*(.bss)
. = ALIGN(0x4) ;
*(COMMON)
. = ALIGN(0x4) ;
__ebss = . ;
__end = . ;
__ramstart = .;
} > ram
.blkimg :
{
__ramend = . ;
__blkimg = . ;
} > disk
.ram_vec : AT(ADDR(.data) + SIZEOF(.data))
{
*(.int_redirect)
} > iram
__vector_lma = LOADADDR(.ram_vec);
.dummy2 :
{
COMMAND_START = . - 0x200 ;
} > eram
}
/*
* 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 <asm/segment.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <linux/timex.h>
#define TMR8CMA2 0x00ffff94
#define TMR8TCSR2 0x00ffff92
#define TMR8TCNT2 0x00ffff90
#define CMFA 6
int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *))
{
outb(CONFIG_CLK_FREQ*10/8192,TMR8CMA2);
outb(0x00,TMR8TCSR2);
request_irq(40,timer_int,0,"timer",0);
outb(0x40|0x08|0x03,TMR8TCNT2);
}
void platform_timer_eoi(void)
{
*(unsigned char *)TMR8TCSR2 &= ~(1 << CMFA);
}
void platform_gettod(int *year, int *mon, int *day, int *hour,
int *min, int *sec)
{
*year = *mon = *day = *hour = *min = *sec = 0;
}
/*
* 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/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/kernel_stat.h>
#include <linux/seq_file.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/hardirq.h>
#include <asm/regs306x.h>
#define INTERNAL_IRQS (64)
#define EXT_IRQ0 12
#define EXT_IRQ1 13
#define EXT_IRQ2 14
#define EXT_IRQ3 15
#define EXT_IRQ4 16
#define EXT_IRQ5 17
#define EXT_IRQ6 18
#define EXT_IRQ7 19
#define WDT_IRQ 20
/* table for system interrupt handlers */
static irq_handler_t irq_list[SYS_IRQS];
/* The number of spurious interrupts */
volatile unsigned int num_spurious;
/* assembler routines */
asmlinkage void system_call(void);
asmlinkage void bad_interrupt(void);
/* irq node variables for the 32 (potential) on chip sources */
/*static irq_node_t *int_irq_list[INTERNAL_IRQS];*/
static int int_irq_count[INTERNAL_IRQS];
#if 0
static void int_badint(int irq, void *dev_id, struct pt_regs *fp)
{
num_spurious += 1;
}
#endif
void init_IRQ(void)
{
int i;
for (i = 0; i < SYS_IRQS; i++) {
irq_list[i].handler = NULL;
irq_list[i].flags = 0;
irq_list[i].devname = NULL;
irq_list[i].dev_id = NULL;
}
}
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
if (irq >= EXT_IRQ0 && irq <= EXT_IRQ3) {
if (H8300_GPIO_RESERVE(H8300_GPIO_P8, 1 << (irq - EXT_IRQ0)) == 0)
return 1;
H8300_GPIO_DDR(H8300_GPIO_P8, (irq - EXT_IRQ0), 0);
}
if (irq >= EXT_IRQ4 && irq <= EXT_IRQ5) {
if (H8300_GPIO_RESERVE(H8300_GPIO_P9, 1 << (irq - EXT_IRQ0)) == 0)
return 1;
H8300_GPIO_DDR(H8300_GPIO_P9, (irq - EXT_IRQ0), 0);
}
irq_list[irq].handler = handler;
irq_list[irq].flags = flags;
irq_list[irq].devname = devname;
irq_list[irq].dev_id = dev_id;
if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5)
*(volatile unsigned char *)IER |= 1 << (irq - EXT_IRQ0);
return 0;
}
void free_irq(unsigned int irq, void *dev_id)
{
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_IRQ5)
*(volatile unsigned char *)IER &= ~(1 << (irq - EXT_IRQ0));
irq_list[irq].handler = NULL;
irq_list[irq].flags = 0;
irq_list[irq].dev_id = NULL;
irq_list[irq].devname = NULL;
}
/*
* Do we need these probe functions on the m68k?
*/
unsigned long probe_irq_on (void)
{
return 0;
}
int probe_irq_off (unsigned long irqs)
{
return 0;
}
struct int_regs {
unsigned long ier;
unsigned long isr;
unsigned char mask;
};
#define REGS_DEF(ier,isr,mask) {ier,isr,mask}
const struct int_regs interrupt_registers[]= {
REGS_DEF(IER,ISR,0x01),
REGS_DEF(IER,ISR,0x02),
REGS_DEF(IER,ISR,0x04),
REGS_DEF(IER,ISR,0x08),
REGS_DEF(IER,ISR,0x10),
REGS_DEF(IER,ISR,0x20),
REGS_DEF(IER,ISR,0x40),
REGS_DEF(IER,ISR,0x80),
REGS_DEF(TCSR,TCSR,0x20),
REGS_DEF(RTMCSR,RTMCSR,0x40),
REGS_DEF(0,0,0),
REGS_DEF(ADCSR,ADCSR,0x40),
REGS_DEF(TISRA,TISRA,0x10),
REGS_DEF(TISRB,TISRB,0x10),
REGS_DEF(TISRC,TISRC,0x10),
REGS_DEF(0,0,0),
REGS_DEF(TISRA,TISRA,0x20),
REGS_DEF(TISRB,TISRB,0x20),
REGS_DEF(TISRC,TISRC,0x20),
REGS_DEF(0,0,0),
REGS_DEF(TISRA,TISRA,0x40),
REGS_DEF(TISRB,TISRB,0x40),
REGS_DEF(TISRC,TISRC,0x40),
REGS_DEF(0,0,0),
REGS_DEF(_8TCR0,_8TCSR0,0x40),
REGS_DEF(_8TCR0,_8TCSR0,0x80),
REGS_DEF(_8TCR1,_8TCSR1,0xC0),
REGS_DEF(_8TCR0,_8TCSR0,0x20),
REGS_DEF(_8TCR2,_8TCSR2,0x40),
REGS_DEF(_8TCR2,_8TCSR2,0x80),
REGS_DEF(_8TCR3,_8TCSR3,0xC0),
REGS_DEF(_8TCR2,_8TCSR2,0x20),
REGS_DEF(DTCR0A,DTCR0A,0x0),
REGS_DEF(DTCR0B,DTCR0B,0x0),
REGS_DEF(DTCR1A,DTCR1A,0x0),
REGS_DEF(DTCR1B,DTCR1B,0x0),
REGS_DEF(0,0,0),
REGS_DEF(0,0,0),
REGS_DEF(0,0,0),
REGS_DEF(0,0,0),
REGS_DEF(SCR0,SSR0,0x40),
REGS_DEF(SCR0,SSR0,0x40),
REGS_DEF(SCR0,SSR0,0x80),
REGS_DEF(SCR0,SSR0,0x04),
REGS_DEF(SCR1,SSR1,0x40),
REGS_DEF(SCR1,SSR1,0x40),
REGS_DEF(SCR1,SSR1,0x80),
REGS_DEF(SCR1,SSR1,0x04),
REGS_DEF(SCR2,SSR2,0x40),
REGS_DEF(SCR2,SSR2,0x40),
REGS_DEF(SCR2,SSR2,0x80),
REGS_DEF(SCR2,SSR2,0x04)
};
void enable_irq(unsigned int irq)
{
unsigned char ier;
const struct int_regs *regs=&interrupt_registers[irq - 12];
if (irq == WDT_IRQ) {
ier = ctrl_inb(TCSR);
ier |= 0x20;
ctrl_outb((0xa500 | ier),TCSR);
} else {
if ((irq > 12) && regs->ier) {
ier = ctrl_inb(regs->ier);
ier |= regs->mask;
ctrl_outb(ier, regs->ier);
} else
panic("Unknown interrupt vector");
}
}
void disable_irq(unsigned int irq)
{
unsigned char ier;
const struct int_regs *regs=&interrupt_registers[irq - 12];
if (irq == WDT_IRQ) {
ier = ctrl_inb(TCSR);
ier &= ~0x20;
ctrl_outb((0xa500 | ier),TCSR);
} else {
if ((irq > 12) && regs->ier) {
ier = ctrl_inb(regs->ier);
ier &= ~(regs->mask);
ctrl_outb(ier, regs->ier);
} else
panic("Unknown interrupt vector");
}
}
asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
{
irq_enter();
if (irq_list[vec].handler) {
irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
int_irq_count[vec]++;
} else
panic("No interrupt handler for %ld\n", vec);
if (vec >= EXT_IRQ0 && vec <= EXT_IRQ5)
*(volatile unsigned char *)ISR &= ~(1 << (vec - EXT_IRQ0));
irq_exit();
}
int show_interrupts(struct seq_file *p, void *v)
{
int i;
for (i = 0; i < NR_IRQS; i++) {
seq_printf(p, "%3d: %10u ",i,int_irq_count[i]);
seq_printf(p, "%s\n", irq_list[i].devname);
}
return 0;
}
void init_irq_proc(void)
{
}
#include <linux/config.h>
#ifdef CONFIG_H8300H_GENERIC
#ifdef CONFIG_ROMKERNEL
#include "platform/h8300h/generic/rom.ld"
#endif
#ifdef CONFIG_RAMKERNEL
#include "platform/h8300h/generic/ram.ld"
#endif
#endif
#ifdef CONFIG_H8300H_AKI3068NET
#ifdef CONFIG_ROMKERNEL
#include "platform/h8300h/aki3068net/rom.ld"
#endif
#ifdef CONFIG_RAMKERNEL
#include "platform/h8300h/aki3068net/ram.ld"
#endif
#endif
#ifdef CONFIG_H8300H_H8MAX
#ifdef CONFIG_ROMKERNEL
#include "platform/h8300h/h8max/rom.ld"
#endif
#ifdef CONFIG_RAMKERNEL
#include "platform/h8300h/h8max/ram.ld"
#endif
#endif
#ifdef CONFIG_H8300H_SIM
#ifdef CONFIG_ROMKERNEL
#include "platform/h8300h/generic/rom.ld"
#endif
#ifdef CONFIG_RAMKERNEL
#include "platform/h8300h/generic/ram.ld"
#endif
#endif
#ifndef __H8300_A_OUT_H__
#define __H8300_A_OUT_H__
struct exec
{
unsigned long a_info; /* Use macros N_MAGIC, etc for access */
unsigned a_text; /* length of text, in bytes */
unsigned a_data; /* length of data, in bytes */
unsigned a_bss; /* length of uninitialized data area for file, in bytes */
unsigned a_syms; /* length of symbol table data in file, in bytes */
unsigned a_entry; /* start address */
unsigned a_trsize; /* length of relocation info for text, in bytes */
unsigned a_drsize; /* length of relocation info for data, in bytes */
};
#define N_TRSIZE(a) ((a).a_trsize)
#define N_DRSIZE(a) ((a).a_drsize)
#define N_SYMSIZE(a) ((a).a_syms)
#ifdef __KERNEL__
#define STACK_TOP TASK_SIZE
#endif
#endif /* __H8300_A_OUT_H__ */
/* AE-3068 (aka. aki3068net) RTL8019AS Config */
#define NE2000_ADDR CONFIG_NE_BASE
#define NE2000_IRQ 5
#define NE2000_IRQ_VECTOR (12 + NE2000_IRQ)
#define NE2000_BYTE volatile unsigned short
#define IER 0xfee015
#define ISR 0xfee016
#define IRQ_MASK (1 << NE2000_IRQ)
#define WCRL 0xfee023
#define MAR0A 0xffff20
#define ETCR0A 0xffff24
#define DTCR0A 0xffff27
#define MAR0B 0xffff28
#define DTCR0B 0xffff2f
#define H8300_INIT_NE() \
do { \
wordlength = 1; \
outb_p(0x48, ioaddr + EN0_DCFG); \
} while(0)
#ifndef __ARCH_H8300_ATOMIC__
#define __ARCH_H8300_ATOMIC__
/*
* Atomic operations that C can't guarantee us. Useful for
* resource counting etc..
*/
typedef struct { int counter; } atomic_t;
#define ATOMIC_INIT(i) { (i) }
#define atomic_read(v) ((v)->counter)
#define atomic_set(v, i) (((v)->counter) = i)
#include <asm/system.h>
#include <linux/kernel.h>
static __inline__ int atomic_add_return(int i, atomic_t *v)
{
int ret,flags;
local_irq_save(flags);
ret = v->counter += i;
local_irq_restore(flags);
return ret;
}
#define atomic_add(i, v) atomic_add_return(i, v)
static __inline__ int atomic_sub_return(int i, atomic_t *v)
{
int ret,flags;
local_irq_save(flags);
ret = v->counter -= i;
local_irq_restore(flags);
return ret;
}
#define atomic_sub(i, v) atomic_sub_return(i, v)
static __inline__ int atomic_inc_return(atomic_t *v)
{
int ret,flags;
local_irq_save(flags);
v->counter++;
ret = v->counter;
local_irq_restore(flags);
return ret;
}
#define atomic_inc(v) atomic_inc_return(v)
static __inline__ int atomic_dec_return(atomic_t *v)
{
int ret,flags;
local_irq_save(flags);
--v->counter;
ret = v->counter;
local_irq_restore(flags);
return ret;
}
#define atomic_dec(v) atomic_dec_return(v)
static __inline__ int atomic_dec_and_test(atomic_t *v)
{
int ret,flags;
local_irq_save(flags);
--v->counter;
ret = v->counter;
local_irq_restore(flags);
return ret == 0;
}
static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *v)
{
__asm__ __volatile__("stc ccr,r2l\n\t"
"orc #0x80,ccr\n\t"
"mov.l %0,er0\n\t"
"mov.l %1,er1\n\t"
"and.l er1,er0\n\t"
"mov.l er0,%0\n\t"
"ldc r2l,ccr"
: "=m" (*v) : "ir" (~(mask)) :"er0","er1","er2");
}
static __inline__ void atomic_set_mask(unsigned long mask, unsigned long *v)
{
__asm__ __volatile__("stc ccr,r2l\n\t"
"orc #0x80,ccr\n\t"
"mov.l %0,er0\n\t"
"mov.l %1,er1\n\t"
"or.l er1,er0\n\t"
"mov.l er0,%0\n\t"
"ldc r2l,ccr"
: "=m" (*v) : "ir" (mask) :"er0","er1","er2");
}
/* Atomic operations are already serializing */
#define smp_mb__before_atomic_dec() barrier()
#define smp_mb__after_atomic_dec() barrier()
#define smp_mb__before_atomic_inc() barrier()
#define smp_mb__after_atomic_inc() barrier()
#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
#endif /* __ARCH_H8300_ATOMIC __ */
#ifndef _H8300_BITOPS_H
#define _H8300_BITOPS_H
/*
* Copyright 1992, Linus Torvalds.
* Copyright 2002, Yoshinori Sato
*/
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/compiler.h>
#include <asm/byteorder.h> /* swab32 */
#ifdef __KERNEL__
/*
* Function prototypes to keep gcc -Wall happy
*/
/*
* The __ functions are not atomic
*/
extern void set_bit(int nr, volatile unsigned long* addr);
extern void clear_bit(int nr, volatile unsigned long* addr);
extern void change_bit(int nr, volatile unsigned long* addr);
extern int test_and_set_bit(int nr, volatile unsigned long* addr);
extern int __test_and_set_bit(int nr, volatile unsigned long* addr);
extern int test_and_clear_bit(int nr, volatile unsigned long* addr);
extern int __test_and_clear_bit(int nr, volatile unsigned long* addr);
extern int test_and_change_bit(int nr, volatile unsigned long* addr);
extern int __test_and_change_bit(int nr, volatile unsigned long* addr);
extern int __constant_test_bit(int nr, const volatile unsigned long* addr);
extern int __test_bit(int nr, volatile unsigned long* addr);
extern int find_first_zero_bit(void * addr, unsigned size);
extern int find_next_zero_bit (void * addr, int size, int offset);
/*
* ffz = Find First Zero in word. Undefined if no zero exists,
* so code should check against ~0UL first..
*/
extern __inline__ unsigned long ffz(unsigned long word)
{
unsigned long result;
__asm__("sub.l %0,%0\n\t"
"dec.l #1,%0\n"
"1:\n\t"
"shlr.l %1\n\t"
"adds #1,%0\n\t"
"bcs 1b"
: "=r" (result) : "r" (word));
return result;
}
extern __inline__ void set_bit(int nr, volatile unsigned long* addr)
{
unsigned char *a = (unsigned char *) addr;
a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
__asm__("mov.l %0,er0\n\t"
"bset r0l,@%1"
::"r"(nr & 7),"r"(a):"er0","er1");
}
/* Bigendian is complexed... */
#define __set_bit(nr, addr) set_bit(nr, addr)
/*
* clear_bit() doesn't provide any barrier for the compiler.
*/
#define smp_mb__before_clear_bit() barrier()
#define smp_mb__after_clear_bit() barrier()
extern __inline__ void clear_bit(int nr, volatile unsigned long* addr)
{
unsigned char *a = (unsigned char *) addr;
a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
__asm__("mov.l %0,er0\n\t"
"bclr r0l,@%1"
::"r"(nr & 7),"r"(a):"er0");
}
#define __clear_bit(nr, addr) clear_bit(nr, addr)
extern __inline__ void change_bit(int nr, volatile unsigned long* addr)
{
unsigned char *a = (unsigned char *) addr;
a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
__asm__("mov.l %0,er0\n\t"
"bnot r0l,@%1"
::"r"(nr & 7),"r"(a):"er0");
}
#define __change_bit(nr, addr) change_bit(nr, addr)
extern __inline__ int test_and_set_bit(int nr, volatile unsigned long* addr)
{
int retval;
unsigned char *a;
a = (unsigned char *) addr;
a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
__asm__("mov.l %1,er0\n\t"
"stc ccr,r0h\n\t"
"orc #0x80,ccr\n\t"
"btst r0l,@%2\n\t"
"bset r0l,@%2\n\t"
"stc ccr,r0l\n\t"
"ldc r0h,ccr\n\t"
"btst #2,r0l\n\t"
"bne 1f\n\t"
"sub.l %0,%0\n\t"
"inc.l #1,%0\n"
"bra 2f\n"
"1:\n\t"
"sub.l %0,%0\n"
"2:"
: "=r"(retval) :"r"(nr & 7),"r"(a):"er0");
return retval;
}
extern __inline__ int __test_and_set_bit(int nr, volatile unsigned long* addr)
{
int retval;
unsigned char *a = (unsigned char *) addr;
a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
__asm__("mov.l %1,er0\n\t"
"btst r0l,@%2\n\t"
"bset r0l,@%2\n\t"
"beq 1f\n\t"
"sub.l %0,%0\n\t"
"inc.l #1,%0\n"
"bra 2f\n"
"1:\n\t"
"sub.l %0,%0\n"
"2:"
: "=r"(retval) :"r"(nr & 7),"r"(a):"er0");
return retval;
}
extern __inline__ int test_and_clear_bit(int nr, volatile unsigned long* addr)
{
int retval;
unsigned char *a = (unsigned char *) addr;
a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
__asm__("mov.l %1,er0\n\t"
"stc ccr,r0h\n\t"
"orc #0x80,ccr\n\t"
"btst r0l,@%2\n\t"
"bclr r0l,@%2\n\t"
"stc ccr,r0l\n\t"
"ldc r0h,ccr\n\t"
"btst #2,r0l\n\t"
"bne 1f\n\t"
"sub.l %0,%0\n\t"
"inc.l #1,%0\n"
"bra 2f\n"
"1:\n\t"
"sub.l %0,%0\n"
"2:"
: "=r"(retval) :"r"(nr & 7),"r"(a):"er0");
return retval;
}
extern __inline__ int __test_and_clear_bit(int nr, volatile unsigned long* addr)
{
int retval;
unsigned char *a = (unsigned char *) addr;
a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
__asm__("mov.l %1,er0\n\t"
"btst r0l,@%2\n\t"
"bclr r0l,@%2\n\t"
"beq 1f\n\t"
"sub.l %0,%0\n\t"
"inc.l #1,%0\n"
"bra 2f\n"
"1:\n\t"
"sub.l %0,%0\n"
"2:"
: "=r"(retval) :"r"(nr & 7),"r"(a):"er0");
return retval;
}
extern __inline__ int test_and_change_bit(int nr, volatile unsigned long* addr)
{
int retval;
unsigned char *a = (unsigned char *) addr;
a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
__asm__("mov.l %1,er0\n\t"
"stc ccr,r0h\n\t"
"orc #0x80,ccr\n\t"
"btst r0l,@%2\n\t"
"bnot r0l,@%2\n\t"
"stc ccr,r0l\n\t"
"ldc r0h,ccr\n\t"
"btst #2,r0l\n\t"
"bne 1f\n\t"
"sub.l %0,%0\n\t"
"inc.l #1,%0\n"
"bra 2f\n"
"1:\n\t"
"sub.l %0,%0\n"
"2:"
: "=r"(retval) :"r"(nr & 7),"r"(a):"er0");
return retval;
}
extern __inline__ int __test_and_change_bit(int nr, volatile unsigned long* addr)
{
int retval;
unsigned char *a = (unsigned char *) addr;
a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
__asm__("mov.l %1,er0\n\t"
"btst r0l,@%2\n\t"
"bnot r0l,@%2\n\t"
"beq 1f\n\t"
"sub.l %0,%0\n\t"
"inc.l #1,%0\n"
"bra 2f\n"
"1:\n\t"
"sub.l %0,%0\n"
"2:"
: "=r"(retval) :"r"(nr & 7),"r"(a):"er0");
return retval;
}
/*
* This routine doesn't need to be atomic.
*/
extern __inline__ int __constant_test_bit(int nr, const volatile unsigned long* addr)
{
return ((1UL << (nr & 7)) &
(((const volatile unsigned char *) addr)
[((nr >> 3) & ~3) + 3 - ((nr >> 3) & 3)])) != 0;
}
extern __inline__ int __test_bit(int nr, volatile unsigned long* addr)
{
int retval;
unsigned char *a = (unsigned char *) addr;
a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
__asm__("mov.l %1,er0\n\t"
"btst r0l,@%2\n\t"
"beq 1f\n\t"
"sub.l %0,%0\n\t"
"inc.l #1,%0\n"
"bra 2f\n"
"1:\n\t"
"sub.l %0,%0\n"
"2:"
: "=r"(retval) :"r"(nr & 7),"r"(a):"er0");
return retval;
}
#define test_bit(nr,addr) \
(__builtin_constant_p(nr) ? \
__constant_test_bit((nr),(addr)) : \
__test_bit((nr),(addr)))
#define find_first_zero_bit(addr, size) \
find_next_zero_bit((addr), (size), 0)
extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
{
unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
unsigned long result = offset & ~31UL;
unsigned long tmp;
if (offset >= size)
return size;
size -= result;
offset &= 31UL;
if (offset) {
tmp = *(p++);
tmp |= ~0UL >> (32-offset);
if (size < 32)
goto found_first;
if (~tmp)
goto found_middle;
size -= 32;
result += 32;
}
while (size & ~31UL) {
if (~(tmp = *(p++)))
goto found_middle;
result += 32;
size -= 32;
}
if (!size)
return result;
tmp = *p;
found_first:
tmp |= ~0UL >> size;
found_middle:
return result + ffz(tmp);
}
extern __inline__ unsigned long ffs(unsigned long word)
{
unsigned long result;
__asm__("sub.l er0,er0\n\t"
"dec.l #1,er0\n"
"1:\n\t"
"shlr.l %1\n\t"
"adds #1,er0\n\t"
"bcc 1b\n\t"
"mov.l er0,%0"
: "=r" (result) : "r"(word) : "er0");
return result;
}
#define __ffs(x) ffs(x)
/*
* fls: find last bit set.
*/
#define fls(x) generic_fls(x)
/*
* Every architecture must define this function. It's the fastest
* way of searching a 140-bit bitmap where the first 100 bits are
* unlikely to be set. It's guaranteed that at least one of the 140
* bits is cleared.
*/
static inline int sched_find_first_bit(unsigned long *b)
{
if (unlikely(b[0]))
return __ffs(b[0]);
if (unlikely(b[1]))
return __ffs(b[1]) + 32;
if (unlikely(b[2]))
return __ffs(b[2]) + 64;
if (b[3])
return __ffs(b[3]) + 96;
return __ffs(b[4]) + 128;
}
/*
* hweightN: returns the hamming weight (i.e. the number
* of bits set) of a N-bit word
*/
#define hweight32(x) generic_hweight32(x)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
extern __inline__ int ext2_set_bit(int nr, volatile void *addr)
{
unsigned char *a = (unsigned char *) addr;
register unsigned short r __asm__("er0");
a += nr >> 3;
__asm__("mov.l %1,er0\n\t"
"sub.w e0,e0\n\t"
"btst r0l,@%2\n\t"
"bset r0l,@%2\n\t"
"beq 1f\n\t"
"inc.w #1,e0\n"
"1:\n\t"
"mov.w e0,r0\n\t"
"sub.w e0,e0"
:"=r"(r):"r"(nr & 7),"r"(a));
return r;
}
extern __inline__ int ext2_clear_bit(int nr, volatile void *addr)
{
unsigned char *a = (unsigned char *) addr;
register unsigned short r __asm__("er0");
a += nr >> 3;
__asm__("mov.l %1,er0\n\t"
"sub.w e0,e0\n\t"
"btst r0l,@%2\n\t"
"bclr r0l,@%2\n\t"
"beq 1f\n\t"
"inc.w #1,e0\n"
"1:\n\t"
"mov.w e0,r0\n\t"
"sub.w e0,e0"
:"=r"(r):"r"(nr & 7),"r"(a));
return r;
}
extern __inline__ int ext2_test_bit(int nr, volatile void *addr)
{
unsigned char *a = (unsigned char *) addr;
int ret;
a += nr >> 3;
__asm__("mov.l %1,er0\n\t"
"sub.l %0,%0\n\t"
"btst r0l,@%2\n\t"
"beq 1f\n\t"
"inc.l #1,%0\n"
"1:"
: "=r"(ret) :"r"(nr & 7),"r"(a):"er0","er1");
return ret;
}
#define ext2_find_first_zero_bit(addr, size) \
ext2_find_next_zero_bit((addr), (size), 0)
extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
{
unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
unsigned long result = offset & ~31UL;
unsigned long tmp;
if (offset >= size)
return size;
size -= result;
offset &= 31UL;
if(offset) {
/* We hold the little endian value in tmp, but then the
* shift is illegal. So we could keep a big endian value
* in tmp, like this:
*
* tmp = __swab32(*(p++));
* tmp |= ~0UL >> (32-offset);
*
* but this would decrease performance, so we change the
* shift:
*/
tmp = *(p++);
tmp |= __swab32(~0UL >> (32-offset));
if(size < 32)
goto found_first;
if(~tmp)
goto found_middle;
size -= 32;
result += 32;
}
while(size & ~31UL) {
if(~(tmp = *(p++)))
goto found_middle;
result += 32;
size -= 32;
}
if(!size)
return result;
tmp = *p;
found_first:
/* tmp is little endian, so we would have to swab the shift,
* see above. But then we have to swab tmp below for ffz, so
* we might as well do this here.
*/
return result + ffz(__swab32(tmp) | (~0UL << size));
found_middle:
return result + ffz(__swab32(tmp));
}
/* Bitmap functions for the minix filesystem. */
#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
#define minix_set_bit(nr,addr) set_bit(nr,addr)
#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
#define minix_test_bit(nr,addr) test_bit(nr,addr)
#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
/**
* hweightN - returns the hamming weight of a N-bit word
* @x: the word to weigh
*
* The Hamming Weight of a number is the total number of bits set in it.
*/
#define hweight32(x) generic_hweight32(x)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
#endif /* __KERNEL__ */
#endif /* _H8300_BITOPS_H */
/* Nothing for h8300 */
#ifndef _H8300_BUG_H
#define _H8300_BUG_H
#define BUG() do { \
printk("%s(%d): kernel BUG!\n", __FILE__, __LINE__); \
} while (0)
#define PAGE_BUG(page) do { \
BUG(); \
} while (0)
#endif
/*
* include/asm-h8300/bugs.h
*
* Copyright (C) 1994 Linus Torvalds
*/
/*
* This is included by init/main.c to check for architecture-dependent bugs.
*
* Needs:
* void check_bugs(void);
*/
static void check_bugs(void)
{
}
#ifndef _H8300_BYTEORDER_H
#define _H8300_BYTEORDER_H
#include <asm/types.h>
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
# define __BYTEORDER_HAS_U64__
# define __SWAB_64_THRU_32__
#endif
#include <linux/byteorder/big_endian.h>
#endif /* _H8300_BYTEORDER_H */
#ifndef __ARCH_H8300_CACHE_H
#define __ARCH_H8300_CACHE_H
/* bytes per L1 cache line */
#define L1_CACHE_BYTES 4
/* m68k-elf-gcc 2.95.2 doesn't like these */
#define __cacheline_aligned
#define ____cacheline_aligned
#endif
#ifndef _H8300_CACHECTL_H
#define _H8300_CACHECTL_H
/* Definitions for the cacheflush system call. */
#define FLUSH_SCOPE_LINE 0 /* Flush a cache line */
#define FLUSH_SCOPE_PAGE 0 /* Flush a page */
#define FLUSH_SCOPE_ALL 0 /* Flush the whole cache -- superuser only */
#define FLUSH_CACHE_DATA 0 /* Writeback and flush data cache */
#define FLUSH_CACHE_INSN 0 /* Flush instruction cache */
#define FLUSH_CACHE_BOTH 0 /* Flush both caches */
#endif /* _H8300_CACHECTL_H */
/*
* (C) Copyright 2002, Yoshinori Sato <ysato@users.sourceforge.jp>
*/
#ifndef _ASM_H8300_CACHEFLUSH_H
#define _AMS_H8300_CACHEFLUSH_H
/*
* Cache handling functions
* No Cache memory all dummy functions
*/
#define flush_cache_all()
#define flush_cache_all()
#define flush_cache_mm(mm)
#define flush_cache_range(vma,a,b)
#define flush_cache_page(vma,p)
#define flush_page_to_ram(page)
#define flush_dcache_page(page)
#define flush_icache()
#define flush_icache_page(vma,page)
#define flush_icache_range(start,len)
#define cache_push_v(vaddr,len)
#define cache_push(paddr,len)
#define cache_clear(paddr,len)
#define flush_dcache_range(a,b)
#define flush_icache_user_range(vma,page,addr,len)
#endif /* _ASM_H8300_CACHEFLUSH_H */
#ifndef _H8300_CHECKSUM_H
#define _H8300_CHECKSUM_H
/*
* 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);
/*
* the same as csum_partial, but copies from src while it
* checksums
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
/*
* the same as csum_partial_copy, but copies from user space.
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
int len, int sum, int *csum_err);
#define csum_partial_copy_nocheck(src, dst, len, sum) \
csum_partial_copy((src), (dst), (len), (sum))
unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl);
/*
* Fold a partial checksum
*/
static inline unsigned int csum_fold(unsigned int sum)
{
__asm__("mov.l %0,er0\n\t"
"sub.w r1,r1\n\t"
"add.w e0,r0\n\t"
"addx #0,r1l\n\t"
"add.w r1,r0\n\t"
"sub.w e0,e0\n\t"
"mov.l er0,%0"
: "=r"(sum)
: "0"(sum)
: "er0","er1");
return ~sum;
}
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
static inline unsigned int
csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
unsigned short proto, unsigned int sum)
{
__asm__ ("sub.l er0,er0\n\t"
"add.l %2,%0\n\t"
"addx #0,r0l\n\t"
"add.l %3,%0\n\t"
"addx #0,r0l\n\t"
"add.l %4,%0\n\t"
"addx #0,r0l\n\t"
"add.l er0,%0\n\t"
"bcc 1f\n\t"
"inc.l #1,%0\n"
"1:"
: "=&r" (sum)
: "0" (sum), "r" (daddr), "r" (saddr), "r" (len + proto)
:"er0");
return sum;
}
static inline unsigned short int
csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
unsigned short proto, unsigned int sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
extern unsigned short ip_compute_csum(const unsigned char * buff, int len);
#endif /* _H8300_CHECKSUM_H */
#ifndef _H8300_CURRENT_H
#define _H8300_CURRENT_H
/*
* current.h
* (C) Copyright 2000, Lineo, David McCullough <davidm@lineo.com>
* (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
*
* rather than dedicate a register (as the m68k source does), we
* just keep a global, we should probably just change it all to be
* current and lose _current_task.
*/
#include <linux/thread_info.h>
#include <asm/thread_info.h>
struct task_struct;
static inline struct task_struct *get_current(void)
{
return(current_thread_info()->task);
}
#define current get_current()
#endif /* _H8300_CURRENT_H */
#define DEBUG 1
#define BREAK asm volatile ("trap #3")
#ifndef _H8300_DELAY_H
#define _H8300_DELAY_H
#include <asm/param.h>
/*
* Copyright (C) 2002 Yoshinori Sato <ysato@sourceforge.jp>
*
* Delay routines, using a pre-computed "loops_per_second" value.
*/
extern __inline__ void __delay(unsigned long loops)
{
__asm__ __volatile__ ("mov.l %0,er0\n\t"
"1:\n\t"
"dec.l #1,er0\n\t"
"bne 1b"
::"r" (loops):"er0");
}
/*
* Use only for very small delays ( < 1 msec). Should probably use a
* lookup table, really, as the multiplications take much too long with
* short delays. This is a "reasonable" implementation, though (and the
* first constant multiplications gets optimized away if the delay is
* a constant)
*/
extern unsigned long loops_per_jiffy;
extern __inline__ void udelay(unsigned long usecs)
{
usecs *= 4295; /* 2**32 / 1000000 */
usecs /= (loops_per_jiffy*HZ);
if (usecs)
__delay(usecs);
}
#endif /* _H8300_DELAY_H */
#ifndef H8300_DIV64_H
#define H8300_DIV64_H
/* n = n / base; return rem; */
#define do_div(n,base) ({ \
int __res; \
__res = ((unsigned long) n) % (unsigned) base; \
n = ((unsigned long) n) / (unsigned) base; \
__res; \
})
#endif /* _H8300_DIV64_H */
#ifndef _H8300_DMA_H
#define _H8300_DMA_H
#include <linux/config.h>
/*
* Set number of channels of DMA on ColdFire for different implementations.
*/
#define MAX_DMA_CHANNELS 0
#define MAX_DMA_ADDRESS PAGE_OFFSET
/* These are in kernel/dma.c: */
extern int request_dma(unsigned int dmanr, const char *device_id); /* reserve a DMA channel */
extern void free_dma(unsigned int dmanr); /* release it again */
#endif /* _H8300_DMA_H */
#ifndef __ASMH8300_ELF_H
#define __ASMH8300_ELF_H
/*
* ELF register definitions..
*/
#include <linux/config.h>
#include <asm/ptrace.h>
#include <asm/user.h>
typedef unsigned long elf_greg_t;
#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef struct user_m68kfp_struct elf_fpregset_t;
/*
* This is used to ensure we don't load something for the wrong architecture.
*/
#define elf_check_arch(x) ((x)->e_machine == EM_68K)
/*
* These are used to set parameters in the core dumps.
*/
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2MSB
#define ELF_ARCH EM_H8_300H
#define ELF_PLAT_INIT(_r) _r->er1 = 0
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
#endif
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
use of this is to invoke "./ld.so someprog" to test out a new version of
the loader. We need to make sure that it is out of the way of the program
that it will "exec", and that there is sufficient room for the brk. */
#define ELF_ET_DYN_BASE 0xD0000000UL
/* This yields a mask that user programs can use to figure out what
instruction set this cpu supports. */
#define ELF_HWCAP (0)
/* This yields a string that ld.so will use to load implementation
specific libraries for optimization. This is more specific in
intent than poking at uname or /proc/cpuinfo. */
#define ELF_PLATFORM (NULL)
#ifdef __KERNEL__
#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX)
#endif
#ifndef _H8300_ERRNO_H
#define _H8300_ERRNO_H
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Function not implemented */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK EDEADLK
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale NFS file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
#endif /* _H8300_ERRNO_H */
#ifndef _H8300_FCNTL_H
#define _H8300_FCNTL_H
/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
located on an ext2 file system */
#define O_ACCMODE 0003
#define O_RDONLY 00
#define O_WRONLY 01
#define O_RDWR 02
#define O_CREAT 0100 /* not fcntl */
#define O_EXCL 0200 /* not fcntl */
#define O_NOCTTY 0400 /* not fcntl */
#define O_TRUNC 01000 /* not fcntl */
#define O_APPEND 02000
#define O_NONBLOCK 04000
#define O_NDELAY O_NONBLOCK
#define O_SYNC 010000
#define FASYNC 020000 /* fcntl, for BSD compatibility */
#define O_DIRECTORY 040000 /* must be a directory */
#define O_NOFOLLOW 0100000 /* don't follow links */
#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */
#define O_LARGEFILE 0400000
#define F_DUPFD 0 /* dup */
#define F_GETFD 1 /* get close_on_exec */
#define F_SETFD 2 /* set/clear close_on_exec */
#define F_GETFL 3 /* get file->f_flags */
#define F_SETFL 4 /* set file->f_flags */
#define F_GETLK 5
#define F_SETLK 6
#define F_SETLKW 7
#define F_SETOWN 8 /* for sockets. */
#define F_GETOWN 9 /* for sockets. */
#define F_SETSIG 10 /* for sockets. */
#define F_GETSIG 11 /* for sockets. */
#define F_GETLK64 12 /* using 'struct flock64' */
#define F_SETLK64 13
#define F_SETLKW64 14
/* for F_[GET|SET]FL */
#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
/* for posix fcntl() and lockf() */
#define F_RDLCK 0
#define F_WRLCK 1
#define F_UNLCK 2
/* for old implementation of bsd flock () */
#define F_EXLCK 4 /* or 3 */
#define F_SHLCK 8 /* or 4 */
/* for leases */
#define F_INPROGRESS 16
/* operations for bsd flock(), also used by the kernel implementation */
#define LOCK_SH 1 /* shared lock */
#define LOCK_EX 2 /* exclusive lock */
#define LOCK_NB 4 /* or'd with one of the above to prevent
blocking */
#define LOCK_UN 8 /* remove lock */
#define LOCK_MAND 32 /* This is a mandatory flock */
#define LOCK_READ 64 /* ... Which allows concurrent read operations */
#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
struct flock {
short l_type;
short l_whence;
off_t l_start;
off_t l_len;
pid_t l_pid;
};
struct flock64 {
short l_type;
short l_whence;
loff_t l_start;
loff_t l_len;
pid_t l_pid;
};
#define F_LINUX_SPECIFIC_BASE 1024
#endif /* _H8300_FCNTL_H */
/*
* include/asm-h8300/flat.h -- uClinux flat-format executables
*/
#ifndef __H8300_FLAT_H__
#define __H8300_FLAT_H__
#define flat_argvp_envp_on_stack() 1
#endif /* __H8300_FLAT_H__ */
#include <linux/config.h>
#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
#define H8300_TIMER_COUNT_DATA CONFIG_CPU_CLOCK*10/8192
#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192
#endif
#if defined(H8_3002) || defined(CONFIG_H83048)
#define H8300_TIMER_COUNT_DATA CONFIG_CPU_CLOCK*10/8
#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8
#endif
#ifndef _H8300_GPIO_H
#define _H8300_GPIO_H
#define H8300_GPIO_P1 0
#define H8300_GPIO_P2 1
#define H8300_GPIO_P3 2
#define H8300_GPIO_P4 3
#define H8300_GPIO_P5 4
#define H8300_GPIO_P6 5
/*#define H8300_GPIO_P7 6*/
#define H8300_GPIO_P8 7
#define H8300_GPIO_P9 8
#define H8300_GPIO_PA 9
#define H8300_GPIO_PB 10
#define H8300_GPIO_B7 0x80
#define H8300_GPIO_B6 0x40
#define H8300_GPIO_B5 0x20
#define H8300_GPIO_B4 0x10
#define H8300_GPIO_B3 0x08
#define H8300_GPIO_B2 0x04
#define H8300_GPIO_B1 0x02
#define H8300_GPIO_B0 0x01
#define H8300_GPIO_INPUT 0
#define H8300_GPIO_OUTPUT 1
#define H8300_GPIO_RESERVE(port, bits) \
h8300_reserved_gpio(port, bits)
#define H8300_GPIO_FREE(port, bits) \
h8300_free_gpio(port, bits)
#define H8300_GPIO_DDR(port, bit, dir) \
h8300_set_gpio_dir(((port) << 8) | bit, dir)
#define H8300_GPIO_GETDIR(port, bit) \
h8300_get_gpio_dir(((port) << 8) | bit)
extern int h8300_reserved_gpio(int port, int bits);
extern int h8300_free_gpio(int port, int bits);
extern int h8300_set_gpio_dir(int port_bit, int dir);
extern int h8300_get_gpio_dir(int port_bit);
extern int h8300_init_gpio(void);
#endif
/****************************************************************************/
/*
* h8300_ne.h -- NE2000 in H8/300H Evalution Board.
*
* (C) Copyright 2002, Yoshinori Sato <ysato@users.sourceforge.jp>
*/
/****************************************************************************/
#ifndef h8300ne_h
#define h8300ne_h
/****************************************************************************/
/* Such a description is OK ? */
#define DEPEND_HEADER(target) <asm/target/ne.h>
#include DEPEND_HEADER(TARGET)
/****************************************************************************/
#endif /* h8300ne_h */
/* H8MAX IDE I/F Config */
#define H8300_IDE_BASE 0x200000
#define H8300_IDE_CTRL 0x60000c
#define H8300_IDE_IRQ 5
#define H8300_IDE_REG_OFFSET 2
#undef outb
#undef inb
#undef outb_p
#undef inb_p
#undef outsw
#undef insw
#define outb(d,a) h8max_outb(d,(unsigned short *)a)
#define inb(a) h8max_inb((unsigned char *)a)
#define outb_p(d,a) h8max_outb(d,(unsigned short *)a)
#define inb_p(a) h8max_inb((unsigned char *)a)
#define outsw(addr,buf,len) h8max_outsw(addr,buf,len);
#define insw(addr,buf,len) h8max_insw(addr,buf,len);
static inline void h8max_outb(unsigned short d,unsigned short *a)
{
*a = d;
}
static inline unsigned char h8max_inb(unsigned char *a)
{
return *(a+1);
}
static inline void h8max_outsw(void *addr, void *buf, int len)
{
unsigned volatile short *ap = (unsigned volatile short *)addr;
unsigned short *bp = (unsigned short *)buf;
unsigned short d;
while(len--) {
d = *bp++;
*ap = (d >> 8) | (d << 8);
}
}
static inline void h8max_insw(void *addr, void *buf, int len)
{
unsigned volatile short *ap = (unsigned volatile short *)addr;
unsigned short *bp = (unsigned short *)buf;
unsigned short d;
while(len--) {
d = *ap;
*bp++ = (d >> 8) | (d << 8);
}
}
static inline void target_ide_fix_driveid(struct hd_driveid *id)
{
int c;
unsigned short *p = (unsigned short *)id;
for (c = 0; c < SECTOR_WORDS; c++, p++)
*p = (*p >> 8) | (*p << 8);
}
/* H8MAX RTL8019AS Config */
#define NE2000_ADDR 0x800600
#define NE2000_IRQ 4
#define NE2000_IRQ_VECTOR (12 + NE2000_IRQ)
#define NE2000_BYTE volatile unsigned short
#define IER 0xfee015
#define ISR 0xfee016
#define IRQ_MASK (1 << NE2000_IRQ)
/* sorry quick hack */
#if defined(outb)
# undef outb
#endif
#define outb(d,a) h8max_outb((d),(a) - NE2000_ADDR)
#if defined(inb)
# undef inb
#endif
#define inb(a) h8max_inb((a) - NE2000_ADDR)
#if defined(outb_p)
# undef outb_p
#endif
#define outb_p(d,a) h8max_outb((d),(a) - NE2000_ADDR)
#if defined(inb_p)
# undef inb_p
#endif
#define inb_p(a) h8max_inb((a) - NE2000_ADDR)
#if defined(outsw)
# undef outsw
#endif
#define outsw(a,p,l) h8max_outsw((a) - NE2000_ADDR,(unsigned short *)p,l)
#if defined(insw)
# undef insw
#endif
#define insw(a,p,l) h8max_insw((a) - NE2000_ADDR,(unsigned short *)p,l)
#define H8300_INIT_NE() \
do { \
wordlength = 2; \
h8max_outb(0x49, ioaddr + EN0_DCFG); \
SA_prom[14] = SA_prom[15] = 0x57;\
} while(0)
static inline void h8max_outb(unsigned char d,unsigned char a)
{
*(unsigned short *)(NE2000_ADDR + (a << 1)) = d;
}
static inline unsigned char h8max_inb(unsigned char a)
{
return *(unsigned char *)(NE2000_ADDR + (a << 1) +1);
}
static inline void h8max_outsw(unsigned char a,unsigned short *p,unsigned long l)
{
unsigned short d;
for (; l != 0; --l, p++) {
d = (((*p) >> 8) & 0xff) | ((*p) << 8);
*(unsigned short *)(NE2000_ADDR + (a << 1)) = d;
}
}
static inline void h8max_insw(unsigned char a,unsigned short *p,unsigned long l)
{
unsigned short d;
for (; l != 0; --l, p++) {
d = *(unsigned short *)(NE2000_ADDR + (a << 1));
*p = (d << 8)|((d >> 8) & 0xff);
}
}
#ifndef __H8300_HARDIRQ_H
#define __H8300_HARDIRQ_H
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/threads.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
typedef struct {
unsigned int __softirq_pending;
unsigned int __syscall_count;
struct task_struct * __ksoftirqd_task;
} ____cacheline_aligned irq_cpustat_t;
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
/*
* We put the hardirq and softirq counter into the preemption
* counter. The bitmask has the following meaning:
*
* - bits 0-7 are the preemption count (max preemption depth: 256)
* - bits 8-15 are the softirq count (max # of softirqs: 256)
* - bits 16-23 are the hardirq count (max # of hardirqs: 256)
*
* - ( bit 26 is the PREEMPT_ACTIVE flag. )
*
* PREEMPT_MASK: 0x000000ff
* HARDIRQ_MASK: 0x0000ff00
* SOFTIRQ_MASK: 0x00ff0000
*/
#define PREEMPT_BITS 8
#define SOFTIRQ_BITS 8
#define HARDIRQ_BITS 8
#define PREEMPT_SHIFT 0
#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS)
#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS)
#define __MASK(x) ((1UL << (x))-1)
#define PREEMPT_MASK (__MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
#define HARDIRQ_MASK (__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
#define SOFTIRQ_MASK (__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
#define hardirq_count() (preempt_count() & HARDIRQ_MASK)
#define softirq_count() (preempt_count() & SOFTIRQ_MASK)
#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))
#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT)
#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT)
#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT)
/*
* The hardirq mask has to be large enough to have
* space for potentially all IRQ sources in the system
* nesting on a single CPU:
*/
#if (1 << HARDIRQ_BITS) < NR_IRQS
# error HARDIRQ_BITS is too low!
#endif
/*
* Are we doing bottom half or hardware interrupt processing?
* Are we in a softirq context? Interrupt context?
*/
#define in_irq() (hardirq_count())
#define in_softirq() (softirq_count())
#define in_interrupt() (irq_count())
#define hardirq_trylock() (!in_interrupt())
#define hardirq_endlock() do { } while (0)
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#if CONFIG_PREEMPT
# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
#else
# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
#endif
#if CONFIG_PREEMPT
# define in_atomic() (preempt_count() != kernel_locked())
# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
#else
# define in_atomic() (preempt_count() != 0)
# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
#endif
#define irq_exit() \
do { \
preempt_count() -= IRQ_EXIT_OFFSET; \
if (!in_interrupt() && softirq_pending(smp_processor_id())) \
do_softirq(); \
preempt_enable_no_resched(); \
} while (0)
#ifndef CONFIG_SMP
# define synchronize_irq(irq) barrier()
#else
# error h8300 SMP is not available
#endif /* CONFIG_SMP */
#endif
/*
* linux/include/asm-h8300/hdreg.h
*
* Copyright (C) 1994-1996 Linus Torvalds & authors
*/
#ifndef _H8300_HDREG_H
#define _H8300_HDREG_H
typedef unsigned int q40ide_ioreg_t;
typedef unsigned char * ide_ioreg_t;
#endif /* _H8300_HDREG_H */
/****************************************************************************/
/*
* linux/include/asm-h8300/ide.h
*
* Copyright (C) 1994-1996 Linus Torvalds & authors
* Copyright (C) 2001 Lineo Inc., davidm@snapgear.com
* Copyright (C) 2002 Greg Ungerer (gerg@snapgear.com)
* Copyright (C) 2002 Yoshinori Sato (ysato@users.sourceforge.jp)
*/
/****************************************************************************/
#ifndef _H8300_IDE_H
#define _H8300_IDE_H
/****************************************************************************/
#ifdef __KERNEL__
/****************************************************************************/
#include <linux/config.h>
#include <linux/interrupt.h>
#include <asm/setup.h>
#include <asm/io.h>
#include <asm/irq.h>
/*
* Some coldfire specifics.
*/
/*
* Save some space, only have 1 interface.
*/
#define MAX_HWIFS 1
/*
* Fix up things that may not have been provided.
*/
#undef SUPPORT_SLOW_DATA_PORTS
#define SUPPORT_SLOW_DATA_PORTS 0
#undef SUPPORT_VLB_SYNC
#define SUPPORT_VLB_SYNC 0
/* this definition is used only on startup .. */
#undef HD_DATA
#define HD_DATA NULL
#define DBGIDE(fmt,a...)
// #define DBGIDE(fmt,a...) printk(fmt, ##a)
#define IDE_INLINE __inline__
// #define IDE_INLINE
#define ide__sti() __sti()
/****************************************************************************/
typedef union {
unsigned all : 8; /* all of the bits together */
struct {
unsigned bit7 : 1; /* always 1 */
unsigned lba : 1; /* using LBA instead of CHS */
unsigned bit5 : 1; /* always 1 */
unsigned unit : 1; /* drive select number, 0 or 1 */
unsigned head : 4; /* always zeros here */
} b;
} select_t;
/*
* Our list of ports/irq's for different boards.
*/
/* Such a description is OK ? */
#define DEPEND_HEADER(target) <asm/target/ide.h>
#include DEPEND_HEADER(TARGET)
/****************************************************************************/
static IDE_INLINE int ide_default_irq(ide_ioreg_t base)
{
return H8300_IDE_IRQ+12;
}
static IDE_INLINE ide_ioreg_t ide_default_io_base(int index)
{
return (ide_ioreg_t)H8300_IDE_BASE;
}
/*
* Set up a hw structure for a specified data port, control port and IRQ.
* This should follow whatever the default interface uses.
*/
static IDE_INLINE void ide_init_hwif_ports(
hw_regs_t *hw,
ide_ioreg_t data_port,
ide_ioreg_t ctrl_port,
int *irq)
{
ide_ioreg_t reg = data_port;
int i;
for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
hw->io_ports[i] = reg;
reg += H8300_IDE_REG_OFFSET;
}
if (ctrl_port) {
hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
} else {
hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t)H8300_IDE_CTRL;
}
}
/*
* This registers the standard ports for this architecture with the IDE
* driver.
*/
static IDE_INLINE void ide_init_default_hwifs(void)
{
hw_regs_t hw;
ide_ioreg_t base;
int index;
for (index = 0; index < MAX_HWIFS; index++) {
base = ide_default_io_base(index);
if (!base)
continue;
memset(&hw, 0, sizeof(hw));
ide_init_hwif_ports(&hw, base, 0, NULL);
hw.irq = ide_default_irq(base);
ide_register_hw(&hw, NULL);
}
}
#define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id))
#define ide_free_irq(irq,dev_id) free_irq((irq), (dev_id))
#define ide_check_region(from,extent) (0)
#define ide_request_region(from,extent,name) do {} while(0)
#define ide_release_region(from,extent) do {} while(0)
/*
* The following are not needed for the non-m68k ports
*/
#define ide_ack_intr(hwif) (1)
#define ide_fix_driveid(id) target_ide_fix_driveid(id)
#define ide_release_lock(lock) do {} while (0)
#define ide_get_lock(lock, hdlr, data) do {} while (0)
static IDE_INLINE void ide_print_resource(char *name,hw_regs_t *hw)
{
printk("%s at 0x%08x-0x%08x,0x%08x on irq %d", name,
(unsigned int)hw->io_ports[IDE_DATA_OFFSET],
(unsigned int)hw->io_ports[IDE_DATA_OFFSET]+(8*H8300_IDE_REG_OFFSET)-1,
(unsigned int)hw->io_ports[IDE_CONTROL_OFFSET],
hw->irq);
}
/****************************************************************************/
#endif /* __KERNEL__ */
#endif /* _H8300_IDE_H */
/****************************************************************************/
#ifndef _H8300_INIT_H
#define _H8300_INIT_H
#define __init __attribute__ ((__section__ (".text.init")))
#define __initdata __attribute__ ((__section__ (".data.init")))
/* For assembly routines */
#define __INIT .section ".text.init",#alloc,#execinstr
#define __FINIT .previous
#define __INITDATA .section ".data.init",#alloc,#write
#endif
#ifndef _H8300_IO_H
#define _H8300_IO_H
#ifdef __KERNEL__
#include <linux/config.h>
#include <asm/virtconvert.h>
/*
* These are for ISA/PCI shared memory _only_ and should never be used
* on any other type of memory, including Zorro memory. They are meant to
* access the bus in the bus byte order which is little-endian!.
*
* readX/writeX() are used to access memory mapped devices. On some
* architectures the memory mapped IO stuff needs to be accessed
* differently. On the m68k architecture, we just read/write the
* memory location directly.
*/
/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
* two accesses to memory, which may be undesireable for some devices.
*/
/*
* swap functions are sometimes needed to interface little-endian hardware
*/
/*
* CHANGES
*
* 020325 Added some #define's for the COBRA5272 board
* (hede)
*/
static inline unsigned short _swapw(volatile unsigned short v)
{
return ((v << 8) | (v >> 8));
}
static inline unsigned int _swapl(volatile unsigned long v)
{
return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
}
#define readb(addr) \
({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
#define readw(addr) \
({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
#define readl(addr) \
({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b))
#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b))
#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
/*
* The following are some defines we need for MTD with our
* COBRA5272 board.
* Because I don't know if they break something I have
* #ifdef'd them.
* (020325 - hede)
*/
#ifdef CONFIG_senTec
#define __raw_readb readb
#define __raw_readw readw
#define __raw_readl readl
#define __raw_writeb writeb
#define __raw_writew writew
#define __raw_writel writel
#endif /* CONFIG_senTec */
static inline void io_outsb(unsigned int addr, void *buf, int len)
{
volatile unsigned char *ap = (volatile unsigned char *) addr;
unsigned char *bp = (unsigned char *) buf;
while (len--)
*ap = *bp++;
}
static inline void io_outsw(unsigned int addr, void *buf, int len)
{
volatile unsigned short *ap = (volatile unsigned short *) addr;
unsigned short *bp = (unsigned short *) buf;
while (len--)
*ap = _swapw(*bp++);
}
static inline void io_outsl(unsigned int addr, void *buf, int len)
{
volatile unsigned int *ap = (volatile unsigned int *) addr;
unsigned int *bp = (unsigned int *) buf;
while (len--)
*ap = _swapl(*bp++);
}
static inline void io_insb(unsigned int addr, void *buf, int len)
{
volatile unsigned char *ap = (volatile unsigned char *) addr;
unsigned char *bp = (unsigned char *) buf;
while (len--)
*bp++ = *ap;
}
static inline void io_insw(unsigned int addr, void *buf, int len)
{
volatile unsigned short *ap = (volatile unsigned short *) addr;
unsigned short *bp = (unsigned short *) buf;
while (len--)
*bp++ = _swapw(*ap);
}
static inline void io_insl(unsigned int addr, void *buf, int len)
{
volatile unsigned int *ap = (volatile unsigned int *) addr;
unsigned int *bp = (unsigned int *) buf;
while (len--)
*bp++ = _swapl(*ap);
}
/*
* make the short names macros so specific devices
* can override them as required
*/
#define memset_io(a,b,c) memset((void *)(a),(b),(c))
#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
#define inb(addr) readb(addr)
#define inw(addr) readw(addr)
#define inl(addr) readl(addr)
#define outb(x,addr) ((void) writeb(x,addr))
#define outw(x,addr) ((void) writew(x,addr))
#define outl(x,addr) ((void) writel(x,addr))
#define inb_p(addr) inb(addr)
#define inw_p(addr) inw(addr)
#define inl_p(addr) inl(addr)
#define outb_p(x,addr) outb(x,addr)
#define outw_p(x,addr) outw(x,addr)
#define outl_p(x,addr) outl(x,addr)
#define outsb(a,b,l) io_outsb(a,b,l)
#define outsw(a,b,l) io_outsw(a,b,l)
#define outsl(a,b,l) io_outsl(a,b,l)
#define insb(a,b,l) io_insb(a,b,l)
#define insw(a,b,l) io_insw(a,b,l)
#define insl(a,b,l) io_insl(a,b,l)
#define IO_SPACE_LIMIT 0xffff
/* Values for nocacheflag and cmode */
#define IOMAP_FULL_CACHING 0
#define IOMAP_NOCACHE_SER 1
#define IOMAP_NOCACHE_NONSER 2
#define IOMAP_WRITETHROUGH 3
extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
extern void __iounmap(void *addr, unsigned long size);
extern inline void *ioremap(unsigned long physaddr, unsigned long size)
{
return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
}
extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
{
return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
}
extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
{
return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
}
extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
{
return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
}
extern void iounmap(void *addr);
/* Nothing to do */
#define dma_cache_inv(_start,_size) do { } while (0)
#define dma_cache_wback(_start,_size) do { } while (0)
#define dma_cache_wback_inv(_start,_size) do { } while (0)
/* H8/300 internal I/O functions */
static __inline__ unsigned char ctrl_inb(unsigned long addr)
{
return *(volatile unsigned char*)addr;
}
static __inline__ unsigned short ctrl_inw(unsigned long addr)
{
return *(volatile unsigned short*)addr;
}
static __inline__ unsigned int ctrl_inl(unsigned long addr)
{
return *(volatile unsigned long*)addr;
}
static __inline__ void ctrl_outb(unsigned char b, unsigned long addr)
{
*(volatile unsigned char*)addr = b;
}
static __inline__ void ctrl_outw(unsigned short b, unsigned long addr)
{
*(volatile unsigned short*)addr = b;
}
static __inline__ void ctrl_outl(unsigned int b, unsigned long addr)
{
*(volatile unsigned long*)addr = b;
}
/* Pages to physical address... */
#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT)
#define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT)
/*
* Macros used for converting between virtual and physical mappings.
*/
#define mm_ptov(vaddr) ((void *) (vaddr))
#define mm_vtop(vaddr) ((unsigned long) (vaddr))
#define phys_to_virt(vaddr) ((void *) (vaddr))
#define virt_to_phys(vaddr) ((unsigned long) (vaddr))
#define virt_to_bus virt_to_phys
#define bus_to_virt phys_to_virt
#endif /* __KERNEL__ */
#endif /* _H8300_IO_H */
/* $Id: ioctl.h,v 1.1 2002/11/19 02:09:26 gerg Exp $
*
* linux/ioctl.h for Linux by H.H. Bergman.
*/
#ifndef _H8300_IOCTL_H
#define _H8300_IOCTL_H
/* ioctl command encoding: 32 bits total, command in lower 16 bits,
* size of the parameter structure in the lower 14 bits of the
* upper 16 bits.
* Encoding the size of the parameter structure in the ioctl request
* is useful for catching programs compiled with old versions
* and to avoid overwriting user space outside the user buffer area.
* The highest 2 bits are reserved for indicating the ``access mode''.
* NOTE: This limits the max parameter size to 16kB -1 !
*/
/*
* I don't really have any idea about what this should look like, so
* for the time being, this is heavily based on the PC definitions.
*/
/*
* The following is for compatibility across the various Linux
* platforms. The i386 ioctl numbering scheme doesn't really enforce
* a type field. De facto, however, the top 8 bits of the lower 16
* bits are indeed used as a type field, so we might just as well make
* this explicit here. Please be sure to use the decoding macros
* below from now on.
*/
#define _IOC_NRBITS 8
#define _IOC_TYPEBITS 8
#define _IOC_SIZEBITS 14
#define _IOC_DIRBITS 2
#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
#define _IOC_NRSHIFT 0
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
/*
* Direction bits.
*/
#define _IOC_NONE 0U
#define _IOC_WRITE 1U
#define _IOC_READ 2U
#define _IOC(dir,type,nr,size) \
(((dir) << _IOC_DIRSHIFT) | \
((type) << _IOC_TYPESHIFT) | \
((nr) << _IOC_NRSHIFT) | \
((size) << _IOC_SIZESHIFT))
/* used to create numbers */
#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
/* used to decode ioctl numbers.. */
#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
/* ...and for the drivers/sound files... */
#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
#endif /* _H8300_IOCTL_H */
#ifndef __ARCH_H8300_IOCTLS_H__
#define __ARCH_H8300_IOCTLS_H__
#include <asm/ioctl.h>
/* 0x54 is just a magic number to make these relatively unique ('T') */
#define TCGETS 0x5401
#define TCSETS 0x5402
#define TCSETSW 0x5403
#define TCSETSF 0x5404
#define TCGETA 0x5405
#define TCSETA 0x5406
#define TCSETAW 0x5407
#define TCSETAF 0x5408
#define TCSBRK 0x5409
#define TCXONC 0x540A
#define TCFLSH 0x540B
#define TIOCEXCL 0x540C
#define TIOCNXCL 0x540D
#define TIOCSCTTY 0x540E
#define TIOCGPGRP 0x540F
#define TIOCSPGRP 0x5410
#define TIOCOUTQ 0x5411
#define TIOCSTI 0x5412
#define TIOCGWINSZ 0x5413
#define TIOCSWINSZ 0x5414
#define TIOCMGET 0x5415
#define TIOCMBIS 0x5416
#define TIOCMBIC 0x5417
#define TIOCMSET 0x5418
#define TIOCGSOFTCAR 0x5419
#define TIOCSSOFTCAR 0x541A
#define FIONREAD 0x541B
#define TIOCINQ FIONREAD
#define TIOCLINUX 0x541C
#define TIOCCONS 0x541D
#define TIOCGSERIAL 0x541E
#define TIOCSSERIAL 0x541F
#define TIOCPKT 0x5420
#define FIONBIO 0x5421
#define TIOCNOTTY 0x5422
#define TIOCSETD 0x5423
#define TIOCGETD 0x5424
#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
#define TIOCSBRK 0x5427 /* BSD compatibility */
#define TIOCCBRK 0x5428 /* BSD compatibility */
#define TIOCGSID 0x5429 /* Return the session ID of FD */
#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
#define FIOCLEX 0x5451
#define FIOASYNC 0x5452
#define TIOCSERCONFIG 0x5453
#define TIOCSERGWILD 0x5454
#define TIOCSERSWILD 0x5455
#define TIOCGLCKTRMIOS 0x5456
#define TIOCSLCKTRMIOS 0x5457
#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
#define TIOCSERGETLSR 0x5459 /* Get line status register */
#define TIOCSERGETMULTI 0x545A /* Get multiport config */
#define TIOCSERSETMULTI 0x545B /* Set multiport config */
#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
#define FIOQSIZE 0x545E
/* Used for packet mode */
#define TIOCPKT_DATA 0
#define TIOCPKT_FLUSHREAD 1
#define TIOCPKT_FLUSHWRITE 2
#define TIOCPKT_STOP 4
#define TIOCPKT_START 8
#define TIOCPKT_NOSTOP 16
#define TIOCPKT_DOSTOP 32
#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
#endif /* __ARCH_H8300_IOCTLS_H__ */
#ifndef __H8300_IPC_H__
#define __H8300_IPC_H__
/*
* These are used to wrap system calls on H8/300.
*
* See arch/h8300/kernel/sys_h8300.c for ugly details..
*/
struct ipc_kludge {
struct msgbuf *msgp;
long msgtyp;
};
#define SEMOP 1
#define SEMGET 2
#define SEMCTL 3
#define MSGSND 11
#define MSGRCV 12
#define MSGGET 13
#define MSGCTL 14
#define SHMAT 21
#define SHMDT 22
#define SHMGET 23
#define SHMCTL 24
/* Used by the DIPC package, try and avoid reusing it */
#define DIPC 25
#define IPCCALL(version,op) ((version)<<16 | (op))
#endif
#ifndef __H8300_IPCBUF_H__
#define __H8300_IPCBUF_H__
/*
* The user_ipc_perm structure for H8/300 architecture.
* Note extra padding because this structure is passed back and forth
* between kernel and user space.
*
* Pad space is left for:
* - 32-bit mode_t and seq
* - 2 miscellaneous 32-bit values
*/
struct ipc64_perm
{
__kernel_key_t key;
__kernel_uid32_t uid;
__kernel_gid32_t gid;
__kernel_uid32_t cuid;
__kernel_gid32_t cgid;
__kernel_mode_t mode;
unsigned short __pad1;
unsigned short seq;
unsigned short __pad2;
unsigned long __unused1;
unsigned long __unused2;
};
#endif /* __H8300_IPCBUF_H__ */
#ifndef _H8300_IRQ_H_
#define _H8300_IRQ_H_
#define SYS_IRQS 64
#define NR_IRQS 64
#include <asm/ptrace.h>
/*
* "Generic" interrupt sources
*/
#define IRQ_SCHED_TIMER (40) /* interrupt source for scheduling timer */
static __inline__ int irq_cannonicalize(int irq)
{
return irq;
}
extern void enable_irq(unsigned int);
extern void disable_irq(unsigned int);
extern int sys_request_irq(unsigned int,
void (*)(int, void *, struct pt_regs *),
unsigned long, const char *, void *);
extern void sys_free_irq(unsigned int, void *);
typedef struct irq_node {
void (*handler)(int, void *, struct pt_regs *);
unsigned long flags;
void *dev_id;
const char *devname;
struct irq_node *next;
} irq_node_t;
/*
* This structure has only 4 elements for speed reasons
*/
typedef struct irq_handler {
void (*handler)(int, void *, struct pt_regs *);
unsigned long flags;
void *dev_id;
const char *devname;
} irq_handler_t;
/* count of spurious interrupts */
extern volatile unsigned int num_spurious;
/*
* Some drivers want these entry points
*/
#define enable_irq_nosync(x) enable_irq(x)
#define disable_irq_nosync(x) disable_irq(x)
#endif /* _H8300_IRQ_H_ */
/*
* linux/include/asm-h8300/keyboard.h
* Created 04 Dec 2001 by Khaled Hassounah <khassounah@mediumware.net>
* This file contains the Dragonball architecture specific keyboard definitions
*/
#ifndef _H8300_KEYBOARD_H
#define _H8300_KEYBOARD_H
#include <linux/config.h>
/* dummy i.e. no real keyboard */
#define kbd_setkeycode(x...) (-ENOSYS)
#define kbd_getkeycode(x...) (-ENOSYS)
#define kbd_translate(x...) (0)
#define kbd_unexpected_up(x...) (1)
#define kbd_leds(x...) do {;} while (0)
#define kbd_init_hw(x...) do {;} while (0)
#define kbd_enable_irq(x...) do {;} while (0)
#define kbd_disable_irq(x...) do {;} while (0)
/* needed if MAGIC_SYSRQ is enabled for serial console */
#ifndef SYSRQ_KEY
#define SYSRQ_KEY ((unsigned char)(-1))
#define kbd_sysrq_xlate ((unsigned char *)NULL)
#endif
#endif /* _H8300_KEYBOARD_H */
#ifndef _ASM_KMAP_TYPES_H
#define _ASM_KMAP_TYPES_H
enum km_type {
KM_BOUNCE_READ,
KM_SKB_SUNRPC_DATA,
KM_SKB_DATA_SOFTIRQ,
KM_USER0,
KM_USER1,
KM_BIO_SRC_IRQ,
KM_BIO_DST_IRQ,
KM_PTE0,
KM_PTE1,
KM_IRQ0,
KM_IRQ1,
KM_TYPE_NR
};
#endif
#ifndef _H8300_LINKAGE_H
#define _H8300_LINKAGE_H
#undef SYMBOL_NAME_LABEL
#undef SYMBOL_NAME
#define SYMBOL_NAME_LABEL(_name_) _##_name_##:
#define SYMBOL_NAME(_name_) _##_name_
#endif
/*
* include/asm-h8300/linux_logo.h: This is a linux logo
* to be displayed on boot.
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/version.h>
#define linux_logo_banner "Linux/m68knommu version " UTS_RELEASE
/*
* Machine dependent access functions for RTC registers.
*/
#ifndef _H8300_MC146818RTC_H
#define _H8300_MC146818RTC_H
/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
#endif /* _H8300_MC146818RTC_H */
/* $Id: md.h,v 1.1 2002/11/19 02:09:26 gerg Exp $
* md.h: High speed xor_block operation for RAID4/5
*
*/
#ifndef __ASM_MD_H
#define __ASM_MD_H
/* #define HAVE_ARCH_XORBLOCK */
#define MD_XORBLOCK_ALIGNMENT sizeof(long)
#endif /* __ASM_MD_H */
#ifndef __H8300_MMAN_H__
#define __H8300_MMAN_H__
#define PROT_READ 0x1 /* page can be read */
#define PROT_WRITE 0x2 /* page can be written */
#define PROT_EXEC 0x4 /* page can be executed */
#define PROT_NONE 0x0 /* page can not be accessed */
#define MAP_SHARED 0x01 /* Share changes */
#define MAP_PRIVATE 0x02 /* Changes are private */
#define MAP_TYPE 0x0f /* Mask for type of mapping */
#define MAP_FIXED 0x10 /* Interpret addr exactly */
#define MAP_ANONYMOUS 0x20 /* don't use a file */
#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
#define MAP_LOCKED 0x2000 /* pages are locked */
#define MAP_NORESERVE 0x4000 /* don't check for reservations */
#define MS_ASYNC 1 /* sync memory asynchronously */
#define MS_INVALIDATE 2 /* invalidate the caches */
#define MS_SYNC 4 /* synchronous memory sync */
#define MCL_CURRENT 1 /* lock all current mappings */
#define MCL_FUTURE 2 /* lock all future mappings */
#define MADV_NORMAL 0x0 /* default page-in behavior */
#define MADV_RANDOM 0x1 /* page-in minimum required */
#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */
#define MADV_WILLNEED 0x3 /* pre-fault pages */
#define MADV_DONTNEED 0x4 /* discard these pages */
/* compatibility flags */
#define MAP_ANON MAP_ANONYMOUS
#define MAP_FILE 0
#endif /* __H8300_MMAN_H__ */
#ifndef __MMU_H
#define __MMU_H
/* Copyright (C) 2002, David McCullough <davidm@snapgear.com> */
struct mm_rblock_struct {
int size;
int refcount;
void *kblock;
};
struct mm_tblock_struct {
struct mm_rblock_struct *rblock;
struct mm_tblock_struct *next;
};
typedef struct {
struct mm_tblock_struct tblock;
unsigned long end_brk;
} mm_context_t;
#endif
#ifndef __H8300_MMU_CONTEXT_H
#define __H8300_MMU_CONTEXT_H
#include <linux/config.h>
#include <asm/setup.h>
#include <asm/page.h>
#include <asm/pgalloc.h>
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
{
}
extern inline int
init_new_context(struct task_struct *tsk, struct mm_struct *mm)
{
// mm->context = virt_to_phys(mm->pgd);
return(0);
}
#define destroy_context(mm) do { } while(0)
#define deactivate_mm(tsk,mm) do { } while(0)
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu)
{
}
extern inline void activate_mm(struct mm_struct *prev_mm,
struct mm_struct *next_mm)
{
}
#endif
#ifndef _ASM_H8300_MODULE_H
#define _ASM_H8300_MODULE_H
/*
* This file contains the H8/300 architecture specific module code.
*/
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
#define module_arch_init(x) (0)
#define arch_init_modules(x) do { } while (0)
#endif /* _ASM_H8/300_MODULE_H */
#ifndef _H8300_MSGBUF_H
#define _H8300_MSGBUF_H
/*
* The msqid64_ds structure for H8/300 architecture.
* Note extra padding because this structure is passed back and forth
* between kernel and user space.
*
* Pad space is left for:
* - 64-bit time_t to solve y2038 problem
* - 2 miscellaneous 32-bit values
*/
struct msqid64_ds {
struct ipc64_perm msg_perm;
__kernel_time_t msg_stime; /* last msgsnd time */
unsigned long __unused1;
__kernel_time_t msg_rtime; /* last msgrcv time */
unsigned long __unused2;
__kernel_time_t msg_ctime; /* last change time */
unsigned long __unused3;
unsigned long msg_cbytes; /* current number of bytes on queue */
unsigned long msg_qnum; /* number of messages in queue */
unsigned long msg_qbytes; /* max number of bytes on queue */
__kernel_pid_t msg_lspid; /* pid of last msgsnd */
__kernel_pid_t msg_lrpid; /* last receive pid */
unsigned long __unused4;
unsigned long __unused5;
};
#endif /* _H8300_MSGBUF_H */
/*
* linux/include/asm-h8300/namei.h
*
* Included from linux/fs/namei.c
*/
#ifndef __H8300_NAMEI_H
#define __H8300_NAMEI_H
/* This dummy routine maybe changed to something useful
* for /usr/gnemul/ emulation stuff.
* Look at asm-sparc/namei.h for details.
*/
#define __emul_prefix() NULL
#endif
#ifndef _H8300NOMMU_PAGE_H
#define _H8300NOMMU_PAGE_H
#include <linux/config.h>
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT (12)
#define PAGE_SIZE (4096)
#define PAGE_MASK (~(PAGE_SIZE-1))
#ifdef __KERNEL__
#include <asm/setup.h>
#if !defined(CONFIG_SMALL_TASKS) && PAGE_SHIFT < 13
#define KTHREAD_SIZE (8192)
#else
#define KTHREAD_SIZE PAGE_SIZE
#endif
#ifndef __ASSEMBLY__
#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
#define free_user_page(page, addr) free_page(addr)
#define clear_page(page) memset((page), 0, PAGE_SIZE)
#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE)
#define clear_user_page(page, vaddr, pg) clear_page(page)
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
/*
* These are used to make use of C type-checking..
*/
typedef struct { unsigned long pte; } pte_t;
typedef struct { unsigned long pmd[16]; } pmd_t;
typedef struct { unsigned long pgd; } pgd_t;
typedef struct { unsigned long pgprot; } pgprot_t;
#define pte_val(x) ((x).pte)
#define pmd_val(x) ((&x)->pmd[0])
#define pgd_val(x) ((x).pgd)
#define pgprot_val(x) ((x).pgprot)
#define __pte(x) ((pte_t) { (x) } )
#define __pmd(x) ((pmd_t) { (x) } )
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
/* Pure 2^n version of get_order */
extern __inline__ int get_order(unsigned long size)
{
int order;
size = (size-1) >> (PAGE_SHIFT-1);
order = -1;
do {
size >>= 1;
order++;
} while (size);
return order;
}
extern unsigned long memory_start;
extern unsigned long memory_end;
#endif /* !__ASSEMBLY__ */
#include <asm/page_offset.h>
#define PAGE_OFFSET (PAGE_OFFSET_RAW)
#ifndef __ASSEMBLY__
#define __pa(vaddr) virt_to_phys((void *)vaddr)
#define __va(paddr) phys_to_virt((unsigned long)paddr)
#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT)
#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT)
#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
#define pfn_to_page(pfn) virt_to_page(pfn_to_virt(pfn))
#define page_to_pfn(page) virt_to_pfn(page_to_virt(page))
#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \
((void *)(kaddr) < (void *)memory_end))
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _H8300NOMMU_PAGE_H */
#include <linux/config.h>
#define PAGE_OFFSET_RAW 0x00000000
#ifndef _H8300_PARAM_H
#define _H8300_PARAM_H
#include <linux/config.h>
#ifndef HZ
#define HZ 100
#endif
#ifdef __KERNEL__
#define USER_HZ HZ
#define CLOCKS_PER_SEC (USER_HZ)
#endif
#define EXEC_PAGESIZE 4096
#ifndef NGROUPS
#define NGROUPS 32
#endif
#ifndef NOGROUP
#define NOGROUP (-1)
#endif
#define MAXHOSTNAMELEN 64 /* max length of hostname */
#endif /* _H8300_PARAM_H */
#ifndef _ASM_H8300_PCI_H
#define _ASM_H8300_PCI_H
/*
* asm-h8300/pci.h - H8/300 specific PCI declarations.
*
* Yoshinori Sato <ysato@users.sourceforge.jp>
*/
#define pcibios_assign_all_busses() 0
extern inline void pcibios_set_master(struct pci_dev *dev)
{
/* No special bus mastering setup handling */
}
extern inline void pcibios_penalize_isa_irq(int irq)
{
/* We don't do dynamic PCI IRQ allocation */
}
/* Return the index of the PCI controller for device PDEV. */
#define pci_controller_num(PDEV) (0)
#endif /* _ASM_H8300_PCI_H */
#ifndef __ARCH_H8300_PERCPU__
#define __ARCH_H8300_PERCPU__
#include <asm-generic/percpu.h>
#endif /* __ARCH_H8300_PERCPU__ */
#ifndef _H8300_PGALLOC_H
#define _H8300_PGALLOC_H
#include <asm/setup.h>
#define check_pgt_cache() do { } while (0)
#endif /* _H8300_PGALLOC_H */
#ifndef _H8300_PGTABLE_H
#define _H8300_PGTABLE_H
#include <linux/config.h>
#include <linux/slab.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/io.h>
typedef pte_t *pte_addr_t;
#define pgd_present(pgd) (1) /* pages are always present on NO_MM */
#define pgd_none(pgd) (0)
#define pgd_bad(pgd) (0)
#define pgd_clear(pgdp)
#define kern_addr_valid(addr) (1)
#define pmd_offset(a, b) ((void *)0)
#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */
#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */
#define PAGE_COPY __pgprot(0) /* these mean nothing to NO_MM */
#define PAGE_READONLY __pgprot(0) /* these mean nothing to NO_MM */
#define PAGE_KERNEL __pgprot(0) /* these mean nothing to NO_MM */
extern void paging_init(void);
#define swapper_pg_dir ((pgd_t *) 0)
#define __swp_type(x) (0)
#define __swp_offset(x) (0)
#define __swp_entry(typ,off) ((swp_entry_t) { ((typ) | ((off) << 7)) })
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
/*
* ZERO_PAGE is a global shared page that is always zero: used
* for zero-mapped memory areas etc..
*/
#define ZERO_PAGE(vaddr) (virt_to_page(0))
/*
* These would be in other places but having them here reduces the diffs.
*/
extern unsigned int kobjsize(const void *objp);
extern int is_in_rom(unsigned long);
/*
* No page table caches to initialise
*/
#define pgtable_cache_init() do { } while (0)
#define io_remap_page_range remap_page_range
#endif /* _H8300_PGTABLE_H */
#ifndef __H8300_POLL_H
#define __H8300_POLL_H
#define POLLIN 1
#define POLLPRI 2
#define POLLOUT 4
#define POLLERR 8
#define POLLHUP 16
#define POLLNVAL 32
#define POLLRDNORM 64
#define POLLWRNORM POLLOUT
#define POLLRDBAND 128
#define POLLWRBAND 256
#define POLLMSG 0x0400
struct pollfd {
int fd;
short events;
short revents;
};
#endif
#ifndef __ARCH_H8300_POSIX_TYPES_H
#define __ARCH_H8300_POSIX_TYPES_H
/*
* This file is generally used by user-level software, so you need to
* be a little careful about namespace pollution etc. Also, we cannot
* assume GCC is being used.
*/
typedef unsigned short __kernel_dev_t;
typedef unsigned long __kernel_ino_t;
typedef unsigned short __kernel_mode_t;
typedef unsigned short __kernel_nlink_t;
typedef long __kernel_off_t;
typedef int __kernel_pid_t;
typedef unsigned short __kernel_ipc_pid_t;
typedef unsigned short __kernel_uid_t;
typedef unsigned short __kernel_gid_t;
typedef unsigned int __kernel_size_t;
typedef int __kernel_ssize_t;
typedef int __kernel_ptrdiff_t;
typedef long __kernel_time_t;
typedef long __kernel_suseconds_t;
typedef long __kernel_clock_t;
typedef int __kernel_timer_t;
typedef int __kernel_clockid_t;
typedef int __kernel_daddr_t;
typedef char * __kernel_caddr_t;
typedef unsigned short __kernel_uid16_t;
typedef unsigned short __kernel_gid16_t;
typedef unsigned int __kernel_uid32_t;
typedef unsigned int __kernel_gid32_t;
typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t;
#ifdef __GNUC__
typedef long long __kernel_loff_t;
#endif
typedef struct {
#if defined(__KERNEL__) || defined(__USE_ALL)
int val[2];
#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
int __val[2];
#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
} __kernel_fsid_t;
#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
#undef __FD_SET
#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
#undef __FD_CLR
#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
#undef __FD_ISSET
#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
#undef __FD_ZERO
#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
#endif
/*
* include/asm-h8300/processor.h
*
* Copyright (C) 2002 Yoshinori Sato
*
* Based on: linux/asm-m68nommu/processor.h
*
* Copyright (C) 1995 Hamish Macdonald
*/
#ifndef __ASM_H8300_PROCESSOR_H
#define __ASM_H8300_PROCESSOR_H
/*
* Default implementation of macro that returns current
* instruction pointer ("program counter").
*/
#define current_text_addr() ({ __label__ _l; _l: &&_l;})
#include <linux/config.h>
#include <asm/segment.h>
#include <asm/fpu.h>
#include <asm/ptrace.h>
#include <asm/current.h>
extern inline unsigned long rdusp(void) {
extern unsigned int sw_usp;
return(sw_usp);
}
extern inline void wrusp(unsigned long usp) {
extern unsigned int sw_usp;
sw_usp = usp;
}
/*
* User space process size: 3.75GB. This is hardcoded into a few places,
* so don't change it unless you know what you are doing.
*/
#define TASK_SIZE (0xFFFFFFFFUL)
/*
* This decides where the kernel will search for a free chunk of vm
* space during mmap's. We won't be using it
*/
#define TASK_UNMAPPED_BASE 0
/*
* Bus types
*/
#define EISA_bus 0
#define MCA_bus 0
struct thread_struct {
unsigned long ksp; /* kernel stack pointer */
unsigned long usp; /* user stack pointer */
unsigned short ccr; /* saved status register */
unsigned long esp0; /* points to SR of stack frame */
unsigned long vfork_ret;
unsigned long debugreg[8]; /* debug info */
} __attribute__((aligned(2),packed));
#define INIT_THREAD { \
sizeof(init_stack) + (unsigned long) init_stack, 0, \
PS_S, 0, 0, \
}
/*
* Do necessary setup to start up a newly executed thread.
*
* pass the data segment into user programs if it exists,
* it can't hurt anything as far as I can tell
*/
#define start_thread(_regs, _pc, _usp) \
do { \
(_regs)->pc = (_pc); \
(_regs)->ccr &= ~0x10; \
*((unsigned long *)(_usp)-1) = _pc; \
wrusp((unsigned long)(_usp) - sizeof(unsigned long)*3); \
} while(0)
/* Forward declaration, a strange C thing */
struct task_struct;
/* Free all resources held by a thread. */
static inline void release_thread(struct task_struct *dead_task)
{
}
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
#define copy_segments(tsk, mm) do { } while (0)
#define release_segments(mm) do { } while (0)
#define forget_segments() do { } while (0)
#define prepare_to_copy(tsk) do { } while (0)
/*
* Free current thread data structures etc..
*/
static inline void exit_thread(void)
{
}
/*
* Return saved PC of a blocked thread.
*/
unsigned long thread_saved_pc(struct task_struct *tsk);
unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) \
({ \
unsigned long eip = 0; \
if ((tsk)->thread.esp0 > PAGE_SIZE && \
MAP_NR((tsk)->thread.esp0) < max_mapnr) \
eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
eip; })
#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp)
#define cpu_relax() do { } while (0)
#endif
#ifndef _H8300_PTRACE_H
#define _H8300_PTRACE_H
#ifndef __ASSEMBLY__
#define PT_ER1 0
#define PT_ER2 1
#define PT_ER3 2
#define PT_ER4 3
#define PT_ER5 4
#define PT_ER6 5
#define PT_ER0 6
#define PT_ORIG_ER0 7
#define PT_CCR 8
#define PT_PC 9
#define PT_USP 10
/* this struct defines the way the registers are stored on the
stack during a system call. */
struct pt_regs {
long er3;
long er2;
long er1;
long orig_er0;
unsigned short ccr;
long er0;
long vector;
unsigned long pc;
} __attribute__((aligned(2),packed));
/*
* This is the extended stack used by signal handlers and the context
* switcher: it's pushed after the normal "struct pt_regs".
*/
struct switch_stack {
unsigned long er6;
unsigned long er5;
unsigned long er4;
unsigned long retpc;
};
#define PTRACE_GETREGS 12
#define PTRACE_SETREGS 13
#ifdef __KERNEL__
#ifndef PS_S
#define PS_S (0x10)
#endif
#define user_mode(regs) (!((regs)->ccr & PS_S))
#define instruction_pointer(regs) ((regs)->pc)
extern void show_regs(struct pt_regs *);
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#endif /* _H8300_PTRACE_H */
/* internal Peripherals Register address define */
/* CPU: H8/306x */
#if !defined(__REGS_H8306x__)
#define __REGS_H8306x__
#if defined(__KERNEL__)
#define DASTCR *(volatile unsigned char *)0xFEE01A
#define DADR0 0xFEE09C
#define DADR1 0xFEE09D
#define DACR 0xFEE09E
#define ADDRAH 0xFFFFE0
#define ADDRAL 0xFFFFE1
#define ADDRBH 0xFFFFE2
#define ADDRBL 0xFFFFE3
#define ADDRCH 0xFFFFE4
#define ADDRCL 0xFFFFE5
#define ADDRDH 0xFFFFE6
#define ADDRDL 0xFFFFE7
#define ADCSR 0xFFFFE8
#define ADCR 0xFFFFE9
#define BRCR 0xFEE013
#define ADRCR 0xFEE01E
#define CSCR 0xFEE01F
#define ABWCR 0xFEE020
#define ASTCR 0xFEE021
#define WCRH 0xFEE022
#define WCRL 0xFEE023
#define BCR 0xFEE024
#define DRCRA 0xFEE026
#define DRCRB 0xFEE027
#define RTMCSR 0xFEE028
#define RTCNT 0xFEE029
#define RTCOR 0xFEE02A
#define MAR0AR 0xFFFF20
#define MAR0AE 0xFFFF21
#define MAR0AH 0xFFFF22
#define MAR0AL 0xFFFF23
#define ETCR0AL 0xFFFF24
#define ETCR0AH 0xFFFF25
#define IOAR0A 0xFFFF26
#define DTCR0A 0xFFFF27
#define MAR0BR 0xFFFF28
#define MAR0BE 0xFFFF29
#define MAR0BH 0xFFFF2A
#define MAR0BL 0xFFFF2B
#define ETCR0BL 0xFFFF2C
#define ETCR0BH 0xFFFF2D
#define IOAR0B 0xFFFF2E
#define DTCR0B 0xFFFF2F
#define MAR1AR 0xFFFF30
#define MAR1AE 0xFFFF31
#define MAR1AH 0xFFFF32
#define MAR1AL 0xFFFF33
#define ETCR1AL 0xFFFF34
#define ETCR1AH 0xFFFF35
#define IOAR1A 0xFFFF36
#define DTCR1A 0xFFFF37
#define MAR1BR 0xFFFF38
#define MAR1BE 0xFFFF39
#define MAR1BH 0xFFFF3A
#define MAR1BL 0xFFFF3B
#define ETCR1BL 0xFFFF3C
#define ETCR1BH 0xFFFF3D
#define IOAR1B 0xFFFF3E
#define DTCR1B 0xFFFF3F
#define ISCR 0xFEE014
#define IER 0xFEE015
#define ISR 0xFEE016
#define IPRA 0xFEE018
#define IPRB 0xFEE019
#define P1DDR 0xFEE000
#define P2DDR 0xFEE001
#define P3DDR 0xFEE002
#define P4DDR 0xFEE003
#define P5DDR 0xFEE004
#define P6DDR 0xFEE005
/*#define P7DDR 0xFEE006*/
#define P8DDR 0xFEE007
#define P9DDR 0xFEE008
#define PADDR 0xFEE009
#define PBDDR 0xFEE00A
#define P1DR 0xFFFFD0
#define P2DR 0xFFFFD1
#define P3DR 0xFFFFD2
#define P4DR 0xFFFFD3
#define P5DR 0xFFFFD4
#define P6DR 0xFFFFD5
/*#define P7DR 0xFFFFD6*/
#define P8DR 0xFFFFD7
#define P9DR 0xFFFFD8
#define PADR 0xFFFFD9
#define PBDR 0xFFFFDA
#define P2CR 0xFEE03C
#define P4CR 0xFEE03E
#define P5CR 0xFEE03F
#define SMR0 0xFFFFB0
#define BRR0 0xFFFFB1
#define SCR0 0xFFFFB2
#define TDR0 0xFFFFB3
#define SSR0 0xFFFFB4
#define RDR0 0xFFFFB5
#define SCMR0 0xFFFFB6
#define SMR1 0xFFFFB8
#define BRR1 0xFFFFB9
#define SCR1 0xFFFFBA
#define TDR1 0xFFFFBB
#define SSR1 0xFFFFBC
#define RDR1 0xFFFFBD
#define SCMR1 0xFFFFBE
#define SMR2 0xFFFFC0
#define BRR2 0xFFFFC1
#define SCR2 0xFFFFC2
#define TDR2 0xFFFFC3
#define SSR2 0xFFFFC4
#define RDR2 0xFFFFC5
#define SCMR2 0xFFFFC6
#define MDCR 0xFEE000
#define SYSCR 0xFEE001
#define DIVCR 0xFEE01B
#define MSTCRH 0xFEE01C
#define MSTCRL 0xFEE01D
#define FLMCR1 0xFEE030
#define FLMCR2 0xFEE031
#define EBR1 0xFEE032
#define EBR2 0xFEE033
#define RAMCR 0xFEE077
#define TSTR 0xFFFF60
#define TSNC 0XFFFF61
#define TMDR 0xFFFF62
#define TOLR 0xFFFF63
#define TISRA 0xFFFF64
#define TISRB 0xFFFF65
#define TISRC 0xFFFF66
#define TCR0 0xFFFF68
#define TIOR0 0xFFFF69
#define TCNT0H 0xFFFF6A
#define TCNT0L 0xFFFF6B
#define GRA0H 0xFFFF6C
#define GRA0L 0xFFFF6D
#define GRB0H 0xFFFF6E
#define GRB0L 0xFFFF6F
#define TCR1 0xFFFF70
#define TIOR1 0xFFFF71
#define TCNT1H 0xFFFF72
#define TCNT1L 0xFFFF73
#define GRA1H 0xFFFF74
#define GRA1L 0xFFFF75
#define GRB1H 0xFFFF76
#define GRB1L 0xFFFF77
#define TCR3 0xFFFF78
#define TIOR3 0xFFFF79
#define TCNT3H 0xFFFF7A
#define TCNT3L 0xFFFF7B
#define GRA3H 0xFFFF7C
#define GRA3L 0xFFFF7D
#define GRB3H 0xFFFF7E
#define GRB3L 0xFFFF7F
#define _8TCR0 0xFFFF80
#define _8TCR1 0xFFFF81
#define _8TCSR0 0xFFFF82
#define _8TCSR1 0xFFFF83
#define TCORA0 0xFFFF84
#define TCORA1 0xFFFF85
#define TCORB0 0xFFFF86
#define TCORB1 0xFFFF87
#define _8TCNT0 0xFFFF88
#define _8TCNT1 0xFFFF89
#define _8TCR2 0xFFFF90
#define _8TCR3 0xFFFF91
#define _8TCSR2 0xFFFF92
#define _8TCSR3 0xFFFF93
#define TCORA2 0xFFFF94
#define TCORA3 0xFFFF95
#define TCORB2 0xFFFF96
#define TCORB3 0xFFFF97
#define _8TCNT2 0xFFFF98
#define _8TCNT3 0xFFFF99
#define TCSR 0xFFFF8C
#define TCNT 0xFFFF8D
#define RSTCSR 0xFFFF8F
#define TPMR 0xFFFFA0
#define TPCR 0xFFFFA1
#define NDERB 0xFFFFA2
#define NDERA 0xFFFFA3
#define NDRB1 0xFFFFA4
#define NDRA1 0xFFFFA5
#define NDRB2 0xFFFFA6
#define NDRA2 0xFFFFA7
#define TCSR 0xFFFF8C
#define TCNT 0xFFFF8D
#define RSTCSRW 0xFFFF8E
#define RSTCSRR 0xFFFF8F
#endif /* __KERNEL__ */
#endif /* __REGS_H8306x__ */
#ifndef _H8300_RESOURCE_H
#define _H8300_RESOURCE_H
/*
* Resource limits
*/
#define RLIMIT_CPU 0 /* CPU time in ms */
#define RLIMIT_FSIZE 1 /* Maximum filesize */
#define RLIMIT_DATA 2 /* max data size */
#define RLIMIT_STACK 3 /* max stack size */
#define RLIMIT_CORE 4 /* max core file size */
#define RLIMIT_RSS 5 /* max resident set size */
#define RLIMIT_NPROC 6 /* max number of processes */
#define RLIMIT_NOFILE 7 /* max number of open files */
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIM_NLIMITS 11
/*
* SuS says limits have to be unsigned.
* Which makes a ton more sense anyway.
*/
#define RLIM_INFINITY (~0UL)
#ifdef __KERNEL__
#define INIT_RLIMITS \
{ \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ _STK_LIM, RLIM_INFINITY }, \
{ 0, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
}
#endif /* __KERNEL__ */
#endif /* _H8300_RESOURCE_H */
#ifndef _H8300_SCATTERLIST_H
#define _H8300_SCATTERLIST_H
struct scatterlist {
struct page *page;
unsigned int offset;
dma_addr_t dma_address;
unsigned int length;
};
#define ISA_DMA_THRESHOLD (0xffffffff)
#endif /* !(_H8300_SCATTERLIST_H) */
#ifndef _H8300_SEGMENT_H
#define _H8300_SEGMENT_H
/* define constants */
#define USER_DATA (1)
#ifndef __USER_DS
#define __USER_DS (USER_DATA)
#endif
#define USER_PROGRAM (2)
#define SUPER_DATA (3)
#ifndef __KERNEL_DS
#define __KERNEL_DS (SUPER_DATA)
#endif
#define SUPER_PROGRAM (4)
#ifndef __ASSEMBLY__
typedef struct {
unsigned long seg;
} mm_segment_t;
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
#define USER_DS MAKE_MM_SEG(__USER_DS)
#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS)
/*
* Get/set the SFC/DFC registers for MOVES instructions
*/
static inline mm_segment_t get_fs(void)
{
return USER_DS;
}
static inline mm_segment_t get_ds(void)
{
/* return the supervisor data space code */
return KERNEL_DS;
}
static inline void set_fs(mm_segment_t val)
{
}
#define segment_eq(a,b) ((a).seg == (b).seg)
#endif /* __ASSEMBLY__ */
#endif /* _H8300_SEGMENT_H */
#ifndef _H8300_SEMAPHORE_HELPER_H
#define _H8300_SEMAPHORE_HELPER_H
/*
* SMP- and interrupt-safe semaphores helper functions.
*
* (C) Copyright 1996 Linus Torvalds
*
* based on
* m68k version by Andreas Schwab
*/
#include <linux/config.h>
#include <linux/errno.h>
/*
* These two _must_ execute atomically wrt each other.
*/
static inline void wake_one_more(struct semaphore * sem)
{
atomic_inc((atomic_t *)&sem->sleepers);
}
static inline int waking_non_zero(struct semaphore *sem)
{
int ret;
unsigned long flags;
spin_lock_irqsave(&semaphore_wake_lock, flags);
ret = 0;
if (sem->sleepers > 0) {
sem->sleepers--;
ret = 1;
}
spin_unlock_irqrestore(&semaphore_wake_lock, flags);
return ret;
}
/*
* waking_non_zero_interruptible:
* 1 got the lock
* 0 go to sleep
* -EINTR interrupted
*/
static inline int waking_non_zero_interruptible(struct semaphore *sem,
struct task_struct *tsk)
{
int ret;
unsigned long flags;
spin_lock_irqsave(&semaphore_wake_lock, flags);
ret = 0;
if (sem->sleepers > 0) {
sem->sleepers--;
ret = 1;
} else if (signal_pending(tsk)) {
atomic_inc(&sem->count);
ret = -EINTR;
}
spin_unlock_irqrestore(&semaphore_wake_lock, flags);
return ret;
}
/*
* waking_non_zero_trylock:
* 1 failed to lock
* 0 got the lock
*/
static inline int waking_non_zero_trylock(struct semaphore *sem)
{
int ret;
unsigned long flags;
spin_lock_irqsave(&semaphore_wake_lock, flags);
ret = 1;
if (sem->sleepers <= 0)
atomic_inc(&sem->count);
else {
sem->sleepers--;
ret = 0;
}
spin_unlock_irqrestore(&semaphore_wake_lock, flags);
return ret;
}
#endif
#ifndef _H8300_SEMAPHORE_H
#define _H8300_SEMAPHORE_H
#define RW_LOCK_BIAS 0x01000000
#ifndef __ASSEMBLY__
#include <linux/linkage.h>
#include <linux/wait.h>
#include <linux/spinlock.h>
#include <linux/rwsem.h>
#include <asm/system.h>
#include <asm/atomic.h>
/*
* Interrupt-safe semaphores..
*
* (C) Copyright 1996 Linus Torvalds
*
* H8/300 version by Yoshinori Sato
*/
struct semaphore {
atomic_t count;
int sleepers;
wait_queue_head_t wait;
#if WAITQUEUE_DEBUG
long __magic;
#endif
};
#if WAITQUEUE_DEBUG
# define __SEM_DEBUG_INIT(name) \
, (long)&(name).__magic
#else
# define __SEM_DEBUG_INIT(name)
#endif
#define __SEMAPHORE_INITIALIZER(name,count) \
{ ATOMIC_INIT(count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
__SEM_DEBUG_INIT(name) }
#define __MUTEX_INITIALIZER(name) \
__SEMAPHORE_INITIALIZER(name,1)
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
extern inline void sema_init (struct semaphore *sem, int val)
{
*sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
}
static inline void init_MUTEX (struct semaphore *sem)
{
sema_init(sem, 1);
}
static inline void init_MUTEX_LOCKED (struct semaphore *sem)
{
sema_init(sem, 0);
}
asmlinkage void __down_failed(void /* special register calling convention */);
asmlinkage int __down_failed_interruptible(void /* params in registers */);
asmlinkage int __down_failed_trylock(void /* params in registers */);
asmlinkage void __up_wakeup(void /* special register calling convention */);
asmlinkage void __down(struct semaphore * sem);
asmlinkage int __down_interruptible(struct semaphore * sem);
asmlinkage int __down_trylock(struct semaphore * sem);
asmlinkage void __up(struct semaphore * sem);
extern spinlock_t semaphore_wake_lock;
/*
* This is ugly, but we want the default case to fall through.
* "down_failed" is a special asm handler that calls the C
* routine that actually waits. See arch/m68k/lib/semaphore.S
*/
extern inline void down(struct semaphore * sem)
{
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
__asm__ __volatile__(
"stc ccr,r4l\n\t"
"orc #0x80,ccr\n\t"
"mov.l @%0, er0\n\t"
"dec.l #1,er0\n\t"
"mov.l er0,@%0\n\t"
"bpl 1f\n\t"
"ldc r4l,ccr\n\t"
"mov.l %0,er0\n\t"
"jsr @___down\n"
"1:\n\t"
"ldc r4l,ccr"
: /* no outputs */
: "r" (&(sem->count))
: "cc", "er0", "er1", "er2", "er3", "er4", "memory");
}
extern inline int down_interruptible(struct semaphore * sem)
{
register int ret __asm__("er0");
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
__asm__ __volatile__(
"stc ccr,r1l\n\t"
"orc #0x80,ccr\n\t"
"mov.l @%1, er2\n\t"
"dec.l #1,er2\n\t"
"mov.l er2,@%1\n\t"
"bpl 1f\n\t"
"ldc r1l,ccr\n\t"
"mov.l %1,er0\n\t"
"jsr @___down_interruptible\n\t"
"bra 2f\n"
"1:\n\t"
"ldc r1l,ccr\n\t"
"sub.l %0,%0\n\t"
"2:\n\t"
: "=r" (ret)
: "r" (&(sem->count))
: "cc", "er1", "er2", "er3", "memory");
return ret;
}
extern inline int down_trylock(struct semaphore * sem)
{
register int result;
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
__asm__ __volatile__(
"stc ccr,r4l\n\t"
"orc #0x80,ccr\n\t"
"mov.l @%1,er0\n\t"
"dec.l #1,er0\n\t"
"mov.l er0,@%1\n\t"
"bpl 1f\n\t"
"ldc r4l,ccr\n\t"
"jmp @3f\n"
"1:\n\t"
"ldc r4l,ccr\n\t"
"sub.l %0,%0\n"
"2:\n"
".section .text.lock,\"ax\"\n"
".align 2\n"
"3:\n\t"
"mov.l %1,er0\n\t"
"jsr @___down_trylock\n"
"mov.l er0,%0\n\t"
"jmp @2b\n\t"
".previous"
: "=r" (result)
: "r" (&(sem->count))
: "cc", "er0","er4", "memory");
return result;
}
/*
* Note! This is subtle. We jump to wake people up only if
* the semaphore was negative (== somebody was waiting on it).
* The default case (no contention) will result in NO
* jumps for both down() and up().
*/
extern inline void up(struct semaphore * sem)
{
#if WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
__asm__ __volatile__(
"stc ccr,r4l\n\t"
"orc #0x80,ccr\n\t"
"mov.l @%0,er0\n\t"
"inc.l #1,er0\n\t"
"mov.l er0,@%0\n\t"
"bmi 1f\n\t"
"bne 2f\n\t"
"1:\n\t"
"ldc r4l,ccr\n\t"
"mov.l %0,er0\n\t"
"jsr @___up\n"
"2:\n\t"
"ldc r4l,ccr"
: /* no outputs */
: "r" (&(sem->count))
: "cc", "er0", "er4", "memory");
}
#endif /* __ASSEMBLY__ */
#endif
#ifndef _H8300_SEMBUF_H
#define _H8300_SEMBUF_H
/*
* The semid64_ds structure for m68k architecture.
* Note extra padding because this structure is passed back and forth
* between kernel and user space.
*
* Pad space is left for:
* - 64-bit time_t to solve y2038 problem
* - 2 miscellaneous 32-bit values
*/
struct semid64_ds {
struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
__kernel_time_t sem_otime; /* last semop time */
unsigned long __unused1;
__kernel_time_t sem_ctime; /* last change time */
unsigned long __unused2;
unsigned long sem_nsems; /* no. of semaphores in array */
unsigned long __unused3;
unsigned long __unused4;
};
#endif /* _H8300_SEMBUF_H */
/* eCos HAL interface header */
#ifndef SH_BIOS_H
#define SH_BIOS_H
#define HAL_IF_VECTOR_TABLE 0xfffe20
#define CALL_IF_SET_CONSOLE_COMM 13
#define QUERY_CURRENT -1
#define MANGLER -3
/* Checking for GDB stub active */
/* suggestion Jonathan Larmour */
static int sh_bios_in_gdb_mode(void)
{
static int gdb_active = -1;
if (gdb_active == -1) {
int (*set_console_comm)(int);
set_console_comm = ((void **)HAL_IF_VECTOR_TABLE)[CALL_IF_SET_CONSOLE_COMM];
gdb_active = (set_console_comm(QUERY_CURRENT) == MANGLER);
}
return gdb_active;
}
static void sh_bios_gdb_detach(void)
{
}
#endif
#ifndef _H8300_SHM_H
#define _H8300_SHM_H
#include <linux/config.h>
/* format of page table entries that correspond to shared memory pages
currently out in swap space (see also mm/swap.c):
bits 0-1 (PAGE_PRESENT) is = 0
bits 8..2 (SWP_TYPE) are = SHM_SWP_TYPE
bits 31..9 are used like this:
bits 15..9 (SHM_ID) the id of the shared memory segment
bits 30..16 (SHM_IDX) the index of the page within the shared memory segment
(actually only bits 25..16 get used since SHMMAX is so low)
bit 31 (SHM_READ_ONLY) flag whether the page belongs to a read-only attach
*/
/* on the m68k both bits 0 and 1 must be zero */
/* format on the sun3 is similar, but bits 30, 31 are set to zero and all
others are reduced by 2. --m */
#ifndef CONFIG_SUN3
#define SHM_ID_SHIFT 9
#else
#define SHM_ID_SHIFT 7
#endif
#define _SHM_ID_BITS 7
#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1)
#define SHM_IDX_SHIFT (SHM_ID_SHIFT+_SHM_ID_BITS)
#define _SHM_IDX_BITS 15
#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)
#endif /* _H8300_SHM_H */
#ifndef _H8300_SHMBUF_H
#define _H8300_SHMBUF_H
/*
* The shmid64_ds structure for m68k architecture.
* Note extra padding because this structure is passed back and forth
* between kernel and user space.
*
* Pad space is left for:
* - 64-bit time_t to solve y2038 problem
* - 2 miscellaneous 32-bit values
*/
struct shmid64_ds {
struct ipc64_perm shm_perm; /* operation perms */
size_t shm_segsz; /* size of segment (bytes) */
__kernel_time_t shm_atime; /* last attach time */
unsigned long __unused1;
__kernel_time_t shm_dtime; /* last detach time */
unsigned long __unused2;
__kernel_time_t shm_ctime; /* last change time */
unsigned long __unused3;
__kernel_pid_t shm_cpid; /* pid of creator */
__kernel_pid_t shm_lpid; /* pid of last operator */
unsigned long shm_nattch; /* no. of current attaches */
unsigned long __unused4;
unsigned long __unused5;
};
struct shminfo64 {
unsigned long shmmax;
unsigned long shmmin;
unsigned long shmmni;
unsigned long shmseg;
unsigned long shmall;
unsigned long __unused1;
unsigned long __unused2;
unsigned long __unused3;
unsigned long __unused4;
};
#endif /* _H8300_SHMBUF_H */
#ifndef _H8300_SHMPARAM_H
#define _H8300_SHMPARAM_H
#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
#endif /* _H8300_SHMPARAM_H */
#ifndef _ASM_H8300_SIGCONTEXT_H
#define _ASM_H8300_SIGCONTEXT_H
struct sigcontext {
unsigned long sc_mask; /* old sigmask */
unsigned long sc_usp; /* old user stack pointer */
unsigned long sc_er0;
unsigned long sc_er1;
unsigned long sc_er2;
unsigned long sc_er3;
unsigned short sc_ccr;
unsigned long sc_pc;
};
#endif
#ifndef _H8300_SIGINFO_H
#define _H8300_SIGINFO_H
#include <asm-generic/siginfo.h>
#endif
#ifndef _H8300_SIGNAL_H
#define _H8300_SIGNAL_H
#include <linux/types.h>
/* Avoid too many header ordering problems. */
struct siginfo;
#ifdef __KERNEL__
/* Most things should be clean enough to redefine this at will, if care
is taken to make libc match. */
#define _NSIG 64
#define _NSIG_BPW 32
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
typedef unsigned long old_sigset_t; /* at least 32 bits */
typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;
#else
/* Here we must cater to libcs that poke about in kernel headers. */
#define NSIG 32
typedef unsigned long sigset_t;
#endif /* __KERNEL__ */
#define SIGHUP 1
#define SIGINT 2
#define SIGQUIT 3
#define SIGILL 4
#define SIGTRAP 5
#define SIGABRT 6
#define SIGIOT 6
#define SIGBUS 7
#define SIGFPE 8
#define SIGKILL 9
#define SIGUSR1 10
#define SIGSEGV 11
#define SIGUSR2 12
#define SIGPIPE 13
#define SIGALRM 14
#define SIGTERM 15
#define SIGSTKFLT 16
#define SIGCHLD 17
#define SIGCONT 18
#define SIGSTOP 19
#define SIGTSTP 20
#define SIGTTIN 21
#define SIGTTOU 22
#define SIGURG 23
#define SIGXCPU 24
#define SIGXFSZ 25
#define SIGVTALRM 26
#define SIGPROF 27
#define SIGWINCH 28
#define SIGIO 29
#define SIGPOLL SIGIO
/*
#define SIGLOST 29
*/
#define SIGPWR 30
#define SIGSYS 31
#define SIGUNUSED 31
/* These should not be considered constants from userland. */
#define SIGRTMIN 32
#define SIGRTMAX (_NSIG-1)
/*
* SA_FLAGS values:
*
* SA_ONSTACK indicates that a registered stack_t will be used.
* SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
* SA_RESTART flag to get restarting signals (which were the default long ago)
* SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
* SA_RESETHAND clears the handler when the signal is delivered.
* SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
* SA_NODEFER prevents the current signal from being masked in the handler.
*
* SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
* Unix names RESETHAND and NODEFER respectively.
*/
#define SA_NOCLDSTOP 0x00000001
#define SA_NOCLDWAIT 0x00000002 /* not supported yet */
#define SA_SIGINFO 0x00000004
#define SA_ONSTACK 0x08000000
#define SA_RESTART 0x10000000
#define SA_NODEFER 0x40000000
#define SA_RESETHAND 0x80000000
#define SA_NOMASK SA_NODEFER
#define SA_ONESHOT SA_RESETHAND
#define SA_INTERRUPT 0x20000000 /* dummy -- ignored */
/*
* sigaltstack controls
*/
#define SS_ONSTACK 1
#define SS_DISABLE 2
#define MINSIGSTKSZ 2048
#define SIGSTKSZ 8192
#ifdef __KERNEL__
/*
* These values of sa_flags are used only by the kernel as part of the
* irq handling routines.
*
* SA_INTERRUPT is also used by the irq handling routines.
* SA_SHIRQ is for shared interrupt support on PCI and EISA.
*/
#define SA_PROBE SA_ONESHOT
#define SA_SAMPLE_RANDOM SA_RESTART
#define SA_SHIRQ 0x04000000
#endif
#define SIG_BLOCK 0 /* for blocking signals */
#define SIG_UNBLOCK 1 /* for unblocking signals */
#define SIG_SETMASK 2 /* for setting the signal mask */
/* Type of a signal handler. */
typedef void (*__sighandler_t)(int);
#define SIG_DFL ((__sighandler_t)0) /* default signal handling */
#define SIG_IGN ((__sighandler_t)1) /* ignore signal */
#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */
#ifdef __KERNEL__
struct old_sigaction {
__sighandler_t sa_handler;
old_sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
};
struct sigaction {
__sighandler_t sa_handler;
unsigned long sa_flags;
void (*sa_restorer)(void);
sigset_t sa_mask; /* mask last for extensibility */
};
struct k_sigaction {
struct sigaction sa;
};
#else
/* Here we must cater to libcs that poke about in kernel headers. */
struct sigaction {
union {
__sighandler_t _sa_handler;
void (*_sa_sigaction)(int, struct siginfo *, void *);
} _u;
sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
};
#define sa_handler _u._sa_handler
#define sa_sigaction _u._sa_sigaction
#endif /* __KERNEL__ */
typedef struct sigaltstack {
void *ss_sp;
int ss_flags;
size_t ss_size;
} stack_t;
#ifdef __KERNEL__
#include <asm/sigcontext.h>
#undef __HAVE_ARCH_SIG_BITOPS
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
#endif /* __KERNEL__ */
#endif /* _H8300_SIGNAL_H */
/* nothing required here yet */
/*
* <asm/smplock.h>
*
* Default SMP lock implementation
*/
#include <linux/interrupt.h>
#include <linux/spinlock.h>
extern spinlock_t kernel_flag;
#define kernel_locked() spin_is_locked(&kernel_flag)
/*
* Release global kernel lock and global interrupt lock
*/
#define release_kernel_lock(task, cpu) \
do { \
if (task->lock_depth >= 0) \
spin_unlock(&kernel_flag); \
release_irqlock(cpu); \
__sti(); \
} while (0)
/*
* Re-acquire the kernel lock
*/
#define reacquire_kernel_lock(task) \
do { \
if (task->lock_depth >= 0) \
spin_lock(&kernel_flag); \
} while (0)
/*
* Getting the big kernel lock.
*
* This cannot happen asynchronously,
* so we only need to worry about other
* CPU's.
*/
extern __inline__ void lock_kernel(void)
{
if (!++current->lock_depth)
spin_lock(&kernel_flag);
}
extern __inline__ void unlock_kernel(void)
{
if (--current->lock_depth < 0)
spin_unlock(&kernel_flag);
}
#ifndef _ASM_SOCKET_H
#define _ASM_SOCKET_H
#include <asm/sockios.h>
/* For setsockoptions(2) */
#define SOL_SOCKET 1
#define SO_DEBUG 1
#define SO_REUSEADDR 2
#define SO_TYPE 3
#define SO_ERROR 4
#define SO_DONTROUTE 5
#define SO_BROADCAST 6
#define SO_SNDBUF 7
#define SO_RCVBUF 8
#define SO_KEEPALIVE 9
#define SO_OOBINLINE 10
#define SO_NO_CHECK 11
#define SO_PRIORITY 12
#define SO_LINGER 13
#define SO_BSDCOMPAT 14
/* To add :#define SO_REUSEPORT 15 */
#define SO_PASSCRED 16
#define SO_PEERCRED 17
#define SO_RCVLOWAT 18
#define SO_SNDLOWAT 19
#define SO_RCVTIMEO 20
#define SO_SNDTIMEO 21
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 22
#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
#define SO_SECURITY_ENCRYPTION_NETWORK 24
#define SO_BINDTODEVICE 25
/* Socket filtering */
#define SO_ATTACH_FILTER 26
#define SO_DETACH_FILTER 27
#define SO_PEERNAME 28
#define SO_TIMESTAMP 29
#define SCM_TIMESTAMP SO_TIMESTAMP
#define SO_ACCEPTCONN 30
/* Nast libc5 fixup - bletch */
#if defined(__KERNEL__)
/* Socket types. */
#define SOCK_STREAM 1 /* stream (connection) socket */
#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
#define SOCK_RAW 3 /* raw socket */
#define SOCK_RDM 4 /* reliably-delivered message */
#define SOCK_SEQPACKET 5 /* sequential packet socket */
#define SOCK_PACKET 10 /* linux specific way of */
/* getting packets at the dev */
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
#define SOCK_MAX (SOCK_PACKET+1)
#endif
#endif /* _ASM_SOCKET_H */
#ifndef __ARCH_H8300_SOCKIOS__
#define __ARCH_H8300_SOCKIOS__
/* Socket-level I/O control calls. */
#define FIOSETOWN 0x8901
#define SIOCSPGRP 0x8902
#define FIOGETOWN 0x8903
#define SIOCGPGRP 0x8904
#define SIOCATMARK 0x8905
#define SIOCGSTAMP 0x8906 /* Get stamp */
#endif /* __ARCH_H8300_SOCKIOS__ */
#ifndef __ASM_SOFTIRQ_H
#define __ASM_SOFTIRQ_H
#include <linux/preempt.h>
#include <asm/hardirq.h>
#define local_bh_disable() \
do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0)
#define __local_bh_enable() \
do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0)
#define local_bh_enable() \
do { \
__local_bh_enable(); \
if (unlikely(!in_interrupt() && softirq_pending(smp_processor_id()))) \
do_softirq(); \
preempt_check_resched(); \
} while (0)
#endif /* __ASM_SOFTIRQ_H */
#ifndef __H8300_SPINLOCK_H
#define __H8300_SPINLOCK_H
#error "H8/300 doesn't do SMP yet"
#endif
#ifndef _H8300_STAT_H
#define _H8300_STAT_H
struct __old_kernel_stat {
unsigned short st_dev;
unsigned short st_ino;
unsigned short st_mode;
unsigned short st_nlink;
unsigned short st_uid;
unsigned short st_gid;
unsigned short st_rdev;
unsigned long st_size;
unsigned long st_atime;
unsigned long st_mtime;
unsigned long st_ctime;
};
struct stat {
unsigned short st_dev;
unsigned short __pad1;
unsigned long st_ino;
unsigned short st_mode;
unsigned short st_nlink;
unsigned short st_uid;
unsigned short st_gid;
unsigned short st_rdev;
unsigned short __pad2;
unsigned long st_size;
unsigned long st_blksize;
unsigned long st_blocks;
unsigned long st_atime;
unsigned long __unused1;
unsigned long st_mtime;
unsigned long __unused2;
unsigned long st_ctime;
unsigned long __unused3;
unsigned long __unused4;
unsigned long __unused5;
};
/* This matches struct stat64 in glibc2.1, hence the absolutely
* insane amounts of padding around dev_t's.
*/
struct stat64 {
unsigned char __pad0[6];
unsigned short st_dev;
unsigned char __pad1[2];
#define STAT64_HAS_BROKEN_ST_INO 1
unsigned long __st_ino;
unsigned int st_mode;
unsigned int st_nlink;
unsigned long st_uid;
unsigned long st_gid;
unsigned char __pad2[6];
unsigned short st_rdev;
unsigned char __pad3[2];
long long st_size;
unsigned long st_blksize;
unsigned long __pad4; /* future possible st_blocks high bits */
unsigned long st_blocks; /* Number 512-byte blocks allocated. */
unsigned long st_atime;
unsigned long st_atime_nsec;
unsigned long st_mtime;
unsigned long st_mtime_nsec;
unsigned long st_ctime;
unsigned long st_ctime_nsec;
unsigned long long st_ino;
};
#endif /* _H8300_STAT_H */
#ifndef _H8300_STATFS_H
#define _H8300_STATFS_H
#ifndef __KERNEL_STRICT_NAMES
#include <linux/types.h>
typedef __kernel_fsid_t fsid_t;
#endif
struct statfs {
long f_type;
long f_bsize;
long f_blocks;
long f_bfree;
long f_bavail;
long f_files;
long f_ffree;
__kernel_fsid_t f_fsid;
long f_namelen;
long f_spare[6];
};
#endif /* _H8300_STATFS_H */
#ifndef _H8300_STRING_H_
#define _H8300_STRING_H_
#ifdef __KERNEL__ /* only set these up for kernel code */
#include <asm/setup.h>
#include <asm/page.h>
#define __HAVE_ARCH_MEMSET
extern void * memset(void * s, int c, size_t count);
#define __HAVE_ARCH_MEMCPY
extern void * memcpy(void *d, const void *s, size_t count);
#else /* KERNEL */
/*
* let user libraries deal with these,
* IMHO the kernel has no place defining these functions for user apps
*/
#define __HAVE_ARCH_STRCPY 1
#define __HAVE_ARCH_STRNCPY 1
#define __HAVE_ARCH_STRCAT 1
#define __HAVE_ARCH_STRNCAT 1
#define __HAVE_ARCH_STRCMP 1
#define __HAVE_ARCH_STRNCMP 1
#define __HAVE_ARCH_STRNICMP 1
#define __HAVE_ARCH_STRCHR 1
#define __HAVE_ARCH_STRRCHR 1
#define __HAVE_ARCH_STRSTR 1
#define __HAVE_ARCH_STRLEN 1
#define __HAVE_ARCH_STRNLEN 1
#define __HAVE_ARCH_MEMSET 1
#define __HAVE_ARCH_MEMCPY 1
#define __HAVE_ARCH_MEMMOVE 1
#define __HAVE_ARCH_MEMSCAN 1
#define __HAVE_ARCH_MEMCMP 1
#define __HAVE_ARCH_MEMCHR 1
#define __HAVE_ARCH_STRTOK 1
#endif /* KERNEL */
#endif /* _M68K_STRING_H_ */
#ifndef _H8300_SYSTEM_H
#define _H8300_SYSTEM_H
#include <linux/config.h> /* get configuration macros */
#include <linux/kernel.h>
#include <linux/linkage.h>
#define prepare_to_switch() do { } while(0)
/*
* switch_to(n) should switch tasks to task ptr, first checking that
* ptr isn't the current task, in which case it does nothing. This
* also clears the TS-flag if the task we switched to has used the
* math co-processor latest.
*/
/*
* switch_to() saves the extra registers, that are not saved
* automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and
* a0-a1. Some of these are used by schedule() and its predecessors
* and so we might get see unexpected behaviors when a task returns
* with unexpected register values.
*
* syscall stores these registers itself and none of them are used
* by syscall after the function in the syscall has been called.
*
* Beware that resume now expects *next to be in d1 and the offset of
* tss to be in a1. This saves a few instructions as we no longer have
* to push them onto the stack and read them back right after.
*
* 02/17/96 - Jes Sorensen (jds@kom.auc.dk)
*
* Changed 96/09/19 by Andreas Schwab
* pass prev in a0, next in a1, offset of tss in d1, and whether
* the mm structures are shared in d2 (to avoid atc flushing).
*
* H8/300 Porting 2002/09/04 Yoshinori Sato
*/
asmlinkage void resume(void);
#define switch_to(prev,next,last) { \
void *_last; \
__asm__ __volatile__( \
"mov.l %1, er0\n\t" \
"mov.l %2, er1\n\t" \
"jsr @_resume" \
: "=r" (_last) \
: "r" (&(prev->thread)), \
"r" (&(next->thread)) \
: "cc", "er0", "er1", "er2", "er3"); \
(last) = _last; \
}
#if defined(__H8300H__)
#define __sti() asm volatile ("andc #0x7f,ccr")
#define __cli() asm volatile ("orc #0x80,ccr")
#define __save_flags(x) \
asm volatile ("sub.l er0,er0\n\tstc ccr,r0l\n\tmov.l er0,%0":"=r" (x) : : "er0")
#define __restore_flags(x) \
asm volatile ("mov.l %0,er0\n\tldc r0l,ccr": :"r" (x) : "er0")
#endif
#if defined(__H8300S__)
#define __sti() asm volatile ("andc #0xf8,exr")
#define __cli() asm volatile ("orc #0x07,exr")
#define __save_flags(x) \
asm volatile ("sub.l er0,er0\n\tstc exr,r0l\n\tmov.l er0,%0":"=r" (x) : : "er0")
#define __restore_flags(x) \
asm volatile ("mov.l %0,er0\n\tldc r0l,exr": :"r" (x) : "er0")
#endif
#define irqs_disabled() \
({ \
unsigned long flags; \
__save_flags(flags); \
((flags & 0x80) == 0x80); \
})
#define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc")
/* For spinlocks etc */
#define local_irq_disable() asm volatile ("orc #0x80,ccr")
#define local_irq_enable() asm volatile ("andc #0x7f,ccr")
#define local_irq_save(x) ({ __save_flags(x); local_irq_disable(); })
#define local_irq_restore(x) __restore_flags(x)
#define local_save_flags(x) __save_flags(x)
/*
* Force strict CPU ordering.
* Not really required on m68k...
*/
#define nop() asm volatile ("nop"::)
#define mb() asm volatile ("" : : :"memory")
#define rmb() asm volatile ("" : : :"memory")
#define wmb() asm volatile ("" : : :"memory")
#define set_rmb(var, value) do { xchg(&var, value); } while (0)
#define set_mb(var, value) set_rmb(var, value)
#define set_wmb(var, value) do { var = value; wmb(); } while (0)
#ifdef CONFIG_SMP
#define smp_mb() mb()
#define smp_rmb() rmb()
#define smp_wmb() wmb()
#define smp_read_barrier_depends() read_barrier_depends()
#else
#define smp_mb() barrier()
#define smp_rmb() barrier()
#define smp_wmb() barrier()
#define smp_read_barrier_depends() do { } while(0)
#endif
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
#define tas(ptr) (xchg((ptr),1))
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((volatile struct __xchg_dummy *)(x))
static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
unsigned long tmp, flags;
local_irq_save(flags);
switch (size) {
case 1:
__asm__ __volatile__
("mov.b %2,%0\n\t"
"mov.b %1,%2"
: "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "er0","memory");
break;
case 2:
__asm__ __volatile__
("mov.w %2,%0\n\t"
"mov.w %1,%2"
: "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory");
break;
case 4:
__asm__ __volatile__
("mov.l %2,%0\n\t"
"mov.l %1,%2"
: "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory");
break;
default:
tmp = 0;
}
local_irq_restore(flags);
return tmp;
}
#define HARD_RESET_NOW() ({ \
local_irq_disable(); \
asm("jmp @@0"); \
})
#endif /* _H8300_SYSTEM_H */
extern int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *));
extern void platform_timer_eoi(void);
extern void platfrom_gettod(unsigned int *year, unsigned int *mon, unsigned int *day,
unsigned int *hour, unsigned int *min, unsigned int *sec);
#ifndef __ARCH_H8300_TERMBITS_H__
#define __ARCH_H8300_TERMBITS_H__
#include <linux/posix_types.h>
typedef unsigned char cc_t;
typedef unsigned int speed_t;
typedef unsigned int tcflag_t;
#define NCCS 19
struct termios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
cc_t c_line; /* line discipline */
cc_t c_cc[NCCS]; /* control characters */
};
/* c_cc characters */
#define VINTR 0
#define VQUIT 1
#define VERASE 2
#define VKILL 3
#define VEOF 4
#define VTIME 5
#define VMIN 6
#define VSWTC 7
#define VSTART 8
#define VSTOP 9
#define VSUSP 10
#define VEOL 11
#define VREPRINT 12
#define VDISCARD 13
#define VWERASE 14
#define VLNEXT 15
#define VEOL2 16
/* c_iflag bits */
#define IGNBRK 0000001
#define BRKINT 0000002
#define IGNPAR 0000004
#define PARMRK 0000010
#define INPCK 0000020
#define ISTRIP 0000040
#define INLCR 0000100
#define IGNCR 0000200
#define ICRNL 0000400
#define IUCLC 0001000
#define IXON 0002000
#define IXANY 0004000
#define IXOFF 0010000
#define IMAXBEL 0020000
/* c_oflag bits */
#define OPOST 0000001
#define OLCUC 0000002
#define ONLCR 0000004
#define OCRNL 0000010
#define ONOCR 0000020
#define ONLRET 0000040
#define OFILL 0000100
#define OFDEL 0000200
#define NLDLY 0000400
#define NL0 0000000
#define NL1 0000400
#define CRDLY 0003000
#define CR0 0000000
#define CR1 0001000
#define CR2 0002000
#define CR3 0003000
#define TABDLY 0014000
#define TAB0 0000000
#define TAB1 0004000
#define TAB2 0010000
#define TAB3 0014000
#define XTABS 0014000
#define BSDLY 0020000
#define BS0 0000000
#define BS1 0020000
#define VTDLY 0040000
#define VT0 0000000
#define VT1 0040000
#define FFDLY 0100000
#define FF0 0000000
#define FF1 0100000
/* c_cflag bit meaning */
#define CBAUD 0010017
#define B0 0000000 /* hang up */
#define B50 0000001
#define B75 0000002
#define B110 0000003
#define B134 0000004
#define B150 0000005
#define B200 0000006
#define B300 0000007
#define B600 0000010
#define B1200 0000011
#define B1800 0000012
#define B2400 0000013
#define B4800 0000014
#define B9600 0000015
#define B19200 0000016
#define B38400 0000017
#define EXTA B19200
#define EXTB B38400
#define CSIZE 0000060
#define CS5 0000000
#define CS6 0000020
#define CS7 0000040
#define CS8 0000060
#define CSTOPB 0000100
#define CREAD 0000200
#define PARENB 0000400
#define PARODD 0001000
#define HUPCL 0002000
#define CLOCAL 0004000
#define CBAUDEX 0010000
#define B57600 0010001
#define B115200 0010002
#define B230400 0010003
#define B460800 0010004
#define B500000 0010005
#define B576000 0010006
#define B921600 0010007
#define B1000000 0010010
#define B1152000 0010011
#define B1500000 0010012
#define B2000000 0010013
#define B2500000 0010014
#define B3000000 0010015
#define B3500000 0010016
#define B4000000 0010017
#define CIBAUD 002003600000 /* input baud rate (not used) */
#define CMSPAR 010000000000 /* mark or space (stick) parity */
#define CRTSCTS 020000000000 /* flow control */
/* c_lflag bits */
#define ISIG 0000001
#define ICANON 0000002
#define XCASE 0000004
#define ECHO 0000010
#define ECHOE 0000020
#define ECHOK 0000040
#define ECHONL 0000100
#define NOFLSH 0000200
#define TOSTOP 0000400
#define ECHOCTL 0001000
#define ECHOPRT 0002000
#define ECHOKE 0004000
#define FLUSHO 0010000
#define PENDIN 0040000
#define IEXTEN 0100000
/* tcflow() and TCXONC use these */
#define TCOOFF 0
#define TCOON 1
#define TCIOFF 2
#define TCION 3
/* tcflush() and TCFLSH use these */
#define TCIFLUSH 0
#define TCOFLUSH 1
#define TCIOFLUSH 2
/* tcsetattr uses these */
#define TCSANOW 0
#define TCSADRAIN 1
#define TCSAFLUSH 2
#endif /* __ARCH_H8300_TERMBITS_H__ */
#ifndef _H8300_TERMIOS_H
#define _H8300_TERMIOS_H
#include <asm/termbits.h>
#include <asm/ioctls.h>
struct winsize {
unsigned short ws_row;
unsigned short ws_col;
unsigned short ws_xpixel;
unsigned short ws_ypixel;
};
#define NCC 8
struct termio {
unsigned short c_iflag; /* input mode flags */
unsigned short c_oflag; /* output mode flags */
unsigned short c_cflag; /* control mode flags */
unsigned short c_lflag; /* local mode flags */
unsigned char c_line; /* line discipline */
unsigned char c_cc[NCC]; /* control characters */
};
#ifdef __KERNEL__
/* intr=^C quit=^| erase=del kill=^U
eof=^D vtime=\0 vmin=\1 sxtc=\0
start=^Q stop=^S susp=^Z eol=\0
reprint=^R discard=^U werase=^W lnext=^V
eol2=\0
*/
#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
#endif
/* modem lines */
#define TIOCM_LE 0x001
#define TIOCM_DTR 0x002
#define TIOCM_RTS 0x004
#define TIOCM_ST 0x008
#define TIOCM_SR 0x010
#define TIOCM_CTS 0x020
#define TIOCM_CAR 0x040
#define TIOCM_RNG 0x080
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
/* line disciplines */
#define N_TTY 0
#define N_SLIP 1
#define N_MOUSE 2
#define N_PPP 3
#define N_STRIP 4
#define N_AX25 5
#define N_X25 6 /* X.25 async */
#define N_6PACK 7
#define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */
#define N_R3964 9 /* Reserved for Simatic R3964 module */
#define N_PROFIBUS_FDL 10 /* Reserved for Profibus <Dave@mvhi.com> */
#define N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */
#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */
#define N_HDLC 13 /* synchronous HDLC */
#define N_SYNC_PPP 14
#define N_HCI 15 /* Bluetooth HCI UART */
#ifdef __KERNEL__
/*
* Translate a "termio" structure into a "termios". Ugh.
*/
#define user_termio_to_kernel_termios(termios, termio) \
({ \
unsigned short tmp; \
get_user(tmp, &(termio)->c_iflag); \
(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
get_user(tmp, &(termio)->c_oflag); \
(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
get_user(tmp, &(termio)->c_cflag); \
(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
get_user(tmp, &(termio)->c_lflag); \
(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
get_user((termios)->c_line, &(termio)->c_line); \
copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
})
/*
* Translate a "termios" structure into a "termio". Ugh.
*/
#define kernel_termios_to_user_termio(termio, termios) \
({ \
put_user((termios)->c_iflag, &(termio)->c_iflag); \
put_user((termios)->c_oflag, &(termio)->c_oflag); \
put_user((termios)->c_cflag, &(termio)->c_cflag); \
put_user((termios)->c_lflag, &(termio)->c_lflag); \
put_user((termios)->c_line, &(termio)->c_line); \
copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
})
#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
#endif /* __KERNEL__ */
#endif /* _H8300_TERMIOS_H */
/* thread_info.h: h8300 low-level thread information
* adapted from the i386 and PPC versions by Yoshinori Sato <ysato@users.sourceforge.jp>
*
* Copyright (C) 2002 David Howells (dhowells@redhat.com)
* - Incorporating suggestions made by Linus Torvalds and Dave Miller
*/
#ifndef _ASM_THREAD_INFO_H
#define _ASM_THREAD_INFO_H
#include <asm/page.h>
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
/*
* low level task data.
* If you change this, change the TI_* offsets below to match.
*/
struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
unsigned long flags; /* low level flags */
int cpu; /* cpu we're on */
int preempt_count; /* 0 => preemptable, <0 => BUG*/
struct restart_block restart_block;
};
/*
* macros/functions for gaining access to the thread information structure
*/
#define INIT_THREAD_INFO(tsk) \
{ \
task: &tsk, \
exec_domain: &default_exec_domain, \
flags: 0, \
cpu: 0, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
}
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
/*
* Size of kernel stack for each process. This must be a power of 2...
*/
#define THREAD_SIZE 8192 /* 2 pages */
/* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void)
{
struct thread_info *ti;
__asm__(
"mov.l sp, %0 \n\t"
"and.l %1, %0"
: "=&r"(ti)
: "r" (~(THREAD_SIZE-1))
);
return ti;
}
/* thread information allocation */
#define alloc_thread_info() ((struct thread_info *) \
__get_free_pages(GFP_KERNEL, 1))
#define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
#define get_thread_info(ti) get_task_struct((ti)->task)
#define put_thread_info(ti) put_task_struct((ti)->task)
#endif /* __ASSEMBLY__ */
/*
* Offsets in thread_info structure, used in assembly code
*/
#define TI_TASK 0
#define TI_EXECDOMAIN 4
#define TI_FLAGS 8
#define TI_CPU 12
#define PREEMPT_ACTIVE 0x4000000
/*
* thread information flag bit numbers
*/
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
#define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling
TIF_NEED_RESCHED */
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
#endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */
/*
* linux/include/asm-h8300/timex.h
*
* H8/300 architecture timex specifications
*/
#ifndef _ASM_H8300_TIMEX_H
#define _ASM_H8300_TIMEX_H
/* Such a description is OK ? */
#define TIMEX_DEPEND_HEADER(target) <asm/target/timer_rate.h>
#include TIMEX_DEPEND_HEADER(TARGET)
#define CLOCK_TICK_RATE H8300_TIMER_FREQ
#define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */
#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
typedef unsigned long cycles_t;
extern short h8300_timer_count;
static inline cycles_t get_cycles(void)
{
return 0;
}
#endif
#include <asm-generic/tlb.h>
#ifndef _H8300_TLBFLUSH_H
#define _H8300_TLBFLUSH_H
/*
* Copyright (C) 2000 Lineo, David McCullough <davidm@uclinux.org>
* Copyright (C) 2000-2002, Greg Ungerer <gerg@snapgear.com>
*/
#include <asm/setup.h>
/*
* flush all user-space atc entries.
*/
static inline void __flush_tlb(void)
{
BUG();
}
static inline void __flush_tlb_one(unsigned long addr)
{
BUG();
}
#define flush_tlb() __flush_tlb()
/*
* flush all atc entries (both kernel and user-space entries).
*/
static inline void flush_tlb_all(void)
{
BUG();
}
static inline void flush_tlb_mm(struct mm_struct *mm)
{
BUG();
}
static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
{
BUG();
}
static inline void flush_tlb_range(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
BUG();
}
extern inline void flush_tlb_kernel_page(unsigned long addr)
{
BUG();
}
extern inline void flush_tlb_pgtables(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
BUG();
}
#endif /* _H8300_TLBFLUSH_H */
#ifndef _ASM_H8300_TOPOLOGY_H
#define _ASM_H8300_TOPOLOGY_H
#include <asm-generic/topology.h>
#endif /* _ASM_H8300_TOPOLOGY_H */
/*
* linux/include/asm/traps.h
*
* Copyright (C) 1993 Hamish Macdonald
*
* 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.
*/
#ifndef _H8300_TRAPS_H
#define _H8300_TRAPS_H
#if 0
#ifndef __ASSEMBLY__
typedef void (*e_vector)(void);
extern e_vector vectors[];
#endif
#define VEC_BUSERR (2)
#define VEC_ADDRERR (3)
#define VEC_ILLEGAL (4)
#define VEC_ZERODIV (5)
#define VEC_CHK (6)
#define VEC_TRAP (7)
#define VEC_PRIV (8)
#define VEC_TRACE (9)
#define VEC_LINE10 (10)
#define VEC_LINE11 (11)
#define VEC_RESV1 (12)
#define VEC_COPROC (13)
#define VEC_FORMAT (14)
#define VEC_UNINT (15)
#define VEC_SPUR (24)
#define VEC_INT1 (25)
#define VEC_INT2 (26)
#define VEC_INT3 (27)
#define VEC_INT4 (28)
#define VEC_INT5 (29)
#define VEC_INT6 (30)
#define VEC_INT7 (31)
#define VEC_SYS (32)
#define VEC_TRAP1 (33)
#define VEC_TRAP2 (34)
#define VEC_TRAP3 (35)
#define VEC_TRAP4 (36)
#define VEC_TRAP5 (37)
#define VEC_TRAP6 (38)
#define VEC_TRAP7 (39)
#define VEC_TRAP8 (40)
#define VEC_TRAP9 (41)
#define VEC_TRAP10 (42)
#define VEC_TRAP11 (43)
#define VEC_TRAP12 (44)
#define VEC_TRAP13 (45)
#define VEC_TRAP14 (46)
#define VEC_TRAP15 (47)
#define VEC_FPBRUC (48)
#define VEC_FPIR (49)
#define VEC_FPDIVZ (50)
#define VEC_FPUNDER (51)
#define VEC_FPOE (52)
#define VEC_FPOVER (53)
#define VEC_FPNAN (54)
#define VEC_FPUNSUP (55)
#define VEC_UNIMPEA (60)
#define VEC_UNIMPII (61)
#define VEC_USER (64)
#define VECOFF(vec) ((vec)<<2)
#ifndef __ASSEMBLY__
/* Status register bits */
#define PS_T (0x8000)
#define PS_S (0x2000)
#define PS_M (0x1000)
#define PS_C (0x0001)
/* bits for 68020/68030 special status word */
#define FC (0x8000)
#define FB (0x4000)
#define RC (0x2000)
#define RB (0x1000)
#define DF (0x0100)
#define RM (0x0080)
#define RW (0x0040)
#define SZ (0x0030)
#define DFC (0x0007)
/* bits for 68030 MMU status register (mmusr,psr) */
#define MMU_B (0x8000) /* bus error */
#define MMU_L (0x4000) /* limit violation */
#define MMU_S (0x2000) /* supervisor violation */
#define MMU_WP (0x0800) /* write-protected */
#define MMU_I (0x0400) /* invalid descriptor */
#define MMU_M (0x0200) /* ATC entry modified */
#define MMU_T (0x0040) /* transparent translation */
#define MMU_NUM (0x0007) /* number of levels traversed */
/* bits for 68040 special status word */
#define CP_040 (0x8000)
#define CU_040 (0x4000)
#define CT_040 (0x2000)
#define CM_040 (0x1000)
#define MA_040 (0x0800)
#define ATC_040 (0x0400)
#define LK_040 (0x0200)
#define RW_040 (0x0100)
#define SIZ_040 (0x0060)
#define TT_040 (0x0018)
#define TM_040 (0x0007)
/* bits for 68040 write back status word */
#define WBV_040 (0x80)
#define WBSIZ_040 (0x60)
#define WBBYT_040 (0x20)
#define WBWRD_040 (0x40)
#define WBLNG_040 (0x00)
#define WBTT_040 (0x18)
#define WBTM_040 (0x07)
/* bus access size codes */
#define BA_SIZE_BYTE (0x20)
#define BA_SIZE_WORD (0x40)
#define BA_SIZE_LONG (0x00)
#define BA_SIZE_LINE (0x60)
/* bus access transfer type codes */
#define BA_TT_MOVE16 (0x08)
/* structure for stack frames */
struct frame {
struct pt_regs ptregs;
union {
struct {
unsigned long iaddr; /* instruction address */
} fmt2;
struct {
unsigned long effaddr; /* effective address */
} fmt3;
struct {
unsigned long effaddr; /* effective address */
unsigned long pc; /* pc of faulted instr */
} fmt4;
struct {
unsigned long effaddr; /* effective address */
unsigned short ssw; /* special status word */
unsigned short wb3s; /* write back 3 status */
unsigned short wb2s; /* write back 2 status */
unsigned short wb1s; /* write back 1 status */
unsigned long faddr; /* fault address */
unsigned long wb3a; /* write back 3 address */
unsigned long wb3d; /* write back 3 data */
unsigned long wb2a; /* write back 2 address */
unsigned long wb2d; /* write back 2 data */
unsigned long wb1a; /* write back 1 address */
unsigned long wb1dpd0; /* write back 1 data/push data 0*/
unsigned long pd1; /* push data 1*/
unsigned long pd2; /* push data 2*/
unsigned long pd3; /* push data 3*/
} fmt7;
struct {
unsigned long iaddr; /* instruction address */
unsigned short int1[4]; /* internal registers */
} fmt9;
struct {
unsigned short int1;
unsigned short ssw; /* special status word */
unsigned short isc; /* instruction stage c */
unsigned short isb; /* instruction stage b */
unsigned long daddr; /* data cycle fault address */
unsigned short int2[2];
unsigned long dobuf; /* data cycle output buffer */
unsigned short int3[2];
} fmta;
struct {
unsigned short int1;
unsigned short ssw; /* special status word */
unsigned short isc; /* instruction stage c */
unsigned short isb; /* instruction stage b */
unsigned long daddr; /* data cycle fault address */
unsigned short int2[2];
unsigned long dobuf; /* data cycle output buffer */
unsigned short int3[4];
unsigned long baddr; /* stage B address */
unsigned short int4[2];
unsigned long dibuf; /* data cycle input buffer */
unsigned short int5[3];
unsigned ver : 4; /* stack frame version # */
unsigned int6:12;
unsigned short int7[18];
} fmtb;
} un;
};
#endif /* __ASSEMBLY__ */
#endif
#endif /* _H8300_TRAPS_H */
#ifndef _H8300_TYPES_H
#define _H8300_TYPES_H
/*
* This file is never included by application software unless
* explicitly requested (e.g., via linux/types.h) in which case the
* application is Linux specific so (user-) name space pollution is
* not a major issue. However, for interoperability, libraries still
* need to be careful to avoid a name clashes.
*/
typedef unsigned short umode_t;
/*
* __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
* header files exported to user space
*/
typedef __signed__ char __s8;
typedef unsigned char __u8;
typedef __signed__ short __s16;
typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
typedef __signed__ long long __s64;
typedef unsigned long long __u64;
#endif
/*
* These aren't exported outside the kernel to avoid name space clashes
*/
#ifdef __KERNEL__
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef signed long long s64;
typedef unsigned long long u64;
#define BITS_PER_LONG 32
/* Dma addresses are 32-bits wide. */
typedef u32 dma_addr_t;
#endif /* __KERNEL__ */
#endif /* _H8300_TYPES_H */
#ifndef __H8300_UACCESS_H
#define __H8300_UACCESS_H
/*
* User space memory access functions
*/
#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/segment.h>
#define VERIFY_READ 0
#define VERIFY_WRITE 1
/* We let the MMU do all checking */
extern inline int access_ok(int type, const void * addr, unsigned long size)
{
#define RANGE_CHECK_OK(addr, size, lower, upper) \
(((addr) >= (lower)) && (((addr) + (size)) < (upper)))
extern unsigned long _ramend;
return(RANGE_CHECK_OK((unsigned long) addr, size, 0L, (unsigned long)&_ramend));
}
extern inline int verify_area(int type, const void * addr, unsigned long size)
{
return access_ok(type,addr,size)?0:-EFAULT;
}
/*
* The exception table consists of pairs of addresses: the first is the
* address of an instruction that is allowed to fault, and the second is
* the address at which the program should continue. No registers are
* modified, so it is entirely up to the continuation code to figure out
* what to do.
*
* All the routines below use bits of fixup code that are out of line
* with the main instruction path. This means when everything is well,
* we don't even have to jump over them. Further, they do not intrude
* on our cache or tlb entries.
*/
struct exception_table_entry
{
unsigned long insn, fixup;
};
/* Returns 0 if exception not found and fixup otherwise. */
extern unsigned long search_exception_table(unsigned long);
/*
* These are the main single-value transfer routines. They automatically
* use the right size if we just have the right pointer type.
*/
#define put_user(x, ptr) \
({ \
int __pu_err = 0; \
typeof(*(ptr)) __pu_val = (x); \
switch (sizeof (*(ptr))) { \
case 1: \
case 2: \
case 4: \
*(ptr) = (__pu_val); \
break; \
case 8: \
memcpy(ptr, &__pu_val, sizeof (*(ptr))); \
break; \
default: \
__pu_err = __put_user_bad(); \
break; \
} \
__pu_err; \
})
#define __put_user(x, ptr) put_user(x, ptr)
extern int __put_user_bad(void);
/*
* Tell gcc we read from memory instead of writing: this is because
* we do not write to any memory gcc knows about, so there are no
* aliasing issues.
*/
#define __ptr(x) ((unsigned long *)(x))
/*
* Tell gcc we read from memory instead of writing: this is because
* we do not write to any memory gcc knows about, so there are no
* aliasing issues.
*/
#define get_user(x, ptr) \
({ \
int __gu_err = 0; \
typeof(*(ptr)) __gu_val = 0; \
switch (sizeof(*(ptr))) { \
case 1: \
case 2: \
case 4: \
__gu_val = *(ptr); \
break; \
case 8: \
memcpy(&__gu_val, ptr, sizeof (*(ptr))); \
break; \
default: \
__gu_val = 0; \
__gu_err = __get_user_bad(); \
break; \
} \
(x) = __gu_val; \
__gu_err; \
})
#define __get_user(x, ptr) get_user(x, ptr)
extern int __get_user_bad(void);
#define copy_from_user(to, from, n) (memcpy(to, from, n), 0)
#define copy_to_user(to, from, n) (memcpy(to, from, n), 0)
#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
/*
* Copy a null terminated string from userspace.
*/
static inline long
strncpy_from_user(char *dst, const char *src, long count)
{
char *tmp;
strncpy(dst, src, count);
for (tmp = dst; *tmp && count > 0; tmp++, count--)
;
return(tmp - dst); /* DAVIDM should we count a NUL ? check getname */
}
/*
* Return the size of a string (including the ending 0)
*
* Return 0 on exception, a value greater than N if too long
*/
static inline long strnlen_user(const char *src, long n)
{
return(strlen(src) + 1); /* DAVIDM make safer */
}
#define strlen_user(str) strnlen_user(str, 32767)
/*
* Zero Userspace
*/
static inline unsigned long
clear_user(void *to, unsigned long n)
{
memset(to, 0, n);
return(0);
}
#endif /* _H8300_UACCESS_H */
#ifndef _H8300_UCONTEXT_H
#define _H8300_UCONTEXT_H
typedef int greg_t;
#define NGREG 10
typedef greg_t gregset_t[NGREG];
struct mcontext {
int version;
gregset_t gregs;
};
#define MCONTEXT_VERSION 1
struct ucontext {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
struct mcontext uc_mcontext;
sigset_t uc_sigmask; /* mask last for extensibility */
};
#endif
#ifndef __H8300_UNALIGNED_H
#define __H8300_UNALIGNED_H
#include <linux/config.h>
/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
#define get_unaligned(ptr) \
({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
#define put_unaligned(val, ptr) \
({ __typeof__(*(ptr)) __tmp = (val); \
memmove((ptr), &__tmp, sizeof(*(ptr))); \
(void)0; })
#endif
#ifndef _ASM_H8300_UNISTD_H_
#define _ASM_H8300_UNISTD_H_
/*
* This file contains the system call numbers.
*/
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_waitpid 7
#define __NR_creat 8
#define __NR_link 9
#define __NR_unlink 10
#define __NR_execve 11
#define __NR_chdir 12
#define __NR_time 13
#define __NR_mknod 14
#define __NR_chmod 15
#define __NR_chown 16
#define __NR_break 17
#define __NR_oldstat 18
#define __NR_lseek 19
#define __NR_getpid 20
#define __NR_mount 21
#define __NR_umount 22
#define __NR_setuid 23
#define __NR_getuid 24
#define __NR_stime 25
#define __NR_ptrace 26
#define __NR_alarm 27
#define __NR_oldfstat 28
#define __NR_pause 29
#define __NR_utime 30
#define __NR_stty 31
#define __NR_gtty 32
#define __NR_access 33
#define __NR_nice 34
#define __NR_ftime 35
#define __NR_sync 36
#define __NR_kill 37
#define __NR_rename 38
#define __NR_mkdir 39
#define __NR_rmdir 40
#define __NR_dup 41
#define __NR_pipe 42
#define __NR_times 43
#define __NR_prof 44
#define __NR_brk 45
#define __NR_setgid 46
#define __NR_getgid 47
#define __NR_signal 48
#define __NR_geteuid 49
#define __NR_getegid 50
#define __NR_acct 51
#define __NR_umount2 52
#define __NR_lock 53
#define __NR_ioctl 54
#define __NR_fcntl 55
#define __NR_mpx 56
#define __NR_setpgid 57
#define __NR_ulimit 58
#define __NR_oldolduname 59
#define __NR_umask 60
#define __NR_chroot 61
#define __NR_ustat 62
#define __NR_dup2 63
#define __NR_getppid 64
#define __NR_getpgrp 65
#define __NR_setsid 66
#define __NR_sigaction 67
#define __NR_sgetmask 68
#define __NR_ssetmask 69
#define __NR_setreuid 70
#define __NR_setregid 71
#define __NR_sigsuspend 72
#define __NR_sigpending 73
#define __NR_sethostname 74
#define __NR_setrlimit 75
#define __NR_getrlimit 76
#define __NR_getrusage 77
#define __NR_gettimeofday 78
#define __NR_settimeofday 79
#define __NR_getgroups 80
#define __NR_setgroups 81
#define __NR_select 82
#define __NR_symlink 83
#define __NR_oldlstat 84
#define __NR_readlink 85
#define __NR_uselib 86
#define __NR_swapon 87
#define __NR_reboot 88
#define __NR_readdir 89
#define __NR_mmap 90
#define __NR_munmap 91
#define __NR_truncate 92
#define __NR_ftruncate 93
#define __NR_fchmod 94
#define __NR_fchown 95
#define __NR_getpriority 96
#define __NR_setpriority 97
#define __NR_profil 98
#define __NR_statfs 99
#define __NR_fstatfs 100
#define __NR_ioperm 101
#define __NR_socketcall 102
#define __NR_syslog 103
#define __NR_setitimer 104
#define __NR_getitimer 105
#define __NR_stat 106
#define __NR_lstat 107
#define __NR_fstat 108
#define __NR_olduname 109
#define __NR_iopl /* 110 */ not supported
#define __NR_vhangup 111
#define __NR_idle /* 112 */ Obsolete
#define __NR_vm86 /* 113 */ not supported
#define __NR_wait4 114
#define __NR_swapoff 115
#define __NR_sysinfo 116
#define __NR_ipc 117
#define __NR_fsync 118
#define __NR_sigreturn 119
#define __NR_clone 120
#define __NR_setdomainname 121
#define __NR_uname 122
#define __NR_cacheflush 123
#define __NR_adjtimex 124
#define __NR_mprotect 125
#define __NR_sigprocmask 126
#define __NR_create_module 127
#define __NR_init_module 128
#define __NR_delete_module 129
#define __NR_get_kernel_syms 130
#define __NR_quotactl 131
#define __NR_getpgid 132
#define __NR_fchdir 133
#define __NR_bdflush 134
#define __NR_sysfs 135
#define __NR_personality 136
#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
#define __NR_setfsuid 138
#define __NR_setfsgid 139
#define __NR__llseek 140
#define __NR_getdents 141
#define __NR__newselect 142
#define __NR_flock 143
#define __NR_msync 144
#define __NR_readv 145
#define __NR_writev 146
#define __NR_getsid 147
#define __NR_fdatasync 148
#define __NR__sysctl 149
#define __NR_mlock 150
#define __NR_munlock 151
#define __NR_mlockall 152
#define __NR_munlockall 153
#define __NR_sched_setparam 154
#define __NR_sched_getparam 155
#define __NR_sched_setscheduler 156
#define __NR_sched_getscheduler 157
#define __NR_sched_yield 158
#define __NR_sched_get_priority_max 159
#define __NR_sched_get_priority_min 160
#define __NR_sched_rr_get_interval 161
#define __NR_nanosleep 162
#define __NR_mremap 163
#define __NR_setresuid 164
#define __NR_getresuid 165
#define __NR_getpagesize 166
#define __NR_query_module 167
#define __NR_poll 168
#define __NR_nfsservctl 169
#define __NR_setresgid 170
#define __NR_getresgid 171
#define __NR_prctl 172
#define __NR_rt_sigreturn 173
#define __NR_rt_sigaction 174
#define __NR_rt_sigprocmask 175
#define __NR_rt_sigpending 176
#define __NR_rt_sigtimedwait 177
#define __NR_rt_sigqueueinfo 178
#define __NR_rt_sigsuspend 179
#define __NR_pread64 180
#define __NR_pwrite64 181
#define __NR_lchown 182
#define __NR_getcwd 183
#define __NR_capget 184
#define __NR_capset 185
#define __NR_sigaltstack 186
#define __NR_sendfile 187
#define __NR_getpmsg 188 /* some people actually want streams */
#define __NR_putpmsg 189 /* some people actually want streams */
#define __NR_vfork 190
#define __NR_ugetrlimit 191
#define __NR_mmap2 192
#define __NR_truncate64 193
#define __NR_ftruncate64 194
#define __NR_stat64 195
#define __NR_lstat64 196
#define __NR_fstat64 197
#define __NR_chown32 198
#define __NR_getuid32 199
#define __NR_getgid32 200
#define __NR_geteuid32 201
#define __NR_getegid32 202
#define __NR_setreuid32 203
#define __NR_setregid32 204
#define __NR_getgroups32 205
#define __NR_setgroups32 206
#define __NR_fchown32 207
#define __NR_setresuid32 208
#define __NR_getresuid32 209
#define __NR_setresgid32 210
#define __NR_getresgid32 211
#define __NR_lchown32 212
#define __NR_setuid32 213
#define __NR_setgid32 214
#define __NR_setfsuid32 215
#define __NR_setfsgid32 216
#define __NR_pivot_root 217
#define __NR_getdents64 220
#define __NR_fcntl64 221
#define __NR_security 223
#define __NR_gettid 224
#define __NR_readahead 225
#define __NR_setxattr 226
#define __NR_lsetxattr 227
#define __NR_fsetxattr 228
#define __NR_getxattr 229
#define __NR_lgetxattr 230
#define __NR_fgetxattr 231
#define __NR_listxattr 232
#define __NR_llistxattr 233
#define __NR_flistxattr 234
#define __NR_removexattr 235
#define __NR_lremovexattr 236
#define __NR_fremovexattr 237
#define __NR_tkill 238
#define __NR_sendfile64 239
#define __NR_futex 240
#define __NR_sched_setaffinity 241
#define __NR_sched_getaffinity 242
#define __NR_set_thread_area 243
#define __NR_get_thread_area 244
#define __NR_io_setup 245
#define __NR_io_destroy 246
#define __NR_io_getevents 247
#define __NR_io_submit 248
#define __NR_io_cancel 249
#define __NR_alloc_hugepages 250
#define __NR_free_hugepages 251
#define __NR_exit_group 252
#define __NR_lookup_dcookie 253
#define __NR_sys_epoll_create 254
#define __NR_sys_epoll_ctl 255
#define __NR_sys_epoll_wait 256
#define __NR_remap_file_pages 257
#define __NR_set_tid_address 258
#define __NR_timer_create 259
#define __NR_timer_settime (__NR_timer_create+1)
#define __NR_timer_gettime (__NR_timer_create+2)
#define __NR_timer_getoverrun (__NR_timer_create+3)
#define __NR_timer_delete (__NR_timer_create+4)
#define __NR_clock_settime (__NR_timer_create+5)
#define __NR_clock_gettime (__NR_timer_create+6)
#define __NR_clock_getres (__NR_timer_create+7)
#define __NR_clock_nanosleep (__NR_timer_create+8)
#define NR_syscalls 268
/* user-visible error numbers are in the range -1 - -122: see
<asm-m68k/errno.h> */
#define __syscall_return(type, res) \
do { \
if ((unsigned long)(res) >= (unsigned long)(-125)) { \
/* avoid using res which is declared to be in register d0; \
errno might expand to a function call and clobber it. */ \
int __err = -(res); \
errno = __err; \
res = -1; \
} \
return (type) (res); \
} while (0)
#define _syscall0(type, name) \
type name(void) \
{ \
register long __res __asm__("er0"); \
__asm__ __volatile__ ("mov.l %1,er0\n\t" \
"trapa #0\n\t" \
: "=r" (__res) \
: "ir" (__NR_##name) \
: "cc"); \
if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
errno = -__res; \
__res = -1; \
} \
return (type)__res; \
}
#define _syscall1(type, name, atype, a) \
type name(atype a) \
{ \
register long __res __asm__("er0"); \
__asm__ __volatile__ ("mov.l %2, er1\n\t" \
"mov.l %1, er0\n\t" \
"trapa #0\n\t" \
: "=r" (__res) \
: "ir" (__NR_##name), \
"g" ((long)a) \
: "cc", "er1"); \
if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
errno = -__res; \
__res = -1; \
} \
return (type)__res; \
}
#define _syscall2(type, name, atype, a, btype, b) \
type name(atype a, btype b) \
{ \
register long __res __asm__("er0"); \
__asm__ __volatile__ ("mov.l %3, er2\n\t" \
"mov.l %2, er1\n\t" \
"mov.l %1, er0\n\t" \
"trapa #0\n\t" \
: "=r" (__res) \
: "ir" (__NR_##name), \
"g" ((long)a), \
"g" ((long)b) \
: "cc", "er1", "er2"); \
if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
errno = -__res; \
__res = -1; \
} \
return (type)__res; \
}
#define _syscall3(type, name, atype, a, btype, b, ctype, c) \
type name(atype a, btype b, ctype c) \
{ \
register long __res __asm__("er0"); \
__asm__ __volatile__ ("mov.l %4, er3\n\t" \
"mov.l %3, er2\n\t" \
"mov.l %2, er1\n\t" \
"mov.l %1, er0\n\t" \
"trapa #0\n\t" \
: "=r" (__res) \
: "ir" (__NR_##name), \
"g" ((long)a), \
"g" ((long)b), \
"g" ((long)c) \
: "cc", "er1", "er2", "er3"); \
if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
errno = -__res; \
__res = -1; \
} \
return (type)__res; \
}
#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d) \
type name(atype a, btype b, ctype c, dtype d) \
{ \
register long __res __asm__("er0"); \
__asm__ __volatile__ ("mov.l %5, er4\n\t" \
"mov.l %4, er3\n\t" \
"mov.l %3, er2\n\t" \
"mov.l %2, er1\n\t" \
"mov.l %1, er0\n\t" \
"trapa #0\n\t" \
: "=r" (__res) \
: "ir" (__NR_##name), \
"g" ((long)a), \
"g" ((long)b), \
"g" ((long)c), \
"g" ((long)d) \
: "cc", "er1", "er2", "er3", "er4"); \
if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
errno = -__res; \
__res = -1; \
} \
return (type)__res; \
}
#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e) \
type name(atype a, btype b, ctype c, dtype d, etype e) \
{ \
register long __res __asm__("er0"); \
__asm__ __volatile__ ("mov.l %6, er5\n\t" \
"mov.l %5, er4\n\t" \
"mov.l %4, er3\n\t" \
"mov.l %3, er2\n\t" \
"mov.l %2, er1\n\t" \
"mov.l %1, er0\n\t" \
"trapa #0\n\t" \
: "=r" (__res) \
: "ir" (__NR_##name), \
"g" ((long)a), \
"g" ((long)b), \
"g" ((long)c), \
"g" ((long)d), \
"g" ((long)e) \
: "cc", "er1", "er2", "er3", "er4"); \
if ((unsigned long)(__res) >= (unsigned long)(-125)) { \
errno = -__res; \
__res = -1; \
} \
return (type)__res; \
}
#ifdef __KERNEL_SYSCALLS__
/*
* we need this inline - forking from kernel space will result
* in NO COPY ON WRITE (!!!), until an execve is executed. This
* is no problem, but for the stack. This is handled by not letting
* main() use the stack at all after fork(). Thus, no function
* calls - which means inline code for fork too, as otherwise we
* would use the stack upon exit from 'fork()'.
*
* Actually only pause and fork are needed inline, so that there
* won't be any messing with the stack from main(), but we define
* some others too.
*/
#define __NR__exit __NR_exit
static inline _syscall0(int,pause)
static inline _syscall0(int,sync)
static inline _syscall0(pid_t,setsid)
static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
static inline _syscall1(int,dup,int,fd)
static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
static inline _syscall1(int,close,int,fd)
static inline _syscall1(int,_exit,int,exitcode)
static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
static inline _syscall1(int,delete_module,const char *,name)
static inline pid_t wait(int * wait_stat)
{
return waitpid(-1,wait_stat,0);
}
#endif
/*
* "Conditional" syscalls
*/
#define cond_syscall(name) \
asm (".weak\t_" #name "\n" \
".set\t_" #name ",_sys_ni_syscall");
#endif /* _ASM_H8300_UNISTD_H_ */
#ifndef _H8300_USER_H
#define _H8300_USER_H
#include <asm/page.h>
/* Core file format: The core file is written in such a way that gdb
can understand it and provide useful information to the user (under
linux we use the 'trad-core' bfd). There are quite a number of
obstacles to being able to view the contents of the floating point
registers, and until these are solved you will not be able to view the
contents of them. Actually, you can read in the core file and look at
the contents of the user struct to find out what the floating point
registers contain.
The actual file contents are as follows:
UPAGE: 1 page consisting of a user struct that tells gdb what is present
in the file. Directly after this is a copy of the task_struct, which
is currently not used by gdb, but it may come in useful at some point.
All of the registers are stored as part of the upage. The upage should
always be only one page.
DATA: The data area is stored. We use current->end_text to
current->brk to pick up all of the user variables, plus any memory
that may have been malloced. No attempt is made to determine if a page
is demand-zero or if a page is totally unused, we just cover the entire
range. All of the addresses are rounded in such a way that an integral
number of pages is written.
STACK: We need the stack information in order to get a meaningful
backtrace. We need to write the data from (esp) to
current->start_stack, so we round each of these off in order to be able
to write an integer number of pages.
The minimum core file size is 3 pages, or 12288 bytes.
*/
/* This is the old layout of "struct pt_regs" as of Linux 1.x, and
is still the layout used by user (the new pt_regs doesn't have
all registers). */
struct user_regs_struct {
long er1,er2,er3,er4,er5,er6;
long er0;
long usp;
long orig_er0;
short ccr;
long pc;
};
/* When the kernel dumps core, it starts by dumping the user struct -
this will be used by gdb to figure out where the data and stack segments
are within the file, and what virtual addresses to use. */
struct user{
/* We start with the registers, to mimic the way that "memory" is returned
from the ptrace(3,...) function. */
struct user_regs_struct regs; /* Where the registers are actually stored */
/* ptrace does not yet supply these. Someday.... */
/* The rest of this junk is to help gdb figure out what goes where */
unsigned long int u_tsize; /* Text segment size (pages). */
unsigned long int u_dsize; /* Data segment size (pages). */
unsigned long int u_ssize; /* Stack segment size (pages). */
unsigned long start_code; /* Starting virtual address of text. */
unsigned long start_stack; /* Starting virtual address of stack area.
This is actually the bottom of the stack,
the top of the stack is always found in the
esp register. */
long int signal; /* Signal that caused the core dump. */
int reserved; /* No longer used */
struct user_regs_struct *u_ar0;
/* Used by gdb to help find the values for */
/* the registers. */
unsigned long magic; /* To uniquely identify a core file */
char u_comm[32]; /* User command that was responsible */
};
#define NBPG PAGE_SIZE
#define UPAGES 1
#define HOST_TEXT_START_ADDR (u.start_code)
#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
#endif
#ifndef __H8300_VIRT_CONVERT__
#define __H8300_VIRT_CONVERT__
/*
* Macros used for converting between virtual and physical mappings.
*/
#ifdef __KERNEL__
#include <linux/config.h>
#include <asm/setup.h>
#include <asm/page.h>
#define mm_ptov(vaddr) ((void *) (vaddr))
#define mm_vtop(vaddr) ((unsigned long) (vaddr))
#define phys_to_virt(vaddr) ((void *) (vaddr))
#define virt_to_phys(vaddr) ((unsigned long) (vaddr))
#define virt_to_bus virt_to_phys
#define bus_to_virt phys_to_virt
#endif
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment