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