Changes for v3
- Fix clone
- Add dma functions
- Add missing library
- Fix various errors
Changes for v2
- Use Common Clock Framework
- Use common unistd.h
- Use common ptrace function
- clocksource driver move to drivers/clocksource
- some cleanup
Changes for latest relase (v3.12)
- standard ELF toolchain (h8300-linux)
- use common driver support
- exception handling fix
- too many cleanup
git repository
git://git.sourceforge.jp/gitroot/uclinux-h8/linux.git h8300
Yoshinori Sato (15):
h8300: Assembly headers.
h8300: UAPI headers
h8300: Exception and Interrupt handling
h8300: kernel booting
h8300: Process and signal
h8300 CPU depend helpers
h8300: miscellaneous functions
h8300: Memory management
h8300: library functions
h8300: Build scripts
h8300: clock driver
h8300: clocksource
h8300: configs
serial: Add h8300
Add ELF machine
arch/h8300/Kconfig | 119 ++++++++
arch/h8300/Kconfig.cpu | 136 ++++++++++
arch/h8300/Kconfig.debug | 23 ++
arch/h8300/Makefile | 45 ++++
arch/h8300/boot/Makefile | 27 ++
arch/h8300/boot/compressed/Makefile | 37 +++
arch/h8300/boot/compressed/head.S | 48 ++++
arch/h8300/boot/compressed/misc.c | 74 +++++
arch/h8300/boot/compressed/vmlinux.lds | 32 +++
arch/h8300/boot/compressed/vmlinux.scr | 9 +
arch/h8300/configs/h8300h-sim_defconfig | 54 ++++
arch/h8300/configs/h8s-sim_defconfig | 56 ++++
arch/h8300/include/asm/Kbuild | 65 +++++
arch/h8300/include/asm/asm-offsets.h | 1 +
arch/h8300/include/asm/atomic.h | 159 +++++++++++
arch/h8300/include/asm/bitops.h | 185 +++++++++++++
arch/h8300/include/asm/bootparams.h | 17 ++
arch/h8300/include/asm/bug.h | 12 +
arch/h8300/include/asm/cache.h | 11 +
arch/h8300/include/asm/checksum.h | 102 +++++++
arch/h8300/include/asm/cmpxchg.h | 65 +++++
arch/h8300/include/asm/cputime.h | 6 +
arch/h8300/include/asm/delay.h | 38 +++
arch/h8300/include/asm/device.h | 7 +
arch/h8300/include/asm/dma-mapping.h | 121 +++++++++
arch/h8300/include/asm/elf.h | 101 +++++++
arch/h8300/include/asm/emergency-restart.h | 6 +
arch/h8300/include/asm/flat.h | 27 ++
arch/h8300/include/asm/io.h | 372 +++++++++++++++++++++++++
arch/h8300/include/asm/irq.h | 26 ++
arch/h8300/include/asm/irqflags.h | 92 +++++++
arch/h8300/include/asm/mc146818rtc.h | 9 +
arch/h8300/include/asm/mutex.h | 9 +
arch/h8300/include/asm/page.h | 11 +
arch/h8300/include/asm/page_offset.h | 3 +
arch/h8300/include/asm/pci.h | 19 ++
arch/h8300/include/asm/pgtable.h | 49 ++++
arch/h8300/include/asm/processor.h | 144 ++++++++++
arch/h8300/include/asm/ptrace.h | 36 +++
arch/h8300/include/asm/segment.h | 49 ++++
arch/h8300/include/asm/sh_bios.h | 33 +++
arch/h8300/include/asm/signal.h | 24 ++
arch/h8300/include/asm/smp.h | 1 +
arch/h8300/include/asm/spinlock.h | 6 +
arch/h8300/include/asm/string.h | 17 ++
arch/h8300/include/asm/switch_to.h | 51 ++++
arch/h8300/include/asm/syscall.h | 56 ++++
arch/h8300/include/asm/thread_info.h | 119 ++++++++
arch/h8300/include/asm/timer.h | 31 +++
arch/h8300/include/asm/timex.h | 19 ++
arch/h8300/include/asm/tlb.h | 8 +
arch/h8300/include/asm/topology.h | 6 +
arch/h8300/include/asm/traps.h | 31 +++
arch/h8300/include/asm/uaccess.h | 145 ++++++++++
arch/h8300/include/asm/unaligned.h | 11 +
arch/h8300/include/asm/user.h | 74 +++++
arch/h8300/include/uapi/asm/Kbuild | 29 ++
arch/h8300/include/uapi/asm/auxvec.h | 4 +
arch/h8300/include/uapi/asm/byteorder.h | 6 +
arch/h8300/include/uapi/asm/ptrace.h | 42 +++
arch/h8300/include/uapi/asm/sigcontext.h | 18 ++
arch/h8300/include/uapi/asm/signal.h | 115 ++++++++
arch/h8300/include/uapi/asm/swab.h | 1 +
arch/h8300/include/uapi/asm/unistd.h | 3 +
arch/h8300/kernel/Makefile | 16 ++
arch/h8300/kernel/asm-offsets.c | 60 +++++
arch/h8300/kernel/cpu/Makefile | 5 +
arch/h8300/kernel/cpu/h83069/Makefile | 1 +
arch/h8300/kernel/cpu/h83069/setup.c | 202 ++++++++++++++
arch/h8300/kernel/cpu/h8s2678/Makefile | 1 +
arch/h8300/kernel/cpu/h8s2678/setup.c | 161 +++++++++++
arch/h8300/kernel/cpu/irq_h.c | 62 +++++
arch/h8300/kernel/cpu/irq_s.c | 70 +++++
arch/h8300/kernel/cpu/ptrace_h.c | 256 ++++++++++++++++++
arch/h8300/kernel/cpu/ptrace_s.c | 42 +++
arch/h8300/kernel/dma.c | 94 +++++++
arch/h8300/kernel/entry.S | 418 +++++++++++++++++++++++++++++
arch/h8300/kernel/h8300_ksyms.c | 34 +++
arch/h8300/kernel/head_ram.S | 60 +++++
arch/h8300/kernel/head_rom.S | 108 ++++++++
arch/h8300/kernel/irq.c | 106 ++++++++
arch/h8300/kernel/module.c | 70 +++++
arch/h8300/kernel/process.c | 170 ++++++++++++
arch/h8300/kernel/ptrace.c | 203 ++++++++++++++
arch/h8300/kernel/setup.c | 174 ++++++++++++
arch/h8300/kernel/signal.c | 326 ++++++++++++++++++++++
arch/h8300/kernel/sim-console.c | 79 ++++++
arch/h8300/kernel/syscalls.c | 14 +
arch/h8300/kernel/traps.c | 166 ++++++++++++
arch/h8300/kernel/vmlinux.lds.S | 85 ++++++
arch/h8300/lib/Makefile | 7 +
arch/h8300/lib/abs.S | 20 ++
arch/h8300/lib/ashldi3.c | 58 ++++
arch/h8300/lib/ashrdi3.c | 59 ++++
arch/h8300/lib/checksum.c | 167 ++++++++++++
arch/h8300/lib/libgcc.h | 76 ++++++
arch/h8300/lib/lshrdi3.c | 58 ++++
arch/h8300/lib/memcpy.S | 85 ++++++
arch/h8300/lib/memset.S | 69 +++++
arch/h8300/lib/moddivsi3.S | 106 ++++++++
arch/h8300/lib/modsi3.S | 106 ++++++++
arch/h8300/lib/muldi3.c | 76 ++++++
arch/h8300/lib/mulsi3.S | 67 +++++
arch/h8300/lib/strncpy.S | 34 +++
arch/h8300/lib/ucmpdi2.c | 18 ++
arch/h8300/lib/udivsi3.S | 107 ++++++++
arch/h8300/mm/Makefile | 5 +
arch/h8300/mm/fault.c | 58 ++++
arch/h8300/mm/init.c | 153 +++++++++++
arch/h8300/mm/kmap.c | 61 +++++
arch/h8300/mm/memory.c | 54 ++++
drivers/clk/Makefile | 1 +
drivers/clk/h8300/Makefile | 2 +
drivers/clk/h8300/clk-h83069.c | 73 +++++
drivers/clk/h8300/clk-h8s2678.c | 165 ++++++++++++
drivers/clocksource/Kconfig | 9 +
drivers/clocksource/Makefile | 3 +
drivers/clocksource/h8300_timer16.c | 335 +++++++++++++++++++++++
drivers/clocksource/h8300_timer8.c | 400 +++++++++++++++++++++++++++
drivers/clocksource/h8300_tpu.c | 205 ++++++++++++++
drivers/tty/serial/Kconfig | 2 +-
include/linux/clk-provider.h | 12 +
include/uapi/linux/elf-em.h | 1 +
123 files changed, 8886 insertions(+), 1 deletion(-)
create mode 100644 arch/h8300/Kconfig
create mode 100644 arch/h8300/Kconfig.cpu
create mode 100644 arch/h8300/Kconfig.debug
create mode 100644 arch/h8300/Makefile
create mode 100644 arch/h8300/boot/Makefile
create mode 100644 arch/h8300/boot/compressed/Makefile
create mode 100644 arch/h8300/boot/compressed/head.S
create mode 100644 arch/h8300/boot/compressed/misc.c
create mode 100644 arch/h8300/boot/compressed/vmlinux.lds
create mode 100644 arch/h8300/boot/compressed/vmlinux.scr
create mode 100644 arch/h8300/configs/h8300h-sim_defconfig
create mode 100644 arch/h8300/configs/h8s-sim_defconfig
create mode 100644 arch/h8300/include/asm/Kbuild
create mode 100644 arch/h8300/include/asm/asm-offsets.h
create mode 100644 arch/h8300/include/asm/atomic.h
create mode 100644 arch/h8300/include/asm/bitops.h
create mode 100644 arch/h8300/include/asm/bootparams.h
create mode 100644 arch/h8300/include/asm/bug.h
create mode 100644 arch/h8300/include/asm/cache.h
create mode 100644 arch/h8300/include/asm/checksum.h
create mode 100644 arch/h8300/include/asm/cmpxchg.h
create mode 100644 arch/h8300/include/asm/cputime.h
create mode 100644 arch/h8300/include/asm/delay.h
create mode 100644 arch/h8300/include/asm/device.h
create mode 100644 arch/h8300/include/asm/dma-mapping.h
create mode 100644 arch/h8300/include/asm/elf.h
create mode 100644 arch/h8300/include/asm/emergency-restart.h
create mode 100644 arch/h8300/include/asm/flat.h
create mode 100644 arch/h8300/include/asm/io.h
create mode 100644 arch/h8300/include/asm/irq.h
create mode 100644 arch/h8300/include/asm/irqflags.h
create mode 100644 arch/h8300/include/asm/mc146818rtc.h
create mode 100644 arch/h8300/include/asm/mutex.h
create mode 100644 arch/h8300/include/asm/page.h
create mode 100644 arch/h8300/include/asm/page_offset.h
create mode 100644 arch/h8300/include/asm/pci.h
create mode 100644 arch/h8300/include/asm/pgtable.h
create mode 100644 arch/h8300/include/asm/processor.h
create mode 100644 arch/h8300/include/asm/ptrace.h
create mode 100644 arch/h8300/include/asm/segment.h
create mode 100644 arch/h8300/include/asm/sh_bios.h
create mode 100644 arch/h8300/include/asm/signal.h
create mode 100644 arch/h8300/include/asm/smp.h
create mode 100644 arch/h8300/include/asm/spinlock.h
create mode 100644 arch/h8300/include/asm/string.h
create mode 100644 arch/h8300/include/asm/switch_to.h
create mode 100644 arch/h8300/include/asm/syscall.h
create mode 100644 arch/h8300/include/asm/thread_info.h
create mode 100644 arch/h8300/include/asm/timer.h
create mode 100644 arch/h8300/include/asm/timex.h
create mode 100644 arch/h8300/include/asm/tlb.h
create mode 100644 arch/h8300/include/asm/topology.h
create mode 100644 arch/h8300/include/asm/traps.h
create mode 100644 arch/h8300/include/asm/uaccess.h
create mode 100644 arch/h8300/include/asm/unaligned.h
create mode 100644 arch/h8300/include/asm/user.h
create mode 100644 arch/h8300/include/uapi/asm/Kbuild
create mode 100644 arch/h8300/include/uapi/asm/auxvec.h
create mode 100644 arch/h8300/include/uapi/asm/byteorder.h
create mode 100644 arch/h8300/include/uapi/asm/ptrace.h
create mode 100644 arch/h8300/include/uapi/asm/sigcontext.h
create mode 100644 arch/h8300/include/uapi/asm/signal.h
create mode 100644 arch/h8300/include/uapi/asm/swab.h
create mode 100644 arch/h8300/include/uapi/asm/unistd.h
create mode 100644 arch/h8300/kernel/Makefile
create mode 100644 arch/h8300/kernel/asm-offsets.c
create mode 100644 arch/h8300/kernel/cpu/Makefile
create mode 100644 arch/h8300/kernel/cpu/h83069/Makefile
create mode 100644 arch/h8300/kernel/cpu/h83069/setup.c
create mode 100644 arch/h8300/kernel/cpu/h8s2678/Makefile
create mode 100644 arch/h8300/kernel/cpu/h8s2678/setup.c
create mode 100644 arch/h8300/kernel/cpu/irq_h.c
create mode 100644 arch/h8300/kernel/cpu/irq_s.c
create mode 100644 arch/h8300/kernel/cpu/ptrace_h.c
create mode 100644 arch/h8300/kernel/cpu/ptrace_s.c
create mode 100644 arch/h8300/kernel/dma.c
create mode 100644 arch/h8300/kernel/entry.S
create mode 100644 arch/h8300/kernel/h8300_ksyms.c
create mode 100644 arch/h8300/kernel/head_ram.S
create mode 100644 arch/h8300/kernel/head_rom.S
create mode 100644 arch/h8300/kernel/irq.c
create mode 100644 arch/h8300/kernel/module.c
create mode 100644 arch/h8300/kernel/process.c
create mode 100644 arch/h8300/kernel/ptrace.c
create mode 100644 arch/h8300/kernel/setup.c
create mode 100644 arch/h8300/kernel/signal.c
create mode 100644 arch/h8300/kernel/sim-console.c
create mode 100644 arch/h8300/kernel/syscalls.c
create mode 100644 arch/h8300/kernel/traps.c
create mode 100644 arch/h8300/kernel/vmlinux.lds.S
create mode 100644 arch/h8300/lib/Makefile
create mode 100644 arch/h8300/lib/abs.S
create mode 100644 arch/h8300/lib/ashldi3.c
create mode 100644 arch/h8300/lib/ashrdi3.c
create mode 100644 arch/h8300/lib/checksum.c
create mode 100644 arch/h8300/lib/libgcc.h
create mode 100644 arch/h8300/lib/lshrdi3.c
create mode 100644 arch/h8300/lib/memcpy.S
create mode 100644 arch/h8300/lib/memset.S
create mode 100644 arch/h8300/lib/moddivsi3.S
create mode 100644 arch/h8300/lib/modsi3.S
create mode 100644 arch/h8300/lib/muldi3.c
create mode 100644 arch/h8300/lib/mulsi3.S
create mode 100644 arch/h8300/lib/strncpy.S
create mode 100644 arch/h8300/lib/ucmpdi2.c
create mode 100644 arch/h8300/lib/udivsi3.S
create mode 100644 arch/h8300/mm/Makefile
create mode 100644 arch/h8300/mm/fault.c
create mode 100644 arch/h8300/mm/init.c
create mode 100644 arch/h8300/mm/kmap.c
create mode 100644 arch/h8300/mm/memory.c
create mode 100644 drivers/clk/h8300/Makefile
create mode 100644 drivers/clk/h8300/clk-h83069.c
create mode 100644 drivers/clk/h8300/clk-h8s2678.c
create mode 100644 drivers/clocksource/h8300_timer16.c
create mode 100644 drivers/clocksource/h8300_timer8.c
create mode 100644 drivers/clocksource/h8300_tpu.c
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
arch/h8300/include/asm/Kbuild | 65 +++++
arch/h8300/include/asm/asm-offsets.h | 1 +
arch/h8300/include/asm/atomic.h | 159 ++++++++++++
arch/h8300/include/asm/bitops.h | 185 ++++++++++++++
arch/h8300/include/asm/bootparams.h | 17 ++
arch/h8300/include/asm/bug.h | 12 +
arch/h8300/include/asm/cache.h | 11 +
arch/h8300/include/asm/checksum.h | 102 ++++++++
arch/h8300/include/asm/cmpxchg.h | 65 +++++
arch/h8300/include/asm/cputime.h | 6 +
arch/h8300/include/asm/delay.h | 38 +++
arch/h8300/include/asm/device.h | 7 +
arch/h8300/include/asm/dma-mapping.h | 121 ++++++++++
arch/h8300/include/asm/elf.h | 101 ++++++++
arch/h8300/include/asm/emergency-restart.h | 6 +
arch/h8300/include/asm/flat.h | 27 +++
arch/h8300/include/asm/io.h | 372 +++++++++++++++++++++++++++++
arch/h8300/include/asm/irq.h | 26 ++
arch/h8300/include/asm/irqflags.h | 92 +++++++
arch/h8300/include/asm/mc146818rtc.h | 9 +
arch/h8300/include/asm/mutex.h | 9 +
arch/h8300/include/asm/page.h | 11 +
arch/h8300/include/asm/page_offset.h | 3 +
arch/h8300/include/asm/pci.h | 19 ++
arch/h8300/include/asm/pgtable.h | 49 ++++
arch/h8300/include/asm/processor.h | 144 +++++++++++
arch/h8300/include/asm/ptrace.h | 36 +++
arch/h8300/include/asm/segment.h | 49 ++++
arch/h8300/include/asm/sh_bios.h | 33 +++
arch/h8300/include/asm/signal.h | 24 ++
arch/h8300/include/asm/smp.h | 1 +
arch/h8300/include/asm/spinlock.h | 6 +
arch/h8300/include/asm/string.h | 17 ++
arch/h8300/include/asm/switch_to.h | 51 ++++
arch/h8300/include/asm/syscall.h | 56 +++++
arch/h8300/include/asm/thread_info.h | 119 +++++++++
arch/h8300/include/asm/timer.h | 31 +++
arch/h8300/include/asm/timex.h | 19 ++
arch/h8300/include/asm/tlb.h | 8 +
arch/h8300/include/asm/topology.h | 6 +
arch/h8300/include/asm/traps.h | 31 +++
arch/h8300/include/asm/uaccess.h | 145 +++++++++++
arch/h8300/include/asm/unaligned.h | 11 +
arch/h8300/include/asm/user.h | 74 ++++++
44 files changed, 2374 insertions(+)
create mode 100644 arch/h8300/include/asm/Kbuild
create mode 100644 arch/h8300/include/asm/asm-offsets.h
create mode 100644 arch/h8300/include/asm/atomic.h
create mode 100644 arch/h8300/include/asm/bitops.h
create mode 100644 arch/h8300/include/asm/bootparams.h
create mode 100644 arch/h8300/include/asm/bug.h
create mode 100644 arch/h8300/include/asm/cache.h
create mode 100644 arch/h8300/include/asm/checksum.h
create mode 100644 arch/h8300/include/asm/cmpxchg.h
create mode 100644 arch/h8300/include/asm/cputime.h
create mode 100644 arch/h8300/include/asm/delay.h
create mode 100644 arch/h8300/include/asm/device.h
create mode 100644 arch/h8300/include/asm/dma-mapping.h
create mode 100644 arch/h8300/include/asm/elf.h
create mode 100644 arch/h8300/include/asm/emergency-restart.h
create mode 100644 arch/h8300/include/asm/flat.h
create mode 100644 arch/h8300/include/asm/io.h
create mode 100644 arch/h8300/include/asm/irq.h
create mode 100644 arch/h8300/include/asm/irqflags.h
create mode 100644 arch/h8300/include/asm/mc146818rtc.h
create mode 100644 arch/h8300/include/asm/mutex.h
create mode 100644 arch/h8300/include/asm/page.h
create mode 100644 arch/h8300/include/asm/page_offset.h
create mode 100644 arch/h8300/include/asm/pci.h
create mode 100644 arch/h8300/include/asm/pgtable.h
create mode 100644 arch/h8300/include/asm/processor.h
create mode 100644 arch/h8300/include/asm/ptrace.h
create mode 100644 arch/h8300/include/asm/segment.h
create mode 100644 arch/h8300/include/asm/sh_bios.h
create mode 100644 arch/h8300/include/asm/signal.h
create mode 100644 arch/h8300/include/asm/smp.h
create mode 100644 arch/h8300/include/asm/spinlock.h
create mode 100644 arch/h8300/include/asm/string.h
create mode 100644 arch/h8300/include/asm/switch_to.h
create mode 100644 arch/h8300/include/asm/syscall.h
create mode 100644 arch/h8300/include/asm/thread_info.h
create mode 100644 arch/h8300/include/asm/timer.h
create mode 100644 arch/h8300/include/asm/timex.h
create mode 100644 arch/h8300/include/asm/tlb.h
create mode 100644 arch/h8300/include/asm/topology.h
create mode 100644 arch/h8300/include/asm/traps.h
create mode 100644 arch/h8300/include/asm/uaccess.h
create mode 100644 arch/h8300/include/asm/unaligned.h
create mode 100644 arch/h8300/include/asm/user.h
diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild
new file mode 100644
index 0000000..8bab926
--- /dev/null
+++ b/arch/h8300/include/asm/Kbuild
@@ -0,0 +1,65 @@
+generic-y += barrier.h
+generic-y += bitsperlong.h
+generic-y += bugs.h
+generic-y += cacheflush.h
+generic-y += clkdev.h
+generic-y += cputime.h
+generic-y += current.h
+generic-y += div64.h
+generic-y += dma.h
+generic-y += emergency-restart.h
+generic-y += errno.h
+generic-y += exec.h
+generic-y += fb.h
+generic-y += fcntl.h
+generic-y += ftrace.h
+generic-y += futex.h
+generic-y += hardirq.h
+generic-y += hash.h
+generic-y += hw_irq.h
+generic-y += ioctl.h
+generic-y += ioctls.h
+generic-y += ipcbuf.h
+generic-y += irq_regs.h
+generic-y += irq_work.h
+generic-y += kdebug.h
+generic-y += kmap_types.h
+generic-y += kvm_para.h
+generic-y += linkage.h
+generic-y += local.h
+generic-y += local64.h
+generic-y += mcs_spinlock.h
+generic-y += mman.h
+generic-y += mmu.h
+generic-y += mmu_context.h
+generic-y += module.h
+generic-y += msgbuf.h
+generic-y += param.h
+generic-y += parport.h
+generic-y += percpu.h
+generic-y += pgalloc.h
+generic-y += poll.h
+generic-y += posix_types.h
+generic-y += preempt.h
+generic-y += resource.h
+generic-y += scatterlist.h
+generic-y += sections.h
+generic-y += sembuf.h
+generic-y += serial.h
+generic-y += setup.h
+generic-y += shmbuf.h
+generic-y += shmparam.h
+generic-y += siginfo.h
+generic-y += sizes.h
+generic-y += socket.h
+generic-y += sockios.h
+generic-y += stat.h
+generic-y += statfs.h
+generic-y += termbits.h
+generic-y += termios.h
+generic-y += tlbflush.h
+generic-y += trace_clock.h
+generic-y += types.h
+generic-y += ucontext.h
+generic-y += vga.h
+generic-y += xor.h
diff --git a/arch/h8300/include/asm/asm-offsets.h b/arch/h8300/include/asm/asm-offsets.h
new file mode 100644
index 0000000..d370ee3
--- /dev/null
+++ b/arch/h8300/include/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/arch/h8300/include/asm/atomic.h b/arch/h8300/include/asm/atomic.h
new file mode 100644
index 0000000..f50a7de
--- /dev/null
+++ b/arch/h8300/include/asm/atomic.h
@@ -0,0 +1,159 @@
+#ifndef __ARCH_H8300_ATOMIC__
+#define __ARCH_H8300_ATOMIC__
+
+#include <linux/types.h>
+#include <asm/cmpxchg.h>
+
+/*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc..
+ */
+
+#define ATOMIC_INIT(i) { (i) }
+
+#define atomic_read(v) ACCESS_ONCE((v)->counter)
+#define atomic_set(v, i) (((v)->counter) = i)
+
+#include <linux/kernel.h>
+
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+ unsigned long flags;
+ int ret;
+
+ local_irq_save(flags);
+ ret = v->counter += i;
+ local_irq_restore(flags);
+ return ret;
+}
+
+#define atomic_add(i, v) atomic_add_return(i, v)
+#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+ unsigned long flags;
+ int ret;
+
+ local_irq_save(flags);
+ ret = v->counter -= i;
+ local_irq_restore(flags);
+ return ret;
+}
+
+#define atomic_sub(i, v) atomic_sub_return(i, v)
+#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
+
+static inline int atomic_inc_return(atomic_t *v)
+{
+ unsigned long flags;
+ int ret;
+
+ local_irq_save(flags);
+ v->counter++;
+ ret = v->counter;
+ local_irq_restore(flags);
+ return ret;
+}
+
+#define atomic_inc(v) atomic_inc_return(v)
+
+/*
+ * atomic_inc_and_test - increment and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
+
+static inline int atomic_dec_return(atomic_t *v)
+{
+ unsigned long flags;
+ int ret;
+
+ local_irq_save(flags);
+ --v->counter;
+ ret = v->counter;
+ local_irq_restore(flags);
+ return ret;
+}
+
+#define atomic_dec(v) atomic_dec_return(v)
+
+static inline int atomic_dec_and_test(atomic_t *v)
+{
+ unsigned long flags;
+ int ret;
+
+ local_irq_save(flags);
+ --v->counter;
+ ret = v->counter;
+ local_irq_restore(flags);
+ return ret == 0;
+}
+
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+ int ret;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ ret = v->counter;
+ if (likely(ret == old))
+ v->counter = new;
+ local_irq_restore(flags);
+ return ret;
+}
+
+static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int ret;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ ret = v->counter;
+ if (ret != u)
+ v->counter += a;
+ local_irq_restore(flags);
+ return ret;
+}
+
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *v)
+{
+ unsigned char ccr;
+ unsigned long tmp;
+
+ __asm__ __volatile__("stc ccr,%w3\n\t"
+ "orc #0x80,ccr\n\t"
+ "mov.l %0,%1\n\t"
+ "and.l %2,%1\n\t"
+ "mov.l %1,%0\n\t"
+ "ldc %w3,ccr"
+ : "=m"(*v), "=r"(tmp)
+ : "g"(~(mask)), "r"(ccr));
+}
+
+static inline void atomic_set_mask(unsigned long mask, unsigned long *v)
+{
+ unsigned char ccr;
+ unsigned long tmp;
+
+ __asm__ __volatile__("stc ccr,%w3\n\t"
+ "orc #0x80,ccr\n\t"
+ "mov.l %0,%1\n\t"
+ "or.l %2,%1\n\t"
+ "mov.l %1,%0\n\t"
+ "ldc %w3,ccr"
+ : "=m"(*v), "=r"(tmp)
+ : "g"(~(mask)), "r"(ccr));
+}
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec() barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc() barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+#endif /* __ARCH_H8300_ATOMIC __ */
diff --git a/arch/h8300/include/asm/bitops.h b/arch/h8300/include/asm/bitops.h
new file mode 100644
index 0000000..05999ab
--- /dev/null
+++ b/arch/h8300/include/asm/bitops.h
@@ -0,0 +1,185 @@
+#ifndef _H8300_BITOPS_H
+#define _H8300_BITOPS_H
+
+/*
+ * Copyright 1992, Linus Torvalds.
+ * Copyright 2002, Yoshinori Sato
+ */
+
+#include <linux/compiler.h>
+
+#ifdef __KERNEL__
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
+/*
+ * Function prototypes to keep gcc -Wall happy
+ */
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+static inline unsigned long ffz(unsigned long word)
+{
+ unsigned long result;
+
+ result = -1;
+ __asm__("1:\n\t"
+ "shlr.l %2\n\t"
+ "adds #1,%0\n\t"
+ "bcs 1b"
+ : "=r"(result)
+ : "0"(result), "r"(word));
+ return result;
+}
+
+#define H8300_GEN_BITOP(FNAME, OP) \
+static inline void FNAME(int nr, volatile unsigned long *addr) \
+{ \
+ unsigned char *b_addr; \
+ unsigned char bit = nr & 7; \
+ \
+ b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3); \
+ if (__builtin_constant_p(nr)) { \
+ __asm__(OP " %1,%0" : "+WU"(*b_addr) : "i"(nr & 7)); \
+ } else { \
+ __asm__(OP " %s1,%0" : "+WU"(*b_addr) : "r"(bit)); \
+ } \
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit() barrier()
+#define smp_mb__after_clear_bit() barrier()
+
+H8300_GEN_BITOP(set_bit, "bset")
+H8300_GEN_BITOP(clear_bit, "bclr")
+H8300_GEN_BITOP(change_bit, "bnot")
+#define __set_bit(nr, addr) set_bit((nr), (addr))
+#define __clear_bit(nr, addr) clear_bit((nr), (addr))
+#define __change_bit(nr, addr) change_bit((nr), (addr))
+
+#undef H8300_GEN_BITOP
+
+static inline int test_bit(int nr, const unsigned long *addr)
+{
+ int ret = 0;
+ unsigned char *b_addr;
+ unsigned char bit = nr & 7;
+
+ b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3);
+ if (__builtin_constant_p(nr)) {
+ __asm__("bld %Z2,%1\n\t"
+ "rotxl %0\n\t"
+ : "=r"(ret)
+ : "WU"(*b_addr), "i"(nr & 7), "0"(ret) : "cc");
+ } else {
+ __asm__("btst %w2,%1\n\t"
+ "beq 1f\n\t"
+ "inc.l #1,%0\n"
+ "1:"
+ : "=r"(ret)
+ : "WU"(*b_addr), "r"(bit), "0"(ret) : "cc");
+ }
+ return ret;
+}
+
+#define __test_bit(nr, addr) test_bit(nr, addr)
+
+#define H8300_GEN_TEST_BITOP(FNNAME, OP) \
+static inline int FNNAME(int nr, void *addr) \
+{ \
+ int retval = 0; \
+ char ccrsave; \
+ unsigned char *b_addr; \
+ unsigned char bit = nr & 7; \
+ \
+ b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3); \
+ if (__builtin_constant_p(nr)) { \
+ __asm__("stc ccr,%s2\n\t" \
+ "orc #0x80,ccr\n\t" \
+ "bld %4,%1\n\t" \
+ OP " %4,%1\n\t" \
+ "rotxl.l %0\n\t" \
+ "ldc %s2,ccr" \
+ : "=r"(retval), "+WU" (*b_addr), "=&r"(ccrsave) \
+ : "0"(retval), "i"(nr & 7) : "cc"); \
+ } else { \
+ __asm__("stc ccr,%t3\n\t" \
+ "orc #0x80,ccr\n\t" \
+ "btst %s3,%1\n\t" \
+ OP " %s3,%1\n\t" \
+ "beq 1f\n\t" \
+ "inc.l #1,%0\n\t" \
+ "1:\n" \
+ "ldc %t3,ccr" \
+ : "=r"(retval), "+WU" (*b_addr) \
+ : "0" (retval), "r"(bit) : "cc"); \
+ } \
+ return retval; \
+} \
+ \
+static inline int __ ## FNNAME(int nr, void *addr) \
+{ \
+ int retval = 0; \
+ unsigned char *b_addr; \
+ unsigned char bit = nr & 7; \
+ \
+ b_addr = (unsigned char *)addr + ((nr >> 3) ^ 3); \
+ if (__builtin_constant_p(nr)) { \
+ __asm__("bld %3,%1\n\t" \
+ OP " %3,%1\n\t" \
+ "rotxl.l %0\n\t" \
+ : "=r"(retval), "+WU"(*b_addr) \
+ : "0" (retval), "i"(nr & 7)); \
+ } else { \
+ __asm__("btst %s3,%1\n\t" \
+ OP " %s3,%1\n\t" \
+ "beq 1f\n\t" \
+ "inc.l #1,%0\n\t" \
+ "1:" \
+ : "=r"(retval), "+WU"(*b_addr) \
+ : "0" (retval), "r"(bit)); \
+ } \
+ return retval; \
+}
+
+H8300_GEN_TEST_BITOP(test_and_set_bit, "bset")
+H8300_GEN_TEST_BITOP(test_and_clear_bit, "bclr")
+H8300_GEN_TEST_BITOP(test_and_change_bit, "bnot")
+#undef H8300_GEN_TEST_BITOP
+
+#include <asm-generic/bitops/ffs.h>
+
+static inline unsigned long __ffs(unsigned long word)
+{
+ unsigned long result;
+
+ result = -1;
+ __asm__("1:\n\t"
+ "shlr.l %2\n\t"
+ "adds #1,%0\n\t"
+ "bcc 1b"
+ : "=r" (result)
+ : "0"(result), "r"(word));
+ return result;
+}
+
+#include <asm-generic/bitops/find.h>
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
+#include <asm-generic/bitops/le.h>
+#include <asm-generic/bitops/ext2-atomic.h>
+
+#endif /* __KERNEL__ */
+
+#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/__fls.h>
+#include <asm-generic/bitops/fls64.h>
+
+#endif /* _H8300_BITOPS_H */
diff --git a/arch/h8300/include/asm/bootparams.h b/arch/h8300/include/asm/bootparams.h
new file mode 100644
index 0000000..6c0b145
--- /dev/null
+++ b/arch/h8300/include/asm/bootparams.h
@@ -0,0 +1,17 @@
+/*
+H8/300 kernel boot parameters
+*/
+
+#ifndef __ASM_H8300_BOOTPARAMS__
+#define __ASM_H8300_BOOTPARAMS__
+
+struct bootparams {
+ short size;
+ unsigned char gpio_ddr[24];
+ unsigned char gpio_use[24];
+ unsigned int clock_freq;
+ unsigned int ram_end;
+ unsigned char *command_line;
+} __packed __aligned(2);
+
+#endif
diff --git a/arch/h8300/include/asm/bug.h b/arch/h8300/include/asm/bug.h
new file mode 100644
index 0000000..1e1be81
--- /dev/null
+++ b/arch/h8300/include/asm/bug.h
@@ -0,0 +1,12 @@
+#ifndef _H8300_BUG_H
+#define _H8300_BUG_H
+
+/* always true */
+#define is_valid_bugaddr(addr) (1)
+
+#include <asm-generic/bug.h>
+
+struct pt_regs;
+extern void die(const char *str, struct pt_regs *fp, unsigned long err);
+
+#endif
diff --git a/arch/h8300/include/asm/cache.h b/arch/h8300/include/asm/cache.h
new file mode 100644
index 0000000..0ef1edc
--- /dev/null
+++ b/arch/h8300/include/asm/cache.h
@@ -0,0 +1,11 @@
+#ifndef __ARCH_H8300_CACHE_H
+#define __ARCH_H8300_CACHE_H
+
+/* bytes per L1 cache line */
+#define L1_CACHE_SHIFT 2
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+
+#define __cacheline_aligned
+#define ____cacheline_aligned
+
+#endif
diff --git a/arch/h8300/include/asm/checksum.h b/arch/h8300/include/asm/checksum.h
new file mode 100644
index 0000000..59e2adc9
--- /dev/null
+++ b/arch/h8300/include/asm/checksum.h
@@ -0,0 +1,102 @@
+#ifndef _H8300_CHECKSUM_H
+#define _H8300_CHECKSUM_H
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+__wsum csum_partial(const void *buff, int len, __wsum sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+__wsum csum_partial_copy_nocheck(const void *src, void *dst,
+ int len, __wsum sum);
+
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
+ int len, __wsum sum, int *csum_err);
+
+__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
+
+
+/*
+ * Fold a partial checksum
+ */
+
+static inline __sum16 csum_fold(__wsum sum)
+{
+ __asm__("add.w %e0,%f0\n\t"
+ "xor.w %e0,%e0\n\t"
+ "rotxl.w %e0\n\t"
+ "add.w %e0,%f0\n\t"
+ "sub.w %e0,%e0\n\t"
+ : "=r"(sum)
+ : "0"(sum));
+ return (__force __sum16)~sum;
+}
+
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+
+static inline __wsum
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
+ unsigned short proto, __wsum sum)
+{
+ int tmp;
+
+ __asm__ ("sub.l %1,%1\n\t"
+ "add.l %3,%0\n\t"
+ "addx #0,%w1\n\t"
+ "add.l %4,%0\n\t"
+ "addx #0,%w1\n\t"
+ "add.l %5,%0\n\t"
+ "addx #0,%w1\n\t"
+ "add.l %1,%0\n\t"
+ "bcc 1f\n\t"
+ "inc.l #1,%0\n"
+ "1:"
+ : "=&r" (sum), "=&r"(tmp)
+ : "0" (sum), "1" (daddr),
+ "r" (saddr), "r" (len + proto));
+ return sum;
+}
+
+static inline __sum16
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
+ unsigned short proto, __wsum sum)
+{
+ return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+extern __sum16 ip_compute_csum(const void *buff, int len);
+
+#endif /* _H8300_CHECKSUM_H */
diff --git a/arch/h8300/include/asm/cmpxchg.h b/arch/h8300/include/asm/cmpxchg.h
new file mode 100644
index 0000000..95fec4c
--- /dev/null
+++ b/arch/h8300/include/asm/cmpxchg.h
@@ -0,0 +1,65 @@
+#ifndef __ARCH_H8300_CMPXCHG__
+#define __ARCH_H8300_CMPXCHG__
+
+#include <linux/irqflags.h>
+
+#define xchg(ptr, x) \
+ ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), \
+ sizeof(*(ptr))))
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((volatile struct __xchg_dummy *)(x))
+
+static inline unsigned long __xchg(unsigned long x,
+ volatile void *ptr, int size)
+{
+ unsigned long tmp, flags;
+
+ local_irq_save(flags);
+
+ switch (size) {
+ case 1:
+ __asm__ __volatile__
+ ("mov.b %2,%0\n\t"
+ "mov.b %1,%2"
+ : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)));
+ break;
+ case 2:
+ __asm__ __volatile__
+ ("mov.w %2,%0\n\t"
+ "mov.w %1,%2"
+ : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)));
+ break;
+ case 4:
+ __asm__ __volatile__
+ ("mov.l %2,%0\n\t"
+ "mov.l %1,%2"
+ : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)));
+ break;
+ default:
+ tmp = 0;
+ }
+ local_irq_restore(flags);
+ return tmp;
+}
+
+#include <asm-generic/cmpxchg-local.h>
+
+/*
+ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
+ * them available.
+ */
+#define cmpxchg_local(ptr, o, n) \
+ ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), \
+ (unsigned long)(o), \
+ (unsigned long)(n), \
+ sizeof(*(ptr))))
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+
+#ifndef CONFIG_SMP
+#include <asm-generic/cmpxchg.h>
+#endif
+
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+#endif /* __ARCH_H8300_CMPXCHG__ */
diff --git a/arch/h8300/include/asm/cputime.h b/arch/h8300/include/asm/cputime.h
new file mode 100644
index 0000000..092e187
--- /dev/null
+++ b/arch/h8300/include/asm/cputime.h
@@ -0,0 +1,6 @@
+#ifndef __H8300_CPUTIME_H
+#define __H8300_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __H8300_CPUTIME_H */
diff --git a/arch/h8300/include/asm/delay.h b/arch/h8300/include/asm/delay.h
new file mode 100644
index 0000000..2bdde59
--- /dev/null
+++ b/arch/h8300/include/asm/delay.h
@@ -0,0 +1,38 @@
+#ifndef _H8300_DELAY_H
+#define _H8300_DELAY_H
+
+#include <asm/param.h>
+
+/*
+ * Copyright (C) 2002 Yoshinori Sato <[email protected]>
+ *
+ * Delay routines, using a pre-computed "loops_per_second" value.
+ */
+
+static inline void __delay(unsigned long loops)
+{
+ __asm__ __volatile__ ("1:\n\t"
+ "dec.l #1,%0\n\t"
+ "bne 1b"
+ : "=r" (loops) : "0"(loops));
+}
+
+/*
+ * Use only for very small delays ( < 1 msec). Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays. This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)
+ */
+
+extern unsigned long loops_per_jiffy;
+
+static inline void udelay(unsigned long usecs)
+{
+ usecs *= 4295; /* 2**32 / 1000000 */
+ usecs /= (loops_per_jiffy*HZ);
+ if (usecs)
+ __delay(usecs);
+}
+
+#endif /* _H8300_DELAY_H */
diff --git a/arch/h8300/include/asm/device.h b/arch/h8300/include/asm/device.h
new file mode 100644
index 0000000..d8f9872
--- /dev/null
+++ b/arch/h8300/include/asm/device.h
@@ -0,0 +1,7 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ */
+#include <asm-generic/device.h>
+
diff --git a/arch/h8300/include/asm/dma-mapping.h b/arch/h8300/include/asm/dma-mapping.h
new file mode 100644
index 0000000..732df62
--- /dev/null
+++ b/arch/h8300/include/asm/dma-mapping.h
@@ -0,0 +1,121 @@
+#ifndef _H8300_DMA_MAPPING_H
+#define _H8300_DMA_MAPPING_H
+
+struct scatterlist;
+
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+ return 1;
+}
+
+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+ return 0;
+}
+
+extern void *dma_alloc_coherent(struct device *, size_t,
+ dma_addr_t *, gfp_t);
+extern void dma_free_coherent(struct device *, size_t,
+ void *, dma_addr_t);
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag,
+ struct dma_attrs *attrs)
+{
+ /* attrs is not supported and ignored */
+ return dma_alloc_coherent(dev, size, dma_handle, flag);
+}
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+ void *cpu_addr, dma_addr_t dma_handle,
+ struct dma_attrs *attrs)
+{
+ /* attrs is not supported and ignored */
+ dma_free_coherent(dev, size, cpu_addr, dma_handle);
+}
+
+static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t flag)
+{
+ return dma_alloc_coherent(dev, size, handle, flag);
+}
+static inline void dma_free_noncoherent(struct device *dev, size_t size,
+ void *addr, dma_addr_t handle)
+{
+ dma_free_coherent(dev, size, addr, handle);
+}
+static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+ enum dma_data_direction dir)
+{
+ /* we use coherent allocation, so not much to do here. */
+}
+
+extern dma_addr_t dma_map_single(struct device *, void *, size_t,
+ enum dma_data_direction);
+static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
+ size_t size, enum dma_data_direction dir)
+{
+}
+
+extern dma_addr_t dma_map_page(struct device *, struct page *,
+ unsigned long, size_t size,
+ enum dma_data_direction);
+static inline void dma_unmap_page(struct device *dev, dma_addr_t address,
+ size_t size, enum dma_data_direction dir)
+{
+}
+
+extern int dma_map_sg(struct device *, struct scatterlist *, int,
+ enum dma_data_direction);
+static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nhwentries, enum dma_data_direction dir)
+{
+}
+
+extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t,
+ enum dma_data_direction);
+extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
+ enum dma_data_direction);
+
+static inline void dma_sync_single_range_for_device(struct device *dev,
+ dma_addr_t dma_handle, unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ /* just sync everything for now */
+ dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
+}
+
+static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+}
+
+static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+}
+
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+ dma_addr_t dma_handle, unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ /* just sync everything for now */
+ dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
+}
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t handle)
+{
+ return 0;
+}
+
+/* drivers/base/dma-mapping.c */
+extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size);
+extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
+ void *cpu_addr, dma_addr_t dma_addr,
+ size_t size);
+
+#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
+#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
+
+#endif
diff --git a/arch/h8300/include/asm/elf.h b/arch/h8300/include/asm/elf.h
new file mode 100644
index 0000000..7d17c19
--- /dev/null
+++ b/arch/h8300/include/asm/elf.h
@@ -0,0 +1,101 @@
+#ifndef __ASM_H8300_ELF_H
+#define __ASM_H8300_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+typedef unsigned long elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_H8_300)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2MSB
+#define ELF_ARCH EM_H8_300
+#if defined(CONFIG_CPU_H8300H)
+#define ELF_CORE_EFLAGS 0x810000
+#endif
+#if defined(CONFIG_CPU_H8S)
+#define ELF_CORE_EFLAGS 0x820000
+#endif
+
+#define ELF_PLAT_INIT(_r) (_r)->er1 = 0
+
+#define ELF_EXEC_PAGESIZE 4096
+
+/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
+ use of this is to invoke "./ld.so someprog" to test out a new version of
+ the loader. We need to make sure that it is out of the way of the program
+ that it will "exec", and that there is sufficient room for the brk. */
+
+#define ELF_ET_DYN_BASE 0xD0000000UL
+
+/* This yields a mask that user programs can use to figure out what
+ instruction set this cpu supports. */
+
+#define ELF_HWCAP (0)
+
+/* This yields a string that ld.so will use to load implementation
+ specific libraries for optimization. This is more specific in
+ intent than poking at uname or /proc/cpuinfo. */
+
+#define ELF_PLATFORM (NULL)
+
+#define R_H8_NONE 0
+#define R_H8_DIR32 1
+#define R_H8_DIR32_28 2
+#define R_H8_DIR32_24 3
+#define R_H8_DIR32_16 4
+#define R_H8_DIR32U 6
+#define R_H8_DIR32U_28 7
+#define R_H8_DIR32U_24 8
+#define R_H8_DIR32U_20 9
+#define R_H8_DIR32U_16 10
+#define R_H8_DIR24 11
+#define R_H8_DIR24_20 12
+#define R_H8_DIR24_16 13
+#define R_H8_DIR24U 14
+#define R_H8_DIR24U_20 15
+#define R_H8_DIR24U_16 16
+#define R_H8_DIR16 17
+#define R_H8_DIR16U 18
+#define R_H8_DIR16S_32 19
+#define R_H8_DIR16S_28 20
+#define R_H8_DIR16S_24 21
+#define R_H8_DIR16S_20 22
+#define R_H8_DIR16S 23
+#define R_H8_DIR8 24
+#define R_H8_DIR8U 25
+#define R_H8_DIR8Z_32 26
+#define R_H8_DIR8Z_28 27
+#define R_H8_DIR8Z_24 28
+#define R_H8_DIR8Z_20 29
+#define R_H8_DIR8Z_16 30
+#define R_H8_PCREL16 31
+#define R_H8_PCREL8 32
+#define R_H8_BPOS 33
+#define R_H8_PCREL32 34
+#define R_H8_GOT32O 35
+#define R_H8_GOT16O 36
+#define R_H8_DIR16A8 59
+#define R_H8_DIR16R8 60
+#define R_H8_DIR24A8 61
+#define R_H8_DIR24R8 62
+#define R_H8_DIR32A16 63
+#define R_H8_ABS32 65
+#define R_H8_ABS32A16 127
+
+#endif
diff --git a/arch/h8300/include/asm/emergency-restart.h b/arch/h8300/include/asm/emergency-restart.h
new file mode 100644
index 0000000..108d8c4
--- /dev/null
+++ b/arch/h8300/include/asm/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/arch/h8300/include/asm/flat.h b/arch/h8300/include/asm/flat.h
new file mode 100644
index 0000000..760296d
--- /dev/null
+++ b/arch/h8300/include/asm/flat.h
@@ -0,0 +1,27 @@
+/*
+ * arch/h8300/asm/include/flat.h -- uClinux flat-format executables
+ */
+
+#ifndef __H8300_FLAT_H__
+#define __H8300_FLAT_H__
+
+#define flat_argvp_envp_on_stack() 1
+#define flat_old_ram_flag(flags) 1
+#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
+#define flat_set_persistent(relval, p) 0
+
+/*
+ * on the H8 a couple of the relocations have an instruction in the
+ * top byte. As there can only be 24bits of address space, we just
+ * always preserve that 8bits at the top, when it isn't an instruction
+ * is is 0 ([email protected])
+ */
+
+#define flat_get_relocate_addr(rel) (rel & ~0x00000001)
+#define flat_get_addr_from_rp(rp, relval, flags, persistent) \
+ (get_unaligned(rp) & (((flags) & FLAT_FLAG_GOTPIC) ? \
+ 0xffffffff : 0x00ffffff))
+#define flat_put_addr_at_rp(rp, addr, rel) \
+ put_unaligned (((*(char *)(rp)) << 24) | ((addr) & 0x00ffffff), (rp))
+
+#endif /* __H8300_FLAT_H__ */
diff --git a/arch/h8300/include/asm/io.h b/arch/h8300/include/asm/io.h
new file mode 100644
index 0000000..bb64c21
--- /dev/null
+++ b/arch/h8300/include/asm/io.h
@@ -0,0 +1,372 @@
+#ifndef _H8300_IO_H
+#define _H8300_IO_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+
+/*
+ * These are for ISA/PCI shared memory _only_ and should never be used
+ * on any other type of memory, including Zorro memory. They are meant to
+ * access the bus in the bus byte order which is little-endian!.
+ *
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the m68k architecture, we just read/write the
+ * memory location directly.
+ */
+/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
+ * two accesses to memory, which may be undesirable for some devices.
+ */
+
+/*
+ * swap functions are sometimes needed to interface little-endian hardware
+ */
+
+static inline unsigned short _swapw(volatile unsigned short v)
+{
+#ifndef H8300_IO_NOSWAP
+ unsigned short r;
+
+ __asm__("xor.b %w0,%x0\n\t"
+ "xor.b %x0,%w0\n\t"
+ "xor.b %w0,%x0"
+ : "=r"(r)
+ : "0"(v));
+ return r;
+#else
+ return v;
+#endif
+}
+
+static inline unsigned long _swapl(volatile unsigned long v)
+{
+#ifndef H8300_IO_NOSWAP
+ unsigned long r;
+
+ __asm__("xor.b %w0,%x0\n\t"
+ "xor.b %x0,%w0\n\t"
+ "xor.b %w0,%x0\n\t"
+ "xor.w %e0,%f0\n\t"
+ "xor.w %f0,%e0\n\t"
+ "xor.w %e0,%f0\n\t"
+ "xor.b %w0,%x0\n\t"
+ "xor.b %x0,%w0\n\t"
+ "xor.b %w0,%x0"
+ : "=r"(r)
+ : "0"(v));
+ return r;
+#else
+ return v;
+#endif
+}
+
+#define readb(addr) \
+ ({ u8 __v = *(volatile u8 *)((uintptr_t)(addr) & 0x00ffffff); __v; })
+
+#define readw(addr) \
+ ({ u16 __v = *(volatile u16 *)((uintptr_t)(addr) & 0x00ffffff); __v; })
+
+#define readl(addr) \
+ ({ u32 __v = *(volatile u32 *)((uintptr_t)(addr) & 0x00ffffff); __v; })
+
+#define writeb(b, addr) (void)((*(volatile u8 *) \
+ ((uintptr_t)(addr) & 0x00ffffff)) = (b))
+
+#define writew(b, addr) (void)((*(volatile u16 *) \
+ ((uintptr_t)(addr) & 0x00ffffff)) = (b))
+
+#define writel(b, addr) (void)((*(volatile u32 *) \
+ ((uintptr_t)(addr) & 0x00ffffff)) = (b))
+
+#define readb_relaxed(addr) readb(addr)
+#define readw_relaxed(addr) readw(addr)
+#define readl_relaxed(addr) readl(addr)
+#define writeb_relaxed(b, addr) writeb(b, addr)
+#define writew_relaxed(b, addr) writew(b, addr)
+#define writel_relaxed(b, addr) writel(b, addr)
+
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
+
+#if defined(CONFIG_H83069)
+#define ABWCR 0xFEE020
+#elif defined(CONFIG_H8S2678)
+#define ABWCR 0xFFFEC0
+#endif
+
+static inline int h8300_buswidth(unsigned int addr)
+{
+ return (*(volatile u8 *)ABWCR & (1 << ((addr >> 21) & 7))) == 0;
+}
+
+static inline void io_outsb(unsigned int addr, const void *buf, int len)
+{
+ volatile unsigned char *ap_b = (volatile unsigned char *) addr;
+ volatile unsigned short *ap_w = (volatile unsigned short *) addr;
+ unsigned char *bp = (unsigned char *) buf;
+
+ if (h8300_buswidth(addr) && (addr & 1)) {
+ while (len--)
+ *ap_w = *bp++;
+ } else {
+ while (len--)
+ *ap_b = *bp++;
+ }
+}
+
+static inline void io_outsw(unsigned int addr, const void *buf, int len)
+{
+ volatile unsigned short *ap = (volatile unsigned short *) addr;
+ unsigned short *bp = (unsigned short *) buf;
+
+ while (len--)
+ *ap = _swapw(*bp++);
+}
+
+static inline void io_outsl(unsigned int addr, const void *buf, int len)
+{
+ volatile unsigned long *ap = (volatile unsigned long *) addr;
+ unsigned long *bp = (unsigned long *) buf;
+
+ while (len--)
+ *ap = _swapl(*bp++);
+}
+
+static inline void io_outsw_noswap(unsigned int addr, const void *buf, int len)
+{
+ volatile unsigned short *ap = (volatile unsigned short *) addr;
+ unsigned short *bp = (unsigned short *) buf;
+
+ while (len--)
+ *ap = *bp++;
+}
+
+static inline void io_outsl_noswap(unsigned int addr, const void *buf, int len)
+{
+ volatile unsigned long *ap = (volatile unsigned long *) addr;
+ unsigned long *bp = (unsigned long *) buf;
+
+ while (len--)
+ *ap = *bp++;
+}
+
+static inline void io_insb(unsigned int addr, void *buf, int len)
+{
+ volatile unsigned char *ap_b;
+ volatile unsigned short *ap_w;
+ unsigned char *bp = (unsigned char *) buf;
+
+ if (h8300_buswidth(addr)) {
+ ap_w = (volatile unsigned short *)(addr & ~1);
+ while (len--)
+ *bp++ = *ap_w & 0xff;
+ } else {
+ ap_b = (volatile unsigned char *)addr;
+ while (len--)
+ *bp++ = *ap_b;
+ }
+}
+
+static inline void io_insw(unsigned int addr, void *buf, int len)
+{
+ volatile unsigned short *ap = (volatile unsigned short *) addr;
+ unsigned short *bp = (unsigned short *) buf;
+
+ while (len--)
+ *bp++ = _swapw(*ap);
+}
+
+static inline void io_insl(unsigned int addr, void *buf, int len)
+{
+ volatile unsigned long *ap = (volatile unsigned long *) addr;
+ unsigned long *bp = (unsigned long *) buf;
+
+ while (len--)
+ *bp++ = _swapl(*ap);
+}
+
+static inline void io_insw_noswap(unsigned int addr, void *buf, int len)
+{
+ volatile unsigned short *ap = (volatile unsigned short *) addr;
+ unsigned short *bp = (unsigned short *) buf;
+
+ while (len--)
+ *bp++ = *ap;
+}
+
+static inline void io_insl_noswap(unsigned int addr, void *buf, int len)
+{
+ volatile unsigned long *ap = (volatile unsigned long *) addr;
+ unsigned long *bp = (unsigned long *) buf;
+
+ while (len--)
+ *bp++ = *ap;
+}
+
+/*
+ * make the short names macros so specific devices
+ * can override them as required
+ */
+
+#define memset_io(a, b, c) memset((void *)(a), (b), (c))
+#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c))
+#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c))
+
+#define mmiowb()
+
+#define inb(addr) ((h8300_buswidth(addr)) ? \
+ readw((addr) & ~1) & 0xff:readb(addr))
+#define inw(addr) _swapw(readw(addr))
+#define inl(addr) _swapl(readl(addr))
+#define outb(x, addr) ((void)((h8300_buswidth(addr) && \
+ ((addr) & 1)) ? \
+ writew(x, (addr) & ~1) : writeb(x, addr)))
+#define outw(x, addr) ((void) writew(_swapw(x), addr))
+#define outl(x, addr) ((void) writel(_swapl(x), addr))
+
+#define inb_p(addr) inb(addr)
+#define inw_p(addr) inw(addr)
+#define inl_p(addr) inl(addr)
+#define outb_p(x, addr) outb(x, addr)
+#define outw_p(x, addr) outw(x, addr)
+#define outl_p(x, addr) outl(x, addr)
+
+#define outsb(a, b, l) io_outsb(a, b, l)
+#define outsw(a, b, l) io_outsw(a, b, l)
+#define outsl(a, b, l) io_outsl(a, b, l)
+
+#define insb(a, b, l) io_insb(a, b, l)
+#define insw(a, b, l) io_insw(a, b, l)
+#define insl(a, b, l) io_insl(a, b, l)
+
+#define ioread8(a) __raw_readb(a)
+#define ioread16(a) __raw_readw(a)
+#define ioread32(a) __raw_readl(a)
+
+#define iowrite8(v, a) __raw_writeb((v), (a))
+#define iowrite16(v, a) __raw_writew((v), (a))
+#define iowrite32(v, a) __raw_writel((v), (a))
+
+#define ioread8_rep(p,d,c) insb(p,d,c)
+#define ioread16_rep(p,d,c) insw(p,d,c)
+#define ioread32_rep(p,d,c) insl(p,d,c)
+#define iowrite8_rep(p,s,c) outsb(p,s,c)
+#define iowrite16_rep(p,s,c) outsw(p,s,c)
+#define iowrite32_rep(p,s,c) outsl(p,s,c)
+
+#define ioread16be(a) __raw_readw((a))
+#define ioread32be(a) __raw_readl((a))
+#define iowrite16be(v, a) __raw_writew((v), (a))
+#define iowrite32be(v, a) __raw_writel((v), (a))
+
+#define IO_SPACE_LIMIT 0xffffff
+
+
+/* Values for nocacheflag and cmode */
+#define IOMAP_FULL_CACHING 0
+#define IOMAP_NOCACHE_SER 1
+#define IOMAP_NOCACHE_NONSER 2
+#define IOMAP_WRITETHROUGH 3
+
+extern void *__ioremap(unsigned long physaddr, unsigned long size,
+ int cacheflag);
+extern void __iounmap(void *addr, unsigned long size);
+
+static inline void *ioremap(unsigned long physaddr, unsigned long size)
+{
+ return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+static inline void *ioremap_nocache(unsigned long physaddr,
+ unsigned long size)
+{
+ return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+static inline void *ioremap_writethrough(unsigned long physaddr,
+ unsigned long size)
+{
+ return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
+}
+static inline void *ioremap_fullcache(unsigned long physaddr,
+ unsigned long size)
+{
+ return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
+}
+
+extern void iounmap(void *addr);
+
+#define ioremap_wc ioremap_nocache
+
+/* H8/300 internal I/O functions */
+static inline unsigned char ctrl_inb(unsigned long addr)
+{
+ return *(volatile unsigned char *)addr;
+}
+
+static inline unsigned short ctrl_inw(unsigned long addr)
+{
+ return *(volatile unsigned short *)addr;
+}
+
+static inline unsigned long ctrl_inl(unsigned long addr)
+{
+ return *(volatile unsigned long *)addr;
+}
+
+static inline void ctrl_outb(unsigned char b, unsigned long addr)
+{
+ *(volatile unsigned char *)addr = b;
+}
+
+static inline void ctrl_outw(unsigned short b, unsigned long addr)
+{
+ *(volatile unsigned short *)addr = b;
+}
+
+static inline void ctrl_outl(unsigned long b, unsigned long addr)
+{
+ *(volatile unsigned long *)addr = b;
+}
+
+static inline void ctrl_bclr(int b, unsigned long addr)
+{
+ if (__builtin_constant_p(b))
+ __asm__("bclr %1,@%o0:8" : : "i"(addr & 0xff), "i"(b));
+ else
+ __asm__("bclr %w1,@%o0:8" : : "i"(addr & 0xff), "r"(b));
+}
+
+static inline void ctrl_bset(int b, unsigned long addr)
+{
+ if (__builtin_constant_p(b))
+ __asm__("bset %1,@%o0:8" : : "i"(addr & 0xff), "i"(b));
+ else
+ __asm__("bset %w1,@%o0:8" : : "i"(addr & 0xff), "r"(b));
+}
+
+/*
+ * Macros used for converting between virtual and physical mappings.
+ */
+#define phys_to_virt(vaddr) ((void *) (vaddr))
+#define virt_to_phys(vaddr) ((unsigned long) (vaddr))
+
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p) __va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p) (p)
+
+#endif /* __KERNEL__ */
+
+#endif /* _H8300_IO_H */
diff --git a/arch/h8300/include/asm/irq.h b/arch/h8300/include/asm/irq.h
new file mode 100644
index 0000000..afa958e
--- /dev/null
+++ b/arch/h8300/include/asm/irq.h
@@ -0,0 +1,26 @@
+#ifndef _H8300_IRQ_H_
+#define _H8300_IRQ_H_
+
+#include <linux/irqchip.h>
+
+#if defined(CONFIG_CPU_H8300H)
+#define NR_IRQS 64
+#define IRQ_CHIP h8300h_irq_chip
+#define EXT_IRQ0 12
+#define EXT_IRQS 6
+#elif defined(CONFIG_CPU_H8S)
+#define NR_IRQS 128
+#define IRQ_CHIP h8s_irq_chip
+#define EXT_IRQ0 16
+#define EXT_IRQS 16
+#endif
+
+static __inline__ int irq_canonicalize(int irq)
+{
+ return irq;
+}
+
+void h8300_init_ipr(void);
+extern struct irq_chip h8300h_irq_chip;
+extern struct irq_chip h8s_irq_chip;
+#endif /* _H8300_IRQ_H_ */
diff --git a/arch/h8300/include/asm/irqflags.h b/arch/h8300/include/asm/irqflags.h
new file mode 100644
index 0000000..801ade3
--- /dev/null
+++ b/arch/h8300/include/asm/irqflags.h
@@ -0,0 +1,92 @@
+#ifndef _H8300_IRQFLAGS_H
+#define _H8300_IRQFLAGS_H
+
+#ifdef CONFIG_CPU_H8300H
+static inline unsigned char arch_local_save_flags(void)
+{
+ unsigned char flags;
+
+ __asm__ volatile ("stc ccr,%w0" : "=r" (flags));
+ return flags;
+}
+
+static inline void arch_local_irq_disable(void)
+{
+ __asm__ volatile ("orc #0xc0,ccr");
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ __asm__ volatile ("andc #0x3f,ccr");
+}
+
+static inline unsigned char arch_local_irq_save(void)
+{
+ unsigned char flags;
+
+ __asm__ volatile ("stc ccr,%w0\n\t"
+ "orc #0xc0,ccr" : "=r" (flags));
+ return flags;
+}
+
+static inline void arch_local_irq_restore(unsigned char flags)
+{
+ __asm__ volatile ("ldc %w0,ccr" : : "r" (flags) : "cc");
+}
+
+static inline int arch_irqs_disabled_flags(unsigned long flags)
+{
+ return (flags & 0xc0) == 0xc0;
+}
+#endif
+#ifdef CONFIG_CPU_H8S
+static inline unsigned short arch_local_save_flags(void)
+{
+ unsigned short flags;
+
+ __asm__ volatile ("stc ccr,%w0\n\tstc exr,%x0" : "=r" (flags));
+ return flags;
+}
+
+static inline void arch_local_irq_disable(void)
+{
+ __asm__ volatile ("orc #0x80,ccr\n\t");
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ __asm__ volatile ("andc #0x7f,ccr\n\t"
+ "andc #0xf0,exr\n\t");
+}
+
+static inline unsigned short arch_local_irq_save(void)
+{
+ unsigned short flags;
+
+ __asm__ volatile ("stc ccr,%w0\n\t"
+ "stc exr,%x0\n\t"
+ "orc #0x80,ccr\n\t"
+ : "=r" (flags));
+ return flags;
+}
+
+static inline void arch_local_irq_restore(unsigned short flags)
+{
+ __asm__ volatile ("ldc %w0,ccr\n\t"
+ "ldc %x0,exr"
+ : : "r" (flags) : "cc");
+}
+
+static inline int arch_irqs_disabled_flags(unsigned short flags)
+{
+ return (flags & 0x0080) == 0x0080;
+}
+
+#endif
+
+static inline int arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+#endif /* _H8300_IRQFLAGS_H */
diff --git a/arch/h8300/include/asm/mc146818rtc.h b/arch/h8300/include/asm/mc146818rtc.h
new file mode 100644
index 0000000..ab9d964
--- /dev/null
+++ b/arch/h8300/include/asm/mc146818rtc.h
@@ -0,0 +1,9 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _H8300_MC146818RTC_H
+#define _H8300_MC146818RTC_H
+
+/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
+
+#endif /* _H8300_MC146818RTC_H */
diff --git a/arch/h8300/include/asm/mutex.h b/arch/h8300/include/asm/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/arch/h8300/include/asm/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/arch/h8300/include/asm/page.h b/arch/h8300/include/asm/page.h
new file mode 100644
index 0000000..ee2f07c
--- /dev/null
+++ b/arch/h8300/include/asm/page.h
@@ -0,0 +1,11 @@
+#ifndef _H8300_PAGE_H
+#define _H8300_PAGE_H
+
+#include <asm-generic/page.h>
+#include <linux/types.h>
+
+#define MAP_NR(addr) (((uintptr_t)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
+#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#endif
diff --git a/arch/h8300/include/asm/page_offset.h b/arch/h8300/include/asm/page_offset.h
new file mode 100644
index 0000000..f870646
--- /dev/null
+++ b/arch/h8300/include/asm/page_offset.h
@@ -0,0 +1,3 @@
+
+#define PAGE_OFFSET_RAW 0x00000000
+
diff --git a/arch/h8300/include/asm/pci.h b/arch/h8300/include/asm/pci.h
new file mode 100644
index 0000000..0b2acaa
--- /dev/null
+++ b/arch/h8300/include/asm/pci.h
@@ -0,0 +1,19 @@
+#ifndef _ASM_H8300_PCI_H
+#define _ASM_H8300_PCI_H
+
+/*
+ * asm-h8300/pci.h - H8/300 specific PCI declarations.
+ *
+ * Yoshinori Sato <[email protected]>
+ */
+
+#define pcibios_assign_all_busses() 0
+
+static inline void pcibios_penalize_isa_irq(int irq, int active)
+{
+ /* We don't do dynamic PCI IRQ allocation */
+}
+
+#define PCI_DMA_BUS_IS_PHYS (1)
+
+#endif /* _ASM_H8300_PCI_H */
diff --git a/arch/h8300/include/asm/pgtable.h b/arch/h8300/include/asm/pgtable.h
new file mode 100644
index 0000000..8341db6
--- /dev/null
+++ b/arch/h8300/include/asm/pgtable.h
@@ -0,0 +1,49 @@
+#ifndef _H8300_PGTABLE_H
+#define _H8300_PGTABLE_H
+#include <asm-generic/pgtable-nopud.h>
+#include <asm-generic/pgtable.h>
+#define pgtable_cache_init() do { } while (0)
+extern void paging_init(void);
+#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_COPY __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_READONLY __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_KERNEL __pgprot(0) /* these mean nothing to NO_MM */
+#define __swp_type(x) (0)
+#define __swp_offset(x) (0)
+#define __swp_entry(typ, off) ((swp_entry_t) { ((typ) | ((off) << 7)) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
+#define kern_addr_valid(addr) (1)
+#define pgprot_writecombine(prot) (prot)
+#define pgprot_noncached pgprot_writecombine
+
+static inline int pte_file(pte_t pte) { return 0; }
+#define swapper_pg_dir ((pgd_t *) 0)
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+#define ZERO_PAGE(vaddr) (virt_to_page(0))
+
+/*
+ * These would be in other places but having them here reduces the diffs.
+ */
+extern unsigned int kobjsize(const void *objp);
+extern int is_in_rom(unsigned long);
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init() do { } while (0)
+
+/*
+ * All 32bit addresses are effectively valid for vmalloc...
+ * Sort of meaningless for non-VM targets.
+ */
+#define VMALLOC_START 0
+#define VMALLOC_END 0xffffffff
+
+#define arch_enter_lazy_cpu_mode() do {} while (0)
+
+#endif /* _H8300_PGTABLE_H */
diff --git a/arch/h8300/include/asm/processor.h b/arch/h8300/include/asm/processor.h
new file mode 100644
index 0000000..bb2c3fd
--- /dev/null
+++ b/arch/h8300/include/asm/processor.h
@@ -0,0 +1,144 @@
+/*
+ * include/asm-h8300/processor.h
+ *
+ * Copyright (C) 2002 Yoshinori Sato
+ *
+ * Based on: linux/asm-m68nommu/processor.h
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ */
+
+#ifndef __ASM_H8300_PROCESSOR_H
+#define __ASM_H8300_PROCESSOR_H
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l; })
+
+#include <linux/compiler.h>
+#include <asm/segment.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+
+static inline unsigned long rdusp(void)
+{
+ extern unsigned int _sw_usp;
+
+ return _sw_usp;
+}
+
+static inline void wrusp(unsigned long usp)
+{
+ extern unsigned int _sw_usp;
+
+ _sw_usp = usp;
+}
+
+/*
+ * User space process size: 3.75GB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ */
+#define TASK_SIZE (0xFFFFFFFFUL)
+
+#ifdef __KERNEL__
+#define STACK_TOP TASK_SIZE
+#define STACK_TOP_MAX STACK_TOP
+#endif
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's. We won't be using it
+ */
+#define TASK_UNMAPPED_BASE 0
+
+struct thread_struct {
+ unsigned long ksp; /* kernel stack pointer */
+ unsigned long usp; /* user stack pointer */
+ unsigned long ccr; /* saved status register */
+ unsigned long esp0; /* points to SR of stack frame */
+ struct {
+ unsigned short *addr;
+ unsigned short inst;
+ } breakinfo;
+};
+
+#define INIT_THREAD { \
+ .ksp = sizeof(init_stack) + (unsigned long)init_stack, \
+ .usp = 0, \
+ .ccr = PS_S, \
+ .esp0 = 0, \
+ .breakinfo = { \
+ .addr = (unsigned short *)-1, \
+ .inst = 0 \
+ } \
+}
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ *
+ * pass the data segment into user programs if it exists,
+ * it can't hurt anything as far as I can tell
+ */
+#if defined(CONFIG_CPU_H8300H)
+#define start_thread(_regs, _pc, _usp) \
+do { \
+ (_regs)->pc = (_pc); \
+ (_regs)->ccr = 0x00; /* clear all flags */ \
+ (_regs)->er5 = current->mm->start_data; /* GOT base */ \
+ (_regs)->sp =((unsigned long)(_usp)) - sizeof(unsigned long)*3; \
+} while (0)
+#endif
+#if defined(CONFIG_CPU_H8S)
+#define start_thread(_regs, _pc, _usp) \
+do { \
+ (_regs)->pc = (_pc); \
+ (_regs)->ccr = 0x00; /* clear kernel flag */ \
+ (_regs)->exr = 0x78; /* enable all interrupts */ \
+ (_regs)->er5 = current->mm->start_data; /* GOT base */ \
+ /* 14 = space for retaddr(4), vector(4), er0(4) and exr(2) on stack */ \
+ (_regs)->sp =((unsigned long)(_usp)) - 14; \
+} while (0)
+#endif
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+/*
+ * Free current thread data structures etc..
+ */
+static inline void exit_thread(void)
+{
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+unsigned long thread_saved_pc(struct task_struct *tsk);
+unsigned long get_wchan(struct task_struct *p);
+
+#define KSTK_EIP(tsk) \
+ ({ \
+ unsigned long eip = 0; \
+ if ((tsk)->thread.esp0 > PAGE_SIZE && \
+ MAP_NR((tsk)->thread.esp0) < max_mapnr) \
+ eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
+ eip; })
+
+#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp)
+
+#define cpu_relax() barrier()
+#define cpu_relax_lowlatency() cpu_relax()
+
+#define HARD_RESET_NOW() ({ \
+ local_irq_disable(); \
+ asm("jmp @@0"); \
+})
+
+#endif
diff --git a/arch/h8300/include/asm/ptrace.h b/arch/h8300/include/asm/ptrace.h
new file mode 100644
index 0000000..e693fb4
--- /dev/null
+++ b/arch/h8300/include/asm/ptrace.h
@@ -0,0 +1,36 @@
+#ifndef _H8300_PTRACE_H
+#define _H8300_PTRACE_H
+
+#include <uapi/asm/ptrace.h>
+
+#ifndef __ASSEMBLY__
+#ifndef PS_S
+#define PS_S (0x10)
+#endif
+
+#if defined(CONFIG_CPU_H8300H)
+#define H8300_REGS_NO 11
+#endif
+#if defined(CONFIG_CPU_H8S)
+#define H8300_REGS_NO 12
+#endif
+
+#define arch_has_single_step() (1)
+
+#define user_mode(regs) (!((regs)->ccr & PS_S))
+#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
+#define user_stack_pointer(regs) ((regs)->sp)
+#define current_pt_regs() ((struct pt_regs *) \
+ (THREAD_SIZE + (unsigned long)current_thread_info()) - 1)
+#define signal_pt_regs() ((struct pt_regs *)current->thread.esp0)
+#define current_user_stack_pointer() rdusp()
+#define task_pt_regs(task) \
+ ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE) - 1)
+
+extern long h8300_get_reg(struct task_struct *task, int regno);
+extern int h8300_put_reg(struct task_struct *task, int regno,
+ unsigned long data);
+
+#endif /* __ASSEMBLY__ */
+#endif /* _H8300_PTRACE_H */
diff --git a/arch/h8300/include/asm/segment.h b/arch/h8300/include/asm/segment.h
new file mode 100644
index 0000000..c8bc68e
--- /dev/null
+++ b/arch/h8300/include/asm/segment.h
@@ -0,0 +1,49 @@
+#ifndef _H8300_SEGMENT_H
+#define _H8300_SEGMENT_H
+
+/* define constants */
+#define USER_DATA (1)
+#ifndef __USER_DS
+#define __USER_DS (USER_DATA)
+#endif
+#define USER_PROGRAM (2)
+#define SUPER_DATA (3)
+#ifndef __KERNEL_DS
+#define __KERNEL_DS (SUPER_DATA)
+#endif
+#define SUPER_PROGRAM (4)
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+ unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
+#define USER_DS MAKE_MM_SEG(__USER_DS)
+#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS)
+
+/*
+ * Get/set the SFC/DFC registers for MOVES instructions
+ */
+
+static inline mm_segment_t get_fs(void)
+{
+ return USER_DS;
+}
+
+static inline mm_segment_t get_ds(void)
+{
+ /* return the supervisor data space code */
+ return KERNEL_DS;
+}
+
+static inline void set_fs(mm_segment_t val)
+{
+}
+
+#define segment_eq(a, b) ((a).seg == (b).seg)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _H8300_SEGMENT_H */
diff --git a/arch/h8300/include/asm/sh_bios.h b/arch/h8300/include/asm/sh_bios.h
new file mode 100644
index 0000000..ac0675f
--- /dev/null
+++ b/arch/h8300/include/asm/sh_bios.h
@@ -0,0 +1,33 @@
+/* eCos HAL interface header */
+
+#ifndef SH_BIOS_H
+#define SH_BIOS_H
+
+#define HAL_IF_VECTOR_TABLE 0xfffe20
+#define CALL_IF_SET_CONSOLE_COMM 13
+#define QUERY_CURRENT -1
+#define MANGLER -3
+
+/* Checking for GDB stub active */
+/* suggestion Jonathan Larmour */
+static int sh_bios_in_gdb_mode(void)
+{
+ static int gdb_active = -1;
+
+ if (gdb_active == -1) {
+ int (*set_console_comm)(int);
+
+ set_console_comm =
+ ((void **)HAL_IF_VECTOR_TABLE)[CALL_IF_SET_CONSOLE_COMM];
+ gdb_active =
+ (set_console_comm(QUERY_CURRENT) == MANGLER);
+ }
+ return gdb_active;
+}
+
+static void sh_bios_gdb_detach(void)
+{
+
+}
+
+#endif
diff --git a/arch/h8300/include/asm/signal.h b/arch/h8300/include/asm/signal.h
new file mode 100644
index 0000000..6341e36
--- /dev/null
+++ b/arch/h8300/include/asm/signal.h
@@ -0,0 +1,24 @@
+#ifndef _H8300_SIGNAL_H
+#define _H8300_SIGNAL_H
+
+#include <uapi/asm/signal.h>
+
+/* Most things should be clean enough to redefine this at will, if care
+ is taken to make libc match. */
+
+#define _NSIG 64
+#define _NSIG_BPW 32
+#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t; /* at least 32 bits */
+
+typedef struct {
+ unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#define __ARCH_HAS_SA_RESTORER
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#endif /* _H8300_SIGNAL_H */
diff --git a/arch/h8300/include/asm/smp.h b/arch/h8300/include/asm/smp.h
new file mode 100644
index 0000000..9e9bd7e
--- /dev/null
+++ b/arch/h8300/include/asm/smp.h
@@ -0,0 +1 @@
+/* nothing required here yet */
diff --git a/arch/h8300/include/asm/spinlock.h b/arch/h8300/include/asm/spinlock.h
new file mode 100644
index 0000000..d5407fa
--- /dev/null
+++ b/arch/h8300/include/asm/spinlock.h
@@ -0,0 +1,6 @@
+#ifndef __H8300_SPINLOCK_H
+#define __H8300_SPINLOCK_H
+
+#error "H8/300 doesn't do SMP yet"
+
+#endif
diff --git a/arch/h8300/include/asm/string.h b/arch/h8300/include/asm/string.h
new file mode 100644
index 0000000..5dc5a8a
--- /dev/null
+++ b/arch/h8300/include/asm/string.h
@@ -0,0 +1,17 @@
+#ifndef _H8300_STRING_H_
+#define _H8300_STRING_H_
+
+#ifdef __KERNEL__ /* only set these up for kernel code */
+
+#include <asm/setup.h>
+#include <asm/page.h>
+
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *s, int c, size_t count);
+
+#define __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *d, const void *s, size_t count);
+
+#endif /* KERNEL */
+
+#endif
diff --git a/arch/h8300/include/asm/switch_to.h b/arch/h8300/include/asm/switch_to.h
new file mode 100644
index 0000000..7ad1bf9
--- /dev/null
+++ b/arch/h8300/include/asm/switch_to.h
@@ -0,0 +1,51 @@
+#ifndef _H8300_SWITCH_TO_H
+#define _H8300_SWITCH_TO_H
+
+/*
+ * switch_to(n) should switch tasks to task ptr, first checking that
+ * ptr isn't the current task, in which case it does nothing. This
+ * also clears the TS-flag if the task we switched to has used the
+ * math co-processor latest.
+ */
+/*
+ * switch_to() saves the extra registers, that are not saved
+ * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and
+ * a0-a1. Some of these are used by schedule() and its predecessors
+ * and so we might get see unexpected behaviors when a task returns
+ * with unexpected register values.
+ *
+ * syscall stores these registers itself and none of them are used
+ * by syscall after the function in the syscall has been called.
+ *
+ * Beware that resume now expects *next to be in d1 and the offset of
+ * tss to be in a1. This saves a few instructions as we no longer have
+ * to push them onto the stack and read them back right after.
+ *
+ * 02/17/96 - Jes Sorensen ([email protected])
+ *
+ * Changed 96/09/19 by Andreas Schwab
+ * pass prev in a0, next in a1, offset of tss in d1, and whether
+ * the mm structures are shared in d2 (to avoid atc flushing).
+ *
+ * H8/300 Porting 2002/09/04 Yoshinori Sato
+ */
+
+asmlinkage void resume(void);
+#define switch_to(prev, next, last) \
+do { \
+ void *_last; \
+ __asm__ __volatile__( \
+ "mov.l %1, er0\n\t" \
+ "mov.l %2, er1\n\t" \
+ "mov.l %3, er2\n\t" \
+ "jsr @_resume\n\t" \
+ "mov.l er2,%0\n\t" \
+ : "=r" (_last) \
+ : "r" (&(prev->thread)), \
+ "r" (&(next->thread)), \
+ "g" (prev) \
+ : "cc", "er0", "er1", "er2", "er3"); \
+ (last) = _last; \
+} while (0)
+
+#endif /* _H8300_SWITCH_TO_H */
diff --git a/arch/h8300/include/asm/syscall.h b/arch/h8300/include/asm/syscall.h
new file mode 100644
index 0000000..b41f688
--- /dev/null
+++ b/arch/h8300/include/asm/syscall.h
@@ -0,0 +1,56 @@
+#ifndef __ASM_H8300_SYSCALLS_32_H
+#define __ASM_H8300_SYSCALLS_32_H
+
+#ifdef __KERNEL__
+
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+static inline int
+syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+ return regs->orig_er0;
+}
+
+static inline void
+syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
+ unsigned int i, unsigned int n, unsigned long *args)
+{
+ BUG_ON(i + n > 6);
+
+ while (n > 0) {
+ switch (i) {
+ case 0:
+ *args++ = regs->er1;
+ break;
+ case 1:
+ *args++ = regs->er2;
+ break;
+ case 2:
+ *args++ = regs->er3;
+ break;
+ case 3:
+ *args++ = regs->er4;
+ break;
+ case 4:
+ *args++ = regs->er5;
+ break;
+ case 5:
+ *args++ = regs->er6;
+ break;
+ }
+ i++;
+ n--;
+ }
+}
+
+
+
+/* Misc syscall related bits */
+asmlinkage long do_syscall_trace_enter(struct pt_regs *regs);
+asmlinkage void do_syscall_trace_leave(struct pt_regs *regs);
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_H8300_SYSCALLS_32_H */
diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h
new file mode 100644
index 0000000..aa5cc7d
--- /dev/null
+++ b/arch/h8300/include/asm/thread_info.h
@@ -0,0 +1,119 @@
+/* thread_info.h: h8300 low-level thread information
+ * adapted from the i386 and PPC versions by Yoshinori Sato <[email protected]>
+ *
+ * Copyright (C) 2002 David Howells ([email protected])
+ * - Incorporating suggestions made by Linus Torvalds and Dave Miller
+ */
+
+#ifndef _ASM_THREAD_INFO_H
+#define _ASM_THREAD_INFO_H
+
+#include <asm/page.h>
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+/*
+ * low level task data.
+ * If you change this, change the TI_* offsets below to match.
+ */
+struct thread_info {
+ struct task_struct *task; /* main task structure */
+ struct exec_domain *exec_domain; /* execution domain */
+ unsigned long flags; /* low level flags */
+ int cpu; /* cpu we're on */
+ int preempt_count; /* 0 => preemptable, <0 => BUG */
+ struct restart_block restart_block;
+};
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ */
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .task = &tsk, \
+ .exec_domain = &default_exec_domain, \
+ .flags = 0, \
+ .cpu = 0, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
+}
+
+#define init_thread_info (init_thread_union.thread_info)
+#define init_stack (init_thread_union.stack)
+
+
+/*
+ * Size of kernel stack for each process. This must be a power of 2...
+ */
+#define THREAD_SIZE_ORDER 1
+#define THREAD_SIZE 8192 /* 2 pages */
+
+
+/* how to get the thread information struct from C */
+static inline struct thread_info *current_thread_info(void)
+{
+ struct thread_info *ti;
+
+ __asm__("mov.l sp, %0 \n\t"
+ "and.w %1, %T0"
+ : "=&r"(ti)
+ : "i" (~(THREAD_SIZE-1) & 0xffff));
+ return ti;
+}
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Offsets in thread_info structure, used in assembly code
+ */
+#define TI_TASK 0
+#define TI_EXECDOMAIN 4
+#define TI_FLAGS 8
+#define TI_CPU 12
+#define TI_PRE_COUNT 16
+
+/*
+ * thread information flag bit numbers
+ */
+#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
+#define TIF_SIGPENDING 1 /* signal pending */
+#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
+#define TIF_SINGLESTEP 3 /* singlestepping active */
+#define TIF_MEMDIE 4 /* is terminating due to OOM killer */
+#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */
+#define TIF_NOTIFY_RESUME 6 /* callback before returning to user */
+#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */
+#define TIF_SYSCALL_TRACEPOINT 8 /* for ftrace syscall instrumentation */
+#define TIF_POLLING_NRFLAG 9 /* true if poll_idle() is polling TIF_NEED_RESCHED */
+
+/* as above, but as bit values */
+#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
+#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
+#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
+#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
+#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
+#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
+#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
+
+/* work to do in syscall trace */
+#define _TIF_WORK_SYSCALL_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
+ _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT)
+
+/* work to do on any return to u-space */
+#define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \
+ _TIF_NEED_RESCHED | _TIF_SYSCALL_AUDIT | \
+ _TIF_SINGLESTEP | _TIF_NOTIFY_RESUME | \
+ _TIF_SYSCALL_TRACEPOINT)
+
+/* work to do on interrupt/exception return */
+#define _TIF_WORK_MASK (_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \
+ _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP))
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/h8300/include/asm/timer.h b/arch/h8300/include/asm/timer.h
new file mode 100644
index 0000000..c905f4e
--- /dev/null
+++ b/arch/h8300/include/asm/timer.h
@@ -0,0 +1,31 @@
+#ifndef __H8300_TIMER_H
+#define __H8300_TIMER_H
+
+unsigned long get_cpu_clock(void);
+
+#define H8300_TIMER_FREQ get_cpu_clock() /* Timer input freq. */
+
+#define H8300_TMR8_CLKSRC 0
+#define H8300_TMR8_CLKEVTDEV 1
+
+#define H8300_TMR8_DIV_8 0
+#define H8300_TMR8_DIV_64 1
+#define H8300_TMR8_DIV_8192 2
+
+struct h8300_timer8_config {
+ int mode;
+ int div;
+ int rating;
+};
+
+struct h8300_timer16_config {
+ int rating;
+ __u8 enb;
+ __u8 imfa;
+ __u8 imiea;
+};
+
+struct h8300_tpu_config {
+ int rating;
+};
+#endif
diff --git a/arch/h8300/include/asm/timex.h b/arch/h8300/include/asm/timex.h
new file mode 100644
index 0000000..23e6701
--- /dev/null
+++ b/arch/h8300/include/asm/timex.h
@@ -0,0 +1,19 @@
+/*
+ * linux/include/asm-h8300/timex.h
+ *
+ * H8/300 architecture timex specifications
+ */
+#ifndef _ASM_H8300_TIMEX_H
+#define _ASM_H8300_TIMEX_H
+
+#define CLOCK_TICK_RATE (CONFIG_CPU_CLOCK*1000/8192) /* Timer input freq. */
+
+typedef unsigned long cycles_t;
+extern short h8300_timer_count;
+
+static inline cycles_t get_cycles(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/arch/h8300/include/asm/tlb.h b/arch/h8300/include/asm/tlb.h
new file mode 100644
index 0000000..2c6fa4ee
--- /dev/null
+++ b/arch/h8300/include/asm/tlb.h
@@ -0,0 +1,8 @@
+#ifndef __H8300_TLB_H__
+#define __H8300_TLB_H__
+
+#define tlb_flush(tlb) do { } while (0)
+
+#include <asm-generic/tlb.h>
+
+#endif
diff --git a/arch/h8300/include/asm/topology.h b/arch/h8300/include/asm/topology.h
new file mode 100644
index 0000000..fdc1219
--- /dev/null
+++ b/arch/h8300/include/asm/topology.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_H8300_TOPOLOGY_H
+#define _ASM_H8300_TOPOLOGY_H
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_H8300_TOPOLOGY_H */
diff --git a/arch/h8300/include/asm/traps.h b/arch/h8300/include/asm/traps.h
new file mode 100644
index 0000000..460d5e6
--- /dev/null
+++ b/arch/h8300/include/asm/traps.h
@@ -0,0 +1,31 @@
+/*
+ * linux/include/asm-h8300/traps.h
+ *
+ * Copyright (C) 2003 Yoshinori Sato <[email protected]>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _H8300_TRAPS_H
+#define _H8300_TRAPS_H
+
+extern void _system_call(void);
+extern void _interrupt_entry(void);
+extern void _trace_break(void);
+extern void _nmi(void);
+
+#define JMP_OP 0x5a000000
+#define JSR_OP 0x5e000000
+#define VECTOR(address) ((JMP_OP)|((unsigned long)address))
+#define REDIRECT(address) ((JSR_OP)|((unsigned long)address))
+
+#define TRACE_VEC 5
+
+#define TRAP0_VEC 8
+#define TRAP1_VEC 9
+#define TRAP2_VEC 10
+#define TRAP3_VEC 11
+
+#endif /* _H8300_TRAPS_H */
diff --git a/arch/h8300/include/asm/uaccess.h b/arch/h8300/include/asm/uaccess.h
new file mode 100644
index 0000000..d85e4f6
--- /dev/null
+++ b/arch/h8300/include/asm/uaccess.h
@@ -0,0 +1,145 @@
+#ifndef __H8300_UACCESS_H
+#define __H8300_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+
+#include <asm/segment.h>
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+/* We let the MMU do all checking */
+#define access_ok(type, addr, size) __access_ok((unsigned long)addr, size)
+static inline int __access_ok(unsigned long addr, unsigned long size)
+{
+#define RANGE_CHECK_OK(addr, size, lower, upper) \
+ (((addr) >= (lower)) && (((addr) + (size)) < (upper)))
+
+ extern unsigned long memory_end;
+
+ return RANGE_CHECK_OK(addr, size, 0L, memory_end);
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue. No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path. This means when everything is well,
+ * we don't even have to jump over them. Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry {
+ unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise. */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines. They automatically
+ * use the right size if we just have the right pointer type.
+ */
+
+#define put_user(x, ptr) \
+({ \
+ int __pu_err = 0; \
+ typeof(*(ptr)) __pu_val = (x); \
+ switch (sizeof(*(ptr))) { \
+ case 1: \
+ /* failthrough */ \
+ case 2: \
+ /* failthrough */ \
+ case 4: \
+ *(ptr) = x; \
+ break; \
+ case 8: \
+ memcpy(ptr, &__pu_val, sizeof(*(ptr))); \
+ break; \
+ default: \
+ __pu_err = __put_user_bad(); \
+ break; \
+ } \
+ __pu_err; \
+})
+#define __put_user_asm(x, addr, err, size) \
+do { \
+} while (0)
+
+#define __put_user(x, ptr) put_user(x, ptr)
+
+extern int __put_user_bad(void);
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+
+#define __ptr(x) ((unsigned long *)(x))
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+
+#define get_user(x, ptr) \
+({ \
+ typeof(*(ptr)) __gu_val; \
+ int __gu_err = 0; \
+ switch (sizeof(*(ptr))) { \
+ case 1: \
+ *(u8 *)&__gu_val = *((u8 *)(ptr)); \
+ break; \
+ case 2: \
+ *(u16 *)&__gu_val = *((u16 *)ptr); \
+ break; \
+ case 4: \
+ *(u32 *)&__gu_val = *((u32 *)ptr); \
+ break; \
+ case 8: \
+ memcpy((void *)&__gu_val, ptr, sizeof(*(ptr))); \
+ break; \
+ default: \
+ __gu_err = __get_user_bad(); \
+ break; \
+ } \
+ (x) = (typeof(*(ptr)))__gu_val; \
+ __gu_err; \
+})
+#define __get_user(x, ptr) get_user(x, ptr)
+
+extern int __get_user_bad(void);
+
+#define copy_from_user(to, from, n) (memcpy(to, from, n), 0)
+#define copy_to_user(to, from, n) (memcpy(to, from, n), 0)
+
+#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
+#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
+
+#define copy_to_user_ret(to, from, n, retval) \
+ ({ if (copy_to_user(to, from, n)) return retval; })
+
+#define copy_from_user_ret(to, from, n, retval) \
+ ({ if (copy_from_user(to, from, n)) return retval; })
+
+unsigned long clear_user(void __user *addr, unsigned long size);
+#define strnlen_user(s, n) (strnlen(s, n) + 1)
+long strncpy_from_user(char *d, const char *s, long n);
+
+#define __clear_user clear_user
+
+#endif /* _H8300_UACCESS_H */
diff --git a/arch/h8300/include/asm/unaligned.h b/arch/h8300/include/asm/unaligned.h
new file mode 100644
index 0000000..b8d06c7
--- /dev/null
+++ b/arch/h8300/include/asm/unaligned.h
@@ -0,0 +1,11 @@
+#ifndef _ASM_H8300_UNALIGNED_H
+#define _ASM_H8300_UNALIGNED_H
+
+#include <linux/unaligned/be_memmove.h>
+#include <linux/unaligned/le_byteshift.h>
+#include <linux/unaligned/generic.h>
+
+#define get_unaligned __get_unaligned_be
+#define put_unaligned __put_unaligned_be
+
+#endif /* _ASM_H8300_UNALIGNED_H */
diff --git a/arch/h8300/include/asm/user.h b/arch/h8300/include/asm/user.h
new file mode 100644
index 0000000..2e3555f
--- /dev/null
+++ b/arch/h8300/include/asm/user.h
@@ -0,0 +1,74 @@
+#ifndef _H8300_USER_H
+#define _H8300_USER_H
+
+#include <asm/page.h>
+
+/* Core file format: The core file is written in such a way that gdb
+ can understand it and provide useful information to the user (under
+ linux we use the 'trad-core' bfd). There are quite a number of
+ obstacles to being able to view the contents of the floating point
+ registers, and until these are solved you will not be able to view the
+ contents of them. Actually, you can read in the core file and look at
+ the contents of the user struct to find out what the floating point
+ registers contain.
+ The actual file contents are as follows:
+ UPAGE: 1 page consisting of a user struct that tells gdb what is present
+ in the file. Directly after this is a copy of the task_struct, which
+ is currently not used by gdb, but it may come in useful at some point.
+ All of the registers are stored as part of the upage. The upage should
+ always be only one page.
+ DATA: The data area is stored. We use current->end_text to
+ current->brk to pick up all of the user variables, plus any memory
+ that may have been malloced. No attempt is made to determine if a page
+ is demand-zero or if a page is totally unused, we just cover the entire
+ range. All of the addresses are rounded in such a way that an integral
+ number of pages is written.
+ STACK: We need the stack information in order to get a meaningful
+ backtrace. We need to write the data from (esp) to
+ current->start_stack, so we round each of these off in order to be able
+ to write an integer number of pages.
+ The minimum core file size is 3 pages, or 12288 bytes.
+*/
+
+/* This is the old layout of "struct pt_regs" as of Linux 1.x, and
+ is still the layout used by user (the new pt_regs doesn't have
+ all registers). */
+struct user_regs_struct {
+ long er1, er2, er3, er4, er5, er6;
+ long er0;
+ long usp;
+ long orig_er0;
+ long ccr;
+ long pc;
+};
+
+/* When the kernel dumps core, it starts by dumping the user struct -
+ this will be used by gdb to figure out where the data and stack segments
+ are within the file, and what virtual addresses to use. */
+struct user {
+/* We start with the registers, to mimic the way that "memory" is returned
+ from the ptrace(3,...) function. */
+ struct user_regs_struct regs; /* Where the registers are actually stored */
+/* ptrace does not yet supply these. Someday.... */
+/* The rest of this junk is to help gdb figure out what goes where */
+ unsigned long int u_tsize; /* Text segment size (pages). */
+ unsigned long int u_dsize; /* Data segment size (pages). */
+ unsigned long int u_ssize; /* Stack segment size (pages). */
+ unsigned long start_code; /* Starting virtual address of text. */
+ unsigned long start_stack; /* Starting virtual address of stack area.
+ This is actually the bottom of the stack,
+ the top of the stack is always found in the
+ esp register. */
+ long int signal; /* Signal that caused the core dump. */
+ int reserved; /* No longer used */
+ unsigned long u_ar0; /* Used by gdb to help find the values for */
+ /* the registers. */
+ unsigned long magic; /* To uniquely identify a core file */
+ char u_comm[32]; /* User command that was responsible */
+};
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
arch/h8300/include/uapi/asm/Kbuild | 29 ++++++++
arch/h8300/include/uapi/asm/auxvec.h | 4 ++
arch/h8300/include/uapi/asm/byteorder.h | 6 ++
arch/h8300/include/uapi/asm/ptrace.h | 42 +++++++++++
arch/h8300/include/uapi/asm/sigcontext.h | 18 +++++
arch/h8300/include/uapi/asm/signal.h | 115 +++++++++++++++++++++++++++++++
arch/h8300/include/uapi/asm/swab.h | 1 +
arch/h8300/include/uapi/asm/unistd.h | 3 +
8 files changed, 218 insertions(+)
create mode 100644 arch/h8300/include/uapi/asm/Kbuild
create mode 100644 arch/h8300/include/uapi/asm/auxvec.h
create mode 100644 arch/h8300/include/uapi/asm/byteorder.h
create mode 100644 arch/h8300/include/uapi/asm/ptrace.h
create mode 100644 arch/h8300/include/uapi/asm/sigcontext.h
create mode 100644 arch/h8300/include/uapi/asm/signal.h
create mode 100644 arch/h8300/include/uapi/asm/swab.h
create mode 100644 arch/h8300/include/uapi/asm/unistd.h
diff --git a/arch/h8300/include/uapi/asm/Kbuild b/arch/h8300/include/uapi/asm/Kbuild
new file mode 100644
index 0000000..077e720
--- /dev/null
+++ b/arch/h8300/include/uapi/asm/Kbuild
@@ -0,0 +1,29 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += kvm_para.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += siginfo.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += unistd.h
diff --git a/arch/h8300/include/uapi/asm/auxvec.h b/arch/h8300/include/uapi/asm/auxvec.h
new file mode 100644
index 0000000..1d36fe38
--- /dev/null
+++ b/arch/h8300/include/uapi/asm/auxvec.h
@@ -0,0 +1,4 @@
+#ifndef __ASMH8300_AUXVEC_H
+#define __ASMH8300_AUXVEC_H
+
+#endif
diff --git a/arch/h8300/include/uapi/asm/byteorder.h b/arch/h8300/include/uapi/asm/byteorder.h
new file mode 100644
index 0000000..13539da
--- /dev/null
+++ b/arch/h8300/include/uapi/asm/byteorder.h
@@ -0,0 +1,6 @@
+#ifndef _H8300_BYTEORDER_H
+#define _H8300_BYTEORDER_H
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* _H8300_BYTEORDER_H */
diff --git a/arch/h8300/include/uapi/asm/ptrace.h b/arch/h8300/include/uapi/asm/ptrace.h
new file mode 100644
index 0000000..e132670d
--- /dev/null
+++ b/arch/h8300/include/uapi/asm/ptrace.h
@@ -0,0 +1,42 @@
+#ifndef _UAPI_H8300_PTRACE_H
+#define _UAPI_H8300_PTRACE_H
+
+#ifndef __ASSEMBLY__
+
+#define PT_ER1 0
+#define PT_ER2 1
+#define PT_ER3 2
+#define PT_ER4 3
+#define PT_ER5 4
+#define PT_ER6 5
+#define PT_ER0 6
+#define PT_USP 7
+#define PT_ORIG_ER0 8
+#define PT_CCR 9
+#define PT_PC 10
+#define PT_EXR 11
+
+/* this struct defines the way the registers are stored on the
+ stack during a system call. */
+
+struct pt_regs {
+ long retpc;
+ long er4;
+ long er5;
+ long er6;
+ long er3;
+ long er2;
+ long er1;
+ long orig_er0;
+ long sp;
+ unsigned short ccr;
+ long er0;
+ long vector;
+#if defined(__H8300S__)
+ unsigned short exr;
+#endif
+ unsigned long pc;
+} __attribute__((aligned(2), packed));
+
+#endif /* __ASSEMBLY__ */
+#endif /* _UAPI_H8300_PTRACE_H */
diff --git a/arch/h8300/include/uapi/asm/sigcontext.h b/arch/h8300/include/uapi/asm/sigcontext.h
new file mode 100644
index 0000000..c41fdaa
--- /dev/null
+++ b/arch/h8300/include/uapi/asm/sigcontext.h
@@ -0,0 +1,18 @@
+#ifndef _ASM_H8300_SIGCONTEXT_H
+#define _ASM_H8300_SIGCONTEXT_H
+
+struct sigcontext {
+ unsigned long sc_mask; /* old sigmask */
+ unsigned long sc_usp; /* old user stack pointer */
+ unsigned long sc_er0;
+ unsigned long sc_er1;
+ unsigned long sc_er2;
+ unsigned long sc_er3;
+ unsigned long sc_er4;
+ unsigned long sc_er5;
+ unsigned long sc_er6;
+ unsigned short sc_ccr;
+ unsigned long sc_pc;
+};
+
+#endif
diff --git a/arch/h8300/include/uapi/asm/signal.h b/arch/h8300/include/uapi/asm/signal.h
new file mode 100644
index 0000000..af3a6c3
--- /dev/null
+++ b/arch/h8300/include/uapi/asm/signal.h
@@ -0,0 +1,115 @@
+#ifndef _UAPI_H8300_SIGNAL_H
+#define _UAPI_H8300_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems. */
+struct siginfo;
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+#define NSIG 32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+/*
+#define SIGLOST 29
+*/
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED 31
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP 0x00000001
+#define SA_NOCLDWAIT 0x00000002 /* not supported yet */
+#define SA_SIGINFO 0x00000004
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+#define SA_RESTORER 0x04000000
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+#include <asm-generic/signal-defs.h>
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+struct sigaction {
+ union {
+ __sighandler_t _sa_handler;
+ void (*_sa_sigaction)(int, struct siginfo *, void *);
+ } _u;
+ sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+};
+
+#define sa_handler _u._sa_handler
+#define sa_sigaction _u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+ void *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+
+#endif /* _UAPI_H8300_SIGNAL_H */
diff --git a/arch/h8300/include/uapi/asm/swab.h b/arch/h8300/include/uapi/asm/swab.h
new file mode 100644
index 0000000..7847e56
--- /dev/null
+++ b/arch/h8300/include/uapi/asm/swab.h
@@ -0,0 +1 @@
+#include <asm-generic/swab.h>
diff --git a/arch/h8300/include/uapi/asm/unistd.h b/arch/h8300/include/uapi/asm/unistd.h
new file mode 100644
index 0000000..7a2eb69
--- /dev/null
+++ b/arch/h8300/include/uapi/asm/unistd.h
@@ -0,0 +1,3 @@
+#define __ARCH_NOMMU
+
+#include <asm-generic/unistd.h>
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
arch/h8300/kernel/entry.S | 418 ++++++++++++++++++++++++++++++++++++++++++++++
arch/h8300/kernel/irq.c | 106 ++++++++++++
arch/h8300/kernel/traps.c | 166 ++++++++++++++++++
3 files changed, 690 insertions(+)
create mode 100644 arch/h8300/kernel/entry.S
create mode 100644 arch/h8300/kernel/irq.c
create mode 100644 arch/h8300/kernel/traps.c
diff --git a/arch/h8300/kernel/entry.S b/arch/h8300/kernel/entry.S
new file mode 100644
index 0000000..ba50639
--- /dev/null
+++ b/arch/h8300/kernel/entry.S
@@ -0,0 +1,418 @@
+/*
+ *
+ * linux/arch/h8300/kernel/entry.S
+ *
+ * Yoshinori Sato <[email protected]>
+ * David McCullough <[email protected]>
+ *
+ */
+
+/*
+ * entry.S
+ * include exception/interrupt gateway
+ * system call entry
+ */
+
+#include <linux/sys.h>
+#include <asm/unistd.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+
+#if defined(CONFIG_CPU_H8300H)
+#define USERRET 8
+INTERRUPTS = 64
+ .h8300h
+ .macro SHLL2 reg
+ shll.l \reg
+ shll.l \reg
+ .endm
+ .macro SHLR2 reg
+ shlr.l \reg
+ shlr.l \reg
+ .endm
+ .macro SAVEREGS
+ mov.l er0,@-sp
+ mov.l er1,@-sp
+ mov.l er2,@-sp
+ mov.l er3,@-sp
+ .endm
+ .macro RESTOREREGS
+ mov.l @sp+,er3
+ mov.l @sp+,er2
+ .endm
+ .macro SAVEEXR
+ .endm
+ .macro RESTOREEXR
+ .endm
+#endif
+#if defined(CONFIG_CPU_H8S)
+#define USERRET 10
+#define USEREXR 8
+INTERRUPTS = 128
+ .h8300s
+ .macro SHLL2 reg
+ shll.l #2,\reg
+ .endm
+ .macro SHLR2 reg
+ shlr.l #2,\reg
+ .endm
+ .macro SAVEREGS
+ stm.l er0-er3,@-sp
+ .endm
+ .macro RESTOREREGS
+ ldm.l @sp+,er2-er3
+ .endm
+ .macro SAVEEXR
+ mov.w @(USEREXR:16,er0),r1
+ mov.w r1,@(LEXR-LER3:16,sp) /* copy EXR */
+ .endm
+ .macro RESTOREEXR
+ mov.w @(LEXR-LER1:16,sp),r1 /* restore EXR */
+ mov.b r1l,r1h
+ mov.w r1,@(USEREXR:16,er0)
+ .endm
+#endif
+
+
+/* CPU context save/restore macros. */
+
+ .macro SAVE_ALL
+ mov.l er0,@-sp
+ stc ccr,r0l /* check kernel mode */
+ btst #4,r0l
+ bne 5f
+
+ /* user mode */
+ mov.l sp,@_sw_usp
+ mov.l @sp,er0 /* restore saved er0 */
+ orc #0x10,ccr /* switch kernel stack */
+ mov.l @_sw_ksp,sp
+ sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */
+ SAVEREGS
+ mov.l @_sw_usp,er0
+ mov.l @(USERRET:16,er0),er1 /* copy the RET addr */
+ mov.l er1,@(LRET-LER3:16,sp)
+ SAVEEXR
+
+ mov.l @(LORIG-LER3:16,sp),er0
+ mov.l er0,@(LER0-LER3:16,sp) /* copy ER0 */
+ mov.w e1,r1 /* e1 highbyte = ccr */
+ and #0xef,r1h /* mask mode? flag */
+ bra 6f
+5:
+ /* kernel mode */
+ mov.l @sp,er0 /* restore saved er0 */
+ subs #2,sp /* set dummy ccr */
+ subs #4,sp /* set dummp sp */
+ SAVEREGS
+ mov.w @(LRET-LER3:16,sp),r1 /* copy old ccr */
+6:
+ mov.b r1h,r1l
+ mov.b #0,r1h
+ mov.w r1,@(LCCR-LER3:16,sp) /* set ccr */
+ mov.l @_sw_usp,er2
+ mov.l er2,@(LSP-LER3:16,sp) /* set usp */
+ mov.l er6,@-sp /* syscall arg #6 */
+ mov.l er5,@-sp /* syscall arg #5 */
+ mov.l er4,@-sp /* syscall arg #4 */
+ .endm /* r1 = ccr */
+
+ .macro RESTORE_ALL
+ mov.l @sp+,er4
+ mov.l @sp+,er5
+ mov.l @sp+,er6
+ RESTOREREGS
+ mov.w @(LCCR-LER1:16,sp),r0 /* check kernel mode */
+ btst #4,r0l
+ bne 7f
+
+ orc #0xc0,ccr
+ mov.l @(LSP-LER1:16,sp),er0
+ mov.l @(LER0-LER1:16,sp),er1 /* restore ER0 */
+ mov.l er1,@er0
+ RESTOREEXR
+ mov.w @(LCCR-LER1:16,sp),r1 /* restore the RET addr */
+ mov.b r1l,r1h
+ mov.b @(LRET+1-LER1:16,sp),r1l
+ mov.w r1,e1
+ mov.w @(LRET+2-LER1:16,sp),r1
+ mov.l er1,@(USERRET:16,er0)
+
+ mov.l @sp+,er1
+ add.l #(LRET-LER1),sp /* remove LORIG - LRET */
+ mov.l sp,@_sw_ksp
+ andc #0xef,ccr /* switch to user mode */
+ mov.l er0,sp
+ bra 8f
+7:
+ mov.l @sp+,er1
+ add.l #10,sp
+8:
+ mov.l @sp+,er0
+ adds #4,sp /* remove the sw created LVEC */
+ rte
+ .endm
+
+.globl _system_call
+.globl ret_from_exception
+.globl ret_from_fork
+.globl ret_from_kernel_thread
+.globl ret_from_interrupt
+.globl _interrupt_redirect_table
+.globl _sw_ksp,_sw_usp
+.globl _resume
+.globl _interrupt_entry
+.globl _trace_break
+.globl _nmi
+
+#if defined(CONFIG_ROMKERNEL)
+ .section .int_redirect,"ax"
+_interrupt_redirect_table:
+#if defined(CONFIG_CPU_H8300H)
+ .rept 7
+ .long 0
+ .endr
+#endif
+#if defined(CONFIG_CPU_H8S)
+ .rept 5
+ .long 0
+ .endr
+ jmp @_trace_break
+ .long 0
+#endif
+
+ jsr @_interrupt_entry /* NMI */
+ jmp @_system_call /* TRAPA #0 (System call) */
+ .long 0
+ .long 0
+ jmp @_trace_break /* TRAPA #3 (breakpoint) */
+ .rept INTERRUPTS-12
+ jsr @_interrupt_entry
+ .endr
+#endif
+#if defined(CONFIG_RAMKERNEL)
+.globl _interrupt_redirect_table
+ .section .bss
+_interrupt_redirect_table:
+ .space 4
+#endif
+
+ .section .text
+ .align 2
+_interrupt_entry:
+ SAVE_ALL
+/* r1l is saved ccr */
+ mov.l sp,er0
+ add.l #LVEC,er0
+ btst #4,r1l
+ bne 1f
+ /* user LVEC */
+ mov.l @_sw_usp,er0
+ adds #4,er0
+1:
+ mov.l @er0,er0 /* LVEC address */
+#if defined(CONFIG_ROMKERNEL)
+ sub.l #_interrupt_redirect_table,er0
+#endif
+#if defined(CONFIG_RAMKERNEL)
+ mov.l @_interrupt_redirect_table,er1
+ sub.l er1,er0
+#endif
+ SHLR2 er0
+ dec.l #1,er0
+ mov.l sp,er1
+ subs #4,er1 /* adjust ret_pc */
+#if defined(CONFIG_CPU_H8S)
+ orc #7,exr
+#endif
+ jsr @do_IRQ
+ jmp @ret_from_interrupt
+
+_system_call:
+ subs #4,sp /* dummy LVEC */
+ SAVE_ALL
+ /* er0: syscall nr */
+ andc #0xbf,ccr
+ mov.l er0,er4
+
+ /* save top of frame */
+ mov.l sp,er0
+ jsr @set_esp0
+ mov.l sp,er2
+ and.w #0xe000,r2
+ mov.l @(TI_FLAGS:16,er2),er2
+ and.w #_TIF_WORK_SYSCALL_MASK,r2
+ beq 1f
+ mov.l sp,er0
+ jsr @do_syscall_trace_enter
+1:
+ cmp.l #__NR_syscalls,er4
+ bcc badsys
+ SHLL2 er4
+ mov.l #_sys_call_table,er0
+ add.l er4,er0
+ mov.l @er0,er4
+ beq ret_from_exception:16
+ mov.l @(LER1:16,sp),er0
+ mov.l @(LER2:16,sp),er1
+ mov.l @(LER3:16,sp),er2
+ jsr @er4
+ mov.l er0,@(LER0:16,sp) /* save the return value */
+ mov.l sp,er2
+ and.w #0xe000,r2
+ mov.l @(TI_FLAGS:16,er2),er2
+ and.w #_TIF_WORK_SYSCALL_MASK,r2
+ beq 2f
+ mov.l sp,er0
+ jsr @do_syscall_trace_leave
+2:
+ orc #0xc0,ccr
+ bra resume_userspace
+
+badsys:
+ mov.l #-ENOSYS,er0
+ mov.l er0,@(LER0:16,sp)
+ bra resume_userspace
+
+#if !defined(CONFIG_PREEMPT)
+#define resume_kernel restore_all
+#endif
+
+ret_from_exception:
+#if defined(CONFIG_PREEMPT)
+ orc #0xc0,ccr
+#endif
+ret_from_interrupt:
+ mov.b @(LCCR+1:16,sp),r0l
+ btst #4,r0l
+#if defined(CONFIG_PREEMPT)
+ bne resume_kernel:16 /* return from kernel */
+#else
+ bne restore_all:16 /* return from kernel */
+#endif
+resume_userspace:
+ andc #0xbf,ccr
+ mov.l sp,er4
+ and.w #0xe000,r4 /* er4 <- current thread info */
+ mov.l @(TI_FLAGS:16,er4),er1
+ and.l #_TIF_WORK_MASK,er1
+ beq restore_all:8
+work_pending:
+ btst #TIF_NEED_RESCHED,r1l
+ bne work_resched:8
+ /* work notifysig */
+ mov.l sp,er0
+ subs #4,er0 /* er0: pt_regs */
+ jsr @do_notify_resume
+ bra restore_all:8
+work_resched:
+ mov.l sp,er0
+ jsr @set_esp0
+ jsr @schedule
+ bra resume_userspace:8
+restore_all:
+ RESTORE_ALL /* Does RTE */
+
+#if defined(CONFIG_PREEMPT)
+resume_kernel:
+ mov.l @(TI_PRE_COUNT:16,er4),er0
+ bne restore_all:8
+need_resched:
+ mov.l @(TI_FLAGS:16,er4),er0
+ btst #TIF_NEED_RESCHED,r0l
+ beq restore_all:8
+ mov.b @(LCCR+1:16,sp),r0l /* Interrupt Enabled? */
+ bmi restore_all:8
+ mov.l sp,er0
+ jsr @set_esp0
+ jsr @preempt_schedule_irq
+ bra need_resched:8
+#endif
+
+ret_from_fork:
+ mov.l er2,er0
+ jsr @schedule_tail
+ jmp @ret_from_exception
+
+ret_from_kernel_thread:
+ mov.l er2,er0
+ jsr @schedule_tail
+ mov.l @(LER4:16,sp),er0
+ mov.l @(LER5:16,sp),er1
+ jsr @er1
+ jmp @ret_from_exception
+
+_resume:
+ /*
+ * Beware - when entering resume, offset of tss is in d1,
+ * prev (the current task) is in a0, next (the new task)
+ * is in a1 and d2.b is non-zero if the mm structure is
+ * shared between the tasks, so don't change these
+ * registers until their contents are no longer needed.
+ */
+
+ /* save sr */
+ sub.w r3,r3
+ stc ccr,r3l
+ mov.w r3,@(THREAD_CCR+2:16,er0)
+
+ /* disable interrupts */
+ orc #0xc0,ccr
+ mov.l @_sw_usp,er3
+ mov.l er3,@(THREAD_USP:16,er0)
+ mov.l sp,@(THREAD_KSP:16,er0)
+
+ /* Skip address space switching if they are the same. */
+ /* FIXME: what did we hack out of here, this does nothing! */
+
+ mov.l @(THREAD_USP:16,er1),er0
+ mov.l er0,@_sw_usp
+ mov.l @(THREAD_KSP:16,er1),sp
+
+ /* restore status register */
+ mov.w @(THREAD_CCR+2:16,er1),r3
+
+ ldc r3l,ccr
+ rts
+
+_trace_break:
+ subs #4,sp
+ SAVE_ALL
+ sub.l er1,er1
+ dec.l #1,er1
+ mov.l er1,@(LORIG,sp)
+ mov.l sp,er0
+ jsr @set_esp0
+ mov.l @_sw_usp,er0
+ mov.l @er0,er1
+ mov.w @(-2:16,er1),r2
+ cmp.w #0x5730,r2
+ beq 1f
+ subs #2,er1
+ mov.l er1,@er0
+1:
+ and.w #0xff,e1
+ mov.l er1,er0
+ jsr @trace_trap
+ jmp @ret_from_exception
+
+_nmi:
+ subs #4, sp
+ mov.l er0, @-sp
+ mov.l @_interrupt_redirect_table, er0
+ add.l #8*4, er0
+ mov.l er0, @(4,sp)
+ mov.l @sp+, er0
+ jmp @_interrupt_entry
+
+ .section .bss
+_sw_ksp:
+ .space 4
+_sw_usp:
+ .space 4
+
+ .end
diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c
new file mode 100644
index 0000000..dbff621
--- /dev/null
+++ b/arch/h8300/kernel/irq.c
@@ -0,0 +1,106 @@
+/*
+ * linux/arch/h8300/kernel/irq.c
+ *
+ * Copyright 2014 Yoshinori Sato <[email protected]>
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/traps.h>
+
+#ifdef CONFIG_RAMKERNEL
+#define CPU_VECTOR ((unsigned long *)0x000000)
+#define ADDR_MASK (0xffffff)
+
+extern unsigned long *_interrupt_redirect_table;
+void _interrupt_entry(void);
+
+typedef void (*h8300_vector)(void);
+
+static const h8300_vector __initconst trap_table[] = {
+ 0, 0, 0, 0,
+ _trace_break,
+ 0, 0,
+ _nmi,
+ _system_call,
+ 0, 0,
+ _trace_break,
+};
+
+static unsigned long __init *get_vector_address(void)
+{
+ unsigned long *rom_vector = CPU_VECTOR;
+ unsigned long base, tmp;
+ int vec_no;
+
+ base = rom_vector[EXT_IRQ0] & ADDR_MASK;
+
+ /* check romvector format */
+ for (vec_no = EXT_IRQ0 + 1; vec_no <= EXT_IRQ0+EXT_IRQS; vec_no++) {
+ if ((base+(vec_no - EXT_IRQ0)*4) !=
+ (rom_vector[vec_no] & ADDR_MASK))
+ return NULL;
+ }
+
+ /* ramvector base address */
+ base -= EXT_IRQ0*4;
+
+ /* writerble? */
+ tmp = ~(*(volatile unsigned long *)base);
+ (*(volatile unsigned long *)base) = tmp;
+ if ((*(volatile unsigned long *)base) != tmp)
+ return NULL;
+ return (unsigned long *)base;
+}
+
+static void __init setup_vector(void)
+{
+ int i;
+ unsigned long *ramvec, *ramvec_p;
+ const h8300_vector *trap_entry;
+
+ ramvec = get_vector_address();
+ if (ramvec == NULL)
+ panic("interrupt vector serup failed.");
+ else
+ pr_debug("virtual vector at 0x%p\n", ramvec);
+
+ /* create redirect table */
+ ramvec_p = ramvec;
+ trap_entry = trap_table;
+ for (i = 0; i < NR_IRQS; i++) {
+ if (i < 12) {
+ if (*trap_entry)
+ *ramvec_p = VECTOR(*trap_entry);
+ ramvec_p++;
+ trap_entry++;
+ } else
+ *ramvec_p++ = REDIRECT(_interrupt_entry);
+ }
+ _interrupt_redirect_table = ramvec;
+}
+#else
+void setup_vector(void)
+{
+ /* noting do */
+}
+#endif
+
+void __init init_IRQ(void)
+{
+ int c;
+
+ setup_vector();
+ h8300_init_ipr();
+
+ for (c = 0; c < NR_IRQS; c++)
+ irq_set_chip_and_handler(c, &IRQ_CHIP, handle_simple_irq);
+}
+
+asmlinkage void do_IRQ(int irq)
+{
+ irq_enter();
+ generic_handle_irq(irq);
+ irq_exit();
+}
diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c
new file mode 100644
index 0000000..5a15f42
--- /dev/null
+++ b/arch/h8300/kernel/traps.c
@@ -0,0 +1,166 @@
+/*
+ * linux/arch/h8300/boot/traps.c -- general exception handling code
+ * H8/300 support Yoshinori Sato <[email protected]>
+ *
+ * Cloned from Linux/m68k.
+ *
+ * No original Copyright holder listed,
+ * Probable original (C) Roman Zippel (assigned DJD, 1999)
+ *
+ * Copyright 1999-2000 D. Jeff Dionne, <[email protected]>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/bug.h>
+
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+
+static DEFINE_SPINLOCK(die_lock);
+
+/*
+ * this must be called very early as the kernel might
+ * use some instruction that are emulated on the 060
+ */
+
+void __init base_trap_init(void)
+{
+}
+
+void __init trap_init(void)
+{
+}
+
+asmlinkage void set_esp0 (unsigned long ssp)
+{
+ current->thread.esp0 = ssp;
+}
+
+/*
+ * Generic dumping code. Used for panic and debug.
+ */
+
+static void dump(struct pt_regs *fp)
+{
+ unsigned long *sp;
+ unsigned char *tp;
+ int i;
+
+ pr_info("\nCURRENT PROCESS:\n\n");
+ pr_info("COMM=%s PID=%d\n", current->comm, current->pid);
+ if (current->mm) {
+ pr_info("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+ (int) current->mm->start_code,
+ (int) current->mm->end_code,
+ (int) current->mm->start_data,
+ (int) current->mm->end_data,
+ (int) current->mm->end_data,
+ (int) current->mm->brk);
+ pr_info("USER-STACK=%08x KERNEL-STACK=%08lx\n\n",
+ (int) current->mm->start_stack,
+ (int) PAGE_SIZE+(unsigned long)current);
+ }
+
+ show_regs(fp);
+ pr_info("\nCODE:");
+ tp = ((unsigned char *) fp->pc) - 0x20;
+ for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) {
+ if ((i % 0x10) == 0)
+ pr_info("\n%08x: ", (int) (tp + i));
+ pr_info("%08x ", (int) *sp++);
+ }
+ pr_info("\n");
+
+ pr_info("\nKERNEL STACK:");
+ tp = ((unsigned char *) fp) - 0x40;
+ for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+ if ((i % 0x10) == 0)
+ pr_info("\n%08x: ", (int) (tp + i));
+ pr_info("%08x ", (int) *sp++);
+ }
+ pr_info("\n");
+ if (STACK_MAGIC != *(unsigned long *)((unsigned long)current+PAGE_SIZE))
+ pr_info("(Possibly corrupted stack page??)\n");
+
+ pr_info("\n\n");
+}
+
+void die(const char *str, struct pt_regs *fp, unsigned long err)
+{
+ static int diecount;
+
+ oops_enter();
+
+ console_verbose();
+ spin_lock_irq(&die_lock);
+ report_bug(fp->pc, fp);
+ pr_crit("%s: %04lx [#%d] ", str, err & 0xffff, ++diecount);
+ dump(fp);
+
+ spin_unlock_irq(&die_lock);
+ do_exit(SIGSEGV);
+}
+
+extern char _start, _etext;
+#define check_kernel_text(addr) \
+ ((addr >= (unsigned long)(&_start)) && \
+ (addr < (unsigned long)(&_etext)))
+
+static int kstack_depth_to_print = 24;
+
+void show_stack(struct task_struct *task, unsigned long *esp)
+{
+ unsigned long *stack, addr;
+ int i;
+
+ if (esp == NULL)
+ esp = (unsigned long *) &esp;
+
+ stack = esp;
+
+ pr_info("Stack from %08lx:", (unsigned long)stack);
+ for (i = 0; i < kstack_depth_to_print; i++) {
+ if (((unsigned long)stack & (THREAD_SIZE - 1)) == 0)
+ break;
+ if (i % 8 == 0)
+ pr_info("\n ");
+ pr_info(" %08lx", *stack++);
+ }
+
+ pr_info("\nCall Trace:");
+ i = 0;
+ stack = esp;
+ while (((unsigned long)stack & (THREAD_SIZE - 1)) != 0) {
+ addr = *stack++;
+ /*
+ * If the address is either in the text segment of the
+ * kernel, or in the region which contains vmalloc'ed
+ * memory, it *may* be the address of a calling
+ * routine; if so, print it so that someone tracing
+ * down the cause of the crash will be able to figure
+ * out the call path that was taken.
+ */
+ if (check_kernel_text(addr)) {
+ if (i % 4 == 0)
+ pr_info("\n ");
+ pr_info(" [<%08lx>]", addr);
+ i++;
+ }
+ }
+ pr_info("\n");
+}
+
+void show_trace_task(struct task_struct *tsk)
+{
+ show_stack(tsk, (unsigned long *)tsk->thread.esp0);
+}
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
arch/h8300/boot/Makefile | 27 +++++
arch/h8300/boot/compressed/Makefile | 37 +++++++
arch/h8300/boot/compressed/head.S | 48 +++++++++
arch/h8300/boot/compressed/misc.c | 74 ++++++++++++++
arch/h8300/boot/compressed/vmlinux.lds | 32 ++++++
arch/h8300/boot/compressed/vmlinux.scr | 9 ++
arch/h8300/kernel/head_ram.S | 60 ++++++++++++
arch/h8300/kernel/head_rom.S | 108 ++++++++++++++++++++
arch/h8300/kernel/setup.c | 174 +++++++++++++++++++++++++++++++++
9 files changed, 569 insertions(+)
create mode 100644 arch/h8300/boot/Makefile
create mode 100644 arch/h8300/boot/compressed/Makefile
create mode 100644 arch/h8300/boot/compressed/head.S
create mode 100644 arch/h8300/boot/compressed/misc.c
create mode 100644 arch/h8300/boot/compressed/vmlinux.lds
create mode 100644 arch/h8300/boot/compressed/vmlinux.scr
create mode 100644 arch/h8300/kernel/head_ram.S
create mode 100644 arch/h8300/kernel/head_rom.S
create mode 100644 arch/h8300/kernel/setup.c
diff --git a/arch/h8300/boot/Makefile b/arch/h8300/boot/Makefile
new file mode 100644
index 0000000..5072b36
--- /dev/null
+++ b/arch/h8300/boot/Makefile
@@ -0,0 +1,27 @@
+# arch/h8300/boot/Makefile
+
+targets := vmlinux.srec vmlinux.bin zImage
+subdir- := compressed
+
+OBJCOPYFLAGS_vmlinux.srec := -Osrec
+OBJCOPYFLAGS_vmlinux.bin := -Obinary
+OBJCOPYFLAGS_zImage := -O binary -R .note -R .comment -R .stab -R .stabstr -S
+
+UIMAGE_LOADADDR = $(CONFIG_RAMBASE)
+UIMAGE_ENTRYADDR = $(shell /bin/bash -c 'printf "0x%08x" \
+ $$[$(CONFIG_RAMBASE) + $(CONFIG_OFFSET)]')
+
+$(obj)/vmlinux.srec $(obj)/vmlinux.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/compressed/vmlinux: FORCE
+ $(Q)$(MAKE) $(build)=$(obj)/compressed $@
+
+$(obj)/uImage.bin: $(obj)/vmlinux.bin
+ $(call if_changed,uimage,none)
+
+CLEAN_FILES += arch/$(ARCH)/vmlinux.bin arch/$(ARCH)/vmlinux.srec arch/$(ARCH)/uImage.bin
+
diff --git a/arch/h8300/boot/compressed/Makefile b/arch/h8300/boot/compressed/Makefile
new file mode 100644
index 0000000..87d03b7
--- /dev/null
+++ b/arch/h8300/boot/compressed/Makefile
@@ -0,0 +1,37 @@
+#
+# linux/arch/sh/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
+
+OBJECTS = $(obj)/head.o $(obj)/misc.o
+
+#
+# IMAGE_OFFSET is the load offset of the compression loader
+# Assign dummy values if these 2 variables are not defined,
+# in order to suppress error message.
+#
+CONFIG_MEMORY_START ?= 0x00400000
+CONFIG_BOOT_LINK_OFFSET ?= 0x00140000
+IMAGE_OFFSET := $(shell printf "0x%08x" $$(($(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET))))
+
+LIBGCC := $(shell $(CROSS-COMPILE)$(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
+LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -estartup $(obj)/vmlinux.lds
+
+$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
+ $(call if_changed,ld)
+ @:
+
+$(obj)/vmlinux.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,gzip)
+
+LDFLAGS_piggy.o := -r --format binary --oformat elf32-h8300-linux -T
+OBJCOPYFLAGS := -O binary
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+ $(call if_changed,ld)
diff --git a/arch/h8300/boot/compressed/head.S b/arch/h8300/boot/compressed/head.S
new file mode 100644
index 0000000..74c0d8cc
--- /dev/null
+++ b/arch/h8300/boot/compressed/head.S
@@ -0,0 +1,48 @@
+/*
+ * linux/arch/h8300/boot/compressed/head.S
+ *
+ * Copyright (C) 2006 Yoshinori Sato
+ */
+
+#include <linux/linkage.h>
+
+ .section .text..startup,"ax"
+ .global startup
+startup:
+ mov.l er0, er4
+ mov.l er0, sp
+ mov.l #__sbss, er0
+ mov.l #__ebss, er1
+ sub.l er0, er1
+ shlr er1
+ shlr er1
+ sub.l er2, er2
+1:
+ mov.l er2, @er0
+ adds #4, er0
+ dec.l #1, er1
+ bne 1b
+ jsr @decompress_kernel
+ mov.l er4, er0
+ jmp @0x400000
+
+ .align 9
+fake_headers_as_bzImage:
+ .word 0
+ .ascii "HdrS" ; header signature
+ .word 0x0202 ; header version number (>= 0x0105)
+ ; or else old loadlin-1.5 will fail)
+ .word 0 ; default_switch
+ .word 0 ; SETUPSEG
+ .word 0x1000
+ .word 0 ; pointing to kernel version string
+ .byte 0 ; = 0, old one (LILO, Loadlin,
+ ; 0xTV: T=0 for LILO
+ ; V = version
+ .byte 1 ; Load flags bzImage=1
+ .word 0x8000 ; size to move, when setup is not
+ .long 0x100000 ; 0x100000 = default for big kernel
+ .long 0 ; address of loaded ramdisk image
+ .long 0 ; its size in bytes
+
+ .end
diff --git a/arch/h8300/boot/compressed/misc.c b/arch/h8300/boot/compressed/misc.c
new file mode 100644
index 0000000..7042741
--- /dev/null
+++ b/arch/h8300/boot/compressed/misc.c
@@ -0,0 +1,74 @@
+/*
+ * arch/h8300/boot/compressed/misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for h8300 by Yoshinori Sato 2006
+ */
+
+#include <asm/uaccess.h>
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args) args
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#define memzero(s, n) memset((s), (0), (n))
+
+extern int _end;
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+extern char input_data[];
+extern int input_len;
+static unsigned char *output;
+
+#define HEAP_SIZE 0x10000
+
+#include "../../../../lib/decompress_inflate.c"
+
+void *memset(void *s, int c, size_t n)
+{
+ int i;
+ char *ss = (char *)s;
+
+ for (i = 0; i < n; i++)
+ ss[i] = c;
+ return s;
+}
+
+void *memcpy(void *dest, const void *src, size_t n)
+{
+ int i;
+ char *d = (char *)dest, *s = (char *)src;
+
+ for (i = 0; i < n; i++)
+ d[i] = s[i];
+ return dest;
+}
+
+static void error(char *x)
+{
+
+ while (1)
+ ; /* Halt */
+}
+
+#define STACK_SIZE (4096)
+long user_stack[STACK_SIZE];
+long *stack_start = &user_stack[STACK_SIZE];
+
+void decompress_kernel(void)
+{
+ free_mem_ptr = (unsigned long)&_end;
+ free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
+ decompress(input_data, input_len, NULL, NULL, output, NULL, error);
+}
diff --git a/arch/h8300/boot/compressed/vmlinux.lds b/arch/h8300/boot/compressed/vmlinux.lds
new file mode 100644
index 0000000..a0a3a0e
--- /dev/null
+++ b/arch/h8300/boot/compressed/vmlinux.lds
@@ -0,0 +1,32 @@
+SECTIONS
+{
+ .text :
+ {
+ __stext = . ;
+ __text = .;
+ *(.text..startup)
+ *(.text)
+ __etext = . ;
+ }
+
+ .rodata :
+ {
+ *(.rodata)
+ }
+ .data :
+
+ {
+ __sdata = . ;
+ ___data_start = . ;
+ *(.data.*)
+ }
+ .bss :
+ {
+ . = ALIGN(0x4) ;
+ __sbss = . ;
+ *(.bss*)
+ . = ALIGN(0x4) ;
+ __ebss = . ;
+ __end = . ;
+ }
+}
diff --git a/arch/h8300/boot/compressed/vmlinux.scr b/arch/h8300/boot/compressed/vmlinux.scr
new file mode 100644
index 0000000..a0849036
--- /dev/null
+++ b/arch/h8300/boot/compressed/vmlinux.scr
@@ -0,0 +1,9 @@
+SECTIONS
+{
+ .data : {
+ input_len = .;
+ LONG(input_data_end - input_data) input_data = .;
+ *(.data)
+ input_data_end = .;
+ }
+}
diff --git a/arch/h8300/kernel/head_ram.S b/arch/h8300/kernel/head_ram.S
new file mode 100644
index 0000000..f64b3d9
--- /dev/null
+++ b/arch/h8300/kernel/head_ram.S
@@ -0,0 +1,60 @@
+
+#include <linux/sys.h>
+#include <linux/init.h>
+#include <asm/unistd.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+
+#if defined(CONFIG_CPU_H8300H)
+ .h8300h
+#define SYSCR 0xfee012
+#define IRAMTOP 0xffff20
+#endif
+#if defined(CONFIG_CPU_H8S)
+ .h8300s
+#define INTCR 0xffff31
+#define IRAMTOP 0xffc000
+#endif
+
+ __HEAD
+ .global _start
+_start:
+ mov.l #IRAMTOP,sp
+ /* .bss clear */
+ mov.l #_sbss,er5
+ mov.l #_ebss,er4
+ sub.l er5,er4
+ shlr er4
+ shlr er4
+ sub.l er1,er1
+1:
+ mov.l er1,@er5
+ adds #4,er5
+ dec.l #1,er4
+ bne 1b
+ jsr @parse_bootparam
+
+ /* linux kernel start */
+#if defined(CONFIG_CPU_H8300H)
+ ldc #0xd0,ccr /* running kernel */
+ mov.l #SYSCR,er0
+ bclr #3,@er0
+#endif
+#if defined(CONFIG_CPU_H8S)
+ ldc #0x07,exr
+ bclr #4,@INTCR:8
+ bset #5,@INTCR:8 /* Interrupt mode 2 */
+ ldc #0x90,ccr /* running kernel */
+#endif
+ mov.l #init_thread_union,sp
+ add.l #0x2000,sp
+ jsr @start_kernel
+
+1:
+ bra 1b
+
+ .end
diff --git a/arch/h8300/kernel/head_rom.S b/arch/h8300/kernel/head_rom.S
new file mode 100644
index 0000000..60ca8fa
--- /dev/null
+++ b/arch/h8300/kernel/head_rom.S
@@ -0,0 +1,108 @@
+#include <linux/init.h>
+#include <asm/thread_info.h>
+
+#if defined(CONFIG_CPU_H8300H)
+ .h8300h
+#define SYSCR 0xfee012
+#define IRAMTOP 0xffff20
+#define NR_INT 64
+#endif
+#if defined(CONFIG_CPU_H8S)
+ .h8300s
+#define INTCR 0xffff31
+#define IRAMTOP 0xffc000
+#define NR_INT 128
+#endif
+
+ __HEAD
+ .global _start
+_start:
+ mov.l #IRAMTOP,sp
+#if !defined(CONFIG_H8300H_SIM) && \
+ !defined(CONFIG_H8S_SIM)
+ jsr @lowlevel_init
+
+ /* copy .data */
+ mov.l #_begin_data,er5
+ mov.l #_sdata,er6
+ mov.l #_edata,er4
+ sub.l er6,er4
+ shlr.l er4
+ shlr.l er4
+1:
+ mov.l @er5+,er0
+ mov.l er0,@er6
+ adds #4,er6
+ dec.l #1,er4
+ bne 1b
+ /* .bss clear */
+ mov.l #_sbss,er5
+ mov.l #_ebss,er4
+ sub.l er5,er4
+ shlr er4
+ shlr er4
+ sub.l er0,er0
+1:
+ mov.l er0,@er5
+ adds #4,er5
+ dec.l #1,er4
+ bne 1b
+#else
+ /* get cmdline from gdb */
+ jsr @0xcc
+ ;; er0 - argc
+ ;; er1 - argv
+ mov.l #command_line,er3
+ adds #4,er1
+ dec.l #1,er0
+ beq 4f
+1:
+ mov.l @er1+,er2
+2:
+ mov.b @er2+,r4l
+ beq 3f
+ mov.b r4l,@er3
+ adds #1,er3
+ bra 2b
+3:
+ mov.b #' ',r4l
+ mov.b r4l,@er3
+ adds #1,er3
+ dec.l #1,er0
+ bne 1b
+ subs #1,er3
+ mov.b #0,r4l
+ mov.b r4l,@er3
+4:
+#endif
+ /* linux kernel start */
+#if defined(CONFIG_CPU_H8300H)
+ ldc #0xd0,ccr /* running kernel */
+ mov.l #SYSCR,er0
+ bclr #3,@er0
+#endif
+#if defined(CONFIG_CPU_H8S)
+ ldc #0x07,exr
+ bclr #4,@INTCR:8
+ bset #5,@INTCR:8 /* Interrupt mode 2 */
+ ldc #0x90,ccr /* running kernel */
+#endif
+ mov.l #init_thread_union,sp
+ add.l #0x2000,sp
+ jsr @start_kernel
+
+1:
+ bra 1b
+
+#if defined(CONFIG_ROMKERNEL)
+ /* interrupt vector */
+ .section .vectors,"ax"
+ .long _start
+ .long _start
+vector = 2
+ .rept NR_INT - 2
+ .long _interrupt_redirect_table+vector*4
+vector = vector + 1
+ .endr
+#endif
+ .end
diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c
new file mode 100644
index 0000000..812a55f
--- /dev/null
+++ b/arch/h8300/kernel/setup.c
@@ -0,0 +1,174 @@
+/*
+ * linux/arch/h8300/kernel/setup.c
+ *
+ * Copyright (C) 2001-2014 Yoshinori Sato <[email protected]>
+ */
+
+/*
+ * This file handles the architecture-dependent parts of system setup
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/console.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/bootmem.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/sections.h>
+#include <asm/bootparams.h>
+
+#if defined(CONFIG_CPU_H8300H)
+#define CPU "H8/300H"
+#elif defined(CONFIG_CPU_H8S)
+#define CPU "H8S"
+#else
+#define CPU "Unknown"
+#endif
+
+struct bootparams bootparams;
+unsigned long rom_length;
+unsigned long memory_start;
+unsigned long memory_end;
+EXPORT_SYMBOL(memory_end);
+
+char __initdata command_line[COMMAND_LINE_SIZE];
+
+extern unsigned long _ramend;
+void sim_console_register(void);
+int h8300_clk_init(unsigned long hz);
+
+void __init __attribute__((weak)) early_device_init(void)
+{
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+ int bootmap_size;
+
+#if defined(CONFIG_ROMKERNEL)
+ bootparams.ram_end = CONFIG_RAMBASE + CONFIG_RAMSIZE;
+ bootparams.clock_freq = CONFIG_CPU_CLOCK;
+#endif
+
+ memory_start = (unsigned long) &_ramend;
+
+ memory_start = PAGE_ALIGN(memory_start);
+ memory_end = bootparams.ram_end;
+
+ init_mm.start_code = (unsigned long) _stext;
+ init_mm.end_code = (unsigned long) _etext;
+ init_mm.end_data = (unsigned long) _edata;
+ init_mm.brk = (unsigned long) 0;
+
+ pr_notice("\r\n\nuClinux " CPU "\n");
+ pr_notice("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
+
+ strcpy(boot_command_line, command_line);
+ *cmdline_p = command_line;
+
+ parse_early_param();
+
+ /*
+ * give all the memory to the bootmap allocator, tell it to put the
+ * boot mem_map at the start of memory
+ */
+ bootmap_size = init_bootmem_node(
+ NODE_DATA(0),
+ memory_start >> PAGE_SHIFT, /* map goes here */
+ PAGE_OFFSET >> PAGE_SHIFT, /* 0 on coldfire */
+ memory_end >> PAGE_SHIFT);
+ /*
+ * free the usable memory, we have to make sure we do not free
+ * the bootmem bitmap so we then reserve it after freeing it :-)
+ */
+ free_bootmem(memory_start, memory_end - memory_start);
+ reserve_bootmem(memory_start, bootmap_size, BOOTMEM_DEFAULT);
+#if defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)
+ sim_console_register();
+#endif
+
+ early_device_init();
+ early_platform_driver_probe("earlyprintk", 1, 0);
+ /*
+ * get kmalloc into gear
+ */
+ paging_init();
+}
+
+/*
+ * Get CPU information for use by the procfs.
+ */
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+ char *cpu;
+ u_long clockfreq;
+
+ cpu = CPU;
+ clockfreq = bootparams.clock_freq;
+
+ seq_printf(m, "CPU:\t\t%s\n"
+ "Clock:\t\t%lu.%1luMHz\n"
+ "BogoMips:\t%lu.%02lu\n"
+ "Calibration:\t%lu loops\n",
+ cpu,
+ clockfreq/1000, clockfreq%1000,
+ (loops_per_jiffy*HZ)/500000,
+ ((loops_per_jiffy*HZ)/5000)%100,
+ (loops_per_jiffy*HZ));
+
+ return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ return *pos < num_possible_cpus() ?
+ ((void *) 0x12345678) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+const struct seq_operations cpuinfo_op = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = show_cpuinfo,
+};
+
+void __init parse_bootparam(struct bootparams *bp)
+{
+ memcpy(&bootparams, bp, bp->size);
+ strncpy(command_line, bootparams.command_line, sizeof(command_line));
+}
+
+static void __init timer_setup(void)
+{
+ early_platform_driver_register_all("earlytimer");
+ early_platform_driver_probe("earlytimer", 1, 0);
+}
+
+void __init time_init(void)
+{
+ h8300_clk_init(bootparams.clock_freq);
+ late_time_init = timer_setup;
+}
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
arch/h8300/kernel/process.c | 170 +++++++++++++++++++++++
arch/h8300/kernel/ptrace.c | 203 +++++++++++++++++++++++++++
arch/h8300/kernel/signal.c | 326 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 699 insertions(+)
create mode 100644 arch/h8300/kernel/process.c
create mode 100644 arch/h8300/kernel/ptrace.c
create mode 100644 arch/h8300/kernel/signal.c
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
new file mode 100644
index 0000000..c0f7511
--- /dev/null
+++ b/arch/h8300/kernel/process.c
@@ -0,0 +1,170 @@
+/*
+ * linux/arch/h8300/kernel/process.c
+ *
+ * Yoshinori Sato <[email protected]>
+ *
+ * Based on:
+ *
+ * linux/arch/m68knommu/kernel/process.c
+ *
+ * Copyright (C) 1998 D. Jeff Dionne <[email protected]>,
+ * Kenneth Albanowski <[email protected]>,
+ * The Silver Hammer Group, Ltd.
+ *
+ * linux/arch/m68k/kernel/process.c
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/rcupdate.h>
+
+#include <asm/uaccess.h>
+#include <asm/traps.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+
+void (*pm_power_off)(void) = NULL;
+EXPORT_SYMBOL(pm_power_off);
+
+asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
+
+/*
+ * The idle loop on an H8/300..
+ */
+void arch_cpu_idle(void)
+{
+ local_irq_enable();
+ __asm__("sleep");
+}
+
+void machine_restart(char *__unused)
+{
+ local_irq_disable();
+ __asm__("jmp @@0");
+}
+
+void machine_halt(void)
+{
+ local_irq_disable();
+ __asm__("sleep");
+ for (;;)
+ ;
+}
+
+void machine_power_off(void)
+{
+ local_irq_disable();
+ __asm__("sleep");
+ for (;;)
+ ;
+}
+
+void show_regs(struct pt_regs *regs)
+{
+ show_regs_print_info(KERN_DEFAULT);
+
+ printk("\nPC: %08lx Status: %02x",
+ regs->pc, regs->ccr);
+ printk("\nORIG_ER0: %08lx ER0: %08lx ER1: %08lx",
+ regs->orig_er0, regs->er0, regs->er1);
+ printk("\nER2: %08lx ER3: %08lx ER4: %08lx ER5: %08lx",
+ regs->er2, regs->er3, regs->er4, regs->er5);
+ printk("\nER6' %08lx ", regs->er6);
+ if (user_mode(regs))
+ printk("USP: %08lx\n", rdusp());
+ else
+ printk("\n");
+}
+
+void flush_thread(void)
+{
+}
+
+int copy_thread(unsigned long clone_flags,
+ unsigned long usp, unsigned long topstk,
+ struct task_struct *p)
+{
+ struct pt_regs *childregs;
+
+ childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1;
+
+ if (unlikely(p->flags & PF_KTHREAD)) {
+ memset(childregs, 0, sizeof(struct pt_regs));
+ childregs->retpc = (unsigned long) ret_from_kernel_thread;
+ childregs->er4 = topstk; /* arg */
+ childregs->er5 = usp; /* fn */
+ } else {
+ *childregs = *current_pt_regs();
+ childregs->er0 = 0;
+ childregs->retpc = (unsigned long) ret_from_fork;
+ p->thread.usp = usp ?: rdusp();
+ }
+ p->thread.ksp = (unsigned long)childregs;
+
+ return 0;
+}
+
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+ return ((struct pt_regs *)tsk->thread.esp0)->pc;
+}
+
+unsigned long get_wchan(struct task_struct *p)
+{
+ unsigned long fp, pc;
+ unsigned long stack_page;
+ int count = 0;
+
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+
+ stack_page = (unsigned long)p;
+ fp = ((struct pt_regs *)p->thread.ksp)->er6;
+ do {
+ if (fp < stack_page+sizeof(struct thread_info) ||
+ fp >= 8184+stack_page)
+ return 0;
+ pc = ((unsigned long *)fp)[1];
+ if (!in_sched_functions(pc))
+ return pc;
+ fp = *(unsigned long *) fp;
+ } while (count++ < 16);
+ return 0;
+}
+
+/* generic sys_clone is not enough registers */
+asmlinkage int sys_clone(unsigned long __user *args)
+{
+ unsigned long clone_flags;
+ unsigned long newsp;
+ uintptr_t parent_tidptr;
+ uintptr_t child_tidptr;
+
+ get_user(clone_flags, &args[0]);
+ get_user(newsp, &args[1]);
+ get_user(parent_tidptr, &args[2]);
+ get_user(child_tidptr, &args[3]);
+ return do_fork(clone_flags, newsp, 0,
+ (int __user *)parent_tidptr, (int __user *)child_tidptr);
+}
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
new file mode 100644
index 0000000..d27d00b
--- /dev/null
+++ b/arch/h8300/kernel/ptrace.c
@@ -0,0 +1,203 @@
+/*
+ * linux/arch/h8300/kernel/ptrace.c
+ *
+ * Copyright 2015 Yoshinori Sato <[email protected]>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/audit.h>
+#include <linux/tracehook.h>
+#include <linux/regset.h>
+#include <linux/elf.h>
+
+#define CCR_MASK 0x6f /* mode/imask not set */
+#define EXR_MASK 0x80 /* modify only T */
+
+#define PT_REG(r) offsetof(struct pt_regs, r)
+
+extern void user_disable_single_step(struct task_struct *child);
+
+/* Mapping from PT_xxx to the stack offset at which the register is
+ saved. Notice that usp has no stack-slot and needs to be treated
+ specially (see get_reg/put_reg below). */
+static const int register_offset[] = {
+ PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4),
+ PT_REG(er5), PT_REG(er6), PT_REG(er0), -1,
+ PT_REG(orig_er0), PT_REG(ccr), PT_REG(pc),
+#if defined(CONFIG_CPU_H8S)
+ PT_REG(exr),
+#endif
+};
+
+/* read register */
+long h8300_get_reg(struct task_struct *task, int regno)
+{
+ switch (regno) {
+ case PT_USP:
+ return task->thread.usp + sizeof(long)*2;
+ case PT_CCR:
+ case PT_EXR:
+ return *(unsigned short *)(task->thread.esp0 +
+ register_offset[regno]);
+ default:
+ return *(unsigned long *)(task->thread.esp0 +
+ register_offset[regno]);
+ }
+}
+
+int h8300_put_reg(struct task_struct *task, int regno, unsigned long data)
+{
+ unsigned short oldccr;
+ unsigned short oldexr;
+
+ switch (regno) {
+ case PT_USP:
+ task->thread.usp = data - sizeof(long)*2;
+ case PT_CCR:
+ oldccr = *(unsigned short *)(task->thread.esp0 +
+ register_offset[regno]);
+ oldccr &= ~CCR_MASK;
+ data &= CCR_MASK;
+ data |= oldccr;
+ *(unsigned short *)(task->thread.esp0 +
+ register_offset[regno]) = data;
+ break;
+ case PT_EXR:
+ oldexr = *(unsigned short *)(task->thread.esp0 +
+ register_offset[regno]);
+ oldccr &= ~EXR_MASK;
+ data &= EXR_MASK;
+ data |= oldexr;
+ *(unsigned short *)(task->thread.esp0 +
+ register_offset[regno]) = data;
+ break;
+ default:
+ *(unsigned long *)(task->thread.esp0 +
+ register_offset[regno]) = data;
+ break;
+ }
+ return 0;
+}
+
+static int regs_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int r;
+ struct user_regs_struct regs;
+ long *reg = (long *)®s;
+
+ /* build user regs in buffer */
+ for (r = 0; r < ARRAY_SIZE(register_offset); r++)
+ *reg++ = h8300_get_reg(target, r);
+
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ ®s, 0, sizeof(regs));
+}
+
+static int regs_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int r;
+ int ret;
+ struct user_regs_struct regs;
+ long *reg;
+
+ /* build user regs in buffer */
+ for (reg = (long *)®s, r = 0; r < ARRAY_SIZE(register_offset); r++)
+ *reg++ = h8300_get_reg(target, r);
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ ®s, 0, sizeof(regs));
+ if (ret)
+ return ret;
+
+ /* write back to pt_regs */
+ for (reg = (long *)®s, r = 0; r < ARRAY_SIZE(register_offset); r++)
+ h8300_put_reg(target, r, *reg++);
+ return 0;
+}
+
+enum h8300_regset {
+ REGSET_GENERAL,
+};
+
+static const struct user_regset h8300_regsets[] = {
+ [REGSET_GENERAL] = {
+ .core_note_type = NT_PRSTATUS,
+ .n = ELF_NGREG,
+ .size = sizeof(long),
+ .align = sizeof(long),
+ .get = regs_get,
+ .set = regs_set,
+ },
+};
+
+static const struct user_regset_view user_h8300_native_view = {
+ .name = "h8300",
+ .e_machine = EM_H8_300,
+ .regsets = h8300_regsets,
+ .n = ARRAY_SIZE(h8300_regsets),
+};
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+ return &user_h8300_native_view;
+}
+
+void ptrace_disable(struct task_struct *child)
+{
+ user_disable_single_step(child);
+}
+
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
+{
+ int ret;
+
+ switch (request) {
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+ return ret;
+}
+
+asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
+{
+ long ret = 0;
+
+ if (test_thread_flag(TIF_SYSCALL_TRACE) &&
+ tracehook_report_syscall_entry(regs))
+ /*
+ * Tracing decided this syscall should not happen.
+ * We'll return a bogus call number to get an ENOSYS
+ * error, but leave the original number in regs->regs[0].
+ */
+ ret = -1L;
+
+ audit_syscall_entry(regs->er1, regs->er2, regs->er3,
+ regs->er4, regs->er5);
+
+ return ret ?: regs->er0;
+}
+
+asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
+{
+ int step;
+
+ audit_syscall_exit(regs);
+
+ step = test_thread_flag(TIF_SINGLESTEP);
+ if (step || test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall_exit(regs, step);
+}
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
new file mode 100644
index 0000000..1222783
--- /dev/null
+++ b/arch/h8300/kernel/signal.c
@@ -0,0 +1,326 @@
+/*
+ * linux/arch/h8300/kernel/signal.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * uClinux H8/300 support by Yoshinori Sato <[email protected]>
+ * and David McCullough <[email protected]>
+ *
+ * Based on
+ * Linux/m68k by Hamish Macdonald
+ */
+
+/*
+ * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
+ * Atari :-) Current limitation: Only one sigstack can be active at one time.
+ * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
+ * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
+ * signal handlers!
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/syscalls.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/highuid.h>
+#include <linux/personality.h>
+#include <linux/tty.h>
+#include <linux/binfmts.h>
+#include <linux/tracehook.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/traps.h>
+#include <asm/ucontext.h>
+
+/*
+ * Do a signal return; undo the signal stack.
+ *
+ * Keep the return code on the stack quadword aligned!
+ * That makes the cache flush below easier.
+ */
+
+struct rt_sigframe {
+ long dummy_er0;
+ long dummy_vector;
+#if defined(CONFIG_CPU_H8S)
+ short dummy_exr;
+#endif
+ long dummy_pc;
+ char *pretcode;
+ struct siginfo *pinfo;
+ void *puc;
+ unsigned char retcode[8];
+ struct siginfo info;
+ struct ucontext uc;
+ int sig;
+} __packed __aligned(2);
+
+static inline int
+restore_sigcontext(struct sigcontext *usc, int *pd0)
+{
+ struct pt_regs *regs = current_pt_regs();
+ int err = 0;
+ unsigned int ccr;
+ unsigned int usp;
+ unsigned int er0;
+
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+#define COPY(r) err |= __get_user(regs->r, &usc->sc_##r) /* restore passed registers */
+ COPY(er1);
+ COPY(er2);
+ COPY(er3);
+ COPY(er5);
+ COPY(pc);
+ ccr = regs->ccr & 0x10;
+ COPY(ccr);
+#undef COPY
+ regs->ccr &= 0xef;
+ regs->ccr |= ccr;
+ regs->orig_er0 = -1; /* disable syscall checks */
+ err |= __get_user(usp, &usc->sc_usp);
+ wrusp(usp);
+
+ err |= __get_user(er0, &usc->sc_er0);
+ *pd0 = er0;
+ return err;
+}
+
+asmlinkage int sys_rt_sigreturn(void)
+{
+ unsigned long usp = rdusp();
+ struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
+ sigset_t set;
+ int er0;
+
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+ goto badframe;
+
+ set_current_blocked(&set);
+
+ if (restore_sigcontext(&frame->uc.uc_mcontext, &er0))
+ goto badframe;
+
+ if (restore_altstack(&frame->uc.uc_stack))
+ goto badframe;
+
+ return er0;
+
+badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
+ unsigned long mask)
+{
+ int err = 0;
+
+ err |= __put_user(regs->er0, &sc->sc_er0);
+ err |= __put_user(regs->er1, &sc->sc_er1);
+ err |= __put_user(regs->er2, &sc->sc_er2);
+ err |= __put_user(regs->er3, &sc->sc_er3);
+ err |= __put_user(regs->er4, &sc->sc_er4);
+ err |= __put_user(regs->er5, &sc->sc_er5);
+ err |= __put_user(regs->er6, &sc->sc_er6);
+ err |= __put_user(rdusp(), &sc->sc_usp);
+ err |= __put_user(regs->pc, &sc->sc_pc);
+ err |= __put_user(regs->ccr, &sc->sc_ccr);
+ err |= __put_user(mask, &sc->sc_mask);
+
+ return err;
+}
+
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+ unsigned long usp;
+
+ /* Default to using normal stack. */
+ usp = rdusp();
+
+ /* This is the X/Open sanctioned signal stack switching. */
+ if (ka->sa.sa_flags & SA_ONSTACK) {
+ if (!sas_ss_flags(usp))
+ usp = current->sas_ss_sp + current->sas_ss_size;
+ }
+ return (void *)((usp - frame_size) & -8UL);
+}
+
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
+{
+ struct rt_sigframe *frame;
+ int err = 0;
+ int usig;
+ int sig = ksig->sig;
+ unsigned char *ret;
+
+ frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
+
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ return -EFAULT;
+
+ usig = current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig;
+
+ err |= __put_user(usig, &frame->sig);
+ if (err)
+ return -EFAULT;
+
+ err |= __put_user(&frame->info, &frame->pinfo);
+ err |= __put_user(&frame->uc, &frame->puc);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
+ if (err)
+ return -EFAULT;
+
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->uc.uc_flags);
+ err |= __put_user(0, &frame->uc.uc_link);
+ err |= __save_altstack(&frame->uc.uc_stack, rdusp());
+ err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
+ err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+ if (err)
+ return -EFAULTl
+
+ /* Set up to return from userspace. */
+ ret = frame->retcode;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER)
+ ret = (unsigned char *)(ksig->ka.sa.sa_restorer);
+ else {
+ /* sub.l er0,er0; mov.b #__NR_rt_sigreturn,r0l; trapa #0 */
+ err |= __put_user(0x1a80f800 + (__NR_rt_sigreturn & 0xff),
+ (unsigned long *)(frame->retcode + 0));
+ err |= __put_user(0x5700,
+ (unsigned short *)(frame->retcode + 4));
+ }
+ err |= __put_user(ret, &frame->pretcode);
+
+ if (err)
+ goto give_sigsegv;
+
+ /* Set up registers for signal handler */
+ wrusp((unsigned long) frame);
+ regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
+ regs->er0 = (current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig);
+ regs->er1 = (unsigned long)&(frame->info);
+ regs->er2 = (unsigned long)&frame->uc;
+ regs->er5 = current->mm->start_data; /* GOT base */
+
+ return 0;
+}
+
+static void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka)
+{
+ switch (regs->er0) {
+ case -ERESTARTNOHAND:
+ if (!ka)
+ goto do_restart;
+ regs->er0 = -EINTR;
+ break;
+ case -ERESTART_RESTARTBLOCK:
+ if (!ka) {
+ regs->er0 = __NR_restart_syscall;
+ regs->pc -= 2;
+ } else
+ regs->er0 = -EINTR;
+ break;
+ case -ERESTARTSYS:
+ if (!(ka->sa.sa_flags & SA_RESTART)) {
+ regs->er0 = -EINTR;
+ break;
+ }
+ /* fallthrough */
+ case -ERESTARTNOINTR:
+do_restart:
+ regs->er0 = regs->orig_er0;
+ regs->pc -= 2;
+ break;
+ }
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static void
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
+{
+ sigset_t *oldset = sigmask_to_save();
+ int ret;
+ /* are we from a system call? */
+ if (regs->orig_er0 >= 0)
+ handle_restart(regs, &ksig->ka);
+
+ ret = setup_rt_frame(ksig, oldset, regs);
+
+ signal_setup_done(ret, ksig, 0);
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ */
+static void do_signal(struct pt_regs *regs)
+{
+ struct ksignal ksig;
+
+ /*
+ * We want the common case to go fast, which
+ * is why we may in certain cases get here from
+ * kernel mode. Just return without doing anything
+ * if so.
+ */
+ if ((regs->ccr & 0x10))
+ return;
+
+ current->thread.esp0 = (unsigned long) regs;
+
+ if (get_signal(&ksig)) {
+ /* Whee! Actually deliver the signal. */
+ handle_signal(&ksig, regs);
+ return;
+ }
+ /* Did we come from a system call? */
+ if (regs->orig_er0 >= 0)
+ handle_restart(regs, NULL);
+
+ /* If there's no signal to deliver, we just restore the saved mask. */
+ restore_saved_sigmask();
+}
+
+asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
+{
+ if (thread_info_flags & _TIF_SIGPENDING)
+ do_signal(regs);
+
+ if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+ clear_thread_flag(TIF_NOTIFY_RESUME);
+ tracehook_notify_resume(regs);
+ }
+}
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
arch/h8300/kernel/cpu/Makefile | 5 +
arch/h8300/kernel/cpu/h83069/Makefile | 1 +
arch/h8300/kernel/cpu/h83069/setup.c | 202 ++++++++++++++++++++++++++
arch/h8300/kernel/cpu/h8s2678/Makefile | 1 +
arch/h8300/kernel/cpu/h8s2678/setup.c | 161 +++++++++++++++++++++
arch/h8300/kernel/cpu/irq_h.c | 62 ++++++++
arch/h8300/kernel/cpu/irq_s.c | 70 +++++++++
arch/h8300/kernel/cpu/ptrace_h.c | 256 +++++++++++++++++++++++++++++++++
arch/h8300/kernel/cpu/ptrace_s.c | 42 ++++++
9 files changed, 800 insertions(+)
create mode 100644 arch/h8300/kernel/cpu/Makefile
create mode 100644 arch/h8300/kernel/cpu/h83069/Makefile
create mode 100644 arch/h8300/kernel/cpu/h83069/setup.c
create mode 100644 arch/h8300/kernel/cpu/h8s2678/Makefile
create mode 100644 arch/h8300/kernel/cpu/h8s2678/setup.c
create mode 100644 arch/h8300/kernel/cpu/irq_h.c
create mode 100644 arch/h8300/kernel/cpu/irq_s.c
create mode 100644 arch/h8300/kernel/cpu/ptrace_h.c
create mode 100644 arch/h8300/kernel/cpu/ptrace_s.c
diff --git a/arch/h8300/kernel/cpu/Makefile b/arch/h8300/kernel/cpu/Makefile
new file mode 100644
index 0000000..f6d19e6
--- /dev/null
+++ b/arch/h8300/kernel/cpu/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_CPU_H8300H) += ptrace_h.o irq_h.o
+obj-$(CONFIG_CPU_H8S) += ptrace_s.o irq_s.o
+obj-$(CONFIG_H83069) += h83069/
+obj-$(CONFIG_H8S2678) += h8s2678/
+
diff --git a/arch/h8300/kernel/cpu/h83069/Makefile b/arch/h8300/kernel/cpu/h83069/Makefile
new file mode 100644
index 0000000..49d283e
--- /dev/null
+++ b/arch/h8300/kernel/cpu/h83069/Makefile
@@ -0,0 +1 @@
+obj-y = setup.o
diff --git a/arch/h8300/kernel/cpu/h83069/setup.c b/arch/h8300/kernel/cpu/h83069/setup.c
new file mode 100644
index 0000000..99c2716
--- /dev/null
+++ b/arch/h8300/kernel/cpu/h83069/setup.c
@@ -0,0 +1,202 @@
+/*
+ * H8/3069 Internal peripheral setup
+ *
+ * Copyright (C) 2009,2014 Yoshinori Sato <[email protected]>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/serial_sci.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <asm/timer.h>
+
+static struct resource sci0_resources[] = {
+ DEFINE_RES_MEM(0xffffb0, 8),
+ DEFINE_RES_IRQ(52),
+ DEFINE_RES_IRQ(53),
+ DEFINE_RES_IRQ(54),
+ DEFINE_RES_IRQ(55),
+};
+
+
+static struct plat_sci_port sci0_platform_data = {
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .type = PORT_SCI,
+};
+
+static struct resource sci1_resources[] = {
+ DEFINE_RES_MEM(0xffffb8, 8),
+ DEFINE_RES_IRQ(56),
+ DEFINE_RES_IRQ(57),
+ DEFINE_RES_IRQ(58),
+ DEFINE_RES_IRQ(59),
+};
+
+static struct plat_sci_port sci1_platform_data = {
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .type = PORT_SCI,
+};
+
+static struct platform_device sci0_device = {
+ .name = "sh-sci",
+ .id = 0,
+ .resource = sci0_resources,
+ .num_resources = ARRAY_SIZE(sci0_resources),
+ .dev = {
+ .platform_data = &sci0_platform_data,
+ },
+};
+
+static struct platform_device sci1_device = {
+ .name = "sh-sci",
+ .id = 1,
+ .resource = sci1_resources,
+ .num_resources = ARRAY_SIZE(sci1_resources),
+ .dev = {
+ .platform_data = &sci1_platform_data,
+ },
+};
+
+static struct h8300_timer8_config tm8_unit0_platform_data = {
+ .mode = H8300_TMR8_CLKEVTDEV,
+ .div = H8300_TMR8_DIV_8,
+};
+
+static struct resource tm8_unit0_resources[] = {
+ DEFINE_RES_MEM(0xffff80, 9),
+ DEFINE_RES_IRQ(36),
+ DEFINE_RES_IRQ(39),
+};
+
+static struct platform_device timer8_unit0_device = {
+ .name = "h8300-8timer",
+ .id = 0,
+ .dev = {
+ .platform_data = &tm8_unit0_platform_data,
+ },
+ .resource = tm8_unit0_resources,
+ .num_resources = ARRAY_SIZE(tm8_unit0_resources),
+};
+
+static struct h8300_timer8_config tm8_unit1_platform_data = {
+ .mode = H8300_TMR8_CLKSRC,
+ .div = H8300_TMR8_DIV_8,
+};
+
+static struct resource tm8_unit1_resources[] = {
+ DEFINE_RES_MEM(0xffff90, 9),
+ DEFINE_RES_IRQ(40),
+ DEFINE_RES_IRQ(43),
+};
+
+static struct platform_device timer8_unit1_device = {
+ .name = "h8300-8timer",
+ .id = 1,
+ .dev = {
+ .platform_data = &tm8_unit1_platform_data,
+ },
+ .resource = tm8_unit1_resources,
+ .num_resources = ARRAY_SIZE(tm8_unit1_resources),
+};
+
+
+static struct h8300_timer16_config timer16data0 = {
+ .enb = 0,
+ .imfa = 0,
+ .imiea = 4,
+};
+
+static struct h8300_timer16_config timer16data1 = {
+ .enb = 1,
+ .imfa = 1,
+ .imiea = 5,
+};
+
+static struct h8300_timer16_config timer16data2 = {
+ .enb = 2,
+ .imfa = 2,
+ .imiea = 6,
+};
+
+static struct resource tm16ch0_resources[] = {
+ DEFINE_RES_MEM(0xffff68, 8),
+ DEFINE_RES_MEM(0xffff60, 7),
+ DEFINE_RES_IRQ(24),
+};
+
+static struct resource tm16ch1_resources[] = {
+ DEFINE_RES_MEM(0xffff70, 8),
+ DEFINE_RES_MEM(0xffff60, 7),
+ DEFINE_RES_IRQ(28),
+};
+
+static struct resource tm16ch2_resources[] = {
+ DEFINE_RES_MEM(0xffff78, 8),
+ DEFINE_RES_MEM(0xffff60, 7),
+ DEFINE_RES_IRQ(32),
+};
+
+static struct platform_device timer16_ch0_device = {
+ .name = "h8300h-16timer",
+ .id = 0,
+ .dev = {
+ .platform_data = &timer16data0,
+ },
+ .resource = tm16ch0_resources,
+ .num_resources = ARRAY_SIZE(tm16ch0_resources),
+};
+
+static struct platform_device timer16_ch1_device = {
+ .name = "h8300h-16timer",
+ .id = 1,
+ .dev = {
+ .platform_data = &timer16data1,
+ },
+ .resource = tm16ch1_resources,
+ .num_resources = ARRAY_SIZE(tm16ch1_resources),
+};
+
+static struct platform_device timer16_ch2_device = {
+ .name = "h8300h-16timer",
+ .id = 2,
+ .dev = {
+ .platform_data = &timer16data2,
+ },
+ .resource = tm16ch2_resources,
+ .num_resources = ARRAY_SIZE(tm16ch2_resources),
+};
+
+static struct platform_device *devices[] __initdata = {
+ &timer8_unit1_device,
+ &timer16_ch0_device,
+ &timer16_ch1_device,
+ &timer16_ch2_device,
+ &sci0_device,
+ &sci1_device,
+};
+
+static struct platform_device *early_devices[] __initdata = {
+ &timer8_unit0_device,
+ &sci0_device,
+ &sci1_device,
+};
+
+static int __init devices_register(void)
+{
+ return platform_add_devices(devices,
+ ARRAY_SIZE(devices));
+}
+
+arch_initcall(devices_register);
+
+void __init early_device_init(void)
+{
+ early_platform_add_devices(early_devices,
+ ARRAY_SIZE(early_devices));
+}
diff --git a/arch/h8300/kernel/cpu/h8s2678/Makefile b/arch/h8300/kernel/cpu/h8s2678/Makefile
new file mode 100644
index 0000000..49d283e
--- /dev/null
+++ b/arch/h8300/kernel/cpu/h8s2678/Makefile
@@ -0,0 +1 @@
+obj-y = setup.o
diff --git a/arch/h8300/kernel/cpu/h8s2678/setup.c b/arch/h8300/kernel/cpu/h8s2678/setup.c
new file mode 100644
index 0000000..ea743ec
--- /dev/null
+++ b/arch/h8300/kernel/cpu/h8s2678/setup.c
@@ -0,0 +1,161 @@
+/*
+ * H8S2678 Internal peripheral setup
+ *
+ * Copyright (C) 2014 Yoshinori Sato <[email protected]>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/serial_sci.h>
+#include <asm/timer.h>
+
+static struct resource sci0_resources[] = {
+ DEFINE_RES_MEM(0xffff78, 8),
+ DEFINE_RES_IRQ(88),
+ DEFINE_RES_IRQ(89),
+ DEFINE_RES_IRQ(90),
+ DEFINE_RES_IRQ(91),
+};
+
+
+static struct plat_sci_port sci0_platform_data = {
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .type = PORT_SCI,
+};
+
+static struct resource sci1_resources[] = {
+ DEFINE_RES_MEM(0xffff80, 8),
+ DEFINE_RES_IRQ(92),
+ DEFINE_RES_IRQ(93),
+ DEFINE_RES_IRQ(94),
+ DEFINE_RES_IRQ(95),
+};
+
+static struct plat_sci_port sci1_platform_data = {
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .type = PORT_SCI,
+};
+
+static struct resource sci2_resources[] = {
+ DEFINE_RES_MEM(0xffff88, 8),
+ DEFINE_RES_IRQ(96),
+ DEFINE_RES_IRQ(97),
+ DEFINE_RES_IRQ(98),
+ DEFINE_RES_IRQ(99),
+};
+
+static struct plat_sci_port sci2_platform_data = {
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .type = PORT_SCI,
+};
+
+static struct platform_device sci0_device = {
+ .name = "sh-sci",
+ .id = 0,
+ .resource = sci0_resources,
+ .num_resources = ARRAY_SIZE(sci0_resources),
+ .dev = {
+ .platform_data = &sci0_platform_data,
+ },
+};
+
+static struct platform_device sci1_device = {
+ .name = "sh-sci",
+ .id = 1,
+ .resource = sci1_resources,
+ .num_resources = ARRAY_SIZE(sci1_resources),
+ .dev = {
+ .platform_data = &sci1_platform_data,
+ },
+};
+
+static struct platform_device sci2_device = {
+ .name = "sh-sci",
+ .id = 2,
+ .resource = sci2_resources,
+ .num_resources = ARRAY_SIZE(sci2_resources),
+ .dev = {
+ .platform_data = &sci2_platform_data,
+ },
+};
+
+static struct h8300_timer8_config timer8_platform_data = {
+ .mode = H8300_TMR8_CLKEVTDEV,
+ .div = H8300_TMR8_DIV_8,
+};
+
+static struct resource tm8_unit0_resources[] = {
+ DEFINE_RES_MEM(0xffffb0, 10),
+ DEFINE_RES_IRQ(72),
+ DEFINE_RES_IRQ(75),
+};
+
+static struct platform_device tm8_unit0_device = {
+ .name = "h8300-8timer",
+ .id = 0,
+ .dev = {
+ .platform_data = &timer8_platform_data,
+ },
+ .resource = tm8_unit0_resources,
+ .num_resources = ARRAY_SIZE(tm8_unit0_resources),
+};
+
+static struct resource tpu12_resources[] = {
+ DEFINE_RES_MEM(0xffffe0, 16),
+ DEFINE_RES_MEM(0xfffff0, 12),
+};
+
+static struct resource tpu45_resources[] = {
+ DEFINE_RES_MEM(0xfffe90, 16),
+ DEFINE_RES_MEM(0xfffea0, 12),
+};
+
+static struct platform_device tpu12_device = {
+ .name = "h8s-tpu",
+ .id = 0,
+ .resource = tpu12_resources,
+ .num_resources = ARRAY_SIZE(tpu12_resources),
+};
+
+static struct platform_device tpu45_device = {
+ .name = "h8s-tpu",
+ .id = 1,
+ .resource = tpu45_resources,
+ .num_resources = ARRAY_SIZE(tpu45_resources),
+};
+
+static struct platform_device *devices[] __initdata = {
+ &tpu12_device,
+ &tpu45_device,
+ &sci0_device,
+ &sci1_device,
+ &sci2_device,
+};
+
+static struct platform_device *early_devices[] __initdata = {
+ &tm8_unit0_device,
+ &sci0_device,
+ &sci1_device,
+ &sci2_device,
+};
+
+static int __init devices_register(void)
+{
+ return platform_add_devices(devices,
+ ARRAY_SIZE(devices));
+}
+arch_initcall(devices_register);
+
+void __init early_device_init(void)
+{
+ /* SCI / Timer enable */
+ ctrl_outw(0x07f0, 0xffff40);
+ early_platform_add_devices(early_devices,
+ ARRAY_SIZE(early_devices));
+}
diff --git a/arch/h8300/kernel/cpu/irq_h.c b/arch/h8300/kernel/cpu/irq_h.c
new file mode 100644
index 0000000..90021d8
--- /dev/null
+++ b/arch/h8300/kernel/cpu/irq_h.c
@@ -0,0 +1,62 @@
+/*
+ * linux/arch/h8300/kernel/irq_h.c
+ *
+ * Copyright 2014 Yoshinori Sato <[email protected]>
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/io.h>
+
+static const char ipr_bit[] = {
+ 7, 6, 5, 5,
+ 4, 4, 4, 4, 3, 3, 3, 3,
+ 2, 2, 2, 2, 1, 1, 1, 1,
+ 0, 0, 0, 0, 15, 15, 15, 15,
+ 14, 14, 14, 14, 13, 13, 13, 13,
+ -1, -1, -1, -1, 11, 11, 11, 11,
+ 10, 10, 10, 10, 9, 9, 9, 9,
+};
+
+#define IPR 0xffee18
+
+static void h8300h_disable_irq(struct irq_data *data)
+{
+ int bit;
+ int irq = data->irq - 12;
+
+ bit = ipr_bit[irq];
+ if (bit >= 0) {
+ if (bit < 8)
+ ctrl_bclr(bit & 7, IPR);
+ else
+ ctrl_bclr(bit & 7, (IPR+1));
+ }
+}
+
+static void h8300h_enable_irq(struct irq_data *data)
+{
+ int bit;
+ int irq = data->irq - 12;
+
+ bit = ipr_bit[irq];
+ if (bit >= 0) {
+ if (bit < 8)
+ ctrl_bset(bit & 7, IPR);
+ else
+ ctrl_bset(bit & 7, (IPR+1));
+ }
+}
+
+struct irq_chip h8300h_irq_chip = {
+ .name = "H8/300H-INTC",
+ .irq_enable = h8300h_enable_irq,
+ .irq_disable = h8300h_disable_irq,
+};
+
+void __init h8300_init_ipr(void)
+{
+ /* All interrupt priority high */
+ ctrl_outb(0xff, IPR + 0);
+ ctrl_outb(0xee, IPR + 1);
+}
diff --git a/arch/h8300/kernel/cpu/irq_s.c b/arch/h8300/kernel/cpu/irq_s.c
new file mode 100644
index 0000000..71c322e
--- /dev/null
+++ b/arch/h8300/kernel/cpu/irq_s.c
@@ -0,0 +1,70 @@
+/*
+ * linux/arch/h8300/kernel/irq_s.c
+ *
+ * Copyright 2014 Yoshinori Sato <[email protected]>
+ */
+
+#include <linux/irq.h>
+#include <asm/io.h>
+#define IPRA 0xfffe00
+
+static const unsigned char ipr_table[] = {
+ 0x03, 0x02, 0x01, 0x00, 0x13, 0x12, 0x11, 0x10, /* 16 - 23 */
+ 0x23, 0x22, 0x21, 0x20, 0x33, 0x32, 0x31, 0x30, /* 24 - 31 */
+ 0x43, 0x42, 0x41, 0x40, 0x53, 0x53, 0x52, 0x52, /* 32 - 39 */
+ 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, /* 40 - 47 */
+ 0x50, 0x50, 0x50, 0x50, 0x63, 0x63, 0x63, 0x63, /* 48 - 55 */
+ 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, /* 56 - 63 */
+ 0x61, 0x61, 0x61, 0x61, 0x60, 0x60, 0x60, 0x60, /* 64 - 71 */
+ 0x73, 0x73, 0x73, 0x73, 0x72, 0x72, 0x72, 0x72, /* 72 - 79 */
+ 0x71, 0x71, 0x71, 0x71, 0x70, 0x83, 0x82, 0x81, /* 80 - 87 */
+ 0x80, 0x80, 0x80, 0x80, 0x93, 0x93, 0x93, 0x93, /* 88 - 95 */
+ 0x92, 0x92, 0x92, 0x92, 0x91, 0x91, 0x91, 0x91, /* 96 - 103 */
+ 0x90, 0x90, 0x90, 0x90, 0xa3, 0xa3, 0xa3, 0xa3, /* 104 - 111 */
+ 0xa2, 0xa2, 0xa2, 0xa2, 0xa1, 0xa1, 0xa1, 0xa1, /* 112 - 119 */
+ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, /* 120 - 127 */
+};
+
+static void h8s_disable_irq(struct irq_data *data)
+{
+ int pos;
+ unsigned int addr;
+ unsigned short pri;
+ int irq = data->irq;
+
+ addr = IPRA + ((ipr_table[irq - 16] & 0xf0) >> 3);
+ pos = (ipr_table[irq - 16] & 0x0f) * 4;
+ pri = ~(0x000f << pos);
+ pri &= ctrl_inw(addr);
+ ctrl_outw(pri, addr);
+}
+
+static void h8s_enable_irq(struct irq_data *data)
+{
+ int pos;
+ unsigned int addr;
+ unsigned short pri;
+ int irq = data->irq;
+
+ addr = IPRA + ((ipr_table[irq - 16] & 0xf0) >> 3);
+ pos = (ipr_table[irq - 16] & 0x0f) * 4;
+ pri = ~(0x000f << pos);
+ pri &= ctrl_inw(addr);
+ pri |= 1 << pos;
+ ctrl_outw(pri, addr);
+}
+
+struct irq_chip h8s_irq_chip = {
+ .name = "H8S-INTC",
+ .irq_enable = h8s_enable_irq,
+ .irq_disable = h8s_disable_irq,
+};
+
+void __init h8300_init_ipr(void)
+{
+ int n;
+ /* All interrupt priority is 1 */
+ /* IPRA to IPRK */
+ for (n = 0; n <= 'k' - 'a'; n++)
+ ctrl_outw(0x1111, IPRA + (n * 2));
+}
diff --git a/arch/h8300/kernel/cpu/ptrace_h.c b/arch/h8300/kernel/cpu/ptrace_h.c
new file mode 100644
index 0000000..7721e93
--- /dev/null
+++ b/arch/h8300/kernel/cpu/ptrace_h.c
@@ -0,0 +1,256 @@
+/*
+ * ptrace cpu depend helper functions
+ *
+ * Copyright 2003, 2015 Yoshinori Sato <[email protected]>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+#define BREAKINST 0x5730 /* trapa #3 */
+
+/* disable singlestep */
+void user_disable_single_step(struct task_struct *child)
+{
+ if ((long)child->thread.breakinfo.addr != -1L) {
+ *(child->thread.breakinfo.addr) = child->thread.breakinfo.inst;
+ child->thread.breakinfo.addr = (unsigned short *)-1L;
+ }
+}
+
+/* calculate next pc */
+enum jump_type {none, /* normal instruction */
+ jabs, /* absolute address jump */
+ ind, /* indirect address jump */
+ ret, /* return to subrutine */
+ reg, /* register indexed jump */
+ relb, /* pc relative jump (byte offset) */
+ relw, /* pc relative jump (word offset) */
+ };
+
+/* opcode decode table define
+ ptn: opcode pattern
+ msk: opcode bitmask
+ len: instruction length (<0 next table index)
+ jmp: jump operation mode */
+struct optable {
+ unsigned char bitpattern;
+ unsigned char bitmask;
+ signed char length;
+ signed char type;
+} __packed __aligned(1);
+
+#define OPTABLE(ptn, msk, len, jmp) \
+ { \
+ .bitpattern = ptn, \
+ .bitmask = msk, \
+ .length = len, \
+ .type = jmp, \
+ }
+
+static const struct optable optable_0[] = {
+ OPTABLE(0x00, 0xff, 1, none), /* 0x00 */
+ OPTABLE(0x01, 0xff, -1, none), /* 0x01 */
+ OPTABLE(0x02, 0xfe, 1, none), /* 0x02-0x03 */
+ OPTABLE(0x04, 0xee, 1, none), /* 0x04-0x05/0x14-0x15 */
+ OPTABLE(0x06, 0xfe, 1, none), /* 0x06-0x07 */
+ OPTABLE(0x08, 0xea, 1, none), /* 0x08-0x09/0x0c-0x0d/0x18-0x19/0x1c-0x1d */
+ OPTABLE(0x0a, 0xee, 1, none), /* 0x0a-0x0b/0x1a-0x1b */
+ OPTABLE(0x0e, 0xee, 1, none), /* 0x0e-0x0f/0x1e-0x1f */
+ OPTABLE(0x10, 0xfc, 1, none), /* 0x10-0x13 */
+ OPTABLE(0x16, 0xfe, 1, none), /* 0x16-0x17 */
+ OPTABLE(0x20, 0xe0, 1, none), /* 0x20-0x3f */
+ OPTABLE(0x40, 0xf0, 1, relb), /* 0x40-0x4f */
+ OPTABLE(0x50, 0xfc, 1, none), /* 0x50-0x53 */
+ OPTABLE(0x54, 0xfd, 1, ret), /* 0x54/0x56 */
+ OPTABLE(0x55, 0xff, 1, relb), /* 0x55 */
+ OPTABLE(0x57, 0xff, 1, none), /* 0x57 */
+ OPTABLE(0x58, 0xfb, 2, relw), /* 0x58/0x5c */
+ OPTABLE(0x59, 0xfb, 1, reg), /* 0x59/0x5b */
+ OPTABLE(0x5a, 0xfb, 2, jabs), /* 0x5a/0x5e */
+ OPTABLE(0x5b, 0xfb, 2, ind), /* 0x5b/0x5f */
+ OPTABLE(0x60, 0xe8, 1, none), /* 0x60-0x67/0x70-0x77 */
+ OPTABLE(0x68, 0xfa, 1, none), /* 0x68-0x69/0x6c-0x6d */
+ OPTABLE(0x6a, 0xfe, -2, none), /* 0x6a-0x6b */
+ OPTABLE(0x6e, 0xfe, 2, none), /* 0x6e-0x6f */
+ OPTABLE(0x78, 0xff, 4, none), /* 0x78 */
+ OPTABLE(0x79, 0xff, 2, none), /* 0x79 */
+ OPTABLE(0x7a, 0xff, 3, none), /* 0x7a */
+ OPTABLE(0x7b, 0xff, 2, none), /* 0x7b */
+ OPTABLE(0x7c, 0xfc, 2, none), /* 0x7c-0x7f */
+ OPTABLE(0x80, 0x80, 1, none), /* 0x80-0xff */
+};
+
+static const struct optable optable_1[] = {
+ OPTABLE(0x00, 0xff, -3, none), /* 0x0100 */
+ OPTABLE(0x40, 0xf0, -3, none), /* 0x0140-0x14f */
+ OPTABLE(0x80, 0xf0, 1, none), /* 0x0180-0x018f */
+ OPTABLE(0xc0, 0xc0, 2, none), /* 0x01c0-0x01ff */
+};
+
+static const struct optable optable_2[] = {
+ OPTABLE(0x00, 0x20, 2, none), /* 0x6a0?/0x6a8?/0x6b0?/0x6b8? */
+ OPTABLE(0x20, 0x20, 3, none), /* 0x6a2?/0x6aa?/0x6b2?/0x6ba? */
+};
+
+static const struct optable optable_3[] = {
+ OPTABLE(0x69, 0xfb, 2, none), /* 0x010069/0x01006d/014069/0x01406d */
+ OPTABLE(0x6b, 0xff, -4, none), /* 0x01006b/0x01406b */
+ OPTABLE(0x6f, 0xff, 3, none), /* 0x01006f/0x01406f */
+ OPTABLE(0x78, 0xff, 5, none), /* 0x010078/0x014078 */
+};
+
+static const struct optable optable_4[] = {
+/* 0x0100690?/0x01006d0?/0140690?/0x01406d0?/
+ 0x0100698?/0x01006d8?/0140698?/0x01406d8? */
+ OPTABLE(0x00, 0x78, 3, none),
+/* 0x0100692?/0x01006d2?/0140692?/0x01406d2?/
+ 0x010069a?/0x01006da?/014069a?/0x01406da? */
+ OPTABLE(0x20, 0x78, 4, none),
+};
+
+static const struct optables_list {
+ const struct optable *ptr;
+ int size;
+} optables[] = {
+#define OPTABLES(no) \
+ { \
+ .ptr = optable_##no, \
+ .size = sizeof(optable_##no) / sizeof(struct optable), \
+ }
+ OPTABLES(0),
+ OPTABLES(1),
+ OPTABLES(2),
+ OPTABLES(3),
+ OPTABLES(4),
+
+};
+
+const unsigned char condmask[] = {
+ 0x00, 0x40, 0x01, 0x04, 0x02, 0x08, 0x10, 0x20
+};
+
+static int isbranch(struct task_struct *task, int reson)
+{
+ unsigned char cond = h8300_get_reg(task, PT_CCR);
+
+ /* encode complex conditions */
+ /* B4: N^V
+ B5: Z|(N^V)
+ B6: C|Z */
+ __asm__("bld #3,%w0\n\t"
+ "bxor #1,%w0\n\t"
+ "bst #4,%w0\n\t"
+ "bor #2,%w0\n\t"
+ "bst #5,%w0\n\t"
+ "bld #2,%w0\n\t"
+ "bor #0,%w0\n\t"
+ "bst #6,%w0\n\t"
+ : "=&r"(cond) : : "cc");
+ cond &= condmask[reson >> 1];
+ if (!(reson & 1))
+ return cond == 0;
+ else
+ return cond != 0;
+}
+
+static unsigned short *decode(struct task_struct *child, const struct optable *op,
+ char *fetch_p, unsigned short *pc,
+ unsigned char inst)
+{
+ unsigned long addr;
+ unsigned long *sp;
+ int regno;
+
+ switch (op->type) {
+ case none:
+ return (unsigned short *)pc + op->length;
+ case jabs:
+ addr = *(unsigned long *)pc;
+ return (unsigned short *)(addr & 0x00ffffff);
+ case ind:
+ addr = *pc & 0xff;
+ return (unsigned short *)(*(unsigned long *)addr);
+ case ret:
+ sp = (unsigned long *)h8300_get_reg(child, PT_USP);
+ /* user stack frames
+ | er0 | temporary saved
+ +--------+
+ | exp | exception stack frames
+ +--------+
+ | ret pc | userspace return address
+ */
+ return (unsigned short *)(*(sp+2) & 0x00ffffff);
+ case reg:
+ regno = (*pc >> 4) & 0x07;
+ if (regno == 0)
+ addr = h8300_get_reg(child, PT_ER0);
+ else
+ addr = h8300_get_reg(child, regno-1 + PT_ER1);
+ return (unsigned short *)addr;
+ case relb:
+ if (inst == 0x55 || isbranch(child, inst & 0x0f))
+ pc = (unsigned short *)((unsigned long)pc +
+ ((signed char)(*fetch_p)));
+ return pc+1; /* skip myself */
+ case relw:
+ if (inst == 0x5c || isbranch(child, (*fetch_p & 0xf0) >> 4))
+ pc = (unsigned short *)((unsigned long)pc +
+ ((signed short)(*(pc+1))));
+ return pc+2; /* skip myself */
+ default:
+ return NULL;
+ }
+}
+
+static unsigned short *nextpc(struct task_struct *child, unsigned short *pc)
+{
+ const struct optable *op;
+ unsigned char *fetch_p;
+ int op_len;
+ unsigned char inst;
+
+ op = optables[0].ptr;
+ op_len = optables[0].size;
+ fetch_p = (unsigned char *)pc;
+ inst = *fetch_p++;
+ do {
+ if ((inst & op->bitmask) == op->bitpattern) {
+ if (op->length < 0) {
+ op = optables[-op->length].ptr;
+ op_len = optables[-op->length].size + 1;
+ inst = *fetch_p++;
+ } else
+ return decode(child, op, fetch_p, pc, inst);
+ } else
+ op++;
+ } while (--op_len > 0);
+ return NULL;
+}
+
+/* Set breakpoint(s) to simulate a single step from the current PC. */
+
+void user_enable_single_step(struct task_struct *child)
+{
+ unsigned short *next;
+
+ next = nextpc(child, (unsigned short *)h8300_get_reg(child, PT_PC));
+ child->thread.breakinfo.addr = next;
+ child->thread.breakinfo.inst = *next;
+ *next = BREAKINST;
+}
+
+asmlinkage void trace_trap(unsigned long bp)
+{
+ if ((unsigned long)current->thread.breakinfo.addr == bp) {
+ user_disable_single_step(current);
+ force_sig(SIGTRAP, current);
+ } else
+ force_sig(SIGILL, current);
+}
+
diff --git a/arch/h8300/kernel/cpu/ptrace_s.c b/arch/h8300/kernel/cpu/ptrace_s.c
new file mode 100644
index 0000000..7d0b634
--- /dev/null
+++ b/arch/h8300/kernel/cpu/ptrace_s.c
@@ -0,0 +1,42 @@
+/*
+ * linux/arch/h8300/kernel/ptrace_h8s.c
+ * ptrace cpu depend helper functions
+ *
+ * Yoshinori Sato <[email protected]>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <asm/ptrace.h>
+
+#define CCR_MASK 0x6f
+#define EXR_TRACE 0x80
+
+/* disable singlestep */
+void user_disable_single_step(struct task_struct *child)
+{
+ unsigned char exr;
+ exr = h8300_get_reg(child, PT_EXR);
+ exr &= ~EXR_TRACE;
+ h8300_put_reg(child, PT_EXR,exr);
+}
+
+/* enable singlestep */
+void user_enable_single_step(struct task_struct *child)
+{
+ unsigned char exr;
+ exr = h8300_get_reg(child, PT_EXR);
+ exr |= EXR_TRACE;
+ h8300_put_reg(child, PT_EXR,exr);
+}
+
+asmlinkage void trace_trap(unsigned long bp)
+{
+ (void)bp;
+ force_sig(SIGTRAP, current);
+}
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
arch/h8300/kernel/asm-offsets.c | 60 ++++++++++++++++++++++++++
arch/h8300/kernel/dma.c | 94 +++++++++++++++++++++++++++++++++++++++++
arch/h8300/kernel/h8300_ksyms.c | 34 +++++++++++++++
arch/h8300/kernel/module.c | 70 ++++++++++++++++++++++++++++++
arch/h8300/kernel/sim-console.c | 79 ++++++++++++++++++++++++++++++++++
arch/h8300/kernel/syscalls.c | 14 ++++++
6 files changed, 351 insertions(+)
create mode 100644 arch/h8300/kernel/asm-offsets.c
create mode 100644 arch/h8300/kernel/dma.c
create mode 100644 arch/h8300/kernel/h8300_ksyms.c
create mode 100644 arch/h8300/kernel/module.c
create mode 100644 arch/h8300/kernel/sim-console.c
create mode 100644 arch/h8300/kernel/syscalls.c
diff --git a/arch/h8300/kernel/asm-offsets.c b/arch/h8300/kernel/asm-offsets.c
new file mode 100644
index 0000000..8f8fad6
--- /dev/null
+++ b/arch/h8300/kernel/asm-offsets.c
@@ -0,0 +1,60 @@
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ */
+
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/ptrace.h>
+#include <linux/hardirq.h>
+#include <linux/kbuild.h>
+#include <asm/irq.h>
+#include <asm/ptrace.h>
+
+int main(void)
+{
+ /* offsets into the task struct */
+ DEFINE(TASK_STATE, offsetof(struct task_struct, state));
+ DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+ DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
+ DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
+ DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+ DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, stack));
+ DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+ DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+
+ /* offsets into the irq_cpustat_t struct */
+ DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
+
+ /* offsets into the thread struct */
+ DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
+ DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
+ DEFINE(THREAD_CCR, offsetof(struct thread_struct, ccr));
+
+ /* offsets into the pt_regs struct */
+ DEFINE(LER0, offsetof(struct pt_regs, er0) - sizeof(long));
+ DEFINE(LER1, offsetof(struct pt_regs, er1) - sizeof(long));
+ DEFINE(LER2, offsetof(struct pt_regs, er2) - sizeof(long));
+ DEFINE(LER3, offsetof(struct pt_regs, er3) - sizeof(long));
+ DEFINE(LER4, offsetof(struct pt_regs, er4) - sizeof(long));
+ DEFINE(LER5, offsetof(struct pt_regs, er5) - sizeof(long));
+ DEFINE(LER6, offsetof(struct pt_regs, er6) - sizeof(long));
+ DEFINE(LORIG, offsetof(struct pt_regs, orig_er0) - sizeof(long));
+ DEFINE(LSP , offsetof(struct pt_regs, sp) - sizeof(long));
+ DEFINE(LCCR, offsetof(struct pt_regs, ccr) - sizeof(long));
+ DEFINE(LVEC, offsetof(struct pt_regs, vector) - sizeof(long));
+#if defined(CONFIG_CPU_H8S)
+ DEFINE(LEXR, offsetof(struct pt_regs, exr) - sizeof(long));
+#endif
+ DEFINE(LRET, offsetof(struct pt_regs, pc) - sizeof(long));
+
+ DEFINE(PT_PTRACED, PT_PTRACED);
+
+ return 0;
+}
diff --git a/arch/h8300/kernel/dma.c b/arch/h8300/kernel/dma.c
new file mode 100644
index 0000000..76b2139
--- /dev/null
+++ b/arch/h8300/kernel/dma.c
@@ -0,0 +1,94 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#undef DEBUG
+
+#include <linux/dma-mapping.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/export.h>
+
+#include <asm/pgalloc.h>
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
+{
+ void *ret;
+ /* ignore region specifiers */
+ gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+ if (dev == NULL || (*dev->dma_mask < 0xffffffff))
+ gfp |= GFP_DMA;
+ ret = (void *)__get_free_pages(gfp, get_order(size));
+
+ if (ret != NULL) {
+ memset(ret, 0, size);
+ *dma_handle = virt_to_phys(ret);
+ }
+ return ret;
+}
+
+void dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ free_pages((unsigned long)vaddr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_alloc_coherent);
+EXPORT_SYMBOL(dma_free_coherent);
+
+void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+}
+EXPORT_SYMBOL(dma_sync_single_for_device);
+
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir)
+{
+ int i;
+
+ for (i = 0; i < nents; sg++, i++)
+ dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
+}
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size,
+ enum dma_data_direction dir)
+{
+ dma_addr_t handle = virt_to_bus(addr);
+
+ dma_sync_single_for_device(dev, handle, size, dir);
+ return handle;
+}
+EXPORT_SYMBOL(dma_map_single);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir)
+{
+ dma_addr_t handle = page_to_phys(page) + offset;
+
+ dma_sync_single_for_device(dev, handle, size, dir);
+ return handle;
+}
+EXPORT_SYMBOL(dma_map_page);
+
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir)
+{
+ int i;
+
+ for (i = 0; i < nents; sg++, i++) {
+ sg->dma_address = sg_phys(sg);
+ dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
+ }
+ return nents;
+}
+EXPORT_SYMBOL(dma_map_sg);
diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c
new file mode 100644
index 0000000..33bf96a
--- /dev/null
+++ b/arch/h8300/kernel/h8300_ksyms.c
@@ -0,0 +1,34 @@
+#include <linux/module.h>
+#include <linux/linkage.h>
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler... (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+asmlinkage long long __ashldi3(long long, int);
+asmlinkage long long __ashrdi3(long long, int);
+asmlinkage long long __lshrdi3(long long, int);
+asmlinkage long __divsi3(long, long);
+asmlinkage long __modsi3(long, long);
+asmlinkage unsigned long __umodsi3(unsigned long, unsigned long);
+asmlinkage long long __muldi3(long long, long long);
+asmlinkage long __mulsi3(long, long);
+asmlinkage long __udivsi3(long, long);
+asmlinkage void *memcpy(void *, const void *, size_t);
+asmlinkage void *memset(void *, int, size_t);
+asmlinkage long strncpy_from_user(void *to, void *from, size_t n);
+
+ /* gcc lib functions */
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__lshrdi3);
+EXPORT_SYMBOL(__divsi3);
+EXPORT_SYMBOL(__modsi3);
+EXPORT_SYMBOL(__umodsi3);
+EXPORT_SYMBOL(__muldi3);
+EXPORT_SYMBOL(__mulsi3);
+EXPORT_SYMBOL(__udivsi3);
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(strncpy_from_user);
diff --git a/arch/h8300/kernel/module.c b/arch/h8300/kernel/module.c
new file mode 100644
index 0000000..515f6c4
--- /dev/null
+++ b/arch/h8300/kernel/module.c
@@ -0,0 +1,70 @@
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+int apply_relocate_add(Elf32_Shdr *sechdrs,
+ const char *strtab,
+ unsigned int symindex,
+ unsigned int relsec,
+ struct module *me)
+{
+ unsigned int i;
+ Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
+
+ pr_debug("Applying relocate section %u to %u\n", relsec,
+ sechdrs[relsec].sh_info);
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
+ /* This is where to make the change */
+ uint32_t *loc =
+ (uint32_t *)(sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rela[i].r_offset);
+ /* This is the symbol it is referring to. Note that all
+ undefined symbols have been resolved. */
+ Elf32_Sym *sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+ + ELF32_R_SYM(rela[i].r_info);
+ uint32_t v = sym->st_value + rela[i].r_addend;
+
+ switch (ELF32_R_TYPE(rela[i].r_info)) {
+ case R_H8_DIR24R8:
+ loc = (uint32_t *)((uint32_t)loc - 1);
+ *loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v);
+ break;
+ case R_H8_DIR24A8:
+ if (ELF32_R_SYM(rela[i].r_info))
+ *loc += v;
+ break;
+ case R_H8_DIR32:
+ case R_H8_DIR32A16:
+ *loc += v;
+ break;
+ case R_H8_PCREL16:
+ v -= (unsigned long)loc + 2;
+ if ((Elf32_Sword)v > 0x7fff ||
+ (Elf32_Sword)v < -(Elf32_Sword)0x8000)
+ goto overflow;
+ else
+ *(unsigned short *)loc = v;
+ break;
+ case R_H8_PCREL8:
+ v -= (unsigned long)loc + 1;
+ if ((Elf32_Sword)v > 0x7f ||
+ (Elf32_Sword)v < -(Elf32_Sword)0x80)
+ goto overflow;
+ else
+ *(unsigned char *)loc = v;
+ break;
+ default:
+ pr_err("module %s: Unknown relocation: %u\n",
+ me->name, ELF32_R_TYPE(rela[i].r_info));
+ return -ENOEXEC;
+ }
+ }
+ return 0;
+ overflow:
+ pr_err("module %s: relocation offset overflow: %08x\n",
+ me->name, rela[i].r_offset);
+ return -ENOEXEC;
+}
diff --git a/arch/h8300/kernel/sim-console.c b/arch/h8300/kernel/sim-console.c
new file mode 100644
index 0000000..a15edf0
--- /dev/null
+++ b/arch/h8300/kernel/sim-console.c
@@ -0,0 +1,79 @@
+/*
+ * arch/h8300/kernel/early_printk.c
+ *
+ * Copyright (C) 2009 Yoshinori Sato <[email protected]>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+static void sim_write(struct console *co, const char *ptr,
+ unsigned len)
+{
+ register const int fd __asm__("er0") = 1; /* stdout */
+ register const char *_ptr __asm__("er1") = ptr;
+ register const unsigned _len __asm__("er2") = len;
+
+ __asm__(".byte 0x5e,0x00,0x00,0xc7\n\t" /* jsr @0xc7 (sys_write) */
+ : : "g"(fd), "g"(_ptr), "g"(_len));
+}
+
+static struct console sim_console = {
+ .name = "sim_console",
+ .write = sim_write,
+ .setup = NULL,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+
+static char sim_console_buf[32];
+
+static int sim_probe(struct platform_device *pdev)
+{
+ if (sim_console.data)
+ return -EEXIST;
+
+ if (!strstr(sim_console_buf, "keep"))
+ sim_console.flags |= CON_BOOT;
+
+ register_console(&sim_console);
+ return 0;
+}
+
+static int sim_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver sim_driver = {
+ .probe = sim_probe,
+ .remove = sim_remove,
+ .driver = {
+ .name = "h8300-sim",
+ .owner = THIS_MODULE,
+ },
+};
+
+early_platform_init_buffer("earlyprintk", &sim_driver,
+ sim_console_buf, ARRAY_SIZE(sim_console_buf));
+
+static struct platform_device sim_console_device = {
+ .name = "h8300-sim",
+ .id = 0,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &sim_console_device,
+};
+
+void __init sim_console_register(void)
+{
+ early_platform_add_devices(devices,
+ ARRAY_SIZE(devices));
+}
diff --git a/arch/h8300/kernel/syscalls.c b/arch/h8300/kernel/syscalls.c
new file mode 100644
index 0000000..1f9123a
--- /dev/null
+++ b/arch/h8300/kernel/syscalls.c
@@ -0,0 +1,14 @@
+#include <linux/syscalls.h>
+#include <linux/signal.h>
+#include <linux/unistd.h>
+
+#undef __SYSCALL
+#define __SYSCALL(nr, call) [nr] = (call),
+
+#define sys_mmap2 sys_mmap_pgoff
+
+asmlinkage int sys_rt_sigreturn(void);
+
+void *_sys_call_table[__NR_syscalls] = {
+#include <asm/unistd.h>
+};
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
arch/h8300/mm/Makefile | 5 ++
arch/h8300/mm/fault.c | 58 +++++++++++++++++++
arch/h8300/mm/init.c | 153 +++++++++++++++++++++++++++++++++++++++++++++++++
arch/h8300/mm/kmap.c | 61 ++++++++++++++++++++
arch/h8300/mm/memory.c | 54 +++++++++++++++++
5 files changed, 331 insertions(+)
create mode 100644 arch/h8300/mm/Makefile
create mode 100644 arch/h8300/mm/fault.c
create mode 100644 arch/h8300/mm/init.c
create mode 100644 arch/h8300/mm/kmap.c
create mode 100644 arch/h8300/mm/memory.c
diff --git a/arch/h8300/mm/Makefile b/arch/h8300/mm/Makefile
new file mode 100644
index 0000000..117d71f
--- /dev/null
+++ b/arch/h8300/mm/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the linux h8300-specific parts of the memory manager.
+#
+
+obj-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 0000000..d0d6759
--- /dev/null
+++ b/arch/h8300/mm/fault.c
@@ -0,0 +1,58 @@
+/*
+ * linux/arch/h8300/mm/fault.c
+ *
+ * Copyright (C) 1998 D. Jeff Dionne <[email protected]>,
+ * Copyright (C) 2000 Lineo, Inc. (http://www.lineo.com)
+ *
+ * Based on:
+ *
+ * linux/arch/m68knommu/mm/fault.c
+ * linux/arch/m68k/mm/fault.c
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ */
+
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+
+#include <asm/pgtable.h>
+
+void die(const char *str, struct pt_regs *fp, unsigned long err);
+
+/*
+ * This routine handles page faults. It determines the problem, and
+ * then passes it off to one of the appropriate routines.
+ *
+ * error_code:
+ * bit 0 == 0 means no page found, 1 means protection fault
+ * bit 1 == 0 means read, 1 means write
+ *
+ * If this routine detects a bad access, it returns 1, otherwise it
+ * returns 0.
+ */
+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
+ unsigned long error_code)
+{
+#ifdef DEBUG
+ pr_debug("regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n",
+ regs->sr, regs->pc, address, error_code);
+#endif
+
+/*
+ * Oops. The kernel tried to access some bad page. We'll have to
+ * terminate things with extreme prejudice.
+ */
+ if ((unsigned long) address < PAGE_SIZE)
+ pr_alert("Unable to handle kernel NULL pointer dereference");
+ else
+ pr_alert("Unable to handle kernel access");
+ printk(" at virtual address %08lx\n", address);
+ if (!user_mode(regs))
+ die("Oops", regs, error_code);
+ do_exit(SIGKILL);
+
+ return 1;
+}
+
diff --git a/arch/h8300/mm/init.c b/arch/h8300/mm/init.c
new file mode 100644
index 0000000..ddad9e8
--- /dev/null
+++ b/arch/h8300/mm/init.c
@@ -0,0 +1,153 @@
+/*
+ * linux/arch/h8300/mm/init.c
+ *
+ * Copyright (C) 1998 D. Jeff Dionne <[email protected]>,
+ * Kenneth Albanowski <[email protected]>,
+ * Copyright (C) 2000 Lineo, Inc. (http://www.lineo.com)
+ *
+ * Based on:
+ *
+ * linux/arch/m68knommu/mm/init.c
+ * linux/arch/m68k/mm/init.c
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ *
+ * JAN/1999 -- hacked to support ColdFire ([email protected])
+ * DEC/2000 -- linux 2.4 support <[email protected]>
+ */
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/init.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/bootmem.h>
+#include <linux/gfp.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/sections.h>
+
+#undef DEBUG
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+static unsigned long empty_bad_page_table;
+
+static unsigned long empty_bad_page;
+
+unsigned long empty_zero_page;
+
+extern unsigned long rom_length;
+
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
+/*
+ * paging_init() continues the virtual memory environment setup which
+ * was begun by the code in arch/head.S.
+ * The parameters are pointers to where to stick the starting and ending
+ * addresses of available kernel virtual memory.
+ */
+void __init paging_init(void)
+{
+ /*
+ * Make sure start_mem is page aligned, otherwise bootmem and
+ * page_alloc get different views og the world.
+ */
+#ifdef DEBUG
+ unsigned long start_mem = PAGE_ALIGN(memory_start);
+#endif
+ unsigned long end_mem = memory_end & PAGE_MASK;
+
+#ifdef DEBUG
+ pr_debug("start_mem is %#lx\nvirtual_end is %#lx\n",
+ start_mem, end_mem);
+#endif
+
+ /*
+ * Initialize the bad page table and bad page to point
+ * to a couple of allocated pages.
+ */
+ empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+ empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+ empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+ memset((void *)empty_zero_page, 0, PAGE_SIZE);
+
+ /*
+ * Set up SFC/DFC registers (user data space).
+ */
+ set_fs(USER_DS);
+
+#ifdef DEBUG
+ pr_debug("before free_area_init\n");
+
+ pr_debug("free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
+ start_mem, end_mem);
+#endif
+
+ {
+ unsigned long zones_size[MAX_NR_ZONES] = {0, };
+
+ zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT;
+ zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
+#ifdef CONFIG_HIGHMEM
+ zones_size[ZONE_HIGHMEM] = 0;
+#endif
+ free_area_init(zones_size);
+ }
+}
+
+void __init mem_init(void)
+{
+ unsigned long codesize = _etext - _stext;
+
+ pr_devel("Mem_init: start=%lx, end=%lx\n", memory_start, memory_end);
+
+ high_memory = (void *) (memory_end & PAGE_MASK);
+ max_mapnr = MAP_NR(high_memory);
+
+ /* this will put all low memory onto the freelists */
+ free_all_bootmem();
+
+ mem_init_print_info(NULL);
+ if (rom_length > 0 && rom_length > codesize)
+ pr_info("Memory available: %luK/%luK ROM\n",
+ (rom_length - codesize) >> 10, rom_length >> 10);
+}
+
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ free_reserved_area((void *)start, (void *)end, -1, "initrd");
+}
+#endif
+
+void
+free_initmem(void)
+{
+ free_initmem_default(-1);
+}
+
diff --git a/arch/h8300/mm/kmap.c b/arch/h8300/mm/kmap.c
new file mode 100644
index 0000000..4315aa3
--- /dev/null
+++ b/arch/h8300/mm/kmap.c
@@ -0,0 +1,61 @@
+/*
+ * linux/arch/h8300/mm/kmap.c
+ *
+ * Based on
+ * linux/arch/m68knommu/mm/kmap.c
+ *
+ * Copyright (C) 2000 Lineo, <[email protected]>
+ * Copyright (C) 2000-2002 David McCullough <[email protected]>
+ */
+
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+#include <linux/module.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+
+#undef DEBUG
+
+#define VIRT_OFFSET (0x01000000)
+
+/*
+ * Map some physical address range into the kernel address space.
+ */
+void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
+{
+ return (void *)(physaddr + VIRT_OFFSET);
+}
+EXPORT_SYMBOL(__ioremap);
+
+/*
+ * Unmap a ioremap()ed region again.
+ */
+void iounmap(void *addr)
+{
+}
+EXPORT_SYMBOL(iounmap);
+
+/*
+ * __iounmap unmaps nearly everything, so be careful
+ * it doesn't free currently pointer/page tables anymore but it
+ * wans't used anyway and might be added later.
+ */
+void __iounmap(void *addr, unsigned long size)
+{
+}
+
+/*
+ * Set new cache mode for some kernel address space.
+ * The caller must push data for that range itself, if such data may already
+ * be in the cache.
+ */
+void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
+{
+}
diff --git a/arch/h8300/mm/memory.c b/arch/h8300/mm/memory.c
new file mode 100644
index 0000000..c8178a7
--- /dev/null
+++ b/arch/h8300/mm/memory.c
@@ -0,0 +1,54 @@
+/*
+ * linux/arch/h8300/mm/memory.c
+ *
+ * Copyright (C) 2002 Yoshinori Sato <[email protected]>,
+ *
+ * Based on:
+ *
+ * linux/arch/m68knommu/mm/memory.c
+ *
+ * Copyright (C) 1998 Kenneth Albanowski <[email protected]>,
+ * Copyright (C) 1999-2002, Greg Ungerer ([email protected])
+ *
+ * Based on:
+ *
+ * linux/arch/m68k/mm/memory.c
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ */
+
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+
+void cache_clear(unsigned long paddr, int len)
+{
+}
+
+
+void cache_push(unsigned long paddr, int len)
+{
+}
+
+void cache_push_v(unsigned long vaddr, int len)
+{
+}
+
+/*
+ * Map some physical address range into the kernel address space.
+ */
+
+unsigned long kernel_map(unsigned long paddr, unsigned long size,
+ int nocacheflag, unsigned long *memavailp)
+{
+ return paddr;
+}
+
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
arch/h8300/lib/Makefile | 7 ++
arch/h8300/lib/abs.S | 20 ++++++
arch/h8300/lib/ashldi3.c | 58 ++++++++++++++++
arch/h8300/lib/ashrdi3.c | 59 ++++++++++++++++
arch/h8300/lib/checksum.c | 167 +++++++++++++++++++++++++++++++++++++++++++++
arch/h8300/lib/libgcc.h | 76 +++++++++++++++++++++
arch/h8300/lib/lshrdi3.c | 58 ++++++++++++++++
arch/h8300/lib/memcpy.S | 85 +++++++++++++++++++++++
arch/h8300/lib/memset.S | 69 +++++++++++++++++++
arch/h8300/lib/moddivsi3.S | 106 ++++++++++++++++++++++++++++
arch/h8300/lib/modsi3.S | 106 ++++++++++++++++++++++++++++
arch/h8300/lib/muldi3.c | 76 +++++++++++++++++++++
arch/h8300/lib/mulsi3.S | 67 ++++++++++++++++++
arch/h8300/lib/strncpy.S | 34 +++++++++
arch/h8300/lib/ucmpdi2.c | 18 +++++
arch/h8300/lib/udivsi3.S | 107 +++++++++++++++++++++++++++++
16 files changed, 1113 insertions(+)
create mode 100644 arch/h8300/lib/Makefile
create mode 100644 arch/h8300/lib/abs.S
create mode 100644 arch/h8300/lib/ashldi3.c
create mode 100644 arch/h8300/lib/ashrdi3.c
create mode 100644 arch/h8300/lib/checksum.c
create mode 100644 arch/h8300/lib/libgcc.h
create mode 100644 arch/h8300/lib/lshrdi3.c
create mode 100644 arch/h8300/lib/memcpy.S
create mode 100644 arch/h8300/lib/memset.S
create mode 100644 arch/h8300/lib/moddivsi3.S
create mode 100644 arch/h8300/lib/modsi3.S
create mode 100644 arch/h8300/lib/muldi3.c
create mode 100644 arch/h8300/lib/mulsi3.S
create mode 100644 arch/h8300/lib/strncpy.S
create mode 100644 arch/h8300/lib/ucmpdi2.c
create mode 100644 arch/h8300/lib/udivsi3.S
diff --git a/arch/h8300/lib/Makefile b/arch/h8300/lib/Makefile
new file mode 100644
index 0000000..8311a9f
--- /dev/null
+++ b/arch/h8300/lib/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for H8/300-specific library files..
+#
+
+lib-y = checksum.o memcpy.o memset.o abs.o strncpy.o \
+ mulsi3.o udivsi3.o muldi3.o moddivsi3.o \
+ ashldi3.o lshrdi3.o ashrdi3.o ucmpdi2.o
diff --git a/arch/h8300/lib/abs.S b/arch/h8300/lib/abs.S
new file mode 100644
index 0000000..efda749
--- /dev/null
+++ b/arch/h8300/lib/abs.S
@@ -0,0 +1,20 @@
+;;; abs.S
+
+#include <asm/linkage.h>
+
+#if defined(CONFIG_CPU_H8300H)
+ .h8300h
+#endif
+#if defined(CONFIG_CPU_H8S)
+ .h8300s
+#endif
+ .text
+.global _abs
+
+;;; int abs(int n)
+_abs:
+ mov.l er0,er0
+ bpl 1f
+ neg.l er0
+1:
+ rts
diff --git a/arch/h8300/lib/ashldi3.c b/arch/h8300/lib/ashldi3.c
new file mode 100644
index 0000000..d40cdc8
--- /dev/null
+++ b/arch/h8300/lib/ashldi3.c
@@ -0,0 +1,58 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
+
+#include "libgcc.h"
+
+DWtype
+__ashldi3 (DWtype u, word_type b)
+{
+ if (b == 0)
+ return u;
+
+ const DWunion uu = {.ll = u};
+ const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
+ DWunion w;
+
+ if (bm <= 0)
+ {
+ w.s.low = 0;
+ w.s.high = (UWtype) uu.s.low << -bm;
+ }
+ else
+ {
+ const UWtype carries = (UWtype) uu.s.low >> bm;
+
+ w.s.low = (UWtype) uu.s.low << b;
+ w.s.high = ((UWtype) uu.s.high << b) | carries;
+ }
+
+ return w.ll;
+}
diff --git a/arch/h8300/lib/ashrdi3.c b/arch/h8300/lib/ashrdi3.c
new file mode 100644
index 0000000..134f884
--- /dev/null
+++ b/arch/h8300/lib/ashrdi3.c
@@ -0,0 +1,59 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
+
+#include "libgcc.h"
+
+DWtype
+__ashrdi3 (DWtype u, word_type b)
+{
+ if (b == 0)
+ return u;
+
+ const DWunion uu = {.ll = u};
+ const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
+ DWunion w;
+
+ if (bm <= 0)
+ {
+ /* w.s.high = 1..1 or 0..0 */
+ w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
+ w.s.low = uu.s.high >> -bm;
+ }
+ else
+ {
+ const UWtype carries = (UWtype) uu.s.high << bm;
+
+ w.s.high = uu.s.high >> b;
+ w.s.low = ((UWtype) uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
diff --git a/arch/h8300/lib/checksum.c b/arch/h8300/lib/checksum.c
new file mode 100644
index 0000000..40ec5de
--- /dev/null
+++ b/arch/h8300/lib/checksum.c
@@ -0,0 +1,167 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * IP/TCP/UDP checksumming routines
+ *
+ * Authors: Jorge Cwik, <[email protected]>
+ * Arnt Gulbrandsen, <[email protected]>
+ * Tom May, <[email protected]>
+ * Andreas Schwab, <[email protected]>
+ * Lots of code moved from tcp.c and ip.c; see those files
+ * for more names.
+ *
+ * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek:
+ * Fixed some nasty bugs, causing some horrible crashes.
+ * A: At some points, the sum (%0) was used as
+ * length-counter instead of the length counter
+ * (%1). Thanks to Roman Hodek for pointing this out.
+ * B: GCC seems to mess up if one uses too many
+ * data-registers to hold input values and one tries to
+ * specify d0 and d1 as scratch registers. Letting gcc choose these
+ * registers itself solves the problem.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
+ of the assembly has to go. */
+
+#include <net/checksum.h>
+#include <linux/module.h>
+
+static inline unsigned short from32to16(unsigned long x)
+{
+ /* add up 16-bit and 16-bit for 16+c bit */
+ x = (x & 0xffff) + (x >> 16);
+ /* add up carry.. */
+ x = (x & 0xffff) + (x >> 16);
+ return x;
+}
+
+static unsigned long do_csum(const unsigned char *buff, int len)
+{
+ int odd, count;
+ unsigned long result = 0;
+
+ if (len <= 0)
+ goto out;
+ odd = 1 & (unsigned long) buff;
+ if (odd) {
+ result = *buff;
+ len--;
+ buff++;
+ }
+ count = len >> 1; /* nr of 16-bit words.. */
+ if (count) {
+ if (2 & (unsigned long) buff) {
+ result += *(unsigned short *) buff;
+ count--;
+ len -= 2;
+ buff += 2;
+ }
+ count >>= 1; /* nr of 32-bit words.. */
+ if (count) {
+ unsigned long carry = 0;
+
+ do {
+ unsigned long w = *(unsigned long *) buff;
+
+ count--;
+ buff += 4;
+ result += carry;
+ result += w;
+ carry = (w > result);
+ } while (count);
+ result += carry;
+ result = (result & 0xffff) + (result >> 16);
+ }
+ if (len & 2) {
+ result += *(unsigned short *) buff;
+ buff += 2;
+ }
+ }
+ if (len & 1)
+ result += (*buff << 8);
+ result = from32to16(result);
+ if (odd)
+ result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+ return result;
+}
+
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.
+ */
+__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+ return (__force __sum16)~do_csum(iph, ihl*4);
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+/*
+ * Egads... That thing apparently assumes that *all* checksums it ever sees will
+ * be folded. Very likely a bug.
+ */
+__wsum csum_partial(const void *buff, int len, __wsum sum)
+{
+ unsigned int result = do_csum(buff, len);
+
+ /* add in old sum, and carry.. */
+ result += (__force u32)sum;
+ /* 16+c bits -> 16 bits */
+ result = (result & 0xffff) + (result >> 16);
+ return (__force __wsum)result;
+}
+
+EXPORT_SYMBOL(csum_partial);
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+__sum16 ip_compute_csum(const void *buff, int len)
+{
+ return (__force __sum16)~do_csum(buff, len);
+}
+
+/*
+ * copy from fs while checksumming, otherwise like csum_partial
+ */
+
+__wsum
+csum_partial_copy_from_user(const void __user *src, void *dst, int len,
+ __wsum sum, int *csum_err)
+{
+ if (csum_err)
+ *csum_err = 0;
+ memcpy(dst, (__force const void *)src, len);
+ return csum_partial(dst, len, sum);
+}
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+
+__wsum
+csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
+{
+ memcpy(dst, src, len);
+ return csum_partial(dst, len, sum);
+}
diff --git a/arch/h8300/lib/libgcc.h b/arch/h8300/lib/libgcc.h
new file mode 100644
index 0000000..8de547ee
--- /dev/null
+++ b/arch/h8300/lib/libgcc.h
@@ -0,0 +1,76 @@
+#ifndef __H8300_LIBGCC_H__
+#define __H8300_LIBGCC_H__
+
+#ifdef __ASSEMBLY__
+#define A0 r0
+#define A0L r0l
+#define A0H r0h
+
+#define A1 r1
+#define A1L r1l
+#define A1H r1h
+
+#define A2 r2
+#define A2L r2l
+#define A2H r2h
+
+#define A3 r3
+#define A3L r3l
+#define A3H r3h
+
+#define S0 r4
+#define S0L r4l
+#define S0H r4h
+
+#define S1 r5
+#define S1L r5l
+#define S1H r5h
+
+#define S2 r6
+#define S2L r6l
+#define S2H r6h
+
+#define PUSHP push.l
+#define POPP pop.l
+
+#define A0P er0
+#define A1P er1
+#define A2P er2
+#define A3P er3
+#define S0P er4
+#define S1P er5
+#define S2P er6
+
+#define A0E e0
+#define A1E e1
+#define A2E e2
+#define A3E e3
+#else
+#define Wtype SItype
+#define UWtype USItype
+#define HWtype SItype
+#define UHWtype USItype
+#define DWtype DItype
+#define UDWtype UDItype
+#define UWtype USItype
+#define Wtype SItype
+#define UWtype USItype
+#define W_TYPE_SIZE (4 * BITS_PER_UNIT)
+#define BITS_PER_UNIT (8)
+
+typedef int SItype __attribute__ ((mode (SI)));
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef int DItype __attribute__ ((mode (DI)));
+typedef unsigned int UDItype __attribute__ ((mode (DI)));
+struct DWstruct {Wtype high, low;};
+typedef union
+{
+ struct DWstruct s;
+ DWtype ll;
+} DWunion;
+
+typedef int word_type __attribute__ ((mode (__word__)));
+
+#endif
+
+#endif
diff --git a/arch/h8300/lib/lshrdi3.c b/arch/h8300/lib/lshrdi3.c
new file mode 100644
index 0000000..8e3e839
--- /dev/null
+++ b/arch/h8300/lib/lshrdi3.c
@@ -0,0 +1,58 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
+
+#include "libgcc.h"
+
+DWtype
+__lshrdi3 (DWtype u, word_type b)
+{
+ if (b == 0)
+ return u;
+
+ const DWunion uu = {.ll = u};
+ const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
+ DWunion w;
+
+ if (bm <= 0)
+ {
+ w.s.high = 0;
+ w.s.low = (UWtype) uu.s.high >> -bm;
+ }
+ else
+ {
+ const UWtype carries = (UWtype) uu.s.high << bm;
+
+ w.s.high = (UWtype) uu.s.high >> b;
+ w.s.low = ((UWtype) uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
diff --git a/arch/h8300/lib/memcpy.S b/arch/h8300/lib/memcpy.S
new file mode 100644
index 0000000..0c9a51f
--- /dev/null
+++ b/arch/h8300/lib/memcpy.S
@@ -0,0 +1,85 @@
+;;; memcpy.S
+
+#include <asm/linkage.h>
+
+#if defined(CONFIG_CPU_H8300H)
+ .h8300h
+#endif
+#if defined(CONFIG_CPU_H8S)
+ .h8300s
+#endif
+ .text
+.global memcpy
+
+;;; void *memcpy(void *to, void *from, size_t n)
+memcpy:
+ mov.l er2,er2
+ bne 1f
+ rts
+1:
+ ;; address check
+ bld #0,r0l
+ bxor #0,r1l
+ bcs 4f
+ mov.l er4,@-sp
+ mov.l er0,@-sp
+ btst #0,r0l
+ beq 1f
+ ;; (aligned even) odd address
+ mov.b @er1,r3l
+ mov.b r3l,@er0
+ adds #1,er1
+ adds #1,er0
+ dec.l #1,er2
+ beq 3f
+1:
+ ;; n < sizeof(unsigned long) check
+ sub.l er4,er4
+ adds #4,er4 ; loop count check value
+ cmp.l er4,er2
+ blo 2f
+ ;; unsigned long copy
+1:
+ mov.l @er1,er3
+ mov.l er3,@er0
+ adds #4,er0
+ adds #4,er1
+ subs #4,er2
+ cmp.l er4,er2
+ bcc 1b
+ ;; rest
+2:
+ mov.l er2,er2
+ beq 3f
+1:
+ mov.b @er1,r3l
+ mov.b r3l,@er0
+ adds #1,er1
+ adds #1,er0
+ dec.l #1,er2
+ bne 1b
+3:
+ mov.l @sp+,er0
+ mov.l @sp+,er4
+ rts
+
+ ;; odd <- even / even <- odd
+4:
+ mov.l er4,er3
+ mov.l er2,er4
+ mov.l er5,er2
+ mov.l er1,er5
+ mov.l er6,er1
+ mov.l er0,er6
+1:
+ eepmov.w
+ mov.w r4,r4
+ bne 1b
+ dec.w #1,e4
+ bpl 1b
+ mov.l er1,er6
+ mov.l er2,er5
+ mov.l er3,er4
+ rts
+
+ .end
diff --git a/arch/h8300/lib/memset.S b/arch/h8300/lib/memset.S
new file mode 100644
index 0000000..18d4e70
--- /dev/null
+++ b/arch/h8300/lib/memset.S
@@ -0,0 +1,69 @@
+/* memset.S */
+
+#include <asm/linkage.h>
+
+#if defined(CONFIG_CPU_H8300H)
+ .h8300h
+#endif
+#if defined(CONFIG_CPU_H8S)
+ .h8300s
+#endif
+ .text
+
+.global memset
+.global clear_user
+
+;;void *memset(*ptr, int c, size_t count)
+;; ptr = er0
+;; c = er1(r1l)
+;; count = er2
+memset:
+ btst #0,r0l
+ beq 2f
+
+ ;; odd address
+1:
+ mov.b r1l,@er0
+ adds #1,er0
+ dec.l #1,er2
+ beq 6f
+
+ ;; even address
+2:
+ mov.l er2,er3
+ cmp.l #4,er2
+ blo 4f
+ ;; count>=4 -> count/4
+#if defined(CONFIG_CPU_H8300H)
+ shlr.l er2
+ shlr.l er2
+#endif
+#if defined(CONFIG_CPU_H8S)
+ shlr.l #2,er2
+#endif
+ ;; byte -> long
+ mov.b r1l,r1h
+ mov.w r1,e1
+3:
+ mov.l er1,@er0
+ adds #4,er0
+ dec.l #1,er2
+ bne 3b
+4:
+ ;; count % 4
+ and.b #3,r3l
+ beq 6f
+5:
+ mov.b r1l,@er0
+ adds #1,er0
+ dec.b r3l
+ bne 5b
+6:
+ rts
+
+clear_user:
+ mov.l er1, er2
+ sub.l er1, er1
+ bra memset
+
+ .end
diff --git a/arch/h8300/lib/moddivsi3.S b/arch/h8300/lib/moddivsi3.S
new file mode 100644
index 0000000..fae89d6
--- /dev/null
+++ b/arch/h8300/lib/moddivsi3.S
@@ -0,0 +1,106 @@
+;; libgcc routines for the Renesas H8/300 CPU.
+;; Contributed by Steve Chamberlain <[email protected]>
+;; Optimizations by Toshiyasu Morita <[email protected]>
+
+/* Copyright (C) 1994, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING. If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+#include "libgcc.h"
+
+; numerator in A0/A1
+; denominator in A2/A3
+ .global __modsi3
+__modsi3:
+ PUSHP S2P
+ bsr modnorm
+ bsr __divsi3
+ mov.l er3,er0
+ bra exitdiv
+
+ ;; H8/300H and H8S version of ___udivsi3 is defined later in
+ ;; the file.
+
+ .global __umodsi3
+__umodsi3:
+ bsr __udivsi3:16
+ mov.l er3,er0
+ rts
+
+ .global __divsi3
+__divsi3:
+ PUSHP S2P
+ bsr divnorm
+ bsr __udivsi3:16
+
+ ; examine what the sign should be
+exitdiv:
+ btst #3,S2L
+ beq reti
+
+ ; should be -ve
+ neg.l A0P
+
+reti:
+ POPP S2P
+ rts
+
+divnorm:
+ mov.l A0P,A0P ; is the numerator -ve
+ stc ccr,S2L ; keep the sign in bit 3 of S2L
+ bge postive
+
+ neg.l A0P ; negate arg
+
+postive:
+ mov.l A1P,A1P ; is the denominator -ve
+ bge postive2
+
+ neg.l A1P ; negate arg
+ xor.b #0x08,S2L ; toggle the result sign
+
+postive2:
+ rts
+
+;; Basically the same, except that the sign of the divisor determines
+;; the sign.
+modnorm:
+ mov.l A0P,A0P ; is the numerator -ve
+ stc ccr,S2L ; keep the sign in bit 3 of S2L
+ bge mpostive
+
+ neg.l A0P ; negate arg
+
+mpostive:
+ mov.l A1P,A1P ; is the denominator -ve
+ bge mpostive2
+
+ neg.l A1P ; negate arg
+
+mpostive2:
+ rts
+
+ .end
diff --git a/arch/h8300/lib/modsi3.S b/arch/h8300/lib/modsi3.S
new file mode 100644
index 0000000..69ed7ff
--- /dev/null
+++ b/arch/h8300/lib/modsi3.S
@@ -0,0 +1,106 @@
+;; libgcc routines for the Renesas H8/300 CPU.
+;; Contributed by Steve Chamberlain <[email protected]>
+;; Optimizations by Toshiyasu Morita <[email protected]>
+
+/* Copyright (C) 1994, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING. If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+#include "libgcc.h"
+
+; numerator in A0/A1
+; denominator in A2/A3
+ .global __modsi3
+__modsi3:
+ PUSHP S2P
+ bsr modnorm
+ bsr __divsi3
+ mov.l er3,er0
+ bra exitdiv
+
+ ;; H8/300H and H8S version of ___udivsi3 is defined later in
+ ;; the file.
+
+ .global __umodsi3
+__umodsi3:
+ bsr __udivsi3
+ mov.l er3,er0
+ rts
+
+ .global __divsi3
+__divsi3:
+ PUSHP S2P
+ jsr divnorm
+ bsr __udivsi3
+
+ ; examine what the sign should be
+exitdiv:
+ btst #3,S2L
+ beq reti
+
+ ; should be -ve
+ neg.l A0P
+
+reti:
+ POPP S2P
+ rts
+
+divnorm:
+ mov.l A0P,A0P ; is the numerator -ve
+ stc ccr,S2L ; keep the sign in bit 3 of S2L
+ bge postive
+
+ neg.l A0P ; negate arg
+
+postive:
+ mov.l A1P,A1P ; is the denominator -ve
+ bge postive2
+
+ neg.l A1P ; negate arg
+ xor.b #0x08,S2L ; toggle the result sign
+
+postive2:
+ rts
+
+;; Basically the same, except that the sign of the divisor determines
+;; the sign.
+modnorm:
+ mov.l A0P,A0P ; is the numerator -ve
+ stc ccr,S2L ; keep the sign in bit 3 of S2L
+ bge mpostive
+
+ neg.l A0P ; negate arg
+
+mpostive:
+ mov.l A1P,A1P ; is the denominator -ve
+ bge mpostive2
+
+ neg.l A1P ; negate arg
+
+mpostive2:
+ rts
+
+ .end
diff --git a/arch/h8300/lib/muldi3.c b/arch/h8300/lib/muldi3.c
new file mode 100644
index 0000000..d34b030
--- /dev/null
+++ b/arch/h8300/lib/muldi3.c
@@ -0,0 +1,76 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
+
+#include "libgcc.h"
+
+#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
+
+#define umul_ppmm(w1,w0,u,v) \
+ do { \
+ UWtype __x0, __x1, __x2, __x3; \
+ UHWtype __ul, __vl, __uh, __vh; \
+ __ul = __ll_lowpart (u); \
+ __uh = __ll_highpart (u); \
+ __vl = __ll_lowpart (v); \
+ __vh = __ll_highpart (v); \
+ __x0 = (UWtype) __ul * __vl; \
+ __x1 = (UWtype) __ul * __vh; \
+ __x2 = (UWtype) __uh * __vl; \
+ __x3 = (UWtype) __uh * __vh; \
+ __x1 += __ll_highpart (__x0); \
+ __x1 += __x2; \
+ if (__x1 < __x2) \
+ __x3 += __ll_B; \
+ (w1) = __x3 + __ll_highpart (__x1); \
+ (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
+ } while (0)
+
+#define __umulsidi3(u,v) ( \
+ { \
+ DWunion __w; \
+ umul_ppmm (__w.s.high, __w.s.low, u, v); \
+ __w.ll; } \
+ )
+
+DWtype
+__muldi3 (DWtype u, DWtype v)
+{
+ const DWunion uu = {.ll = u};
+ const DWunion vv = {.ll = v};
+ DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
+
+ w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
+ + (UWtype) uu.s.high * (UWtype) vv.s.low);
+
+ return w.ll;
+}
diff --git a/arch/h8300/lib/mulsi3.S b/arch/h8300/lib/mulsi3.S
new file mode 100644
index 0000000..4e29a19
--- /dev/null
+++ b/arch/h8300/lib/mulsi3.S
@@ -0,0 +1,67 @@
+;; libgcc routines for the Renesas H8/300 CPU.
+;; Contributed by Steve Chamberlain <[email protected]>
+;; Optimizations by Toshiyasu Morita <[email protected]>
+
+/* Copyright (C) 1994, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING. If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+;
+; mulsi3 for H8/300H - based on Renesas SH implementation
+;
+; by Toshiyasu Morita
+;
+; Old code:
+;
+; 16b * 16b = 372 states (worst case)
+; 32b * 32b = 724 states (worst case)
+;
+; New code:
+;
+; 16b * 16b = 48 states
+; 16b * 32b = 72 states
+; 32b * 32b = 92 states
+;
+
+ .global __mulsi3
+__mulsi3:
+ mov.w r1,r2 ; ( 2 states) b * d
+ mulxu r0,er2 ; (22 states)
+
+ mov.w e0,r3 ; ( 2 states) a * d
+ beq L_skip1 ; ( 4 states)
+ mulxu r1,er3 ; (22 states)
+ add.w r3,e2 ; ( 2 states)
+
+L_skip1:
+ mov.w e1,r3 ; ( 2 states) c * b
+ beq L_skip2 ; ( 4 states)
+ mulxu r0,er3 ; (22 states)
+ add.w r3,e2 ; ( 2 states)
+
+L_skip2:
+ mov.l er2,er0 ; ( 2 states)
+ rts ; (10 states)
diff --git a/arch/h8300/lib/strncpy.S b/arch/h8300/lib/strncpy.S
new file mode 100644
index 0000000..d00396a
--- /dev/null
+++ b/arch/h8300/lib/strncpy.S
@@ -0,0 +1,34 @@
+;;; strncpy.S
+
+#include <asm/linkage.h>
+
+ .text
+.global strncpy_from_user
+
+;;; long strncpy_from_user(void *to, void *from, size_t n)
+strncpy_from_user:
+ mov.l er2,er2
+ bne 1f
+ sub.l er0,er0
+ rts
+1:
+ mov.l er4,@-sp
+ sub.l er3,er3
+2:
+ mov.b @er1+,r4l
+ mov.b r4l,@er0
+ adds #1,er0
+ beq 3f
+ inc.l #1,er3
+ dec.l #1,er2
+ bne 2b
+3:
+ dec.l #1,er2
+4:
+ mov.b r4l,@er0
+ adds #1,er0
+ dec.l #1,er2
+ bne 4b
+ mov.l er3,er0
+ mov.l @sp+,er4
+ rts
diff --git a/arch/h8300/lib/ucmpdi2.c b/arch/h8300/lib/ucmpdi2.c
new file mode 100644
index 0000000..53b22f6
--- /dev/null
+++ b/arch/h8300/lib/ucmpdi2.c
@@ -0,0 +1,18 @@
+#include "libgcc.h"
+
+word_type
+__ucmpdi2 (DWtype a, DWtype b)
+{
+ const DWunion au = {.ll = a};
+ const DWunion bu = {.ll = b};
+
+ if ((UWtype) au.s.high < (UWtype) bu.s.high)
+ return 0;
+ else if ((UWtype) au.s.high > (UWtype) bu.s.high)
+ return 2;
+ if ((UWtype) au.s.low < (UWtype) bu.s.low)
+ return 0;
+ else if ((UWtype) au.s.low > (UWtype) bu.s.low)
+ return 2;
+ return 1;
+}
diff --git a/arch/h8300/lib/udivsi3.S b/arch/h8300/lib/udivsi3.S
new file mode 100644
index 0000000..bd2d721
--- /dev/null
+++ b/arch/h8300/lib/udivsi3.S
@@ -0,0 +1,107 @@
+;; libgcc routines for the Renesas H8/300 CPU.
+;; Contributed by Steve Chamberlain <[email protected]>
+;; Optimizations by Toshiyasu Morita <[email protected]>
+
+/* Copyright (C) 1994, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING. If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+#include "libgcc.h"
+
+ ;; This function also computes the remainder and stores it in er3.
+ .global __udivsi3
+__udivsi3:
+ mov.w A1E,A1E ; denominator top word 0?
+ bne DenHighNonZero
+
+ ; do it the easy way, see page 107 in manual
+ mov.w A0E,A2
+ extu.l A2P
+ divxu.w A1,A2P
+ mov.w A2E,A0E
+ divxu.w A1,A0P
+ mov.w A0E,A3
+ mov.w A2,A0E
+ extu.l A3P
+ rts
+
+ ; er0 = er0 / er1
+ ; er3 = er0 % er1
+ ; trashes er1 er2
+ ; expects er1 >= 2^16
+DenHighNonZero:
+ mov.l er0,er3
+ mov.l er1,er2
+#ifdef CONFIG_CPU_H8300H
+divmod_L21:
+ shlr.l er0
+ shlr.l er2 ; make divisor < 2^16
+ mov.w e2,e2
+ bne divmod_L21
+#else
+ shlr.l #2,er2 ; make divisor < 2^16
+ mov.w e2,e2
+ beq divmod_L22A
+divmod_L21:
+ shlr.l #2,er0
+divmod_L22:
+ shlr.l #2,er2 ; make divisor < 2^16
+ mov.w e2,e2
+ bne divmod_L21
+divmod_L22A:
+ rotxl.w r2
+ bcs divmod_L23
+ shlr.l er0
+ bra divmod_L24
+divmod_L23:
+ rotxr.w r2
+ shlr.l #2,er0
+divmod_L24:
+#endif
+ ;; At this point,
+ ;; er0 contains shifted dividend
+ ;; er1 contains divisor
+ ;; er2 contains shifted divisor
+ ;; er3 contains dividend, later remainder
+ divxu.w r2,er0 ; r0 now contains the approximate quotient (AQ)
+ extu.l er0
+ beq divmod_L25
+ subs #1,er0 ; er0 = AQ - 1
+ mov.w e1,r2
+ mulxu.w r0,er2 ; er2 = upper (AQ - 1) * divisor
+ sub.w r2,e3 ; dividend - 65536 * er2
+ mov.w r1,r2
+ mulxu.w r0,er2 ; compute er3 = remainder (tentative)
+ sub.l er2,er3 ; er3 = dividend - (AQ - 1) * divisor
+divmod_L25:
+ cmp.l er1,er3 ; is divisor < remainder?
+ blo divmod_L26
+ adds #1,er0
+ sub.l er1,er3 ; correct the remainder
+divmod_L26:
+ rts
+
+ .end
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
arch/h8300/Kconfig | 119 +++++++++++++++++++++++++++++++++++
arch/h8300/Kconfig.cpu | 136 ++++++++++++++++++++++++++++++++++++++++
arch/h8300/Kconfig.debug | 23 +++++++
arch/h8300/Makefile | 45 +++++++++++++
arch/h8300/kernel/Makefile | 16 +++++
arch/h8300/kernel/vmlinux.lds.S | 85 +++++++++++++++++++++++++
6 files changed, 424 insertions(+)
create mode 100644 arch/h8300/Kconfig
create mode 100644 arch/h8300/Kconfig.cpu
create mode 100644 arch/h8300/Kconfig.debug
create mode 100644 arch/h8300/Makefile
create mode 100644 arch/h8300/kernel/Makefile
create mode 100644 arch/h8300/kernel/vmlinux.lds.S
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
new file mode 100644
index 0000000..828c356
--- /dev/null
+++ b/arch/h8300/Kconfig
@@ -0,0 +1,119 @@
+config H8300
+ bool
+ default y
+ select HAVE_IDE
+ select GENERIC_ATOMIC64
+ select HAVE_UID16
+ select VIRT_TO_BUS
+ select ARCH_WANT_IPC_PARSE_VERSION
+ select GENERIC_IRQ_SHOW
+ select FRAME_POINTER
+ select GENERIC_CPU_DEVICES
+ select MODULES_USE_ELF_RELA
+ select GENERIC_CLOCKEVENTS
+ select CLKDEV_LOOKUP
+ select COMMON_CLK
+ select HAVE_ARCH_TRACEHOOK
+ select ARCH_WANT_FRAME_POINTERS
+
+config MMU
+ bool
+ default n
+
+config SWAP
+ bool
+ default n
+
+config ZONE_DMA
+ bool
+ default y
+
+config FPU
+ bool
+ default n
+
+config RWSEM_GENERIC_SPINLOCK
+ bool
+ default y
+
+config RWSEM_XCHGADD_ALGORITHM
+ bool
+ default n
+
+config ARCH_HAS_ILOG2_U32
+ bool
+ default n
+
+config ARCH_HAS_ILOG2_U64
+ bool
+ default n
+
+config GENERIC_HWEIGHT
+ bool
+ default y
+
+config GENERIC_CALIBRATE_DELAY
+ bool
+ default y
+
+config GENERIC_BUG
+ bool
+ depends on BUG
+
+config TIME_LOW_RES
+ bool
+ default y
+
+config NO_IOPORT_MAP
+ def_bool y
+
+config NO_DMA
+ def_bool n
+
+config ISA
+ def_bool n
+
+config PCI
+ def_bool n
+
+config HZ
+ int
+ default 100
+
+config NR_CPUS
+ int
+ default 1
+
+source "init/Kconfig"
+
+source "kernel/Kconfig.freezer"
+
+source "arch/h8300/Kconfig.cpu"
+
+menu "Kernel Features"
+
+source "kernel/Kconfig.preempt"
+
+source "mm/Kconfig"
+
+endmenu
+
+menu "Executable file formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/h8300/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
diff --git a/arch/h8300/Kconfig.cpu b/arch/h8300/Kconfig.cpu
new file mode 100644
index 0000000..2eaa797
--- /dev/null
+++ b/arch/h8300/Kconfig.cpu
@@ -0,0 +1,136 @@
+menu "Processor type and features"
+
+choice
+ prompt "H8/300 platform"
+
+config H8300_AE3068
+ bool "AE-3068/69"
+ select H83069
+ select RAMKERNEL
+ help
+ AKI-H8/3068F / AKI-H8/3069F Flashmicom LAN Board Support
+ More Information. (Japanese Only)
+ <http://akizukidenshi.com/catalog/default.aspx>
+ AE-3068/69 Evaluation Board Support
+ More Information.
+ <http://www.microtronique.com/ae3069lan.htm>
+
+config H8300_H8MAX
+ bool "H8MAX"
+ select H83069
+ select RAMKERNEL
+ help
+ H8MAX Evaluation Board Support
+ More Information. (Japanese Only)
+ <http://strawberry-linux.com/h8/index.html>
+
+config H8300_KANEBEBE
+ bool "KaneBebe"
+ select H83069
+ select RAMKERNEL
+ help
+ KaneBebe Evalition Board Support
+
+config H8300H_SIM
+ bool "H8/300H GDB Simulator"
+ select H83069
+ select ROMKERNEL
+ help
+ GDB Simulator Support
+ More Information.
+ <http://sourceware.org/sid/>
+
+config H8S_EDOSK2674
+ bool "EDOSK-2674"
+ select H8S2678
+ select RAMKERNEL
+ help
+ Renesas EDOSK-2674 Evaluation Board Support
+ More Information.
+ <http://www.azpower.com/H8-uClinux/index.html>
+ <http://www.renesas.eu/products/tools/introductory_evaluation_tools/evaluation_development_os_kits/edosk2674r/edosk2674r_software_tools_root.jsp>
+
+config H8S_SIM
+ bool "H8S GDB Simulator"
+ select H8S2678
+ select ROMKERNEL
+ help
+ GDB Simulator Support
+ More Information.
+ <http://sourceware.org/sid/>
+
+endchoice
+
+choice
+ prompt "CPU Selection"
+
+config H83069
+ bool "H8/3065,3066,3067,3068,3069"
+ select CPU_H8300H
+ select H8300_TMR8
+ select H8300_TMR16
+
+config H8S2678
+ bool "H8S/2670,2673,2674R,2675,2676"
+ select CPU_H8S
+ select H8300_TMR8
+ select H8300_TPU
+
+endchoice
+
+config CPU_CLOCK
+ int "CPU Clock Frequency"
+ depends on ROMKERNEL
+ default "200000000" if H8300H_AKI3068NET || H8300H_SIM
+ default "250000000" if H8300H_H8MAX || H8300H_KANEBEBE
+ default "333333333" if H8S_EDOSK2674 || H8S_SIM
+ help
+ CPU Clock Frequency
+
+choice
+ prompt "Kernel executes from"
+ ---help---
+ Choose the memory type that the kernel will be running in.
+
+config RAMKERNEL
+ bool "RAM"
+ help
+ The kernel will be resident in RAM when running.
+
+config ROMKERNEL
+ bool "ROM"
+ help
+ The kernel will be resident in FLASH/ROM when running.
+endchoice
+
+config CPU_H8300H
+ bool
+ depends on H83069
+ default y
+
+config CPU_H8S
+ bool
+ depends on H8S2678
+ default y
+
+config ROMSIZE
+ hex "ROM size"
+ depends on ROMKERNEL
+ default 0x200000
+
+config RAMBASE
+ hex "RAM base address"
+ default 0x400000
+
+config RAMSIZE
+ hex "RAM size"
+ depends on ROMKERNEL
+ default 0x200000 if H8300_AE3068 || H8300_H8MAX || H8300H_SIM
+ default 0x400000 if H8300_KANEBEBE
+ default 0x800000 if H8S_EDOSK2674 || H8S_SIM
+
+config OFFSET
+ hex "Load offset"
+ default 0
+
+endmenu
diff --git a/arch/h8300/Kconfig.debug b/arch/h8300/Kconfig.debug
new file mode 100644
index 0000000..eb72b01
--- /dev/null
+++ b/arch/h8300/Kconfig.debug
@@ -0,0 +1,23 @@
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config FULLDEBUG
+ bool "Full Symbolic/Source Debugging support"
+ help
+ Enable debugging symbols on kernel build.
+
+config HIGHPROFILE
+ bool "Use fast second timer for profiling"
+ help
+ Use a fast secondary clock to produce profiling information.
+
+config NO_KERNEL_MSG
+ bool "Suppress Kernel BUG Messages"
+ help
+ Do not output any debug BUG messages within the kernel.
+
+config SH_STANDARD_BIOS
+ def_bool n
+
+endmenu
diff --git a/arch/h8300/Makefile b/arch/h8300/Makefile
new file mode 100644
index 0000000..44e915c
--- /dev/null
+++ b/arch/h8300/Makefile
@@ -0,0 +1,45 @@
+#
+# arch/h8300/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# (C) Copyright 2002-2015 Yoshinori Sato <[email protected]>
+#
+
+cflags-$(CONFIG_CPU_H8300H) := -mh
+aflags-$(CONFIG_CPU_H8300H) := -mh -Wa,--mach=h8300h
+ldflags-$(CONFIG_CPU_H8300H) := -mh8300helf_linux
+cflags-$(CONFIG_CPU_H8S) := -ms
+aflags-$(CONFIG_CPU_H8S) := -ms -Wa,--mach=h8300s
+ldflags-$(CONFIG_CPU_H8S) := -mh8300self_linux
+
+KBUILD_CFLAGS += $(cflags-y)
+KBUILD_CFLAGS += -mint32 -fno-builtin
+KBUILD_CFLAGS += -D__linux__
+KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
+KBUILD_AFLAGS += $(aflags-y)
+LDFLAGS += $(ldflags-y)
+
+CROSS_COMPILE := h8300-unknown-linux-
+
+core-y += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/
+
+libs-y += arch/$(ARCH)/lib/
+
+boot := arch/h8300/boot
+
+archmrproper:
+
+archclean:
+ $(Q)$(MAKE) $(clean)=$(boot)
+
+vmlinux.srec vmlinux.bin zImage uImage.bin: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+define archhelp
+ @echo 'vmlinux.bin - Create raw binary'
+ @echo 'vmlinux.srec - Create srec binary'
+ @echo 'zImage - Compressed kernel image'
+endef
diff --git a/arch/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile
new file mode 100644
index 0000000..0b5fe00
--- /dev/null
+++ b/arch/h8300/kernel/Makefile
@@ -0,0 +1,16 @@
+#
+# Makefile for the linux kernel.
+#
+
+extra-y := vmlinux.lds
+
+obj-y := process.o traps.o ptrace.o \
+ signal.o setup.o syscalls.o \
+ irq.o entry.o dma.o cpu/
+
+obj-$(CONFIG_ROMKERNEL) += head_rom.o
+obj-$(CONFIG_RAMKERNEL) += head_ram.o
+
+obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o
+obj-$(CONFIG_H8300H_SIM) += sim-console.o
+obj-$(CONFIG_H8S_SIM) += sim-console.o
diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
new file mode 100644
index 0000000..e1b49aa
--- /dev/null
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -0,0 +1,85 @@
+#include <asm-generic/vmlinux.lds.h>
+#include <asm/page.h>
+
+#define ROMTOP 0x000000
+#define RAMTOP CONFIG_RAMBASE
+
+jiffies = jiffies_64 + 4;
+
+ENTRY(_start)
+
+SECTIONS
+{
+#if defined(CONFIG_ROMKERNEL)
+ . = ROMTOP;
+ .vectors :
+ {
+ _vector = . ;
+ *(.vector*)
+ }
+#else
+ . = RAMTOP;
+ _ramstart = .;
+ . = . + CONFIG_OFFSET;
+#endif
+ _text = .;
+ HEAD_TEXT_SECTION
+ .text : {
+ _stext = . ;
+ TEXT_TEXT
+ SCHED_TEXT
+ LOCK_TEXT
+#if defined(CONFIG_ROMKERNEL)
+ *(.int_redirect)
+#endif
+ _etext = . ;
+ }
+ EXCEPTION_TABLE(16)
+ NOTES
+ RO_DATA(4)
+#if defined(CONFIG_ROMKERNEL)
+ .init.text : {
+ _sinittext = .;
+ INIT_TEXT
+ _einittext = .;
+ }
+ SECURITY_INIT
+#endif
+ ROMEND = .;
+#if defined(CONFIG_ROMKERNEL)
+ . = RAMTOP;
+ _ramstart = .;
+ .data : AT(ROMEND)
+#else
+ .data :
+#endif
+ {
+ _sdata = . ;
+ __data_start = . ;
+ INIT_TASK_DATA(0x2000)
+ NOSAVE_DATA
+ PAGE_ALIGNED_DATA(0x1000)
+ CACHELINE_ALIGNED_DATA(0x0002)
+ READ_MOSTLY_DATA(0x0002)
+ DATA_DATA
+ CONSTRUCTORS
+ }
+ . = ALIGN(0x4) ;
+ __init_begin = .;
+#if defined(CONFIG_RAMKERNEL)
+ INIT_TEXT_SECTION(4)
+#endif
+ INIT_DATA_SECTION(4)
+#if defined(CONFIG_RAMKERNEL)
+ SECURITY_INIT
+#endif
+ __init_end = .;
+ _edata = . ;
+ _begin_data = LOADADDR(.data);
+ _sbss =.;
+ BSS_SECTION(4,4,4)
+ _ebss =.;
+ _ramend = .;
+ _end = .;
+ DISCARDS
+}
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
drivers/clk/Makefile | 1 +
drivers/clk/h8300/Makefile | 2 +
drivers/clk/h8300/clk-h83069.c | 73 ++++++++++++++++++
drivers/clk/h8300/clk-h8s2678.c | 165 ++++++++++++++++++++++++++++++++++++++++
include/linux/clk-provider.h | 12 +++
5 files changed, 253 insertions(+)
create mode 100644 drivers/clk/h8300/Makefile
create mode 100644 drivers/clk/h8300/clk-h83069.c
create mode 100644 drivers/clk/h8300/clk-h8s2678.c
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d5fba5b..37b6e87 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -68,3 +68,4 @@ obj-$(CONFIG_ARCH_U8500) += ux500/
obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
obj-$(CONFIG_X86) += x86/
obj-$(CONFIG_ARCH_ZYNQ) += zynq/
+obj-$(CONFIG_H8300) += h8300/
diff --git a/drivers/clk/h8300/Makefile b/drivers/clk/h8300/Makefile
new file mode 100644
index 0000000..82eab42
--- /dev/null
+++ b/drivers/clk/h8300/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_H83069) += clk-h83069.o
+obj-$(CONFIG_H8S2678) += clk-h8s2678.o
diff --git a/drivers/clk/h8300/clk-h83069.c b/drivers/clk/h8300/clk-h83069.c
new file mode 100644
index 0000000..3334f49
--- /dev/null
+++ b/drivers/clk/h8300/clk-h83069.c
@@ -0,0 +1,73 @@
+/*
+ * H8/3069 clock driver
+ *
+ * Copyright 2015 Yoshinori Sato <[email protected]>
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
+static DEFINE_SPINLOCK(clklock);
+
+#define DIVCR (unsigned char *)0xfee01b
+#define DEVNAME "h83069-cpg"
+
+static int clk_probe(struct platform_device *pdev)
+{
+ struct clk *clk;
+ int *hz = dev_get_platdata(&pdev->dev);
+
+ clk = clk_register_fixed_rate(&pdev->dev, "master_clk", NULL,
+ CLK_IS_ROOT, *hz);
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "failed to register clock");
+ return PTR_ERR(clk);
+ }
+ clk_register_clkdev(clk, "master_clk", DEVNAME ".%d", 0);
+
+ clk = clk_register_divider(&pdev->dev, "core_clk", "master_clk",
+ CLK_SET_RATE_GATE, DIVCR, 0, 2,
+ CLK_DIVIDER_POWER_OF_TWO, &clklock);
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "failed to register clock");
+ return PTR_ERR(clk);
+ }
+ clk_register_clkdev(clk, "core_clk", DEVNAME ".%d", 0);
+
+ clk_add_alias("peripheral_clk", NULL, "core_clk", &pdev->dev);
+ return 0;
+}
+
+static struct platform_driver cpg_driver = {
+ .driver = {
+ .name = DEVNAME,
+ },
+ .probe = clk_probe,
+};
+
+early_platform_init(DEVNAME, &cpg_driver);
+
+static struct platform_device clk_device = {
+ .name = DEVNAME,
+ .id = 0,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &clk_device,
+};
+
+int __init h8300_clk_init(int hz)
+{
+ static int master_hz;
+ master_hz = hz;
+ clk_device.dev.platform_data = &master_hz;
+ early_platform_add_devices(devices,
+ ARRAY_SIZE(devices));
+ early_platform_driver_register_all(DEVNAME);
+ early_platform_driver_probe(DEVNAME, 1, 0);
+ return 0;
+}
diff --git a/drivers/clk/h8300/clk-h8s2678.c b/drivers/clk/h8300/clk-h8s2678.c
new file mode 100644
index 0000000..98cb28f
--- /dev/null
+++ b/drivers/clk/h8300/clk-h8s2678.c
@@ -0,0 +1,165 @@
+/*
+ * H8S2678 clock driver
+ *
+ * Copyright 2015 Yoshinori Sato <[email protected]>
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
+static DEFINE_SPINLOCK(clklock);
+
+#define SCKCR 0xffff3b
+#define PLLCR 0xffff45
+#define DEVNAME "h8s2679-cpg"
+#define MAX_FREQ 33333333
+#define MIN_FREQ 8000000
+
+static unsigned long pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ int mul = 1 << (ctrl_inb(PLLCR) & 3);
+
+ return parent_rate * mul;
+}
+
+static long pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ int i, m = -1;
+ long offset[3];
+
+ if (rate > MAX_FREQ)
+ rate = MAX_FREQ;
+ if (rate < MIN_FREQ)
+ rate = MIN_FREQ;
+
+ for (i = 0; i < 3; i++)
+ offset[i] = abs(rate - (*prate * (1 << i)));
+ for (i = 0; i < 3; i++)
+ if (m < 0)
+ m = i;
+ else
+ m = (offset[i] < offset[m])?i:m;
+
+ return *prate * (1 << m);
+}
+
+static int pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ int pll;
+ unsigned char val;
+ unsigned long flags;
+
+ pll = ((rate / parent_rate) / 2) & 0x03;
+ spin_lock_irqsave(&clklock, flags);
+ val = ctrl_inb(SCKCR);
+ val |= 0x08;
+ ctrl_outb(val, SCKCR);
+ val = ctrl_inb(PLLCR);
+ val &= ~0x03;
+ val |= pll;
+ ctrl_outb(val, PLLCR);
+ spin_unlock_irqrestore(&clklock, flags);
+ return 0;
+}
+
+const static struct clk_ops pll_ops = {
+ .recalc_rate = pll_recalc_rate,
+ .round_rate = pll_round_rate,
+ .set_rate = pll_set_rate,
+};
+
+static struct clk *pll_clk_register(struct device *dev, const char *name,
+ const char *parent)
+{
+ struct clk_hw *hw;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ hw = kzalloc(sizeof(struct clk_hw), GFP_KERNEL);
+ if (!hw) {
+ dev_err(dev, "failed to allocate hw\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ init.name = name;
+ init.ops = &pll_ops;
+ init.flags = CLK_IS_BASIC;
+ init.parent_names = &parent;
+ init.num_parents = 1;
+ hw->init = &init;
+
+ clk = clk_register(dev, hw);
+ if (IS_ERR(clk))
+ kfree(hw);
+
+ return clk;
+}
+
+static int clk_probe(struct platform_device *pdev)
+{
+ struct clk *clk;
+ int *hz = dev_get_platdata(&pdev->dev);
+
+ clk = clk_register_fixed_rate(&pdev->dev, "master_clk", NULL,
+ CLK_IS_ROOT, *hz);
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "failed to register clock");
+ return PTR_ERR(clk);
+ }
+ clk_register_clkdev(clk, "master_clk", DEVNAME ".%d", 0);
+
+ clk = pll_clk_register(&pdev->dev, "pll_clk", "master_clk");
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "failed to register clock");
+ return PTR_ERR(clk);
+ }
+ clk_register_clkdev(clk, "pll_clk", DEVNAME ".%d", 0);
+
+ clk = clk_register_divider(&pdev->dev, "core_clk", "pll_clk",
+ CLK_SET_RATE_GATE, (unsigned char *)SCKCR,
+ 0, 3, CLK_DIVIDER_POWER_OF_TWO, &clklock);
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "failed to register clock");
+ return PTR_ERR(clk);
+ }
+ clk_register_clkdev(clk, "core_clk", DEVNAME ".%d", 0);
+
+ clk_add_alias("peripheral_clk", NULL, "core_clk", &pdev->dev);
+ return 0;
+}
+
+static struct platform_driver cpg_driver = {
+ .driver = {
+ .name = DEVNAME,
+ },
+ .probe = clk_probe,
+};
+
+early_platform_init(DEVNAME, &cpg_driver);
+
+static struct platform_device clk_device = {
+ .name = DEVNAME,
+ .id = 0,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &clk_device,
+};
+
+int __init h8300_clk_init(int hz)
+{
+ static int master_hz;
+ master_hz = hz;
+ clk_device.dev.platform_data = &master_hz;
+ early_platform_add_devices(devices,
+ ARRAY_SIZE(devices));
+ early_platform_driver_register_all(DEVNAME);
+ early_platform_driver_probe(DEVNAME, 1, 0);
+ return 0;
+}
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index d936409..d4a41b5 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -635,6 +635,18 @@ static inline void clk_writel(u32 val, u32 __iomem *reg)
iowrite32be(val, reg);
}
+#elif IS_ENABLED(CONFIG_H8300)
+
+static inline u32 clk_readl(u32 __iomem *reg)
+{
+ return readb(reg);
+}
+
+static inline void clk_writel(u32 val, u32 __iomem *reg)
+{
+ writeb(val, reg);
+}
+
#else /* platform dependent I/O accessors */
static inline u32 clk_readl(u32 __iomem *reg)
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
drivers/clocksource/Kconfig | 9 +
drivers/clocksource/Makefile | 3 +
drivers/clocksource/h8300_timer16.c | 335 ++++++++++++++++++++++++++++++
drivers/clocksource/h8300_timer8.c | 400 ++++++++++++++++++++++++++++++++++++
drivers/clocksource/h8300_tpu.c | 205 ++++++++++++++++++
5 files changed, 952 insertions(+)
create mode 100644 drivers/clocksource/h8300_timer16.c
create mode 100644 drivers/clocksource/h8300_timer8.c
create mode 100644 drivers/clocksource/h8300_tpu.c
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index fc01ec2..04b60b6 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -229,4 +229,13 @@ config CLKSRC_MIPS_GIC
depends on MIPS_GIC
select CLKSRC_OF
+config H8300_TMR8
+ bool
+
+config H8300_TMR16
+ bool
+
+config H8300_TPU
+ bool
+
endmenu
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 94d90b2..b381503 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -48,3 +48,6 @@ obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o
obj-$(CONFIG_ARCH_INTEGRATOR_AP) += timer-integrator-ap.o
obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o
obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o
+obj-$(CONFIG_H8300_TMR8) += h8300_timer8.o
+obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o
+obj-$(CONFIG_H8300_TPU) += h8300_tpu.o
diff --git a/drivers/clocksource/h8300_timer16.c b/drivers/clocksource/h8300_timer16.c
new file mode 100644
index 0000000..81af95c
--- /dev/null
+++ b/drivers/clocksource/h8300_timer16.c
@@ -0,0 +1,335 @@
+/*
+ * linux/arch/h8300/kernel/timer/timer16.c
+ *
+ * Yoshinori Sato <[email protected]>
+ *
+ * 16bit Timer clockevent device
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/clockchips.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/timer.h>
+
+#define TSTR 0
+#define TSNC 1
+#define TMDR 2
+#define TOLR 3
+#define TISRA 4
+#define TISRB 5
+#define TISRC 6
+
+#define TCR 0
+#define TIOR 1
+#define TCNT 2
+#define GRA 4
+#define GRB 6
+
+#define FLAG_REPROGRAM (1 << 0)
+#define FLAG_SKIPEVENT (1 << 1)
+#define FLAG_IRQCONTEXT (1 << 2)
+#define FLAG_STARTED (1 << 3)
+
+#define ONESHOT 0
+#define PERIODIC 1
+
+#define RELATIVE 0
+#define ABSOLUTE 1
+
+struct timer16_priv {
+ struct platform_device *pdev;
+ struct clock_event_device ced;
+ struct irqaction irqaction;
+ unsigned long mapbase;
+ unsigned long mapcommon;
+ unsigned long flags;
+ unsigned int rate;
+ unsigned short gra;
+ unsigned char enb;
+ unsigned char imfa;
+ unsigned char imiea;
+ unsigned char ovf;
+ raw_spinlock_t lock;
+ struct clk *clk;
+};
+
+static unsigned long timer16_get_counter(struct timer16_priv *p)
+{
+ unsigned long v1, v2, v3;
+ int o1, o2;
+
+ o1 = ctrl_inb(p->mapcommon + TISRC) & p->ovf;
+
+ /* Make sure the timer value is stable. Stolen from acpi_pm.c */
+ do {
+ o2 = o1;
+ v1 = ctrl_inw(p->mapbase + TCNT);
+ v2 = ctrl_inw(p->mapbase + TCNT);
+ v3 = ctrl_inw(p->mapbase + TCNT);
+ o1 = ctrl_inb(p->mapcommon + TISRC) & p->ovf;
+ } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
+ || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
+
+ v2 |= 0x10000;
+ return v2;
+}
+
+
+static irqreturn_t timer16_interrupt(int irq, void *dev_id)
+{
+ struct timer16_priv *p = (struct timer16_priv *)dev_id;
+
+ ctrl_outb(ctrl_inb(p->mapcommon + TISRA) & ~p->imfa,
+ p->mapcommon + TISRA);
+
+ p->flags |= FLAG_IRQCONTEXT;
+ ctrl_outw(p->gra, p->mapbase + GRA);
+ if (!(p->flags & FLAG_SKIPEVENT)) {
+ if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) {
+ ctrl_outb(ctrl_inb(p->mapcommon + TSTR) & ~p->enb,
+ p->mapcommon + TISRA);
+ }
+ p->ced.event_handler(&p->ced);
+ }
+
+ p->flags &= ~(FLAG_SKIPEVENT | FLAG_IRQCONTEXT);
+
+ return IRQ_HANDLED;
+}
+
+static void timer16_set_next(struct timer16_priv *p, unsigned long delta)
+{
+ unsigned long flags;
+ unsigned long now;
+
+ raw_spin_lock_irqsave(&p->lock, flags);
+ if (delta >= 0x10000)
+ dev_warn(&p->pdev->dev, "delta out of range\n");
+ now = timer16_get_counter(p);
+ p->gra = delta;
+ ctrl_outb(ctrl_inb(p->mapcommon + TISRA) | p->imiea,
+ p->mapcommon + TISRA);
+ if (delta > now)
+ ctrl_outw(delta, p->mapbase + GRA);
+ else
+ ctrl_outw(now + 1, p->mapbase + GRA);
+
+ raw_spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static int timer16_enable(struct timer16_priv *p)
+{
+ p->rate = clk_get_rate(p->clk) / 8;
+ ctrl_outw(0xffff, p->mapbase + GRA);
+ ctrl_outw(0x0000, p->mapbase + TCNT);
+ ctrl_outb(0xa3, p->mapbase + TCR);
+ ctrl_outb(ctrl_inb(p->mapcommon + TSTR) | p->enb,
+ p->mapcommon + TSTR);
+
+ return 0;
+}
+
+static int timer16_start(struct timer16_priv *p)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&p->lock, flags);
+
+ if (!(p->flags & FLAG_STARTED))
+ ret = timer16_enable(p);
+
+ if (ret)
+ goto out;
+ p->flags |= FLAG_STARTED;
+
+ out:
+ raw_spin_unlock_irqrestore(&p->lock, flags);
+
+ return ret;
+}
+
+static void timer16_stop(struct timer16_priv *p)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&p->lock, flags);
+
+ ctrl_outb(ctrl_inb(p->mapcommon + TSTR) & ~p->enb,
+ p->mapcommon + TSTR);
+
+ raw_spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static inline struct timer16_priv *ced_to_priv(struct clock_event_device *ced)
+{
+ return container_of(ced, struct timer16_priv, ced);
+}
+
+static void timer16_clock_event_start(struct timer16_priv *p, int periodic)
+{
+ struct clock_event_device *ced = &p->ced;
+
+ timer16_start(p);
+
+ ced->shift = 32;
+ ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
+ ced->max_delta_ns = clockevent_delta2ns(0xffff, ced);
+ ced->min_delta_ns = clockevent_delta2ns(0x0001, ced);
+
+ timer16_set_next(p, periodic?(p->rate + HZ/2) / HZ:0x10000);
+}
+
+static void timer16_clock_event_mode(enum clock_event_mode mode,
+ struct clock_event_device *ced)
+{
+ struct timer16_priv *p = ced_to_priv(ced);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ dev_info(&p->pdev->dev, "used for periodic clock events\n");
+ timer16_stop(p);
+ timer16_clock_event_start(p, PERIODIC);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ dev_info(&p->pdev->dev, "used for oneshot clock events\n");
+ timer16_stop(p);
+ timer16_clock_event_start(p, ONESHOT);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ timer16_stop(p);
+ break;
+ default:
+ break;
+ }
+}
+
+static int timer16_clock_event_next(unsigned long delta,
+ struct clock_event_device *ced)
+{
+ struct timer16_priv *p = ced_to_priv(ced);
+
+ BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
+ timer16_set_next(p, delta - 1);
+
+ return 0;
+}
+
+#define REG_CH 0
+#define REG_COMM 1
+
+static int timer16_setup(struct timer16_priv *p, struct platform_device *pdev)
+{
+ struct h8300_timer16_config *cfg = dev_get_platdata(&pdev->dev);
+ struct resource *res[2];
+ int ret, irq;
+
+ memset(p, 0, sizeof(*p));
+ p->pdev = pdev;
+
+ res[REG_CH] = platform_get_resource(p->pdev,
+ IORESOURCE_MEM, REG_CH);
+ res[REG_COMM] = platform_get_resource(p->pdev,
+ IORESOURCE_MEM, REG_COMM);
+ if (!res[REG_CH] || !res[REG_COMM]) {
+ dev_err(&p->pdev->dev, "failed to get I/O memory\n");
+ return -ENXIO;
+ }
+ irq = platform_get_irq(p->pdev, 0);
+ if (irq < 0) {
+ dev_err(&p->pdev->dev, "failed to get irq\n");
+ return irq;
+ }
+
+ p->clk = clk_get(&p->pdev->dev, "peripheral_clk");
+ if (IS_ERR(p->clk)) {
+ dev_err(&p->pdev->dev, "can't get clk\n");
+ return PTR_ERR(p->clk);
+ }
+
+ p->pdev = pdev;
+ p->mapbase = res[REG_CH]->start;
+ p->mapcommon = res[REG_COMM]->start;
+ p->enb = 1 << cfg->enb;
+ p->imfa = 1 << cfg->imfa;
+ p->imiea = 1 << cfg->imiea;
+ p->ced.name = pdev->name;
+ p->ced.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+ p->ced.rating = 200;
+ p->ced.cpumask = cpumask_of(0);
+ p->ced.set_next_event = timer16_clock_event_next;
+ p->ced.set_mode = timer16_clock_event_mode;
+
+ ret = request_irq(irq, timer16_interrupt,
+ IRQF_DISABLED | IRQF_TIMER, pdev->name, p);
+ if (ret < 0) {
+ dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
+ return ret;
+ }
+
+ clockevents_register_device(&p->ced);
+
+ return 0;
+}
+
+static int timer16_probe(struct platform_device *pdev)
+{
+ struct timer16_priv *p = platform_get_drvdata(pdev);
+
+ if (p) {
+ dev_info(&pdev->dev, "kept as earlytimer\n");
+ return 0;
+ }
+
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (p == NULL) {
+ dev_err(&pdev->dev, "failed to allocate driver data."
+ " out of memory.\n");
+ return -ENOMEM;
+ }
+
+ return timer16_setup(p, pdev);
+}
+
+static int timer16_remove(struct platform_device *pdev)
+{
+ return -EBUSY;
+}
+
+static struct platform_driver timer16_driver = {
+ .probe = timer16_probe,
+ .remove = timer16_remove,
+ .driver = {
+ .name = "h8300h-16timer",
+ }
+};
+
+static int __init timer16_init(void)
+{
+ return platform_driver_register(&timer16_driver);
+}
+
+static void __exit timer16_exit(void)
+{
+ platform_driver_unregister(&timer16_driver);
+}
+
+subsys_initcall(timer16_init);
+module_exit(timer16_exit);
+MODULE_AUTHOR("Yoshinori Sato");
+MODULE_DESCRIPTION("H8/300H 16bit Timer Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clocksource/h8300_timer8.c b/drivers/clocksource/h8300_timer8.c
new file mode 100644
index 0000000..331b3ff
--- /dev/null
+++ b/drivers/clocksource/h8300_timer8.c
@@ -0,0 +1,400 @@
+/*
+ * linux/arch/h8300/kernel/cpu/timer/timer8.c
+ *
+ * Yoshinori Sato <[email protected]>
+ *
+ * 8bit Timer driver
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/timer.h>
+
+#define _8TCR 0
+#define _8TCSR 2
+#define TCORA 4
+#define TCORB 6
+#define _8TCNT 8
+
+#define FLAG_REPROGRAM (1 << 0)
+#define FLAG_SKIPEVENT (1 << 1)
+#define FLAG_IRQCONTEXT (1 << 2)
+#define FLAG_STARTED (1 << 3)
+
+#define ONESHOT 0
+#define PERIODIC 1
+
+#define RELATIVE 0
+#define ABSOLUTE 1
+
+struct timer8_priv {
+ struct platform_device *pdev;
+ int mode;
+ union {
+ struct clocksource cs;
+ struct clock_event_device ced;
+ } clk;
+ struct irqaction irqaction;
+ unsigned long mapbase;
+ raw_spinlock_t lock;
+ unsigned long total_cycles;
+ unsigned int cs_enabled;
+ unsigned long flags;
+ unsigned int rate;
+ unsigned short tcora;
+ unsigned short div;
+ struct clk *pclk;
+};
+
+static const int div_rate[] = {8, 64, 8192};
+
+static unsigned long timer8_get_counter(struct timer8_priv *p)
+{
+ unsigned long v1, v2, v3;
+ int o1, o2;
+
+ o1 = ctrl_inb(p->mapbase + _8TCSR) & 0x20;
+
+ /* Make sure the timer value is stable. Stolen from acpi_pm.c */
+ do {
+ o2 = o1;
+ v1 = ctrl_inw(p->mapbase + _8TCNT);
+ v2 = ctrl_inw(p->mapbase + _8TCNT);
+ v3 = ctrl_inw(p->mapbase + _8TCNT);
+ o1 = ctrl_inb(p->mapbase + _8TCSR) & 0x20;
+ } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
+ || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
+
+ v2 |= o1 << 10;
+ return v2;
+}
+
+static irqreturn_t timer8_interrupt(int irq, void *dev_id)
+{
+ struct timer8_priv *p = dev_id;
+
+ switch (p->mode) {
+ case H8300_TMR8_CLKSRC:
+ ctrl_outb(ctrl_inb(p->mapbase + _8TCSR) & ~0x20,
+ p->mapbase + _8TCSR);
+ p->total_cycles += 0x10000;
+ break;
+ case H8300_TMR8_CLKEVTDEV:
+ ctrl_outb(ctrl_inb(p->mapbase + _8TCSR) & ~0x40,
+ p->mapbase + _8TCSR);
+ p->flags |= FLAG_IRQCONTEXT;
+ ctrl_outw(p->tcora, p->mapbase + TCORA);
+ if (!(p->flags & FLAG_SKIPEVENT)) {
+ if (p->clk.ced.mode == CLOCK_EVT_MODE_ONESHOT)
+ ctrl_outw(0x0000, p->mapbase + _8TCR);
+ p->clk.ced.event_handler(&p->clk.ced);
+ }
+ p->flags &= ~(FLAG_SKIPEVENT | FLAG_IRQCONTEXT);
+ break;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static inline struct timer8_priv *cs_to_priv(struct clocksource *cs)
+{
+ return container_of(cs, struct timer8_priv, clk.cs);
+}
+
+static cycle_t timer8_clocksource_read(struct clocksource *cs)
+{
+ struct timer8_priv *p = cs_to_priv(cs);
+ unsigned long flags, raw;
+ unsigned long value;
+
+ raw_spin_lock_irqsave(&p->lock, flags);
+ value = p->total_cycles;
+ raw = timer8_get_counter(p);
+ raw_spin_unlock_irqrestore(&p->lock, flags);
+
+ return value + raw;
+}
+
+static int timer8_clocksource_enable(struct clocksource *cs)
+{
+ struct timer8_priv *p = cs_to_priv(cs);
+
+ WARN_ON(p->cs_enabled);
+
+ p->total_cycles = 0;
+ ctrl_outw(0, p->mapbase + _8TCNT);
+ ctrl_outw(0x2400 | p->div, p->mapbase + _8TCR);
+
+ p->cs_enabled = true;
+ return 0;
+}
+
+static void timer8_clocksource_disable(struct clocksource *cs)
+{
+ struct timer8_priv *p = cs_to_priv(cs);
+
+ WARN_ON(!p->cs_enabled);
+
+ ctrl_outb(0, p->mapbase + _8TCR);
+ p->cs_enabled = false;
+}
+
+static void timer8_set_next(struct timer8_priv *p, unsigned long delta)
+{
+ unsigned long flags;
+ unsigned long now;
+
+ raw_spin_lock_irqsave(&p->lock, flags);
+ if (delta >= 0x10000)
+ dev_warn(&p->pdev->dev, "delta out of range\n");
+ now = timer8_get_counter(p);
+ p->tcora = delta;
+ ctrl_outb(ctrl_inb(p->mapbase + _8TCR) | 0x40, p->mapbase + _8TCR);
+ if (delta > now)
+ ctrl_outw(delta, p->mapbase + TCORA);
+ else
+ ctrl_outw(now + 1, p->mapbase + TCORA);
+
+ raw_spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static int timer8_enable(struct timer8_priv *p)
+{
+ p->rate = clk_get_rate(p->pclk) / div_rate[p->div];
+ ctrl_outw(0xffff, p->mapbase + TCORA);
+ ctrl_outw(0x0000, p->mapbase + _8TCNT);
+ ctrl_outw(0x0c01, p->mapbase + _8TCR);
+
+ return 0;
+}
+
+static int timer8_start(struct timer8_priv *p)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&p->lock, flags);
+
+ if (!(p->flags & FLAG_STARTED))
+ ret = timer8_enable(p);
+
+ if (ret)
+ goto out;
+ p->flags |= FLAG_STARTED;
+
+ out:
+ raw_spin_unlock_irqrestore(&p->lock, flags);
+
+ return ret;
+}
+
+static void timer8_stop(struct timer8_priv *p)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&p->lock, flags);
+
+ ctrl_outw(0x0000, p->mapbase + _8TCR);
+
+ raw_spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static inline struct timer8_priv *ced_to_priv(struct clock_event_device *ced)
+{
+ return container_of(ced, struct timer8_priv, clk.ced);
+}
+
+static void timer8_clock_event_start(struct timer8_priv *p, int periodic)
+{
+ struct clock_event_device *ced = &p->clk.ced;
+
+ timer8_start(p);
+
+ ced->shift = 32;
+ ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
+ ced->max_delta_ns = clockevent_delta2ns(0xffff, ced);
+ ced->min_delta_ns = clockevent_delta2ns(0x0001, ced);
+
+ timer8_set_next(p, periodic?(p->rate + HZ/2) / HZ:0x10000);
+}
+
+static void timer8_clock_event_mode(enum clock_event_mode mode,
+ struct clock_event_device *ced)
+{
+ struct timer8_priv *p = ced_to_priv(ced);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ dev_info(&p->pdev->dev, "used for periodic clock events\n");
+ timer8_stop(p);
+ timer8_clock_event_start(p, PERIODIC);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ dev_info(&p->pdev->dev, "used for oneshot clock events\n");
+ timer8_stop(p);
+ timer8_clock_event_start(p, ONESHOT);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ timer8_stop(p);
+ break;
+ default:
+ break;
+ }
+}
+
+static int timer8_clock_event_next(unsigned long delta,
+ struct clock_event_device *ced)
+{
+ struct timer8_priv *p = ced_to_priv(ced);
+
+ BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
+ timer8_set_next(p, delta - 1);
+
+ return 0;
+}
+
+#define CMI 0
+#define OVI 1
+static int __init timer8_setup(struct timer8_priv *p,
+ struct platform_device *pdev)
+{
+ struct h8300_timer8_config *cfg = dev_get_platdata(&pdev->dev);
+ struct resource *res;
+ int irq[2];
+ int ret;
+
+ memset(p, 0, sizeof(*p));
+ p->pdev = pdev;
+
+ res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&p->pdev->dev, "failed to get I/O memory\n");
+ return -ENXIO;
+ }
+
+ irq[CMI] = platform_get_irq(p->pdev, CMI);
+ irq[OVI] = platform_get_irq(p->pdev, OVI);
+ if (irq[CMI] < 0 || irq[OVI] < 0) {
+ dev_err(&p->pdev->dev, "failed to get irq\n");
+ return -ENXIO;
+ }
+
+ p->mapbase = res->start;
+
+ p->irqaction.name = dev_name(&p->pdev->dev);
+ p->irqaction.handler = timer8_interrupt;
+ p->irqaction.dev_id = p;
+ p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER;
+
+ p->mode = cfg->mode;
+ p->div = cfg->div;
+
+ p->pclk = clk_get(&p->pdev->dev, "peripheral_clk");
+ if (IS_ERR(p->pclk)) {
+ dev_err(&p->pdev->dev, "can't get clk\n");
+ return PTR_ERR(p->pclk);
+ }
+
+ switch (p->mode) {
+ case H8300_TMR8_CLKSRC:
+ p->clk.cs.name = pdev->name;
+ p->clk.cs.rating = 200;
+ p->clk.cs.read = timer8_clocksource_read;
+ p->clk.cs.enable = timer8_clocksource_enable;
+ p->clk.cs.disable = timer8_clocksource_disable;
+ p->clk.cs.mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
+ p->clk.cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
+
+ ret = setup_irq(irq[OVI], &p->irqaction);
+ if (ret < 0) {
+ dev_err(&p->pdev->dev,
+ "failed to request irq %d\n", irq[OVI]);
+ return ret;
+ }
+ clocksource_register_hz(&p->clk.cs,
+ clk_get_rate(p->pclk) / div_rate[p->div]);
+ break;
+ case H8300_TMR8_CLKEVTDEV:
+ p->clk.ced.name = pdev->name;
+ p->clk.ced.features = CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_ONESHOT;
+ p->clk.ced.rating = 200;
+ p->clk.ced.cpumask = cpumask_of(0);
+ p->clk.ced.set_next_event = timer8_clock_event_next;
+ p->clk.ced.set_mode = timer8_clock_event_mode;
+
+ ret = setup_irq(irq[CMI], &p->irqaction);
+ if (ret < 0) {
+ dev_err(&p->pdev->dev,
+ "failed to request irq %d\n", irq[CMI]);
+ return ret;
+ }
+ clockevents_register_device(&p->clk.ced);
+ break;
+ }
+ platform_set_drvdata(pdev, p);
+
+ return 0;
+}
+
+static int timer8_probe(struct platform_device *pdev)
+{
+ struct timer8_priv *p = platform_get_drvdata(pdev);
+
+ if (p) {
+ dev_info(&pdev->dev, "kept as earlytimer\n");
+ return 0;
+ }
+
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (p == NULL) {
+ dev_err(&pdev->dev, "failed to allocate driver data.\n");
+ return -ENOMEM;
+ }
+
+ return timer8_setup(p, pdev);
+}
+
+static int timer8_remove(struct platform_device *pdev)
+{
+ return -EBUSY;
+}
+
+static struct platform_driver timer8_driver = {
+ .probe = timer8_probe,
+ .remove = timer8_remove,
+ .driver = {
+ .name = "h8300-8timer",
+ }
+};
+
+static int __init timer8_init(void)
+{
+ return platform_driver_register(&timer8_driver);
+}
+
+static void __exit timer8_exit(void)
+{
+ platform_driver_unregister(&timer8_driver);
+}
+
+early_platform_init("earlytimer", &timer8_driver);
+subsys_initcall(timer8_init);
+module_exit(timer8_exit);
+MODULE_AUTHOR("Yoshinori Sato");
+MODULE_DESCRIPTION("H8/300 8bit Timer Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clocksource/h8300_tpu.c b/drivers/clocksource/h8300_tpu.c
new file mode 100644
index 0000000..4fac748
--- /dev/null
+++ b/drivers/clocksource/h8300_tpu.c
@@ -0,0 +1,205 @@
+/*
+ * linux/arch/h8300/kernel/cpu/timer/timer_tpu.c
+ *
+ * Yoshinori Sato <[email protected]>
+ *
+ * TPU driver
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/clocksource.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/timer.h>
+
+#define TCR 0
+#define TMDR 1
+#define TIOR 2
+#define TER 4
+#define TSR 5
+#define TCNT 6
+#define TGRA 8
+#define TGRB 10
+#define TGRC 12
+#define TGRD 14
+
+struct tpu_priv {
+ struct platform_device *pdev;
+ struct clocksource cs;
+ struct clk *clk;
+ unsigned long mapbase1;
+ unsigned long mapbase2;
+ raw_spinlock_t lock;
+ unsigned int cs_enabled;
+};
+
+static inline unsigned long read_tcnt32(struct tpu_priv *p)
+{
+ unsigned long tcnt;
+
+ tcnt = ctrl_inw(p->mapbase1 + TCNT) << 16;
+ tcnt |= ctrl_inw(p->mapbase2 + TCNT);
+ return tcnt;
+}
+
+static int tpu_get_counter(struct tpu_priv *p, unsigned long long *val)
+{
+ unsigned long v1, v2, v3;
+ int o1, o2;
+
+ o1 = ctrl_inb(p->mapbase1 + TSR) & 0x10;
+
+ /* Make sure the timer value is stable. Stolen from acpi_pm.c */
+ do {
+ o2 = o1;
+ v1 = read_tcnt32(p);
+ v2 = read_tcnt32(p);
+ v3 = read_tcnt32(p);
+ o1 = ctrl_inb(p->mapbase1 + TSR) & 0x10;
+ } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
+ || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
+
+ *val = v2;
+ return o1;
+}
+
+static inline struct tpu_priv *cs_to_priv(struct clocksource *cs)
+{
+ return container_of(cs, struct tpu_priv, cs);
+}
+
+static cycle_t tpu_clocksource_read(struct clocksource *cs)
+{
+ struct tpu_priv *p = cs_to_priv(cs);
+ unsigned long flags;
+ unsigned long long value;
+
+ raw_spin_lock_irqsave(&p->lock, flags);
+ if (tpu_get_counter(p, &value))
+ value += 0x100000000;
+ raw_spin_unlock_irqrestore(&p->lock, flags);
+
+ return value;
+}
+
+static int tpu_clocksource_enable(struct clocksource *cs)
+{
+ struct tpu_priv *p = cs_to_priv(cs);
+
+ WARN_ON(p->cs_enabled);
+
+ ctrl_outw(0, p->mapbase1 + TCNT);
+ ctrl_outw(0, p->mapbase2 + TCNT);
+ ctrl_outb(0x0f, p->mapbase1 + TCR);
+ ctrl_outb(0x03, p->mapbase2 + TCR);
+
+ p->cs_enabled = true;
+ return 0;
+}
+
+static void tpu_clocksource_disable(struct clocksource *cs)
+{
+ struct tpu_priv *p = cs_to_priv(cs);
+
+ WARN_ON(!p->cs_enabled);
+
+ ctrl_outb(0, p->mapbase1 + TCR);
+ ctrl_outb(0, p->mapbase2 + TCR);
+ p->cs_enabled = false;
+}
+
+#define CH_L 0
+#define CH_H 1
+
+static int __init tpu_setup(struct tpu_priv *p, struct platform_device *pdev)
+{
+ struct resource *res[2];
+
+ memset(p, 0, sizeof(*p));
+ p->pdev = pdev;
+
+ res[CH_L] = platform_get_resource(p->pdev, IORESOURCE_MEM, CH_L);
+ res[CH_H] = platform_get_resource(p->pdev, IORESOURCE_MEM, CH_H);
+ if (!res[CH_L] || !res[CH_H]) {
+ dev_err(&p->pdev->dev, "failed to get I/O memory\n");
+ return -ENXIO;
+ }
+
+ p->clk = clk_get(&p->pdev->dev, "peripheral_clk");
+ if (IS_ERR(p->clk)) {
+ dev_err(&p->pdev->dev, "can't get clk\n");
+ return PTR_ERR(p->clk);
+ }
+
+ p->mapbase1 = res[CH_L]->start;
+ p->mapbase2 = res[CH_H]->start;
+
+ p->cs.name = pdev->name;
+ p->cs.rating = 200;
+ p->cs.read = tpu_clocksource_read;
+ p->cs.enable = tpu_clocksource_enable;
+ p->cs.disable = tpu_clocksource_disable;
+ p->cs.mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
+ p->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
+ clocksource_register_hz(&p->cs, clk_get_rate(p->clk) / 64);
+ platform_set_drvdata(pdev, p);
+
+ return 0;
+}
+
+static int tpu_probe(struct platform_device *pdev)
+{
+ struct tpu_priv *p = platform_get_drvdata(pdev);
+
+ if (p) {
+ dev_info(&pdev->dev, "kept as earlytimer\n");
+ return 0;
+ }
+
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (p == NULL) {
+ dev_err(&pdev->dev, "failed to allocate driver data\n");
+ return -ENOMEM;
+ }
+
+ return tpu_setup(p, pdev);
+}
+
+static int tpu_remove(struct platform_device *pdev)
+{
+ return -EBUSY;
+}
+
+static struct platform_driver tpu_driver = {
+ .probe = tpu_probe,
+ .remove = tpu_remove,
+ .driver = {
+ .name = "h8s-tpu",
+ }
+};
+
+static int __init tpu_init(void)
+{
+ return platform_driver_register(&tpu_driver);
+}
+
+static void __exit tpu_exit(void)
+{
+ platform_driver_unregister(&tpu_driver);
+}
+
+subsys_initcall(tpu_init);
+module_exit(tpu_exit);
+MODULE_AUTHOR("Yoshinori Sato");
+MODULE_DESCRIPTION("H8S Timer Pulse Unit Driver");
+MODULE_LICENSE("GPL v2");
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
arch/h8300/configs/h8300h-sim_defconfig | 54 +++++++++++++++++++++++++++++++
arch/h8300/configs/h8s-sim_defconfig | 56 +++++++++++++++++++++++++++++++++
2 files changed, 110 insertions(+)
create mode 100644 arch/h8300/configs/h8300h-sim_defconfig
create mode 100644 arch/h8300/configs/h8s-sim_defconfig
diff --git a/arch/h8300/configs/h8300h-sim_defconfig b/arch/h8300/configs/h8300h-sim_defconfig
new file mode 100644
index 0000000..060121c
--- /dev/null
+++ b/arch/h8300/configs/h8300h-sim_defconfig
@@ -0,0 +1,54 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_USELIB is not set
+# CONFIG_INIT_FALLBACK is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_UID16 is not set
+# CONFIG_SYSFS_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+# CONFIG_ADVISE_SYSCALLS is not set
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLOB=y
+CONFIG_MODULES=y
+# CONFIG_BLOCK is not set
+CONFIG_H8300H_SIM=y
+CONFIG_CPU_CLOCK=20000000
+CONFIG_ROMKERNEL=y
+# CONFIG_BINFMT_SCRIPT is not set
+CONFIG_BINFMT_FLAT=y
+# CONFIG_COREDUMP is not set
+# CONFIG_UEVENT_HELPER is not set
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_PROC_FS is not set
+# CONFIG_SYSFS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_CRC32 is not set
diff --git a/arch/h8300/configs/h8s-sim_defconfig b/arch/h8300/configs/h8s-sim_defconfig
new file mode 100644
index 0000000..368d23f
--- /dev/null
+++ b/arch/h8300/configs/h8s-sim_defconfig
@@ -0,0 +1,56 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_USELIB is not set
+# CONFIG_INIT_FALLBACK is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_UID16 is not set
+# CONFIG_SYSFS_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+# CONFIG_ADVISE_SYSCALLS is not set
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLOB=y
+CONFIG_MODULES=y
+# CONFIG_BLOCK is not set
+CONFIG_H8S_SIM=y
+CONFIG_H8S2678=y
+CONFIG_CPU_CLOCK=20000000
+CONFIG_ROMKERNEL=y
+CONFIG_RAMSIZE=0x200000
+# CONFIG_BINFMT_SCRIPT is not set
+CONFIG_BINFMT_FLAT=y
+# CONFIG_COREDUMP is not set
+# CONFIG_UEVENT_HELPER is not set
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_PROC_FS is not set
+# CONFIG_SYSFS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_CRC32 is not set
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
drivers/tty/serial/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index c79b43c..ed01f33 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -747,7 +747,7 @@ config SERIAL_IP22_ZILOG_CONSOLE
config SERIAL_SH_SCI
tristate "SuperH SCI(F) serial port support"
- depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST
+ depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST || H8300
select SERIAL_CORE
config SERIAL_SH_SCI_NR_UARTS
--
2.1.4
Signed-off-by: Yoshinori Sato <[email protected]>
---
include/uapi/linux/elf-em.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/uapi/linux/elf-em.h b/include/uapi/linux/elf-em.h
index ae99f77..b088296 100644
--- a/include/uapi/linux/elf-em.h
+++ b/include/uapi/linux/elf-em.h
@@ -25,6 +25,7 @@
#define EM_ARM 40 /* ARM 32 bit */
#define EM_SH 42 /* SuperH */
#define EM_SPARCV9 43 /* SPARC v9 64-bit */
+#define EM_H8_300 46 /* Renesas H8/300 */
#define EM_IA_64 50 /* HP/Intel IA-64 */
#define EM_X86_64 62 /* AMD x86-64 */
#define EM_S390 22 /* IBM S/390 */
--
2.1.4
Sorry. I send too old files.
This patch is correct.
Signed-off-by: Yoshinori Sato <[email protected]>
---
arch/h8300/kernel/process.c | 170 +++++++++++++++++++++++
arch/h8300/kernel/ptrace.c | 203 +++++++++++++++++++++++++++
arch/h8300/kernel/signal.c | 326 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 699 insertions(+)
create mode 100644 arch/h8300/kernel/process.c
create mode 100644 arch/h8300/kernel/ptrace.c
create mode 100644 arch/h8300/kernel/signal.c
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
new file mode 100644
index 0000000..c0f7511
--- /dev/null
+++ b/arch/h8300/kernel/process.c
@@ -0,0 +1,170 @@
+/*
+ * linux/arch/h8300/kernel/process.c
+ *
+ * Yoshinori Sato <[email protected]>
+ *
+ * Based on:
+ *
+ * linux/arch/m68knommu/kernel/process.c
+ *
+ * Copyright (C) 1998 D. Jeff Dionne <[email protected]>,
+ * Kenneth Albanowski <[email protected]>,
+ * The Silver Hammer Group, Ltd.
+ *
+ * linux/arch/m68k/kernel/process.c
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/rcupdate.h>
+
+#include <asm/uaccess.h>
+#include <asm/traps.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+
+void (*pm_power_off)(void) = NULL;
+EXPORT_SYMBOL(pm_power_off);
+
+asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
+
+/*
+ * The idle loop on an H8/300..
+ */
+void arch_cpu_idle(void)
+{
+ local_irq_enable();
+ __asm__("sleep");
+}
+
+void machine_restart(char *__unused)
+{
+ local_irq_disable();
+ __asm__("jmp @@0");
+}
+
+void machine_halt(void)
+{
+ local_irq_disable();
+ __asm__("sleep");
+ for (;;)
+ ;
+}
+
+void machine_power_off(void)
+{
+ local_irq_disable();
+ __asm__("sleep");
+ for (;;)
+ ;
+}
+
+void show_regs(struct pt_regs *regs)
+{
+ show_regs_print_info(KERN_DEFAULT);
+
+ printk("\nPC: %08lx Status: %02x",
+ regs->pc, regs->ccr);
+ printk("\nORIG_ER0: %08lx ER0: %08lx ER1: %08lx",
+ regs->orig_er0, regs->er0, regs->er1);
+ printk("\nER2: %08lx ER3: %08lx ER4: %08lx ER5: %08lx",
+ regs->er2, regs->er3, regs->er4, regs->er5);
+ printk("\nER6' %08lx ", regs->er6);
+ if (user_mode(regs))
+ printk("USP: %08lx\n", rdusp());
+ else
+ printk("\n");
+}
+
+void flush_thread(void)
+{
+}
+
+int copy_thread(unsigned long clone_flags,
+ unsigned long usp, unsigned long topstk,
+ struct task_struct *p)
+{
+ struct pt_regs *childregs;
+
+ childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1;
+
+ if (unlikely(p->flags & PF_KTHREAD)) {
+ memset(childregs, 0, sizeof(struct pt_regs));
+ childregs->retpc = (unsigned long) ret_from_kernel_thread;
+ childregs->er4 = topstk; /* arg */
+ childregs->er5 = usp; /* fn */
+ } else {
+ *childregs = *current_pt_regs();
+ childregs->er0 = 0;
+ childregs->retpc = (unsigned long) ret_from_fork;
+ p->thread.usp = usp ?: rdusp();
+ }
+ p->thread.ksp = (unsigned long)childregs;
+
+ return 0;
+}
+
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+ return ((struct pt_regs *)tsk->thread.esp0)->pc;
+}
+
+unsigned long get_wchan(struct task_struct *p)
+{
+ unsigned long fp, pc;
+ unsigned long stack_page;
+ int count = 0;
+
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+
+ stack_page = (unsigned long)p;
+ fp = ((struct pt_regs *)p->thread.ksp)->er6;
+ do {
+ if (fp < stack_page+sizeof(struct thread_info) ||
+ fp >= 8184+stack_page)
+ return 0;
+ pc = ((unsigned long *)fp)[1];
+ if (!in_sched_functions(pc))
+ return pc;
+ fp = *(unsigned long *) fp;
+ } while (count++ < 16);
+ return 0;
+}
+
+/* generic sys_clone is not enough registers */
+asmlinkage int sys_clone(unsigned long __user *args)
+{
+ unsigned long clone_flags;
+ unsigned long newsp;
+ uintptr_t parent_tidptr;
+ uintptr_t child_tidptr;
+
+ get_user(clone_flags, &args[0]);
+ get_user(newsp, &args[1]);
+ get_user(parent_tidptr, &args[2]);
+ get_user(child_tidptr, &args[3]);
+ return do_fork(clone_flags, newsp, 0,
+ (int __user *)parent_tidptr, (int __user *)child_tidptr);
+}
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
new file mode 100644
index 0000000..d27d00b
--- /dev/null
+++ b/arch/h8300/kernel/ptrace.c
@@ -0,0 +1,203 @@
+/*
+ * linux/arch/h8300/kernel/ptrace.c
+ *
+ * Copyright 2015 Yoshinori Sato <[email protected]>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/audit.h>
+#include <linux/tracehook.h>
+#include <linux/regset.h>
+#include <linux/elf.h>
+
+#define CCR_MASK 0x6f /* mode/imask not set */
+#define EXR_MASK 0x80 /* modify only T */
+
+#define PT_REG(r) offsetof(struct pt_regs, r)
+
+extern void user_disable_single_step(struct task_struct *child);
+
+/* Mapping from PT_xxx to the stack offset at which the register is
+ saved. Notice that usp has no stack-slot and needs to be treated
+ specially (see get_reg/put_reg below). */
+static const int register_offset[] = {
+ PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4),
+ PT_REG(er5), PT_REG(er6), PT_REG(er0), -1,
+ PT_REG(orig_er0), PT_REG(ccr), PT_REG(pc),
+#if defined(CONFIG_CPU_H8S)
+ PT_REG(exr),
+#endif
+};
+
+/* read register */
+long h8300_get_reg(struct task_struct *task, int regno)
+{
+ switch (regno) {
+ case PT_USP:
+ return task->thread.usp + sizeof(long)*2;
+ case PT_CCR:
+ case PT_EXR:
+ return *(unsigned short *)(task->thread.esp0 +
+ register_offset[regno]);
+ default:
+ return *(unsigned long *)(task->thread.esp0 +
+ register_offset[regno]);
+ }
+}
+
+int h8300_put_reg(struct task_struct *task, int regno, unsigned long data)
+{
+ unsigned short oldccr;
+ unsigned short oldexr;
+
+ switch (regno) {
+ case PT_USP:
+ task->thread.usp = data - sizeof(long)*2;
+ case PT_CCR:
+ oldccr = *(unsigned short *)(task->thread.esp0 +
+ register_offset[regno]);
+ oldccr &= ~CCR_MASK;
+ data &= CCR_MASK;
+ data |= oldccr;
+ *(unsigned short *)(task->thread.esp0 +
+ register_offset[regno]) = data;
+ break;
+ case PT_EXR:
+ oldexr = *(unsigned short *)(task->thread.esp0 +
+ register_offset[regno]);
+ oldccr &= ~EXR_MASK;
+ data &= EXR_MASK;
+ data |= oldexr;
+ *(unsigned short *)(task->thread.esp0 +
+ register_offset[regno]) = data;
+ break;
+ default:
+ *(unsigned long *)(task->thread.esp0 +
+ register_offset[regno]) = data;
+ break;
+ }
+ return 0;
+}
+
+static int regs_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int r;
+ struct user_regs_struct regs;
+ long *reg = (long *)®s;
+
+ /* build user regs in buffer */
+ for (r = 0; r < ARRAY_SIZE(register_offset); r++)
+ *reg++ = h8300_get_reg(target, r);
+
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ ®s, 0, sizeof(regs));
+}
+
+static int regs_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int r;
+ int ret;
+ struct user_regs_struct regs;
+ long *reg;
+
+ /* build user regs in buffer */
+ for (reg = (long *)®s, r = 0; r < ARRAY_SIZE(register_offset); r++)
+ *reg++ = h8300_get_reg(target, r);
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ ®s, 0, sizeof(regs));
+ if (ret)
+ return ret;
+
+ /* write back to pt_regs */
+ for (reg = (long *)®s, r = 0; r < ARRAY_SIZE(register_offset); r++)
+ h8300_put_reg(target, r, *reg++);
+ return 0;
+}
+
+enum h8300_regset {
+ REGSET_GENERAL,
+};
+
+static const struct user_regset h8300_regsets[] = {
+ [REGSET_GENERAL] = {
+ .core_note_type = NT_PRSTATUS,
+ .n = ELF_NGREG,
+ .size = sizeof(long),
+ .align = sizeof(long),
+ .get = regs_get,
+ .set = regs_set,
+ },
+};
+
+static const struct user_regset_view user_h8300_native_view = {
+ .name = "h8300",
+ .e_machine = EM_H8_300,
+ .regsets = h8300_regsets,
+ .n = ARRAY_SIZE(h8300_regsets),
+};
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+ return &user_h8300_native_view;
+}
+
+void ptrace_disable(struct task_struct *child)
+{
+ user_disable_single_step(child);
+}
+
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
+{
+ int ret;
+
+ switch (request) {
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+ return ret;
+}
+
+asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
+{
+ long ret = 0;
+
+ if (test_thread_flag(TIF_SYSCALL_TRACE) &&
+ tracehook_report_syscall_entry(regs))
+ /*
+ * Tracing decided this syscall should not happen.
+ * We'll return a bogus call number to get an ENOSYS
+ * error, but leave the original number in regs->regs[0].
+ */
+ ret = -1L;
+
+ audit_syscall_entry(regs->er1, regs->er2, regs->er3,
+ regs->er4, regs->er5);
+
+ return ret ?: regs->er0;
+}
+
+asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
+{
+ int step;
+
+ audit_syscall_exit(regs);
+
+ step = test_thread_flag(TIF_SINGLESTEP);
+ if (step || test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall_exit(regs, step);
+}
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
new file mode 100644
index 0000000..1222783
--- /dev/null
+++ b/arch/h8300/kernel/signal.c
@@ -0,1 +1,326 @@
+/*
+ * linux/arch/h8300/kernel/signal.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * uClinux H8/300 support by Yoshinori Sato <[email protected]>
+ * and David McCullough <[email protected]>
+ *
+ * Based on
+ * Linux/m68k by Hamish Macdonald
+ */
+
+/*
+ * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
+ * Atari :-) Current limitation: Only one sigstack can be active at one time.
+ * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
+ * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
+ * signal handlers!
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/syscalls.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/highuid.h>
+#include <linux/personality.h>
+#include <linux/tty.h>
+#include <linux/binfmts.h>
+#include <linux/tracehook.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/traps.h>
+#include <asm/ucontext.h>
+
+/*
+ * Do a signal return; undo the signal stack.
+ *
+ * Keep the return code on the stack quadword aligned!
+ * That makes the cache flush below easier.
+ */
+
+struct rt_sigframe {
+ long dummy_er0;
+ long dummy_vector;
+#if defined(CONFIG_CPU_H8S)
+ short dummy_exr;
+#endif
+ long dummy_pc;
+ char *pretcode;
+ struct siginfo *pinfo;
+ void *puc;
+ unsigned char retcode[8];
+ struct siginfo info;
+ struct ucontext uc;
+ int sig;
+} __packed __aligned(2);
+
+static inline int
+restore_sigcontext(struct sigcontext *usc, int *pd0)
+{
+ struct pt_regs *regs = current_pt_regs();
+ int err = 0;
+ unsigned int ccr;
+ unsigned int usp;
+ unsigned int er0;
+
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+#define COPY(r) err |= __get_user(regs->r, &usc->sc_##r) /* restore passed registers */
+ COPY(er1);
+ COPY(er2);
+ COPY(er3);
+ COPY(er5);
+ COPY(pc);
+ ccr = regs->ccr & 0x10;
+ COPY(ccr);
+#undef COPY
+ regs->ccr &= 0xef;
+ regs->ccr |= ccr;
+ regs->orig_er0 = -1; /* disable syscall checks */
+ err |= __get_user(usp, &usc->sc_usp);
+ wrusp(usp);
+
+ err |= __get_user(er0, &usc->sc_er0);
+ *pd0 = er0;
+ return err;
+}
+
+asmlinkage int sys_rt_sigreturn(void)
+{
+ unsigned long usp = rdusp();
+ struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
+ sigset_t set;
+ int er0;
+
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+ goto badframe;
+
+ set_current_blocked(&set);
+
+ if (restore_sigcontext(&frame->uc.uc_mcontext, &er0))
+ goto badframe;
+
+ if (restore_altstack(&frame->uc.uc_stack))
+ goto badframe;
+
+ return er0;
+
+badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
+ unsigned long mask)
+{
+ int err = 0;
+
+ err |= __put_user(regs->er0, &sc->sc_er0);
+ err |= __put_user(regs->er1, &sc->sc_er1);
+ err |= __put_user(regs->er2, &sc->sc_er2);
+ err |= __put_user(regs->er3, &sc->sc_er3);
+ err |= __put_user(regs->er4, &sc->sc_er4);
+ err |= __put_user(regs->er5, &sc->sc_er5);
+ err |= __put_user(regs->er6, &sc->sc_er6);
+ err |= __put_user(rdusp(), &sc->sc_usp);
+ err |= __put_user(regs->pc, &sc->sc_pc);
+ err |= __put_user(regs->ccr, &sc->sc_ccr);
+ err |= __put_user(mask, &sc->sc_mask);
+
+ return err;
+}
+
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+ unsigned long usp;
+
+ /* Default to using normal stack. */
+ usp = rdusp();
+
+ /* This is the X/Open sanctioned signal stack switching. */
+ if (ka->sa.sa_flags & SA_ONSTACK) {
+ if (!sas_ss_flags(usp))
+ usp = current->sas_ss_sp + current->sas_ss_size;
+ }
+ return (void *)((usp - frame_size) & -8UL);
+}
+
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
+{
+ struct rt_sigframe *frame;
+ int err = 0;
+ int usig;
+ int sig = ksig->sig;
+ unsigned char *ret;
+
+ frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
+
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ return -EFAULT;
+
+ usig = current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig;
+
+ err |= __put_user(usig, &frame->sig);
+ if (err)
+ return -EFAULT;
+
+ err |= __put_user(&frame->info, &frame->pinfo);
+ err |= __put_user(&frame->uc, &frame->puc);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
+ if (err)
+ return -EFAULT;
+
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->uc.uc_flags);
+ err |= __put_user(0, &frame->uc.uc_link);
+ err |= __save_altstack(&frame->uc.uc_stack, rdusp());
+ err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
+ err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+ if (err)
+ return -EFAULT;
+
+ /* Set up to return from userspace. */
+ ret = frame->retcode;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER)
+ ret = (unsigned char *)(ksig->ka.sa.sa_restorer);
+ else {
+ /* sub.l er0,er0; mov.b #__NR_rt_sigreturn,r0l; trapa #0 */
+ err |= __put_user(0x1a80f800 + (__NR_rt_sigreturn & 0xff),
+ (unsigned long *)(frame->retcode + 0));
+ err |= __put_user(0x5700,
+ (unsigned short *)(frame->retcode + 4));
+ }
+ err |= __put_user(ret, &frame->pretcode);
+
+ if (err)
+ return -EFAULT;
+
+ /* Set up registers for signal handler */
+ wrusp((unsigned long) frame);
+ regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
+ regs->er0 = (current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig);
+ regs->er1 = (unsigned long)&(frame->info);
+ regs->er2 = (unsigned long)&frame->uc;
+ regs->er5 = current->mm->start_data; /* GOT base */
+
+ return 0;
+}
+
+static void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka)
+{
+ switch (regs->er0) {
+ case -ERESTARTNOHAND:
+ if (!ka)
+ goto do_restart;
+ regs->er0 = -EINTR;
+ break;
+ case -ERESTART_RESTARTBLOCK:
+ if (!ka) {
+ regs->er0 = __NR_restart_syscall;
+ regs->pc -= 2;
+ } else
+ regs->er0 = -EINTR;
+ break;
+ case -ERESTARTSYS:
+ if (!(ka->sa.sa_flags & SA_RESTART)) {
+ regs->er0 = -EINTR;
+ break;
+ }
+ /* fallthrough */
+ case -ERESTARTNOINTR:
+do_restart:
+ regs->er0 = regs->orig_er0;
+ regs->pc -= 2;
+ break;
+ }
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static void
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
+{
+ sigset_t *oldset = sigmask_to_save();
+ int ret;
+ /* are we from a system call? */
+ if (regs->orig_er0 >= 0)
+ handle_restart(regs, &ksig->ka);
+
+ ret = setup_rt_frame(ksig, oldset, regs);
+
+ signal_setup_done(ret, ksig, 0);
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ */
+static void do_signal(struct pt_regs *regs)
+{
+ struct ksignal ksig;
+
+ /*
+ * We want the common case to go fast, which
+ * is why we may in certain cases get here from
+ * kernel mode. Just return without doing anything
+ * if so.
+ */
+ if ((regs->ccr & 0x10))
+ return;
+
+ current->thread.esp0 = (unsigned long) regs;
+
+ if (get_signal(&ksig)) {
+ /* Whee! Actually deliver the signal. */
+ handle_signal(&ksig, regs);
+ return;
+ }
+ /* Did we come from a system call? */
+ if (regs->orig_er0 >= 0)
+ handle_restart(regs, NULL);
+
+ /* If there's no signal to deliver, we just restore the saved mask. */
+ restore_saved_sigmask();
+}
+
+asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
+{
+ if (thread_info_flags & _TIF_SIGPENDING)
+ do_signal(regs);
+
+ if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+ clear_thread_flag(TIF_NOTIFY_RESUME);
+ tracehook_notify_resume(regs);
+ }
+}
--
2.1.4
Hi Sato-san,
On Sun, Feb 15, 2015 at 8:49 AM, Yoshinori Sato
<[email protected]> wrote:
> --- /dev/null
> +++ b/arch/h8300/include/asm/io.h
> @@ -0,0 +1,372 @@
> +#ifndef _H8300_IO_H
> +#define _H8300_IO_H
> +
> +#ifdef __KERNEL__
> +
> +#include <linux/types.h>
> +
> +/*
> + * These are for ISA/PCI shared memory _only_ and should never be used
> + * on any other type of memory, including Zorro memory. They are meant to
> + * access the bus in the bus byte order which is little-endian!.
> + *
> + * readX/writeX() are used to access memory mapped devices. On some
> + * architectures the memory mapped IO stuff needs to be accessed
> + * differently. On the m68k architecture, we just read/write the
> + * memory location directly.
> + */
> +/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
> + * two accesses to memory, which may be undesirable for some devices.
> + */
While some of the above applies to h8300, I think you should remove
the parts that don't apply.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
On Sun, 2015-02-15 at 17:11 +0900, Yoshinori Sato wrote:
> Sorry. I send too old files.
> This patch is correct.
>
> Signed-off-by: Yoshinori Sato <[email protected]>
> ---
> arch/h8300/kernel/process.c | 170 +++++++++++++++++++++++
> arch/h8300/kernel/ptrace.c | 203 +++++++++++++++++++++++++++
> arch/h8300/kernel/signal.c | 326 ++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 699 insertions(+)
> create mode 100644 arch/h8300/kernel/process.c
> create mode 100644 arch/h8300/kernel/ptrace.c
> create mode 100644 arch/h8300/kernel/signal.c
>
>[...]
> diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
> new file mode 100644
> index 0000000..1222783
> --- /dev/null
> +++ b/arch/h8300/kernel/signal.c
> @@ -0,1 +1,326 @@
That line should read
@@ -0,0 +1,326 @@
shouldn't it? At least, currently that line makes "git am" here barf
with
fatal: new file arch/h8300/kernel/signal.c depends on old contents
Paul Bolle
On Sun, 2015-02-15 at 16:49 +0900, Yoshinori Sato wrote:
> Yoshinori Sato (15):
> h8300: Assembly headers.
> h8300: UAPI headers
> h8300: Exception and Interrupt handling
> h8300: kernel booting
> h8300: Process and signal
> h8300 CPU depend helpers
> h8300: miscellaneous functions
> h8300: Memory management
> h8300: library functions
> h8300: Build scripts
> h8300: clock driver
> h8300: clocksource
> h8300: configs
> serial: Add h8300
> Add ELF machine
git am warns about various whitespace issues:
Applying: h8300: Assembly headers.
[...]/.git/rebase-apply/patch:831: new blank line at EOF.
+
[...]/.git/rebase-apply/patch:1674: new blank line at EOF.
+
warning: 2 lines add whitespace errors.
Applying: h8300: UAPI headers
Applying: h8300: Exception and Interrupt handling
[...]/.git/rebase-apply/patch:223: trailing whitespace.
/* r1l is saved ccr */
warning: 1 line adds whitespace errors.
Applying: h8300: kernel booting
[...]/.git/rebase-apply/patch:54: new blank line at EOF.
+
warning: 1 line adds whitespace errors.
Applying: h8300: Process and signal
[...]/.git/rebase-apply/patch:314: trailing whitespace.
warning: 1 line adds whitespace errors.
Applying: h8300 CPU depend helpers
[...]/.git/rebase-apply/patch:32: new blank line at EOF.
+
[...]/.git/rebase-apply/patch:827: new blank line at EOF.
+
warning: 2 lines add whitespace errors.
Applying: h8300: miscellaneous functions
Applying: h8300: Memory management
[...]/.git/rebase-apply/patch:88: new blank line at EOF.
+
[...]/.git/rebase-apply/patch:247: new blank line at EOF.
+
[...]/.git/rebase-apply/patch:374: new blank line at EOF.
+
warning: 3 lines add whitespace errors.
Applying: h8300: library functions
[...]/.git/rebase-apply/patch:279: trailing whitespace.
[...]/.git/rebase-apply/patch:1170: trailing whitespace.
[...]/.git/rebase-apply/patch:1188: space before tab in indent.
; er0 = er0 / er1
[...]/.git/rebase-apply/patch:1189: space before tab in indent.
; er3 = er0 % er1
[...]/.git/rebase-apply/patch:1190: space before tab in indent.
; trashes er1 er2
warning: squelched 3 whitespace errors
warning: 8 lines add whitespace errors.
Applying: h8300: Build scripts
[...]/.git/rebase-apply/patch:197: space before tab in indent.
<http://www.renesas.eu/products/tools/introductory_evaluation_tools/evaluation_development_os_kits/edosk2674r/edosk2674r_software_tools_root.jsp>
warning: 1 line adds whitespace errors.
Applying: h8300: clock driver
[...]/.git/rebase-apply/patch:161: trailing whitespace.
[...]/.git/rebase-apply/patch:216: trailing whitespace.
[...]/.git/rebase-apply/patch:236: trailing whitespace.
warning: 3 lines add whitespace errors.
Applying: h8300: clocksource
[...]/.git/rebase-apply/patch:22: trailing whitespace.
warning: 1 line adds whitespace errors.
Applying: h8300: configs
Applying: serial: Add h8300
Applying: Add ELF machine
(I did fix patch 12/15 ("h8300: clocksource") manually, to make it apply
on top of next-20150213, but I don't think I introduced the warning in
that patch.)
Paul Bolle
On Sun, 2015-02-15 at 16:49 +0900, Yoshinori Sato wrote:
> Signed-off-by: Yoshinori Sato <[email protected]>
> ---
> arch/h8300/Kconfig | 119 +++++++++++++++++++++++++++++++++++
> arch/h8300/Kconfig.cpu | 136 ++++++++++++++++++++++++++++++++++++++++
> arch/h8300/Kconfig.debug | 23 +++++++
> arch/h8300/Makefile | 45 +++++++++++++
> arch/h8300/kernel/Makefile | 16 +++++
> arch/h8300/kernel/vmlinux.lds.S | 85 +++++++++++++++++++++++++
> 6 files changed, 424 insertions(+)
> create mode 100644 arch/h8300/Kconfig
> create mode 100644 arch/h8300/Kconfig.cpu
> create mode 100644 arch/h8300/Kconfig.debug
> create mode 100644 arch/h8300/Makefile
> create mode 100644 arch/h8300/kernel/Makefile
> create mode 100644 arch/h8300/kernel/vmlinux.lds.S
>
> diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
> new file mode 100644
> index 0000000..828c356
> --- /dev/null
> +++ b/arch/h8300/Kconfig
> @@ -0,0 +1,119 @@
> +config H8300
> + bool
> + default y
> + select HAVE_IDE
> + select GENERIC_ATOMIC64
> + select HAVE_UID16
> + select VIRT_TO_BUS
> + select ARCH_WANT_IPC_PARSE_VERSION
> + select GENERIC_IRQ_SHOW
> + select FRAME_POINTER
> + select GENERIC_CPU_DEVICES
> + select MODULES_USE_ELF_RELA
> + select GENERIC_CLOCKEVENTS
> + select CLKDEV_LOOKUP
> + select COMMON_CLK
> + select HAVE_ARCH_TRACEHOOK
> + select ARCH_WANT_FRAME_POINTERS
> +
> +config MMU
> + bool
> + default n
> +
> +config SWAP
> + bool
> + default n
> +
MMU will always be 'n'. (So the entry for MMU is not strictly needed,
but I guess it is clearer to explicitly set this to 'n'.) But that means
there's no reason here to mask the global SWAP config (see
init/Kconfig), as that will also always be 'n' for H8300.
> +config ZONE_DMA
> + bool
> + default y
> +
> +config FPU
> + bool
> + default n
Why is this needed?
> +
> +config RWSEM_GENERIC_SPINLOCK
> + bool
> + default y
> +
> +config RWSEM_XCHGADD_ALGORITHM
> + bool
> + default n
Not strictly needed.
> +config ARCH_HAS_ILOG2_U32
> + bool
> + default n
> +
Ditto.
> +config ARCH_HAS_ILOG2_U64
> + bool
> + default n
> +
Ditto.
> +config GENERIC_HWEIGHT
> + bool
> + default y
> +
> +config GENERIC_CALIBRATE_DELAY
> + bool
> + default y
> +
> +config GENERIC_BUG
> + bool
> + depends on BUG
> +
GENERIC_BUG can never be set for H8300, so this entry is not needed.
> +config TIME_LOW_RES
> + bool
> + default y
> +
> +config NO_IOPORT_MAP
> + def_bool y
> +
> +config NO_DMA
> + def_bool n
Not needed (please note that only a few architectures have an entry for
NO_DMA).
> +config ISA
> + def_bool n
> +
> +config PCI
> + def_bool n
> +
Neither ISA nor PCI will ever be set, won't they? So you might as well
drop these too.
> +config HZ
> + int
> + default 100
> +
> +config NR_CPUS
> + int
Eight spaces instead of one tab.
> + default 1
> +
> +source "init/Kconfig"
> +
> +source "kernel/Kconfig.freezer"
> +
> +source "arch/h8300/Kconfig.cpu"
> +
> +menu "Kernel Features"
> +
> +source "kernel/Kconfig.preempt"
> +
> +source "mm/Kconfig"
> +
> +endmenu
> +
> +menu "Executable file formats"
> +
> +source "fs/Kconfig.binfmt"
> +
> +endmenu
> +
> +source "net/Kconfig"
> +
> +source "drivers/Kconfig"
> +
> +source "fs/Kconfig"
> +
> +source "arch/h8300/Kconfig.debug"
> +
> +source "security/Kconfig"
> +
> +source "crypto/Kconfig"
> +
> +source "lib/Kconfig"
> diff --git a/arch/h8300/Kconfig.cpu b/arch/h8300/Kconfig.cpu
> new file mode 100644
> index 0000000..2eaa797
> --- /dev/null
> +++ b/arch/h8300/Kconfig.cpu
> @@ -0,0 +1,136 @@
> +menu "Processor type and features"
> +
> +choice
> + prompt "H8/300 platform"
> +
> +config H8300_AE3068
> + bool "AE-3068/69"
> + select H83069
> + select RAMKERNEL
> + help
> + AKI-H8/3068F / AKI-H8/3069F Flashmicom LAN Board Support
> + More Information. (Japanese Only)
> + <http://akizukidenshi.com/catalog/default.aspx>
> + AE-3068/69 Evaluation Board Support
> + More Information.
> + <http://www.microtronique.com/ae3069lan.htm>
> +
> +config H8300_H8MAX
> + bool "H8MAX"
> + select H83069
> + select RAMKERNEL
> + help
> + H8MAX Evaluation Board Support
> + More Information. (Japanese Only)
> + <http://strawberry-linux.com/h8/index.html>
> +
> +config H8300_KANEBEBE
> + bool "KaneBebe"
> + select H83069
> + select RAMKERNEL
> + help
> + KaneBebe Evalition Board Support
> +
> +config H8300H_SIM
> + bool "H8/300H GDB Simulator"
> + select H83069
> + select ROMKERNEL
> + help
> + GDB Simulator Support
> + More Information.
> + <http://sourceware.org/sid/>
> +
> +config H8S_EDOSK2674
> + bool "EDOSK-2674"
> + select H8S2678
> + select RAMKERNEL
> + help
> + Renesas EDOSK-2674 Evaluation Board Support
> + More Information.
> + <http://www.azpower.com/H8-uClinux/index.html>
> + <http://www.renesas.eu/products/tools/introductory_evaluation_tools/evaluation_development_os_kits/edosk2674r/edosk2674r_software_tools_root.jsp>
> +
> +config H8S_SIM
> + bool "H8S GDB Simulator"
> + select H8S2678
> + select ROMKERNEL
> + help
> + GDB Simulator Support
> + More Information.
> + <http://sourceware.org/sid/>
> +
> +endchoice
> +
> +choice
> + prompt "CPU Selection"
> +
> +config H83069
> + bool "H8/3065,3066,3067,3068,3069"
> + select CPU_H8300H
> + select H8300_TMR8
> + select H8300_TMR16
> +
> +config H8S2678
> + bool "H8S/2670,2673,2674R,2675,2676"
> + select CPU_H8S
> + select H8300_TMR8
> + select H8300_TPU
> +
> +endchoice
> +
All platforms either select H83069 or H8S2678. So this choice looks odd.
Can't you just drop the choice wrapper, and make this two entries
without prompt (ie, make it two symbols that are selected only, and
never set manually)?
Also note that H8300_TMR8 will always be set. So that it seems not
really needed (ie, it's an alias for H8300).
> +config CPU_CLOCK
> + int "CPU Clock Frequency"
> + depends on ROMKERNEL
> + default "200000000" if H8300H_AKI3068NET || H8300H_SIM
There's no symbol H8300H_AKI3068NET. Why is that (optional) dependency
added?
> + default "250000000" if H8300H_H8MAX || H8300H_KANEBEBE
Neither symbols exist. Why is this default needed?
> + default "333333333" if H8S_EDOSK2674 || H8S_SIM
> + help
> + CPU Clock Frequency
> +
> +choice
> + prompt "Kernel executes from"
> + ---help---
> + Choose the memory type that the kernel will be running in.
> +
> +config RAMKERNEL
> + bool "RAM"
> + help
> + The kernel will be resident in RAM when running.
> +
> +config ROMKERNEL
> + bool "ROM"
> + help
> + The kernel will be resident in FLASH/ROM when running.
> +endchoice
All platforms either select RAMKERNEL or ROMKERNEL. So this choice also
looks odd. Can't you, again, drop the choice wrapper, and make these two
entries without prompt?
> +config CPU_H8300H
> + bool
> + depends on H83069
> + default y
> +
> +config CPU_H8S
> + bool
> + depends on H8S2678
> + default y
> +
> +config ROMSIZE
> + hex "ROM size"
> + depends on ROMKERNEL
> + default 0x200000
> +
> +config RAMBASE
> + hex "RAM base address"
> + default 0x400000
> +
> +config RAMSIZE
> + hex "RAM size"
> + depends on ROMKERNEL
> + default 0x200000 if H8300_AE3068 || H8300_H8MAX || H8300H_SIM
> + default 0x400000 if H8300_KANEBEBE
> + default 0x800000 if H8S_EDOSK2674 || H8S_SIM
> +
> +config OFFSET
> + hex "Load offset"
Eight spaces instead of one tab?
> + default 0
> +
> +endmenu
> diff --git a/arch/h8300/Kconfig.debug b/arch/h8300/Kconfig.debug
> new file mode 100644
> index 0000000..eb72b01
> --- /dev/null
> +++ b/arch/h8300/Kconfig.debug
> @@ -0,0 +1,23 @@
> +menu "Kernel hacking"
> +
> +source "lib/Kconfig.debug"
> +
> +config FULLDEBUG
> + bool "Full Symbolic/Source Debugging support"
> + help
> + Enable debugging symbols on kernel build.
> +
> +config HIGHPROFILE
> + bool "Use fast second timer for profiling"
> + help
> + Use a fast secondary clock to produce profiling information.
> +
> +config NO_KERNEL_MSG
> + bool "Suppress Kernel BUG Messages"
> + help
> + Do not output any debug BUG messages within the kernel.
> +
> +config SH_STANDARD_BIOS
> + def_bool n
> +
I don't think this entry is needed.
> +endmenu
> diff --git a/arch/h8300/Makefile b/arch/h8300/Makefile
> new file mode 100644
> index 0000000..44e915c
> --- /dev/null
> +++ b/arch/h8300/Makefile
> @@ -0,0 +1,45 @@
> +#
> +# arch/h8300/Makefile
> +#
> +# This file is subject to the terms and conditions of the GNU General Public
> +# License. See the file "COPYING" in the main directory of this archive
> +# for more details.
> +#
> +# (C) Copyright 2002-2015 Yoshinori Sato <[email protected]>
> +#
> +
> +cflags-$(CONFIG_CPU_H8300H) := -mh
> +aflags-$(CONFIG_CPU_H8300H) := -mh -Wa,--mach=h8300h
> +ldflags-$(CONFIG_CPU_H8300H) := -mh8300helf_linux
> +cflags-$(CONFIG_CPU_H8S) := -ms
> +aflags-$(CONFIG_CPU_H8S) := -ms -Wa,--mach=h8300s
> +ldflags-$(CONFIG_CPU_H8S) := -mh8300self_linux
> +
> +KBUILD_CFLAGS += $(cflags-y)
> +KBUILD_CFLAGS += -mint32 -fno-builtin
> +KBUILD_CFLAGS += -D__linux__
> +KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
> +KBUILD_AFLAGS += $(aflags-y)
> +LDFLAGS += $(ldflags-y)
> +
> +CROSS_COMPILE := h8300-unknown-linux-
> +
> +core-y += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/
> +
> +libs-y += arch/$(ARCH)/lib/
> +
> +boot := arch/h8300/boot
> +
> +archmrproper:
> +
> +archclean:
> + $(Q)$(MAKE) $(clean)=$(boot)
> +
> +vmlinux.srec vmlinux.bin zImage uImage.bin: vmlinux
> + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
> +
> +define archhelp
> + @echo 'vmlinux.bin - Create raw binary'
> + @echo 'vmlinux.srec - Create srec binary'
> + @echo 'zImage - Compressed kernel image'
> +endef
> diff --git a/arch/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile
> new file mode 100644
> index 0000000..0b5fe00
> --- /dev/null
> +++ b/arch/h8300/kernel/Makefile
> @@ -0,0 +1,16 @@
> +#
> +# Makefile for the linux kernel.
> +#
> +
> +extra-y := vmlinux.lds
> +
> +obj-y := process.o traps.o ptrace.o \
> + signal.o setup.o syscalls.o \
> + irq.o entry.o dma.o cpu/
> +
> +obj-$(CONFIG_ROMKERNEL) += head_rom.o
> +obj-$(CONFIG_RAMKERNEL) += head_ram.o
> +
> +obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o
> +obj-$(CONFIG_H8300H_SIM) += sim-console.o
> +obj-$(CONFIG_H8S_SIM) += sim-console.o
> diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
> new file mode 100644
> index 0000000..e1b49aa
> --- /dev/null
> +++ b/arch/h8300/kernel/vmlinux.lds.S
> @@ -0,0 +1,85 @@
> +#include <asm-generic/vmlinux.lds.h>
> +#include <asm/page.h>
> +
> +#define ROMTOP 0x000000
> +#define RAMTOP CONFIG_RAMBASE
> +
> +jiffies = jiffies_64 + 4;
> +
> +ENTRY(_start)
> +
> +SECTIONS
> +{
> +#if defined(CONFIG_ROMKERNEL)
> + . = ROMTOP;
> + .vectors :
> + {
> + _vector = . ;
> + *(.vector*)
> + }
> +#else
> + . = RAMTOP;
> + _ramstart = .;
> + . = . + CONFIG_OFFSET;
> +#endif
> + _text = .;
> + HEAD_TEXT_SECTION
> + .text : {
> + _stext = . ;
> + TEXT_TEXT
> + SCHED_TEXT
> + LOCK_TEXT
> +#if defined(CONFIG_ROMKERNEL)
> + *(.int_redirect)
> +#endif
> + _etext = . ;
> + }
> + EXCEPTION_TABLE(16)
> + NOTES
> + RO_DATA(4)
> +#if defined(CONFIG_ROMKERNEL)
> + .init.text : {
> + _sinittext = .;
> + INIT_TEXT
> + _einittext = .;
> + }
> + SECURITY_INIT
> +#endif
> + ROMEND = .;
> +#if defined(CONFIG_ROMKERNEL)
> + . = RAMTOP;
> + _ramstart = .;
> + .data : AT(ROMEND)
> +#else
> + .data :
> +#endif
> + {
> + _sdata = . ;
> + __data_start = . ;
> + INIT_TASK_DATA(0x2000)
> + NOSAVE_DATA
> + PAGE_ALIGNED_DATA(0x1000)
> + CACHELINE_ALIGNED_DATA(0x0002)
> + READ_MOSTLY_DATA(0x0002)
> + DATA_DATA
> + CONSTRUCTORS
> + }
> + . = ALIGN(0x4) ;
> + __init_begin = .;
> +#if defined(CONFIG_RAMKERNEL)
> + INIT_TEXT_SECTION(4)
> +#endif
> + INIT_DATA_SECTION(4)
> +#if defined(CONFIG_RAMKERNEL)
> + SECURITY_INIT
> +#endif
> + __init_end = .;
> + _edata = . ;
> + _begin_data = LOADADDR(.data);
> + _sbss =.;
> + BSS_SECTION(4,4,4)
> + _ebss =.;
> + _ramend = .;
> + _end = .;
> + DISCARDS
> +}
Paul Bolle
On Sun, Feb 15, 2015 at 8:49 AM, Yoshinori Sato
<[email protected]> wrote:
> + usig = current_thread_info()->exec_domain
> + && current_thread_info()->exec_domain->signal_invmap
> + && sig < 32
> + ? current_thread_info()->exec_domain->signal_invmap[sig]
> + : sig;
Does h8300 really need signal mapping?
I'm very sure you can drop this.
In fact I'm working in patch set to rip it out tree wide as we have
only a single (broken)
in-tree user.
--
Thanks,
//richard
At Sun, 15 Feb 2015 11:33:25 +0100,
Paul Bolle wrote:
>
> On Sun, 2015-02-15 at 17:11 +0900, Yoshinori Sato wrote:
> > Sorry. I send too old files.
> > This patch is correct.
> >
> > Signed-off-by: Yoshinori Sato <[email protected]>
> > ---
> > arch/h8300/kernel/process.c | 170 +++++++++++++++++++++++
> > arch/h8300/kernel/ptrace.c | 203 +++++++++++++++++++++++++++
> > arch/h8300/kernel/signal.c | 326 ++++++++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 699 insertions(+)
> > create mode 100644 arch/h8300/kernel/process.c
> > create mode 100644 arch/h8300/kernel/ptrace.c
> > create mode 100644 arch/h8300/kernel/signal.c
> >
> >[...]
> > diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
> > new file mode 100644
> > index 0000000..1222783
> > --- /dev/null
> > +++ b/arch/h8300/kernel/signal.c
> > @@ -0,1 +1,326 @@
>
> That line should read
> @@ -0,0 +1,326 @@
>
> shouldn't it? At least, currently that line makes "git am" here barf
> with
> fatal: new file arch/h8300/kernel/signal.c depends on old contents
>
>
> Paul Bolle
>
Hmm.
When fixing it, maybe it was broken.
It's checked next patch.
--
Yoshinori Sato
<[email protected]>
At Sun, 15 Feb 2015 20:38:25 +0100,
Richard Weinberger wrote:
>
> On Sun, Feb 15, 2015 at 8:49 AM, Yoshinori Sato
> <[email protected]> wrote:
> > + usig = current_thread_info()->exec_domain
> > + && current_thread_info()->exec_domain->signal_invmap
> > + && sig < 32
> > + ? current_thread_info()->exec_domain->signal_invmap[sig]
> > + : sig;
>
> Does h8300 really need signal mapping?
> I'm very sure you can drop this.
> In fact I'm working in patch set to rip it out tree wide as we have
> only a single (broken)
> in-tree user.
>
I agree.
It remove forgot.
> --
> Thanks,
> //richard
--
Yoshinori Sato
<[email protected]>
At Sun, 15 Feb 2015 20:23:04 +0100,
Paul Bolle wrote:
>
> On Sun, 2015-02-15 at 16:49 +0900, Yoshinori Sato wrote:
> > Signed-off-by: Yoshinori Sato <[email protected]>
> > ---
> > arch/h8300/Kconfig | 119 +++++++++++++++++++++++++++++++++++
> > arch/h8300/Kconfig.cpu | 136 ++++++++++++++++++++++++++++++++++++++++
> > arch/h8300/Kconfig.debug | 23 +++++++
> > arch/h8300/Makefile | 45 +++++++++++++
> > arch/h8300/kernel/Makefile | 16 +++++
> > arch/h8300/kernel/vmlinux.lds.S | 85 +++++++++++++++++++++++++
> > 6 files changed, 424 insertions(+)
> > create mode 100644 arch/h8300/Kconfig
> > create mode 100644 arch/h8300/Kconfig.cpu
> > create mode 100644 arch/h8300/Kconfig.debug
> > create mode 100644 arch/h8300/Makefile
> > create mode 100644 arch/h8300/kernel/Makefile
> > create mode 100644 arch/h8300/kernel/vmlinux.lds.S
> >
> > diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
> > new file mode 100644
> > index 0000000..828c356
> > --- /dev/null
> > +++ b/arch/h8300/Kconfig
> > @@ -0,0 +1,119 @@
> > +config H8300
> > + bool
> > + default y
> > + select HAVE_IDE
> > + select GENERIC_ATOMIC64
> > + select HAVE_UID16
> > + select VIRT_TO_BUS
> > + select ARCH_WANT_IPC_PARSE_VERSION
> > + select GENERIC_IRQ_SHOW
> > + select FRAME_POINTER
> > + select GENERIC_CPU_DEVICES
> > + select MODULES_USE_ELF_RELA
> > + select GENERIC_CLOCKEVENTS
> > + select CLKDEV_LOOKUP
> > + select COMMON_CLK
> > + select HAVE_ARCH_TRACEHOOK
> > + select ARCH_WANT_FRAME_POINTERS
> > +
> > +config MMU
> > + bool
> > + default n
> > +
> > +config SWAP
> > + bool
> > + default n
> > +
>
> MMU will always be 'n'. (So the entry for MMU is not strictly needed,
> but I guess it is clearer to explicitly set this to 'n'.) But that means
> there's no reason here to mask the global SWAP config (see
> init/Kconfig), as that will also always be 'n' for H8300.
OK.
remove it.
> > +config ZONE_DMA
> > + bool
> > + default y
> > +
> > +config FPU
> > + bool
> > + default n
>
> Why is this needed?
Inneeded.
Remove it.
> > +
> > +config RWSEM_GENERIC_SPINLOCK
> > + bool
> > + default y
> > +
> > +config RWSEM_XCHGADD_ALGORITHM
> > + bool
> > + default n
>
> Not strictly needed.
OK.
>
> > +config ARCH_HAS_ILOG2_U32
> > + bool
> > + default n
> > +
>
> Ditto.
>
> > +config ARCH_HAS_ILOG2_U64
> > + bool
> > + default n
> > +
>
> Ditto.
>
> > +config GENERIC_HWEIGHT
> > + bool
> > + default y
> > +
> > +config GENERIC_CALIBRATE_DELAY
> > + bool
> > + default y
> > +
> > +config GENERIC_BUG
> > + bool
> > + depends on BUG
> > +
>
> GENERIC_BUG can never be set for H8300, so this entry is not needed.
OK.
Remove.
> > +config TIME_LOW_RES
> > + bool
> > + default y
> > +
> > +config NO_IOPORT_MAP
> > + def_bool y
> > +
> > +config NO_DMA
> > + def_bool n
>
> Not needed (please note that only a few architectures have an entry for
> NO_DMA).
OK.
Remove.
> > +config ISA
> > + def_bool n
> > +
> > +config PCI
> > + def_bool n
> > +
>
> Neither ISA nor PCI will ever be set, won't they? So you might as well
> drop these too.
>
> > +config HZ
> > + int
> > + default 100
> > +
> > +config NR_CPUS
> > + int
>
> Eight spaces instead of one tab.
OK.
> > + default 1
> > +
> > +source "init/Kconfig"
> > +
> > +source "kernel/Kconfig.freezer"
> > +
> > +source "arch/h8300/Kconfig.cpu"
> > +
> > +menu "Kernel Features"
> > +
> > +source "kernel/Kconfig.preempt"
> > +
> > +source "mm/Kconfig"
> > +
> > +endmenu
> > +
> > +menu "Executable file formats"
> > +
> > +source "fs/Kconfig.binfmt"
> > +
> > +endmenu
> > +
> > +source "net/Kconfig"
> > +
> > +source "drivers/Kconfig"
> > +
> > +source "fs/Kconfig"
> > +
> > +source "arch/h8300/Kconfig.debug"
> > +
> > +source "security/Kconfig"
> > +
> > +source "crypto/Kconfig"
> > +
> > +source "lib/Kconfig"
> > diff --git a/arch/h8300/Kconfig.cpu b/arch/h8300/Kconfig.cpu
> > new file mode 100644
> > index 0000000..2eaa797
> > --- /dev/null
> > +++ b/arch/h8300/Kconfig.cpu
> > @@ -0,0 +1,136 @@
> > +menu "Processor type and features"
> > +
> > +choice
> > + prompt "H8/300 platform"
> > +
> > +config H8300_AE3068
> > + bool "AE-3068/69"
> > + select H83069
> > + select RAMKERNEL
> > + help
> > + AKI-H8/3068F / AKI-H8/3069F Flashmicom LAN Board Support
> > + More Information. (Japanese Only)
> > + <http://akizukidenshi.com/catalog/default.aspx>
> > + AE-3068/69 Evaluation Board Support
> > + More Information.
> > + <http://www.microtronique.com/ae3069lan.htm>
> > +
> > +config H8300_H8MAX
> > + bool "H8MAX"
> > + select H83069
> > + select RAMKERNEL
> > + help
> > + H8MAX Evaluation Board Support
> > + More Information. (Japanese Only)
> > + <http://strawberry-linux.com/h8/index.html>
> > +
> > +config H8300_KANEBEBE
> > + bool "KaneBebe"
> > + select H83069
> > + select RAMKERNEL
> > + help
> > + KaneBebe Evalition Board Support
> > +
> > +config H8300H_SIM
> > + bool "H8/300H GDB Simulator"
> > + select H83069
> > + select ROMKERNEL
> > + help
> > + GDB Simulator Support
> > + More Information.
> > + <http://sourceware.org/sid/>
> > +
> > +config H8S_EDOSK2674
> > + bool "EDOSK-2674"
> > + select H8S2678
> > + select RAMKERNEL
> > + help
> > + Renesas EDOSK-2674 Evaluation Board Support
> > + More Information.
> > + <http://www.azpower.com/H8-uClinux/index.html>
> > + <http://www.renesas.eu/products/tools/introductory_evaluation_tools/evaluation_development_os_kits/edosk2674r/edosk2674r_software_tools_root.jsp>
> > +
> > +config H8S_SIM
> > + bool "H8S GDB Simulator"
> > + select H8S2678
> > + select ROMKERNEL
> > + help
> > + GDB Simulator Support
> > + More Information.
> > + <http://sourceware.org/sid/>
> > +
> > +endchoice
> > +
> > +choice
> > + prompt "CPU Selection"
> > +
> > +config H83069
> > + bool "H8/3065,3066,3067,3068,3069"
> > + select CPU_H8300H
> > + select H8300_TMR8
> > + select H8300_TMR16
> > +
> > +config H8S2678
> > + bool "H8S/2670,2673,2674R,2675,2676"
> > + select CPU_H8S
> > + select H8300_TMR8
> > + select H8300_TPU
> > +
> > +endchoice
> > +
>
> All platforms either select H83069 or H8S2678. So this choice looks odd.
> Can't you just drop the choice wrapper, and make this two entries
> without prompt (ie, make it two symbols that are selected only, and
> never set manually)?
Yes. not needed choice.
Remove.
> Also note that H8300_TMR8 will always be set. So that it seems not
> really needed (ie, it's an alias for H8300).
This entry obsoleted.
Remove.
> > +config CPU_CLOCK
> > + int "CPU Clock Frequency"
> > + depends on ROMKERNEL
> > + default "200000000" if H8300H_AKI3068NET || H8300H_SIM
>
> There's no symbol H8300H_AKI3068NET. Why is that (optional) dependency
> added?
>
> > + default "250000000" if H8300H_H8MAX || H8300H_KANEBEBE
>
> Neither symbols exist. Why is this default needed?
And this not used current code.
Remove.
> > + default "333333333" if H8S_EDOSK2674 || H8S_SIM
> > + help
> > + CPU Clock Frequency
> > +
> > +choice
> > + prompt "Kernel executes from"
> > + ---help---
> > + Choose the memory type that the kernel will be running in.
> > +
> > +config RAMKERNEL
> > + bool "RAM"
> > + help
> > + The kernel will be resident in RAM when running.
> > +
> > +config ROMKERNEL
> > + bool "ROM"
> > + help
> > + The kernel will be resident in FLASH/ROM when running.
> > +endchoice
>
> All platforms either select RAMKERNEL or ROMKERNEL. So this choice also
> looks odd. Can't you, again, drop the choice wrapper, and make these two
> entries without prompt?
Hmm.
It's considered.
> > +config CPU_H8300H
> > + bool
> > + depends on H83069
> > + default y
> > +
> > +config CPU_H8S
> > + bool
> > + depends on H8S2678
> > + default y
> > +
> > +config ROMSIZE
> > + hex "ROM size"
> > + depends on ROMKERNEL
> > + default 0x200000
> > +
> > +config RAMBASE
> > + hex "RAM base address"
> > + default 0x400000
> > +
> > +config RAMSIZE
> > + hex "RAM size"
> > + depends on ROMKERNEL
> > + default 0x200000 if H8300_AE3068 || H8300_H8MAX || H8300H_SIM
> > + default 0x400000 if H8300_KANEBEBE
> > + default 0x800000 if H8S_EDOSK2674 || H8S_SIM
> > +
> > +config OFFSET
> > + hex "Load offset"
>
> Eight spaces instead of one tab?
OK.
> > + default 0
> > +
> > +endmenu
> > diff --git a/arch/h8300/Kconfig.debug b/arch/h8300/Kconfig.debug
> > new file mode 100644
> > index 0000000..eb72b01
> > --- /dev/null
> > +++ b/arch/h8300/Kconfig.debug
> > @@ -0,0 +1,23 @@
> > +menu "Kernel hacking"
> > +
> > +source "lib/Kconfig.debug"
> > +
> > +config FULLDEBUG
> > + bool "Full Symbolic/Source Debugging support"
> > + help
> > + Enable debugging symbols on kernel build.
> > +
> > +config HIGHPROFILE
> > + bool "Use fast second timer for profiling"
> > + help
> > + Use a fast secondary clock to produce profiling information.
> > +
> > +config NO_KERNEL_MSG
> > + bool "Suppress Kernel BUG Messages"
> > + help
> > + Do not output any debug BUG messages within the kernel.
> > +
> > +config SH_STANDARD_BIOS
> > + def_bool n
> > +
>
> I don't think this entry is needed.
This entry using sh-sci.
> > +endmenu
> > diff --git a/arch/h8300/Makefile b/arch/h8300/Makefile
> > new file mode 100644
> > index 0000000..44e915c
> > --- /dev/null
> > +++ b/arch/h8300/Makefile
> > @@ -0,0 +1,45 @@
> > +#
> > +# arch/h8300/Makefile
> > +#
> > +# This file is subject to the terms and conditions of the GNU General Public
> > +# License. See the file "COPYING" in the main directory of this archive
> > +# for more details.
> > +#
> > +# (C) Copyright 2002-2015 Yoshinori Sato <[email protected]>
> > +#
> > +
> > +cflags-$(CONFIG_CPU_H8300H) := -mh
> > +aflags-$(CONFIG_CPU_H8300H) := -mh -Wa,--mach=h8300h
> > +ldflags-$(CONFIG_CPU_H8300H) := -mh8300helf_linux
> > +cflags-$(CONFIG_CPU_H8S) := -ms
> > +aflags-$(CONFIG_CPU_H8S) := -ms -Wa,--mach=h8300s
> > +ldflags-$(CONFIG_CPU_H8S) := -mh8300self_linux
> > +
> > +KBUILD_CFLAGS += $(cflags-y)
> > +KBUILD_CFLAGS += -mint32 -fno-builtin
> > +KBUILD_CFLAGS += -D__linux__
> > +KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
> > +KBUILD_AFLAGS += $(aflags-y)
> > +LDFLAGS += $(ldflags-y)
> > +
> > +CROSS_COMPILE := h8300-unknown-linux-
> > +
> > +core-y += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/
> > +
> > +libs-y += arch/$(ARCH)/lib/
> > +
> > +boot := arch/h8300/boot
> > +
> > +archmrproper:
> > +
> > +archclean:
> > + $(Q)$(MAKE) $(clean)=$(boot)
> > +
> > +vmlinux.srec vmlinux.bin zImage uImage.bin: vmlinux
> > + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
> > +
> > +define archhelp
> > + @echo 'vmlinux.bin - Create raw binary'
> > + @echo 'vmlinux.srec - Create srec binary'
> > + @echo 'zImage - Compressed kernel image'
> > +endef
> > diff --git a/arch/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile
> > new file mode 100644
> > index 0000000..0b5fe00
> > --- /dev/null
> > +++ b/arch/h8300/kernel/Makefile
> > @@ -0,0 +1,16 @@
> > +#
> > +# Makefile for the linux kernel.
> > +#
> > +
> > +extra-y := vmlinux.lds
> > +
> > +obj-y := process.o traps.o ptrace.o \
> > + signal.o setup.o syscalls.o \
> > + irq.o entry.o dma.o cpu/
> > +
> > +obj-$(CONFIG_ROMKERNEL) += head_rom.o
> > +obj-$(CONFIG_RAMKERNEL) += head_ram.o
> > +
> > +obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o
> > +obj-$(CONFIG_H8300H_SIM) += sim-console.o
> > +obj-$(CONFIG_H8S_SIM) += sim-console.o
> > diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
> > new file mode 100644
> > index 0000000..e1b49aa
> > --- /dev/null
> > +++ b/arch/h8300/kernel/vmlinux.lds.S
> > @@ -0,0 +1,85 @@
> > +#include <asm-generic/vmlinux.lds.h>
> > +#include <asm/page.h>
> > +
> > +#define ROMTOP 0x000000
> > +#define RAMTOP CONFIG_RAMBASE
> > +
> > +jiffies = jiffies_64 + 4;
> > +
> > +ENTRY(_start)
> > +
> > +SECTIONS
> > +{
> > +#if defined(CONFIG_ROMKERNEL)
> > + . = ROMTOP;
> > + .vectors :
> > + {
> > + _vector = . ;
> > + *(.vector*)
> > + }
> > +#else
> > + . = RAMTOP;
> > + _ramstart = .;
> > + . = . + CONFIG_OFFSET;
> > +#endif
> > + _text = .;
> > + HEAD_TEXT_SECTION
> > + .text : {
> > + _stext = . ;
> > + TEXT_TEXT
> > + SCHED_TEXT
> > + LOCK_TEXT
> > +#if defined(CONFIG_ROMKERNEL)
> > + *(.int_redirect)
> > +#endif
> > + _etext = . ;
> > + }
> > + EXCEPTION_TABLE(16)
> > + NOTES
> > + RO_DATA(4)
> > +#if defined(CONFIG_ROMKERNEL)
> > + .init.text : {
> > + _sinittext = .;
> > + INIT_TEXT
> > + _einittext = .;
> > + }
> > + SECURITY_INIT
> > +#endif
> > + ROMEND = .;
> > +#if defined(CONFIG_ROMKERNEL)
> > + . = RAMTOP;
> > + _ramstart = .;
> > + .data : AT(ROMEND)
> > +#else
> > + .data :
> > +#endif
> > + {
> > + _sdata = . ;
> > + __data_start = . ;
> > + INIT_TASK_DATA(0x2000)
> > + NOSAVE_DATA
> > + PAGE_ALIGNED_DATA(0x1000)
> > + CACHELINE_ALIGNED_DATA(0x0002)
> > + READ_MOSTLY_DATA(0x0002)
> > + DATA_DATA
> > + CONSTRUCTORS
> > + }
> > + . = ALIGN(0x4) ;
> > + __init_begin = .;
> > +#if defined(CONFIG_RAMKERNEL)
> > + INIT_TEXT_SECTION(4)
> > +#endif
> > + INIT_DATA_SECTION(4)
> > +#if defined(CONFIG_RAMKERNEL)
> > + SECURITY_INIT
> > +#endif
> > + __init_end = .;
> > + _edata = . ;
> > + _begin_data = LOADADDR(.data);
> > + _sbss =.;
> > + BSS_SECTION(4,4,4)
> > + _ebss =.;
> > + _ramend = .;
> > + _end = .;
> > + DISCARDS
> > +}
>
>
> Paul Bolle
>
--
Yoshinori Sato
<[email protected]>
At Sun, 15 Feb 2015 11:59:19 +0100,
Paul Bolle wrote:
>
> On Sun, 2015-02-15 at 16:49 +0900, Yoshinori Sato wrote:
> > Yoshinori Sato (15):
> > h8300: Assembly headers.
> > h8300: UAPI headers
> > h8300: Exception and Interrupt handling
> > h8300: kernel booting
> > h8300: Process and signal
> > h8300 CPU depend helpers
> > h8300: miscellaneous functions
> > h8300: Memory management
> > h8300: library functions
> > h8300: Build scripts
> > h8300: clock driver
> > h8300: clocksource
> > h8300: configs
> > serial: Add h8300
> > Add ELF machine
>
> git am warns about various whitespace issues:
>
> Applying: h8300: Assembly headers.
> [...]/.git/rebase-apply/patch:831: new blank line at EOF.
> +
> [...]/.git/rebase-apply/patch:1674: new blank line at EOF.
> +
> warning: 2 lines add whitespace errors.
> Applying: h8300: UAPI headers
> Applying: h8300: Exception and Interrupt handling
> [...]/.git/rebase-apply/patch:223: trailing whitespace.
> /* r1l is saved ccr */
> warning: 1 line adds whitespace errors.
> Applying: h8300: kernel booting
> [...]/.git/rebase-apply/patch:54: new blank line at EOF.
> +
> warning: 1 line adds whitespace errors.
> Applying: h8300: Process and signal
> [...]/.git/rebase-apply/patch:314: trailing whitespace.
>
> warning: 1 line adds whitespace errors.
> Applying: h8300 CPU depend helpers
> [...]/.git/rebase-apply/patch:32: new blank line at EOF.
> +
> [...]/.git/rebase-apply/patch:827: new blank line at EOF.
> +
> warning: 2 lines add whitespace errors.
> Applying: h8300: miscellaneous functions
> Applying: h8300: Memory management
> [...]/.git/rebase-apply/patch:88: new blank line at EOF.
> +
> [...]/.git/rebase-apply/patch:247: new blank line at EOF.
> +
> [...]/.git/rebase-apply/patch:374: new blank line at EOF.
> +
> warning: 3 lines add whitespace errors.
> Applying: h8300: library functions
> [...]/.git/rebase-apply/patch:279: trailing whitespace.
>
> [...]/.git/rebase-apply/patch:1170: trailing whitespace.
>
> [...]/.git/rebase-apply/patch:1188: space before tab in indent.
> ; er0 = er0 / er1
> [...]/.git/rebase-apply/patch:1189: space before tab in indent.
> ; er3 = er0 % er1
> [...]/.git/rebase-apply/patch:1190: space before tab in indent.
> ; trashes er1 er2
> warning: squelched 3 whitespace errors
> warning: 8 lines add whitespace errors.
> Applying: h8300: Build scripts
> [...]/.git/rebase-apply/patch:197: space before tab in indent.
> <http://www.renesas.eu/products/tools/introductory_evaluation_tools/evaluation_development_os_kits/edosk2674r/edosk2674r_software_tools_root.jsp>
> warning: 1 line adds whitespace errors.
> Applying: h8300: clock driver
> [...]/.git/rebase-apply/patch:161: trailing whitespace.
>
> [...]/.git/rebase-apply/patch:216: trailing whitespace.
>
> [...]/.git/rebase-apply/patch:236: trailing whitespace.
>
> warning: 3 lines add whitespace errors.
> Applying: h8300: clocksource
> [...]/.git/rebase-apply/patch:22: trailing whitespace.
>
> warning: 1 line adds whitespace errors.
> Applying: h8300: configs
> Applying: serial: Add h8300
> Applying: Add ELF machine
>
> (I did fix patch 12/15 ("h8300: clocksource") manually, to make it apply
> on top of next-20150213, but I don't think I introduced the warning in
> that patch.)
>
>
> Paul Bolle
>
OK.
I wll cleanup next patch.
--
Yoshinori Sato
<[email protected]>
At Sun, 15 Feb 2015 10:11:58 +0100,
Geert Uytterhoeven wrote:
>
> Hi Sato-san,
>
> On Sun, Feb 15, 2015 at 8:49 AM, Yoshinori Sato
> <[email protected]> wrote:
> > --- /dev/null
> > +++ b/arch/h8300/include/asm/io.h
> > @@ -0,0 +1,372 @@
> > +#ifndef _H8300_IO_H
> > +#define _H8300_IO_H
> > +
> > +#ifdef __KERNEL__
> > +
> > +#include <linux/types.h>
> > +
> > +/*
> > + * These are for ISA/PCI shared memory _only_ and should never be used
> > + * on any other type of memory, including Zorro memory. They are meant to
> > + * access the bus in the bus byte order which is little-endian!.
> > + *
> > + * readX/writeX() are used to access memory mapped devices. On some
> > + * architectures the memory mapped IO stuff needs to be accessed
> > + * differently. On the m68k architecture, we just read/write the
> > + * memory location directly.
> > + */
> > +/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
> > + * two accesses to memory, which may be undesirable for some devices.
> > + */
>
> While some of the above applies to h8300, I think you should remove
> the parts that don't apply.
It's necessary by several drivers, so it has been left.
An unnecessary part is also included, so I have to remove the part.
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> -- Linus Torvalds
--
Yoshinori Sato
<[email protected]>
On Tue, 2015-02-17 at 16:39 +0900, Yoshinori Sato wrote:
> At Sun, 15 Feb 2015 20:23:04 +0100,
> Paul Bolle wrote:
> > On Sun, 2015-02-15 at 16:49 +0900, Yoshinori Sato wrote:
> > > diff --git a/arch/h8300/Kconfig.debug b/arch/h8300/Kconfig.debug
> > > new file mode 100644
> > > index 0000000..eb72b01
> > > --- /dev/null
> > > +++ b/arch/h8300/Kconfig.debug
> > > @@ -0,0 +1,23 @@
> > > +menu "Kernel hacking"
> > > +
> > > +source "lib/Kconfig.debug"
> > > +
> > > +config FULLDEBUG
> > > + bool "Full Symbolic/Source Debugging support"
> > > + help
> > > + Enable debugging symbols on kernel build.
> > > +
> > > +config HIGHPROFILE
> > > + bool "Use fast second timer for profiling"
> > > + help
> > > + Use a fast secondary clock to produce profiling information.
> > > +
> > > +config NO_KERNEL_MSG
> > > + bool "Suppress Kernel BUG Messages"
> > > + help
> > > + Do not output any debug BUG messages within the kernel.
> > > +
> > > +config SH_STANDARD_BIOS
> > > + def_bool n
> > > +
> >
> > I don't think this entry is needed.
>
> This entry using sh-sci.
This entry will always set SH_STANDARD_BIOS to 'n', and a line reading
# CONFIG_SH_STANDARD_BIOS is not set
will always be included in the generated .config for h8300. But for the
three lines in drivers/tty/serial/sh-sci.c reading
#ifdef CONFIG_SH_STANDARD_BIOS
sh_bios_gdb_detach();
#endif
that line has no effect. Even if there's no entry for SH_STANDARD_BIOS
the preprocessor will still remove that call of sh_bios_gdb_detach().
> > > +endmenu
Thanks,
Paul Bolle
At Tue, 17 Feb 2015 10:46:21 +0100,
Paul Bolle wrote:
>
> On Tue, 2015-02-17 at 16:39 +0900, Yoshinori Sato wrote:
> > At Sun, 15 Feb 2015 20:23:04 +0100,
> > Paul Bolle wrote:
> > > On Sun, 2015-02-15 at 16:49 +0900, Yoshinori Sato wrote:
> > > > diff --git a/arch/h8300/Kconfig.debug b/arch/h8300/Kconfig.debug
> > > > new file mode 100644
> > > > index 0000000..eb72b01
> > > > --- /dev/null
> > > > +++ b/arch/h8300/Kconfig.debug
> > > > @@ -0,0 +1,23 @@
> > > > +menu "Kernel hacking"
> > > > +
> > > > +source "lib/Kconfig.debug"
> > > > +
> > > > +config FULLDEBUG
> > > > + bool "Full Symbolic/Source Debugging support"
> > > > + help
> > > > + Enable debugging symbols on kernel build.
> > > > +
> > > > +config HIGHPROFILE
> > > > + bool "Use fast second timer for profiling"
> > > > + help
> > > > + Use a fast secondary clock to produce profiling information.
> > > > +
> > > > +config NO_KERNEL_MSG
> > > > + bool "Suppress Kernel BUG Messages"
> > > > + help
> > > > + Do not output any debug BUG messages within the kernel.
> > > > +
> > > > +config SH_STANDARD_BIOS
> > > > + def_bool n
> > > > +
> > >
> > > I don't think this entry is needed.
> >
> > This entry using sh-sci.
>
> This entry will always set SH_STANDARD_BIOS to 'n', and a line reading
> # CONFIG_SH_STANDARD_BIOS is not set
>
> will always be included in the generated .config for h8300. But for the
> three lines in drivers/tty/serial/sh-sci.c reading
> #ifdef CONFIG_SH_STANDARD_BIOS
> sh_bios_gdb_detach();
> #endif
>
> that line has no effect. Even if there's no entry for SH_STANDARD_BIOS
> the preprocessor will still remove that call of sh_bios_gdb_detach().
>
> > > > +endmenu
>
> Thanks,
OK
It was used few years ago, but it was removed.
Removed this entry.
>
>
> Paul Bolle
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
--
Yoshinori Sato
<[email protected]>