From e3f197f507babde07eb0a3930b5fd3a392ca3c6e Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 17 Apr 2003 02:27:57 -0700 Subject: [PATCH] [PATCH] H8300 support --- arch/h8300/Kconfig | 427 ++++++++++++ arch/h8300/Makefile | 61 ++ arch/h8300/README | 35 + arch/h8300/defconfig | 199 ++++++ arch/h8300/kernel/Makefile | 13 + arch/h8300/kernel/asm-offsets.c | 49 ++ arch/h8300/kernel/gpio.c | 166 +++++ arch/h8300/kernel/h8300_ksyms.c | 113 +++ arch/h8300/kernel/init_task.c | 38 ++ arch/h8300/kernel/process.c | 317 +++++++++ arch/h8300/kernel/ptrace.c | 470 +++++++++++++ arch/h8300/kernel/semaphore.c | 132 ++++ arch/h8300/kernel/setup.c | 231 +++++++ arch/h8300/kernel/signal.c | 642 ++++++++++++++++++ arch/h8300/kernel/sys_h8300.c | 289 ++++++++ arch/h8300/kernel/syscalls.S | 314 +++++++++ arch/h8300/kernel/time.c | 134 ++++ arch/h8300/kernel/traps.c | 124 ++++ arch/h8300/lib/Makefile | 9 + arch/h8300/lib/abs.S | 21 + arch/h8300/lib/ashrdi3.c | 63 ++ arch/h8300/lib/checksum.c | 156 +++++ arch/h8300/lib/memcpy.S | 84 +++ arch/h8300/lib/memset.S | 61 ++ arch/h8300/mm/Makefile | 10 + arch/h8300/mm/extable.c | 30 + arch/h8300/mm/fault.c | 58 ++ arch/h8300/mm/init.c | 235 +++++++ arch/h8300/mm/kmap.c | 59 ++ arch/h8300/mm/memory.c | 70 ++ arch/h8300/platform/h8300h/Makefile | 22 + arch/h8300/platform/h8300h/Rules.make | 51 ++ .../h8300/platform/h8300h/aki3068net/Makefile | 16 + .../platform/h8300h/aki3068net/crt0_ram.S | 109 +++ arch/h8300/platform/h8300h/aki3068net/ram.ld | 90 +++ arch/h8300/platform/h8300h/aki3068net/timer.c | 46 ++ arch/h8300/platform/h8300h/entry.S | 357 ++++++++++ arch/h8300/platform/h8300h/generic/Makefile | 12 + arch/h8300/platform/h8300h/generic/crt0_rom.S | 118 ++++ arch/h8300/platform/h8300h/generic/ram.ld | 76 +++ arch/h8300/platform/h8300h/generic/rom.ld | 122 ++++ arch/h8300/platform/h8300h/generic/timer.c | 84 +++ arch/h8300/platform/h8300h/h8max/Makefile | 16 + arch/h8300/platform/h8300h/h8max/crt0_ram.S | 109 +++ arch/h8300/platform/h8300h/h8max/ram.ld | 90 +++ arch/h8300/platform/h8300h/h8max/timer.c | 46 ++ arch/h8300/platform/h8300h/ints.c | 252 +++++++ arch/h8300/vmlinux.lds.S | 38 ++ include/asm-h8300/a.out.h | 26 + include/asm-h8300/aki3068net/ne.h | 23 + include/asm-h8300/atomic.h | 107 +++ include/asm-h8300/bitops.h | 480 +++++++++++++ include/asm-h8300/bootinfo.h | 2 + include/asm-h8300/bug.h | 12 + include/asm-h8300/bugs.h | 16 + include/asm-h8300/byteorder.h | 13 + include/asm-h8300/cache.h | 12 + include/asm-h8300/cachectl.h | 14 + include/asm-h8300/cacheflush.h | 31 + include/asm-h8300/checksum.h | 105 +++ include/asm-h8300/current.h | 25 + include/asm-h8300/dbg.h | 2 + include/asm-h8300/delay.h | 39 ++ include/asm-h8300/div64.h | 13 + include/asm-h8300/dma.h | 16 + include/asm-h8300/elf.h | 57 ++ include/asm-h8300/errno.h | 132 ++++ include/asm-h8300/fcntl.h | 86 +++ include/asm-h8300/flat.h | 10 + include/asm-h8300/fpu.h | 1 + include/asm-h8300/generic/timer_rate.h | 11 + include/asm-h8300/gpio.h | 46 ++ include/asm-h8300/h8300_ne.h | 19 + include/asm-h8300/h8max/ide.h | 60 ++ include/asm-h8300/h8max/ne.h | 71 ++ include/asm-h8300/hardirq.h | 105 +++ include/asm-h8300/hdreg.h | 13 + include/asm-h8300/hw_irq.h | 1 + include/asm-h8300/ide.h | 161 +++++ include/asm-h8300/init.h | 11 + include/asm-h8300/io.h | 234 +++++++ include/asm-h8300/ioctl.h | 80 +++ include/asm-h8300/ioctls.h | 81 +++ include/asm-h8300/ipc.h | 31 + include/asm-h8300/ipcbuf.h | 29 + include/asm-h8300/irq.h | 56 ++ include/asm-h8300/keyboard.h | 33 + include/asm-h8300/kmap_types.h | 19 + include/asm-h8300/linkage.h | 8 + include/asm-h8300/linux_logo.h | 11 + include/asm-h8300/mc146818rtc.h | 9 + include/asm-h8300/md.h | 13 + include/asm-h8300/mman.h | 38 ++ include/asm-h8300/mmu.h | 22 + include/asm-h8300/mmu_context.h | 32 + include/asm-h8300/module.h | 12 + include/asm-h8300/msgbuf.h | 31 + include/asm-h8300/namei.h | 17 + include/asm-h8300/page.h | 101 +++ include/asm-h8300/page_offset.h | 4 + include/asm-h8300/param.h | 27 + include/asm-h8300/pci.h | 25 + include/asm-h8300/percpu.h | 6 + include/asm-h8300/pgalloc.h | 8 + include/asm-h8300/pgtable.h | 52 ++ include/asm-h8300/poll.h | 22 + include/asm-h8300/posix_types.h | 65 ++ include/asm-h8300/processor.h | 121 ++++ include/asm-h8300/ptrace.h | 56 ++ include/asm-h8300/regs306x.h | 212 ++++++ include/asm-h8300/resource.h | 47 ++ include/asm-h8300/scatterlist.h | 13 + include/asm-h8300/segment.h | 49 ++ include/asm-h8300/semaphore-helper.h | 86 +++ include/asm-h8300/semaphore.h | 206 ++++++ include/asm-h8300/sembuf.h | 25 + include/asm-h8300/setup.h | 1 + include/asm-h8300/sh_bios.h | 29 + include/asm-h8300/shm.h | 32 + include/asm-h8300/shmbuf.h | 42 ++ include/asm-h8300/shmparam.h | 6 + include/asm-h8300/sigcontext.h | 15 + include/asm-h8300/siginfo.h | 6 + include/asm-h8300/signal.h | 183 +++++ include/asm-h8300/smp.h | 1 + include/asm-h8300/smplock.h | 51 ++ include/asm-h8300/socket.h | 64 ++ include/asm-h8300/sockios.h | 12 + include/asm-h8300/softirq.h | 20 + include/asm-h8300/spinlock.h | 6 + include/asm-h8300/stat.h | 80 +++ include/asm-h8300/statfs.h | 25 + include/asm-h8300/string.h | 44 ++ include/asm-h8300/system.h | 156 +++++ include/asm-h8300/target_time.h | 4 + include/asm-h8300/termbits.h | 174 +++++ include/asm-h8300/termios.h | 108 +++ include/asm-h8300/thread_info.h | 106 +++ include/asm-h8300/timex.h | 27 + include/asm-h8300/tlb.h | 1 + include/asm-h8300/tlbflush.h | 61 ++ include/asm-h8300/topology.h | 6 + include/asm-h8300/traps.h | 207 ++++++ include/asm-h8300/types.h | 58 ++ include/asm-h8300/uaccess.h | 165 +++++ include/asm-h8300/ucontext.h | 23 + include/asm-h8300/unaligned.h | 16 + include/asm-h8300/unistd.h | 461 +++++++++++++ include/asm-h8300/user.h | 76 +++ include/asm-h8300/virtconvert.h | 23 + 150 files changed, 12154 insertions(+) create mode 100644 arch/h8300/Kconfig create mode 100644 arch/h8300/Makefile create mode 100644 arch/h8300/README create mode 100644 arch/h8300/defconfig create mode 100644 arch/h8300/kernel/Makefile create mode 100644 arch/h8300/kernel/asm-offsets.c create mode 100644 arch/h8300/kernel/gpio.c create mode 100644 arch/h8300/kernel/h8300_ksyms.c create mode 100644 arch/h8300/kernel/init_task.c create mode 100644 arch/h8300/kernel/process.c create mode 100644 arch/h8300/kernel/ptrace.c create mode 100644 arch/h8300/kernel/semaphore.c create mode 100644 arch/h8300/kernel/setup.c create mode 100644 arch/h8300/kernel/signal.c create mode 100644 arch/h8300/kernel/sys_h8300.c create mode 100644 arch/h8300/kernel/syscalls.S create mode 100644 arch/h8300/kernel/time.c create mode 100644 arch/h8300/kernel/traps.c create mode 100644 arch/h8300/lib/Makefile create mode 100644 arch/h8300/lib/abs.S create mode 100644 arch/h8300/lib/ashrdi3.c create mode 100644 arch/h8300/lib/checksum.c create mode 100644 arch/h8300/lib/memcpy.S create mode 100644 arch/h8300/lib/memset.S create mode 100644 arch/h8300/mm/Makefile create mode 100644 arch/h8300/mm/extable.c 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 arch/h8300/platform/h8300h/Makefile create mode 100644 arch/h8300/platform/h8300h/Rules.make create mode 100644 arch/h8300/platform/h8300h/aki3068net/Makefile create mode 100644 arch/h8300/platform/h8300h/aki3068net/crt0_ram.S create mode 100644 arch/h8300/platform/h8300h/aki3068net/ram.ld create mode 100644 arch/h8300/platform/h8300h/aki3068net/timer.c create mode 100644 arch/h8300/platform/h8300h/entry.S create mode 100644 arch/h8300/platform/h8300h/generic/Makefile create mode 100644 arch/h8300/platform/h8300h/generic/crt0_rom.S create mode 100644 arch/h8300/platform/h8300h/generic/ram.ld create mode 100644 arch/h8300/platform/h8300h/generic/rom.ld create mode 100644 arch/h8300/platform/h8300h/generic/timer.c create mode 100644 arch/h8300/platform/h8300h/h8max/Makefile create mode 100644 arch/h8300/platform/h8300h/h8max/crt0_ram.S create mode 100644 arch/h8300/platform/h8300h/h8max/ram.ld create mode 100644 arch/h8300/platform/h8300h/h8max/timer.c create mode 100644 arch/h8300/platform/h8300h/ints.c create mode 100644 arch/h8300/vmlinux.lds.S create mode 100644 include/asm-h8300/a.out.h create mode 100644 include/asm-h8300/aki3068net/ne.h create mode 100644 include/asm-h8300/atomic.h create mode 100644 include/asm-h8300/bitops.h create mode 100644 include/asm-h8300/bootinfo.h create mode 100644 include/asm-h8300/bug.h create mode 100644 include/asm-h8300/bugs.h create mode 100644 include/asm-h8300/byteorder.h create mode 100644 include/asm-h8300/cache.h create mode 100644 include/asm-h8300/cachectl.h create mode 100644 include/asm-h8300/cacheflush.h create mode 100644 include/asm-h8300/checksum.h create mode 100644 include/asm-h8300/current.h create mode 100644 include/asm-h8300/dbg.h create mode 100644 include/asm-h8300/delay.h create mode 100644 include/asm-h8300/div64.h create mode 100644 include/asm-h8300/dma.h create mode 100644 include/asm-h8300/elf.h create mode 100644 include/asm-h8300/errno.h create mode 100644 include/asm-h8300/fcntl.h create mode 100644 include/asm-h8300/flat.h create mode 100644 include/asm-h8300/fpu.h create mode 100644 include/asm-h8300/generic/timer_rate.h create mode 100644 include/asm-h8300/gpio.h create mode 100644 include/asm-h8300/h8300_ne.h create mode 100644 include/asm-h8300/h8max/ide.h create mode 100644 include/asm-h8300/h8max/ne.h create mode 100644 include/asm-h8300/hardirq.h create mode 100644 include/asm-h8300/hdreg.h create mode 100644 include/asm-h8300/hw_irq.h create mode 100644 include/asm-h8300/ide.h create mode 100644 include/asm-h8300/init.h create mode 100644 include/asm-h8300/io.h create mode 100644 include/asm-h8300/ioctl.h create mode 100644 include/asm-h8300/ioctls.h create mode 100644 include/asm-h8300/ipc.h create mode 100644 include/asm-h8300/ipcbuf.h create mode 100644 include/asm-h8300/irq.h create mode 100644 include/asm-h8300/keyboard.h create mode 100644 include/asm-h8300/kmap_types.h create mode 100644 include/asm-h8300/linkage.h create mode 100644 include/asm-h8300/linux_logo.h create mode 100644 include/asm-h8300/mc146818rtc.h create mode 100644 include/asm-h8300/md.h create mode 100644 include/asm-h8300/mman.h create mode 100644 include/asm-h8300/mmu.h create mode 100644 include/asm-h8300/mmu_context.h create mode 100644 include/asm-h8300/module.h create mode 100644 include/asm-h8300/msgbuf.h create mode 100644 include/asm-h8300/namei.h create mode 100644 include/asm-h8300/page.h create mode 100644 include/asm-h8300/page_offset.h create mode 100644 include/asm-h8300/param.h create mode 100644 include/asm-h8300/pci.h create mode 100644 include/asm-h8300/percpu.h create mode 100644 include/asm-h8300/pgalloc.h create mode 100644 include/asm-h8300/pgtable.h create mode 100644 include/asm-h8300/poll.h create mode 100644 include/asm-h8300/posix_types.h create mode 100644 include/asm-h8300/processor.h create mode 100644 include/asm-h8300/ptrace.h create mode 100644 include/asm-h8300/regs306x.h create mode 100644 include/asm-h8300/resource.h create mode 100644 include/asm-h8300/scatterlist.h create mode 100644 include/asm-h8300/segment.h create mode 100644 include/asm-h8300/semaphore-helper.h create mode 100644 include/asm-h8300/semaphore.h create mode 100644 include/asm-h8300/sembuf.h create mode 100644 include/asm-h8300/setup.h create mode 100644 include/asm-h8300/sh_bios.h create mode 100644 include/asm-h8300/shm.h create mode 100644 include/asm-h8300/shmbuf.h create mode 100644 include/asm-h8300/shmparam.h create mode 100644 include/asm-h8300/sigcontext.h create mode 100644 include/asm-h8300/siginfo.h create mode 100644 include/asm-h8300/signal.h create mode 100644 include/asm-h8300/smp.h create mode 100644 include/asm-h8300/smplock.h create mode 100644 include/asm-h8300/socket.h create mode 100644 include/asm-h8300/sockios.h create mode 100644 include/asm-h8300/softirq.h create mode 100644 include/asm-h8300/spinlock.h create mode 100644 include/asm-h8300/stat.h create mode 100644 include/asm-h8300/statfs.h create mode 100644 include/asm-h8300/string.h create mode 100644 include/asm-h8300/system.h create mode 100644 include/asm-h8300/target_time.h create mode 100644 include/asm-h8300/termbits.h create mode 100644 include/asm-h8300/termios.h create mode 100644 include/asm-h8300/thread_info.h create mode 100644 include/asm-h8300/timex.h create mode 100644 include/asm-h8300/tlb.h create mode 100644 include/asm-h8300/tlbflush.h create mode 100644 include/asm-h8300/topology.h create mode 100644 include/asm-h8300/traps.h create mode 100644 include/asm-h8300/types.h create mode 100644 include/asm-h8300/uaccess.h create mode 100644 include/asm-h8300/ucontext.h create mode 100644 include/asm-h8300/unaligned.h create mode 100644 include/asm-h8300/unistd.h create mode 100644 include/asm-h8300/user.h create mode 100644 include/asm-h8300/virtconvert.h diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig new file mode 100644 index 0000000000000..1691be19cea6e --- /dev/null +++ b/arch/h8300/Kconfig @@ -0,0 +1,427 @@ +# +# For a description of the syntax of this configuration file, +# see Documentation/kbuild/config-language.txt. +# + +mainmenu "uClinux/h8300 (w/o MMU) Kernel Configuration" + +config MMU + bool + default n + +config SWAP + bool + default n + +config FPU + bool + default n + +config UID16 + bool + default y + +config RWSEM_GENERIC_SPINLOCK + bool + default y + +config RWSEM_XCHGADD_ALGORITHM + bool + default n + + +source "init/Kconfig" + +menu "Processor type and features" + +choice + prompt "H8/300 platform" + default H8300H_GENERIC + +config H8300H_GENERIC + bool "Generic" + help + H8/300H CPU Generic Hardware Support + +config H8300H_AKI3068NET + bool "AE-3068/69" + help + AKI-H8/3068F / AKI-H8/3069F Flashmicom LAN Board Suppot + More Information. (Japanese Only) + + AE-3068/69 Evalution Board Support + More Information. + + +config H8300H_H8MAX + bool "H8MAX" + help + H8MAX Evalution Board Suooprt + More Information. (Japanese Only) + + +config H8300H_SIM + bool "H8/300H Simulator" + help + GDB Simulator Support + More Information. + arch/h8300/Doc/simulator.txt + +endchoice + +choice + prompt "CPU Selection" + +config H83002 + bool "H8/3001,3002,3003" + depends on H8300H_GENERIC + +config H83007 + bool "H8/3006,3007" + depends on (H8300H_GENERIC || H8300H_SIM) + +config H83048 + bool "H8/3044,3045,3046,3047,3048,3052" + depends on H8300H_GENERIC + +config H83068 + bool "H8/3065,3066,3067,3068,3069" + depends on (H8300H_GENERIC || H8300H_AKI3068NET || H8300H_H8MAX) + +endchoice + +config CPU_H8300H + bool + depends on (H8300H_GENERIC || H8300H_AKI3068NET || H8300H_H8MAX || H8300H_SIM) + default y + +config CPU_CLOCK + int "CPU Clock Frequency (/1KHz)" + default "20000" if H8300H_AKI3068NET + default "25000" if H8300H_H8MAX + default "16000" if H8300H_SIM + default "16000" if H8300H_GENERIC + help + CPU Clock Frequency divide to 1000 +choice + prompt "Kernel executes from" + ---help--- + Choose the memory type that the kernel will be running in. + +config RAMKERNEL + bool "RAM" + help + The kernel will be resident in RAM when running. + +config ROMKERNEL + bool "ROM" + help + The kernel will be resident in FLASH/ROM when running. + +endchoice + +config DEFAULT_CMDLINE + bool + help + buildin kernel commandline enabled. + +config KERNEL_COMMAND + string + help + buildin kernel commandline strings. + +endmenu + +menu "Executable file formats" + +config KCORE_AOUT + bool + default y + +config KCORE_ELF + default y + +config BINFMT_FLAT + tristate "Kernel support for flat binaries" + help + Support uClinux FLAT format binaries. + +endmenu + +source "drivers/block/Kconfig" + + +menu "ATA/IDE/MFM/RLL support" + +config IDE + tristate "ATA/ATAPI/MFM/RLL device support" + ---help--- + If you say Y here, your kernel will be able to manage low cost mass + storage units such as ATA/(E)IDE and ATAPI units. The most common + cases are IDE hard drives and ATAPI CD-ROM drives. + + It only makes sense to choose this option if your board actually + has an IDE interface. If unsure, say N. + +source "drivers/ide/Kconfig" + +endmenu + +source "net/Kconfig" + + +menu "Network device support" + depends on NET + +config NETDEVICES + bool "Network device support" + ---help--- + You can say N here if you don't intend to connect your Linux box to + any other computer at all or if all your connections will be over a + telephone line with a modem either via UUCP (UUCP is a protocol to + forward mail and news between unix hosts over telephone lines; read + the UUCP-HOWTO, available from + ) or dialing up a shell + account or a BBS, even using term (term is a program which gives you + almost full Internet connectivity if you have a regular dial up + shell account on some Internet connected Unix computer. Read + ). + + You'll have to say Y if your computer contains a network card that + you want to use under Linux (make sure you know its name because you + will be asked for it and read the Ethernet-HOWTO (especially if you + plan to use more than one network card under Linux)) or if you want + to use SLIP (Serial Line Internet Protocol is the protocol used to + send Internet traffic over telephone lines or null modem cables) or + CSLIP (compressed SLIP) or PPP (Point to Point Protocol, a better + and newer replacement for SLIP) or PLIP (Parallel Line Internet + Protocol is mainly used to create a mini network by connecting the + parallel ports of two local machines) or AX.25/KISS (protocol for + sending Internet traffic over amateur radio links). + + Make sure to read the NET-3-HOWTO. Eventually, you will have to read + Olaf Kirch's excellent and free book "Network Administrator's + Guide", to be found in . If + unsure, say Y. + +endmenu + +source "net/ax25/Kconfig" + +source "net/irda/Kconfig" + +source "drivers/isdn/Kconfig" + +source "drivers/telephony/Kconfig" + +# +# input before char - char/joystick depends on it. As does USB. +# +source "drivers/input/Kconfig" + +# +# Character device configuration +# + +menu "Character devices" + +config VT + bool "Virtual terminal" + requires INPUT=y + ---help--- + If you say Y here, you will get support for terminal devices with + display and keyboard devices. These are called "virtual" because you + can run several virtual terminals (also called virtual consoles) on + one physical terminal. This is rather useful, for example one + virtual terminal can collect system messages and warnings, another + one can be used for a text-mode user session, and a third could run + an X session, all in parallel. Switching between virtual terminals + is done with certain key combinations, usually Alt-. + + The setterm command ("man setterm") can be used to change the + properties (such as colors or beeping) of a virtual terminal. The + man page console_codes(4) ("man console_codes") contains the special + character sequences that can be used to change those properties + directly. The fonts used on virtual terminals can be changed with + the setfont ("man setfont") command and the key bindings are defined + with the loadkeys ("man loadkeys") command. + + You need at least one virtual terminal device in order to make use + of your keyboard and monitor. Therefore, only people configuring an + embedded system would want to say N here in order to save some + memory; the only way to log into such a system is then via a serial + or network connection. + + If unsure, say Y, or else you won't be able to do much with your new + shiny Linux system :-) + +config VT_CONSOLE + bool "Support for console on virtual terminal" + depends on VT + ---help--- + The system console is the device which receives all kernel messages + and warnings and which allows logins in single user mode. If you + answer Y here, a virtual terminal (the device used to interact with + a physical terminal) can be used as system console. This is the most + common mode of operations, so you should say Y here unless you want + the kernel messages be output only to a serial port (in which case + you should say Y to "Console on serial port", below). + + If you do say Y here, by default the currently visible virtual + terminal (/dev/tty0) will be used as system console. You can change + that with a kernel command line option such as "console=tty3" which + would use the third virtual terminal as system console. (Try "man + bootparam" or see the documentation of your boot loader (lilo or + loadlin) about how to pass options to the kernel at boot time.) + + If unsure, say Y. + +config HW_CONSOLE + bool + depends on VT && !S390 && !UM + default y + +config SH_SCI + tristate "Serial (SCI) support" + help + Selecting this option will allow the Linux kernel to transfer data + over SCI (Serial Communication Interface) and/or SCIF (Serial + Communication Interface with FIFO) which are built into the Hitachi + SuperH processor. The option provides 1 to 3 (depending + on the CPU model) standard Linux tty devices, /dev/ttySC[012]; one + of these is normally used as the system console. + + If in doubt, press "y". + +config SERIAL_CONSOLE + bool "Support for console on serial port" + depends on SERIAL=y || SH_SCI=y + ---help--- + If you say Y here, it will be possible to use a serial port as the + system console (the system console is the device which receives all + kernel messages and warnings and which allows logins in single user + mode). This could be useful if some terminal or printer is connected + to that serial port. + + Even if you say Y here, the currently visible virtual console + (/dev/tty0) will still be used as the system console by default, but + you can alter that using a kernel command line option such as + "console=ttyS1". (Try "man bootparam" or see the documentation of + your boot loader (lilo or loadlin) about how to pass options to the + kernel at boot time.) + + If you don't have a VGA card installed and you say Y here, the + kernel will automatically use the first serial line, /dev/ttyS0, as + system console. + + If unsure, say N. + +config UNIX98_PTYS + bool "Unix98 PTY support" + ---help--- + A pseudo terminal (PTY) is a software device consisting of two + halves: a master and a slave. The slave device behaves identical to + a physical terminal; the master device is used by a process to + read data from and write data to the slave, thereby emulating a + terminal. Typical programs for the master side are telnet servers + and xterms. + + Linux has traditionally used the BSD-like names /dev/ptyxx for + masters and /dev/ttyxx for slaves of pseudo terminals. This scheme + has a number of problems. The GNU C library glibc 2.1 and later, + however, supports the Unix98 naming standard: in order to acquire a + pseudo terminal, a process opens /dev/ptmx; the number of the pseudo + terminal is then made available to the process and the pseudo + terminal slave can be accessed as /dev/pts/. What was + traditionally /dev/ttyp2 will then be /dev/pts/2, for example. + + The entries in /dev/pts/ are created on the fly by a virtual + file system; therefore, if you say Y here you should say Y to + "/dev/pts file system for Unix98 PTYs" as well. + + If you want to say Y here, you need to have the C library glibc 2.1 + or later (equal to libc-6.1, check with "ls -l /lib/libc.so.*"). + Read the instructions in pertaining to + pseudo terminals. It's safe to say N. + +config UNIX98_PTY_COUNT + int "Maximum number of Unix98 PTYs in use (0-2048)" + depends on UNIX98_PTYS + default "256" + help + The maximum number of Unix98 PTYs that can be used at any one time. + The default is 256, and should be enough for desktop systems. Server + machines which support incoming telnet/rlogin/ssh connections and/or + serve several X terminals may want to increase this: every incoming + connection and every xterm uses up one PTY. + + When not in use, each additional set of 256 PTYs occupy + approximately 8 KB of kernel memory on 32-bit architectures. + +endmenu + +#source drivers/misc/Config.in +source "drivers/media/Kconfig" + +source "fs/Kconfig" + +source "drivers/usb/Kconfig" + +source "net/bluetooth/Kconfig" + + +menu "Kernel hacking" + +config FULLDEBUG + bool "Full Symbolic/Source Debugging support" + help + Enable debugging symbols on kernel build. + +config MAGIC_SYSRQ + bool "Magic SysRq key" + help + Enables console device to interprent special characters as + commands to dump state information. + +config HIGHPROFILE + bool "Use fast second timer for profiling" + help + Use a fast secondary clock to produce profiling information. + +config NO_KERNEL_MSG + bool "Suppress Kernel BUG Messages" + help + Do not output any debug BUG messages within the kernel. + +config GDB_MAGICPRINT + bool "Message Output for GDB MagicPrint service" + depends on H8300H_SIM + help + kernel messages output useing MagicPrint service from GDB + +config SYSCALL_PRINT + bool "SystemCall trace print" + help + outout history of systemcall + +config GDB_DEBUG + bool "Use gdb stub" + depends on !H8300H_SIM + help + gdb stub exception support + +config CONFIG_SH_STANDARD_BIOS + bool "Use gdb protocol serial console" + depends on !H8300H_SIM + help + serial console output using GDB protocol. + Require eCos/RedBoot + +endmenu + +source "security/Kconfig" + +source "crypto/Kconfig" + +source "lib/Kconfig" + diff --git a/arch/h8300/Makefile b/arch/h8300/Makefile new file mode 100644 index 0000000000000..105db70dbba12 --- /dev/null +++ b/arch/h8300/Makefile @@ -0,0 +1,61 @@ +# +# arch/h8300/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# (C) Copyright 2002, Yoshinori Sato +# +ifndef include-config +-include $(TOPDIR)/.config +endif + +platform-$(CONFIG_CPU_H8300H) := h8300h +PLATFORM := $(platform-y) + +board-$(CONFIG_H8300H_GENERIC) := generic +board-$(CONFIG_H8300H_AKI3068NET) := ucsimm +board-$(CONFIG_H8300H_H8MAX) := ucdimm +board-$(CONFIG_H8300H_SIM) := generic +BOARD := $(board-y) + +model-$(CONFIG_RAMKERNEL) := ram +model-$(CONFIG_ROMKERNEL) := rom +MODEL := $(model-y) + +cflags-$(CONFIG_CPU_H8300H) := -mh +ldflags-$(CONFIG_CPU_H8300H) := -mh8300helf + +CFLAGS += $(cflags-y) +CFLAGS += -mint32 -fno-builtin +CFLAGS += -O2 -g +CFLAGS += -D__linux__ +CFLAGS += -DUTS_SYSNAME=\"uClinux\" -DTARGET=$(BOARD) +AFLAGS += -DPLATFORM=$(PLATFORM) -DTARGET=$(BOARD) -DMODEL=$(MODEL) $(cflags-y) +LDFLAGS += $(ldflags-y) +LDFLAGS_BLOB := --format binary --oformat elf32-h8300 + +CROSS_COMPILE = h8300-elf- +#HEAD := arch/$(ARCH)/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o +LIBGCC := $(shell $(CROSS-COMPILE)$(CC) $(CFLAGS) -print-libgcc-file-name) + +core-y += arch/$(ARCH)/kernel/ \ + arch/$(ARCH)/mm/ \ + arch/$(ARCH)/platform/$(PLATFORM)/ \ + arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/ + +libs-y += arch/$(ARCH)/lib/ $(LIBGCC) + +export MODEL + +archmrproper: + +archclean: + $(call descend arch/$(ARCH), subdirclean) + +prepare: include/asm-$(ARCH)/asm-offsets.h + +include/asm-$(ARCH)/asm-offsets.h: arch/$(ARCH)/kernel/asm-offsets.s \ + include/asm include/linux/version.h + $(call filechk,gen-asm-offsets) diff --git a/arch/h8300/README b/arch/h8300/README new file mode 100644 index 0000000000000..d6f4524991c1d --- /dev/null +++ b/arch/h8300/README @@ -0,0 +1,35 @@ +uClinux-2.4 for H8/300 README +Yoshinori Sato + +* Supported CPU +H8/300H +H8S is planning. + +* Supported Target +1.simulator of GDB + require patches. + +2.AE 3068/AE 3069 + more information + MICROTRONIQUE + Akizuki Denshi Tsusho Ltd. (Japanese Only) + +3.H8MAX + Under development + see http://www.strawbelly-linux.com (Japanese Only) + +* Toolchain Version +gcc-3.1 or higher and patch +see arch/h8300/tools_patch/README +binutils-2.12 or higher +gdb-5.2 or higher +The environment that can compile a h8300-elf binary is necessary. + +* Userland Develop environment +Tempolary used h8300-hms(h8300-coff) Toolchain. +I prepare toolchain corresponding to h8300-elf. + +* A few words of thanks +Porting to H8/300H is support of Information-technology Promotion Agency, Japan. +I thank support. +and All developer/user. diff --git a/arch/h8300/defconfig b/arch/h8300/defconfig new file mode 100644 index 0000000000000..b4ceb909c439e --- /dev/null +++ b/arch/h8300/defconfig @@ -0,0 +1,199 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_MMU is not set +# CONFIG_SWAP is not set +# CONFIG_FPU is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +# CONFIG_SYSVIPC is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_SYSCTL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_IKCONFIG is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Processor type and features +# +# CONFIG_H8300H_GENERIC is not set +# CONFIG_H8300H_AKI3068NET is not set +# CONFIG_H8300H_H8MAX is not set +CONFIG_H8300H_SIM=y +# CONFIG_H83002 is not set +CONFIG_H83007=y +# CONFIG_H83048 is not set +# CONFIG_H83068 is not set +CONFIG_CPU_H8300H=y +CONFIG_CPU_CLOCK=16000 +# CONFIG_RAMKERNEL is not set +CONFIG_ROMKERNEL=y + +# +# Executable file formats +# +CONFIG_KCORE_AOUT=y +CONFIG_BINFMT_FLAT=y + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_RAM is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# Networking support +# +# CONFIG_NET is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# ISDN subsystem +# + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Userland interfaces +# + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# + +# +# Character devices +# +CONFIG_SH_SCI=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_UNIX98_PTYS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# USB support +# + +# +# Kernel hacking +# +CONFIG_FULLDEBUG=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_HIGHPROFILE is not set +CONFIG_NO_KERNEL_MSG=y +# CONFIG_GDB_MAGICPRINT is not set +# CONFIG_SYSCALL_PRINT is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set diff --git a/arch/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile new file mode 100644 index 0000000000000..3eae9fb221165 --- /dev/null +++ b/arch/h8300/kernel/Makefile @@ -0,0 +1,13 @@ +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +obj-y := process.o traps.o ptrace.o \ + sys_h8300.o time.o semaphore.o signal.o \ + setup.o h8300_ksyms.o gpio.o init_task.o \ + syscalls.o diff --git a/arch/h8300/kernel/asm-offsets.c b/arch/h8300/kernel/asm-offsets.c new file mode 100644 index 0000000000000..0ab8c8a003845 --- /dev/null +++ b/arch/h8300/kernel/asm-offsets.c @@ -0,0 +1,49 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#define DEFINE(sym, val) \ + asm volatile("\n->" #sym " %0 " #val : : "i" (val)) + +#define BLANK() asm volatile("\n->" : : ) + +int main(void) +{ + /* offsets into the task struct */ + DEFINE(TASK_STATE, offsetof(struct task_struct, state)); + DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags)); + DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace)); + DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked)); + DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); + DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info)); + DEFINE(TASK_MM, offsetof(struct task_struct, mm)); + DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); + + /* offsets into the irq_cpustat_t struct */ + DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending)); + + /* offsets into the thread struct */ + DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); + DEFINE(THREAD_USP, offsetof(struct thread_struct, usp)); + DEFINE(THREAD_CCR, offsetof(struct thread_struct, ccr)); + DEFINE(THREAD_VFORK, offsetof(struct thread_struct, vfork_ret)); + + DEFINE(PT_PTRACED, PT_PTRACED); + DEFINE(PT_DTRACE, PT_DTRACE); + + return 0; +} diff --git a/arch/h8300/kernel/gpio.c b/arch/h8300/kernel/gpio.c new file mode 100644 index 0000000000000..987b9f680db20 --- /dev/null +++ b/arch/h8300/kernel/gpio.c @@ -0,0 +1,166 @@ +/* + * linux/arch/h8300/kernel/gpio.c + * + * Yoshinori Sato + * + */ + +/* + * H8/300H Internal I/O Port Management + */ + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_H83007) || defined(CONFIG_H83068) +#define P1DDR (unsigned char *)0xfee000 +#define P2DDR (unsigned char *)0xfee001 +#define P3DDR (unsigned char *)0xfee002 +#define P4DDR (unsigned char *)0xfee003 +#define P5DDR (unsigned char *)0xfee004 +#define P6DDR (unsigned char *)0xfee005 +#define P8DDR (unsigned char *)0xfee007 +#define P9DDR (unsigned char *)0xfee008 +#define PADDR (unsigned char *)0xfee009 +#define PBDDR (unsigned char *)0xfee00A +#endif +#if defined(CONFIG_H83002) || defined(CONFIG_H8048) +#define P1DDR (unsigned char *)0xffffc0 +#define P2DDR (unsigned char *)0xffffc1 +#define P3DDR (unsigned char *)0xffffc4 +#define P4DDR (unsigned char *)0xffffc5 +#define P5DDR (unsigned char *)0xffffc8 +#define P6DDR (unsigned char *)0xffffc9 +#define P8DDR (unsigned char *)0xffffcd +#define P9DDR (unsigned char *)0xffffd0 +#define PADDR (unsigned char *)0xffffd1 +#define PBDDR (unsigned char *)0xffffd4 +#endif + +#if defined(P1DDR) + +#define MAX_PORT 11 + +static struct { + unsigned char used; + unsigned char ddr; +} gpio_regs[MAX_PORT]; + +static volatile unsigned char *ddrs[] = { + P1DDR,P2DDR,P3DDR,P4DDR,P5DDR,P6DDR,NULL,P8DDR,P9DDR,PADDR,PBDDR, +}; + +extern char *_platform_gpio_table(int length); + +int h8300_reserved_gpio(int port, unsigned int bits) +{ + unsigned char *used; + if (port < 0 || port >= MAX_PORT) + return -1; + used = &(gpio_regs[port].used); + if ((*used & bits) != 0) + return 0; + *used |= bits; + return 1; +} + +int h8300_free_gpio(int port, unsigned int bits) +{ + unsigned char *used; + if (port < 0 || port >= MAX_PORT) + return -1; + used = &(gpio_regs[port].used); + if ((*used & bits) != bits) + return 0; + *used &= (~bits); + return 1; +} + +int h8300_set_gpio_dir(int port_bit,int dir) +{ + const unsigned char mask[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; + int port = (port_bit >> 8) & 0xff; + int bit = port_bit & 0x07; + if (ddrs[port] == NULL) + return 0; + if (gpio_regs[port].used & mask[bit]) { + if (dir) + gpio_regs[port].ddr |= mask[bit]; + else + gpio_regs[port].ddr &= ~mask[bit]; + *ddrs[port] = gpio_regs[port].ddr; + return 1; + } else + return 0; +} + +int h8300_get_gpio_dir(int port_bit) +{ + const unsigned char mask[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; + int port = (port_bit >> 8) & 0xff; + int bit = port_bit & 0x07; + if (ddrs[port] == NULL) + return 0; + if (gpio_regs[port].used & mask[bit]) { + return (gpio_regs[port].ddr & mask[bit]) != 0; + } else + return -1; +} + +#if defined(CONFIG_PROC_FS) +static char *port_status(int portno) +{ + static char result[10]; + const static char io[2]={'I','O'}; + char *rp; + int c; + unsigned char used,ddr; + + used = gpio_regs[portno].used; + ddr = gpio_regs[portno].ddr; + result[8]='\0'; + rp = result + 7; + for (c = 8; c > 0; c--,rp--,used >>= 1, ddr >>= 1) + if (used & 0x01) + *rp = io[ ddr & 0x01]; + else + *rp = '-'; + return result; +} + +static int gpio_proc_read(char *buf, char **start, off_t offset, int len, int unused) +{ + int c,outlen; + const static char port_name[]="123456789AB"; + outlen = 0; + for (c = 0; c < MAX_PORT; c++) { + if (ddrs[c] == NULL) + continue ; + len = sprintf(buf,"P%c: %s\n",port_name[c],port_status(c)); + buf += len; + outlen += len; + } + return outlen; +} + +static const struct proc_dir_entry proc_gpio = { + 0, 4,"gpio",S_IFREG | S_IRUGO, 1, 0, 0, 0, NULL, gpio_proc_read, +}; +#endif + +int h8300_gpio_init(void) +{ + memcpy(gpio_regs,_platform_gpio_table(sizeof(gpio_regs)),sizeof(gpio_regs)); +#if 0 && defined(CONFIG_PROC_FS) + proc_register(&proc_root,&proc_gpio); +#endif + return 0; +} + +#else +#error Unsuppoted CPU Selection +#endif diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c new file mode 100644 index 0000000000000..79e3a8b7ca31c --- /dev/null +++ b/arch/h8300/kernel/h8300_ksyms.c @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//asmlinkage long long __ashrdi3 (long long, int); +//asmlinkage long long __lshrdi3 (long long, int); +extern char h8300_debug_device[]; + +extern void dump_thread(struct pt_regs *, struct user *); + +/* platform dependent support */ + +EXPORT_SYMBOL(dump_thread); +EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(strrchr); +EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(strchr); +EXPORT_SYMBOL(strcat); +EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strncmp); + +EXPORT_SYMBOL(ip_fast_csum); + +EXPORT_SYMBOL(mach_enable_irq); +EXPORT_SYMBOL(mach_disable_irq); +EXPORT_SYMBOL(kernel_thread); + +/* Networking helper routines. */ +EXPORT_SYMBOL(csum_partial_copy); + +/* The following are special because they're not called + explicitly (the C compiler generates them). Fortunately, + their interface isn't gonna change any time soon now, so + it's OK to leave it out of version control. */ +//EXPORT_SYMBOL_NOVERS(__ashrdi3); +//EXPORT_SYMBOL_NOVERS(__lshrdi3); +EXPORT_SYMBOL_NOVERS(memcpy); +EXPORT_SYMBOL_NOVERS(memset); +EXPORT_SYMBOL_NOVERS(memcmp); +EXPORT_SYMBOL_NOVERS(memscan); +EXPORT_SYMBOL_NOVERS(memmove); + +EXPORT_SYMBOL(get_wchan); + +/* + * libgcc functions - functions that are used internally by the + * compiler... (prototypes are not correct though, but that + * doesn't really matter since they're not versioned). + */ +extern void __gcc_bcmp(void); +extern void __ashldi3(void); +extern void __ashrdi3(void); +extern void __cmpdi2(void); +extern void __divdi3(void); +extern void __divsi3(void); +extern void __lshrdi3(void); +extern void __moddi3(void); +extern void __modsi3(void); +extern void __muldi3(void); +extern void __mulsi3(void); +extern void __negdi2(void); +extern void __ucmpdi2(void); +extern void __udivdi3(void); +extern void __udivmoddi4(void); +extern void __udivsi3(void); +extern void __umoddi3(void); +extern void __umodsi3(void); + + /* gcc lib functions */ +EXPORT_SYMBOL_NOVERS(__gcc_bcmp); +EXPORT_SYMBOL_NOVERS(__ashldi3); +EXPORT_SYMBOL_NOVERS(__ashrdi3); +EXPORT_SYMBOL_NOVERS(__cmpdi2); +EXPORT_SYMBOL_NOVERS(__divdi3); +EXPORT_SYMBOL_NOVERS(__divsi3); +EXPORT_SYMBOL_NOVERS(__lshrdi3); +EXPORT_SYMBOL_NOVERS(__moddi3); +EXPORT_SYMBOL_NOVERS(__modsi3); +EXPORT_SYMBOL_NOVERS(__muldi3); +EXPORT_SYMBOL_NOVERS(__mulsi3); +EXPORT_SYMBOL_NOVERS(__negdi2); +EXPORT_SYMBOL_NOVERS(__ucmpdi2); +EXPORT_SYMBOL_NOVERS(__udivdi3); +EXPORT_SYMBOL_NOVERS(__udivmoddi4); +EXPORT_SYMBOL_NOVERS(__udivsi3); +EXPORT_SYMBOL_NOVERS(__umoddi3); +EXPORT_SYMBOL_NOVERS(__umodsi3); + +EXPORT_SYMBOL_NOVERS(_current_task); + +EXPORT_SYMBOL_NOVERS(is_in_rom); + +EXPORT_SYMBOL_NOVERS(h8300_reserved_gpio) +EXPORT_SYMBOL_NOVERS(h8300_free_gpio) +EXPORT_SYMBOL_NOVERS(h8300_set_gpio_dir) diff --git a/arch/h8300/kernel/init_task.c b/arch/h8300/kernel/init_task.c new file mode 100644 index 0000000000000..6f0a8c72e5c35 --- /dev/null +++ b/arch/h8300/kernel/init_task.c @@ -0,0 +1,38 @@ +/* + * linux/arch/h8300/kernel/init_task.c + */ +#include +#include +#include +#include +#include + +#include +#include + +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +struct mm_struct init_mm = INIT_MM(init_mm); + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +__asm__(".align 4"); +struct task_struct init_task = INIT_TASK(init_task); + + +/* + * Initial thread structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by having a special + * "init_task" linker map entry.. + */ +union thread_union init_thread_union + __attribute__((__section__(".data.init_task"))) = + { INIT_THREAD_INFO(init_task) }; + diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c new file mode 100644 index 0000000000000..519f803772087 --- /dev/null +++ b/arch/h8300/kernel/process.c @@ -0,0 +1,317 @@ +/* + * linux/arch/h8300/kernel/process.c + * + * Yoshinori Sato + * + * Based on: + * + * linux/arch/m68knommu/kernel/process.c + * + * Copyright (C) 1998 D. Jeff Dionne , + * Kenneth Albanowski , + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +asmlinkage void ret_from_exception(void); + +/* + * The idle loop on an H8/300.. + */ +#if !defined(CONFIG_H8300H_SIM) +void default_idle(void) +{ + while(1) { + if (need_resched()) { + sti(); + __asm__("sleep"); + cli(); + } + schedule(); + } +} +#else +void default_idle(void) +{ + while(1) { + if (need_resched()) + schedule(); + } +} +#endif +void (*idle)(void) = default_idle; + +/* + * The idle thread. There's no useful work to be + * done, so just try to conserve power and have a + * low exit latency (ie sit in a loop waiting for + * somebody to say that they'd like to reschedule) + */ +void cpu_idle(void) +{ + idle(); +} + +void machine_restart(char * __unused) +{ + cli(); + __asm__("jmp @@0"); +} + +void machine_halt(void) +{ + cli(); + __asm__("sleep"); + for (;;); +} + +void machine_power_off(void) +{ + cli(); + __asm__("sleep"); + for (;;); +} + +void show_regs(struct pt_regs * regs) +{ + printk("\n"); + printk("PC: %08lx Status: %02x\n", + regs->pc, regs->ccr); + printk("ORIG_ER0: %08lx ER0: %08lx ER1: %08lx\n", + regs->orig_er0, regs->er0, regs->er1); + printk("ER2: %08lx ER3: %08lx\n", + regs->er2, regs->er3); + if (!(regs->ccr & 0x10)) + printk("USP: %08lx\n", rdusp()); +} + +/* + * Create a kernel thread + */ +int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +{ + long retval; + register long clone_arg asm("er1"); + mm_segment_t fs; + + fs = get_fs(); + set_fs (KERNEL_DS); + clone_arg = flags | CLONE_VM; + + __asm__ __volatile__ ( + "mov.l sp, er2\n\t" + "mov.l %1,er0\n\t" + "mov.l %5,er1\n\t" + "trapa #0\n\t" + "cmp.l sp, er2\n\t" + "beq 1f\n\t" + "mov.l %3, er0\n\t" + "jsr @%4\n\t" + "mov.l %2, er0\n\t" + "trapa #0\n" + "1:\n\t" + "mov.l er0,%0" + : "=r" (retval) + : "i" (__NR_clone), + "i" (__NR_exit), + "r" (arg), + "r" (fn), + "r" (clone_arg) + : "cc", "er0", "er1", "er2", "er3"); + + set_fs (fs); + return retval; +} + +void flush_thread(void) +{ +} + +/* + * "h8300_fork()".. By the time we get here, the + * non-volatile registers have also been saved on the + * stack. We do some ugly pointer stuff here.. (see + * also copy_thread) + */ + +asmlinkage int h8300_fork(struct pt_regs *regs) +{ + return -EINVAL; +} + +asmlinkage int h8300_vfork(struct pt_regs *regs) +{ + struct task_struct *p; + p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL); + return IS_ERR(p) ? PTR_ERR(p) : p->pid; +} + +asmlinkage int h8300_clone(struct pt_regs *regs) +{ + unsigned long clone_flags; + unsigned long newsp; + struct task_struct *p; + + /* syscall2 puts clone_flags in er1 and usp in er2 */ + clone_flags = regs->er1; + newsp = regs->er2; + if (!newsp) + newsp = rdusp(); + p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0, NULL, NULL); + return IS_ERR(p) ? PTR_ERR(p) : p->pid; + +} + +int copy_thread(int nr, unsigned long clone_flags, + unsigned long usp, unsigned long topstk, + struct task_struct * p, struct pt_regs * regs) +{ + struct pt_regs * childregs; + struct switch_stack * childstack, *stack; + unsigned long stack_offset, *retp; + + stack_offset = KTHREAD_SIZE - sizeof(struct pt_regs); + childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; + + *childregs = *regs; + + retp = (unsigned long *) regs-2; + stack = ((struct switch_stack *) retp) - 1; + + childstack = ((struct switch_stack *) childregs) - 1; + *childstack = *stack; + childregs->er0 = 0; + childstack->retpc = (unsigned long) ret_from_exception; + + p->thread.usp = usp; + p->thread.ksp = (unsigned long)childstack; + p->thread.vfork_ret = 0; + + return 0; +} + +/* + * fill in the user structure for a core dump.. + */ +void dump_thread(struct pt_regs * regs, struct user * dump) +{ + struct switch_stack *sw; + +/* changed the size calculations - should hopefully work better. lbt */ + dump->magic = CMAGIC; + dump->start_code = 0; + dump->start_stack = rdusp() & ~(PAGE_SIZE - 1); + dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT; + dump->u_dsize = ((unsigned long) (current->mm->brk + + (PAGE_SIZE-1))) >> PAGE_SHIFT; + dump->u_dsize -= dump->u_tsize; + dump->u_ssize = 0; + + dump->u_ar0 = (struct user_regs_struct *)(((int)(&dump->regs)) -((int)(dump))); + sw = ((struct switch_stack *)regs) - 1; + dump->regs.er0 = regs->er0; + dump->regs.er1 = regs->er1; + dump->regs.er2 = regs->er2; + dump->regs.er3 = regs->er3; + dump->regs.er4 = sw->er4; + dump->regs.er5 = sw->er5; + dump->regs.er6 = sw->er6; + dump->regs.orig_er0 = regs->orig_er0; + dump->regs.ccr = regs->ccr; + dump->regs.pc = regs->pc; +} + +/* + * sys_execve() executes a new program. + */ +asmlinkage int sys_execve(char *name, char **argv, char **envp,int dummy,...) +{ + int error; + char * filename; + struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy+4); + + lock_kernel(); + filename = getname(name); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + error = do_execve(filename, argv, envp, regs); + putname(filename); +out: + unlock_kernel(); + return error; +} + +/* + * These bracket the sleeping functions.. + */ +extern void scheduling_functions_start_here(void); +extern void scheduling_functions_end_here(void); +#define first_sched ((unsigned long) scheduling_functions_start_here) +#define last_sched ((unsigned long) scheduling_functions_end_here) + +unsigned long thread_saved_pc(struct task_struct *tsk) +{ + struct switch_stack *sw = (struct switch_stack *)(tsk->thread.ksp); + + /* Check whether the thread is blocked in resume() */ + if (sw->retpc > (unsigned long)scheduling_functions_start_here && + sw->retpc < (unsigned long)scheduling_functions_end_here) + return ((unsigned long *)sw->er6)[1]; + else + return sw->retpc; +} + +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long fp, pc; + unsigned long stack_page; + int count = 0; + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + + stack_page = (unsigned long)p; + fp = ((struct switch_stack *)p->thread.ksp)->er6; + do { + if (fp < stack_page+sizeof(struct task_struct) || + fp >= 8184+stack_page) + return 0; + pc = ((unsigned long *)fp)[1]; + /* FIXME: This depends on the order of these functions. */ + if (pc < first_sched || pc >= last_sched) + return pc; + fp = *(unsigned long *) fp; + } while (count++ < 16); + return 0; +} diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c new file mode 100644 index 0000000000000..eb4d56205d695 --- /dev/null +++ b/arch/h8300/kernel/ptrace.c @@ -0,0 +1,470 @@ +/* + * linux/arch/h8300/kernel/ptrace.c + * + * Yoshinori Sato + * + * Based on: + * linux/arch/m68k/kernel/ptrace.c + * + * Copyright (C) 1994 by Hamish Macdonald + * Taken from linux/kernel/ptrace.c and modified for M680x0. + * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of + * this archive for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* + * does not yet catch signals sent when the child dies. + * in exit.c or in signal.c. + */ + +/* determines which bits in the SR the user has access to. */ +/* 1 = access 0 = no access */ +#define SR_MASK 0x001f + +/* sets the trace bits. */ +#define TRACE_BITS 0x8000 + +/* Find the stack offset for a register, relative to thread.esp0. */ +#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg) +#define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \ + - sizeof(struct switch_stack)) +/* Mapping from PT_xxx to the stack offset at which the register is + saved. Notice that usp has no stack-slot and needs to be treated + specially (see get_reg/put_reg below). */ +static const int regoff[] = { + PT_REG(er1), PT_REG(er2), PT_REG(er3), SW_REG(er4), + SW_REG(er5), SW_REG(er6), PT_REG(er0), PT_REG(orig_er0), + PT_REG(ccr), PT_REG(pc) +}; + +/* + * Get contents of register REGNO in task TASK. + */ +static inline long get_reg(struct task_struct *task, int regno) +{ + unsigned long *addr; + + if (regno == PT_USP) + addr = &task->thread.usp; + else if (regno < sizeof(regoff)/sizeof(regoff[0])) + addr = (unsigned long *)(task->thread.esp0 + regoff[regno]); + else + return 0; + return *addr; +} + +/* + * Write contents of register REGNO in task TASK. + */ +static inline int put_reg(struct task_struct *task, int regno, + unsigned long data) +{ + unsigned long *addr; + + if (regno == PT_USP) + addr = &task->thread.usp; + else if (regno < sizeof(regoff)/sizeof(regoff[0])) + addr = (unsigned long *) (task->thread.esp0 + regoff[regno]); + else + return -1; + *addr = data; + return 0; +} + +/* + * Called by kernel/ptrace.c when detaching.. + * + * Make sure the single step bit is not set. + */ +int ptrace_cancel_bpt(struct task_struct *child) +{ + int i,r=0; + + for(i=0; i<4; i++) { + if (child->thread.debugreg[i]) { + if (child->thread.debugreg[i] != ~0) + put_user(child->thread.debugreg[i+4], + (unsigned short *)child->thread.debugreg[i]); + r = 1; + child->thread.debugreg[i] = 0; + } + } + return r; +} + +const static unsigned char opcode0[]={ + 0x04,0x02,0x04,0x02,0x04,0x02,0x04,0x02, /* 0x58 */ + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, /* 0x60 */ + 0x02,0x02,0x11,0x11,0x02,0x02,0x04,0x04, /* 0x68 */ + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, /* 0x70 */ + 0x08,0x04,0x06,0x04,0x04,0x04,0x04,0x04}; /* 0x78 */ + +const static int table_parser01(unsigned char *pc); +const static int table_parser02(unsigned char *pc); +const static int table_parser100(unsigned char *pc); +const static int table_parser101(unsigned char *pc); + +const static int (*parsers[])(unsigned char *pc)={table_parser01,table_parser02}; + +static int insn_length(unsigned char *pc) +{ + if (*pc == 0x01) + return table_parser01(pc+1); + if (*pc < 0x58 || *pc>=0x80) + return 2; + else + if (opcode0[*pc-0x58]<0x10) + return opcode0[*pc-0x58]; + else + return (*parsers[opcode0[*pc-0x58]-0x10])(pc+1); +} + +const static int table_parser01(unsigned char *pc) +{ + const unsigned char codelen[]={0x10,0x00,0x00,0x00,0x11,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,0x04,0x04,0x00,0x04}; + const static int (*parsers[])(unsigned char *)={table_parser100,table_parser101}; + unsigned char second_index; + second_index = (*pc) >> 4; + if (codelen[second_index]<0x10) + return codelen[second_index]; + else + return parsers[codelen[second_index]-0x10](pc); +} + +const static int table_parser02(unsigned char *pc) +{ + return (*pc & 0x20)?0x06:0x04; +} + +const static int table_parser100(unsigned char *pc) +{ + return (*(pc+2) & 0x02)?0x08:0x06; +} + +const static int table_parser101(unsigned char *pc) +{ + return (*(pc+2) & 0x02)?0x08:0x06; +} + +#define BREAK_INST 0x5730 /* TRAPA #3 */ + +int ptrace_set_bpt(struct task_struct *child) +{ + unsigned long pc,next; + unsigned short insn; + pc = get_reg(child,PT_PC); + next = insn_length((unsigned char *)pc) + pc; + get_user(insn,(unsigned short *)pc); + if (insn == 0x5470) { + /* rts */ + unsigned long sp; + sp = get_reg(child,PT_USP); + get_user(next,(unsigned long *)sp); + } else if ((insn & 0xfb00) != 0x5800) { + /* jmp / jsr */ + int regs; + const short reg_tbl[]={PT_ER0,PT_ER1,PT_ER2,PT_ER3, + PT_ER4,PT_ER5,PT_ER6,PT_USP}; + switch(insn & 0xfb00) { + case 0x5900: + regs = (insn & 0x0070) >> 8; + next = get_reg(child,reg_tbl[regs]); + break; + case 0x5a00: + get_user(next,(unsigned long *)(pc+2)); + next &= 0x00ffffff; + break; + case 0x5b00: + /* unneccessary? */ + next = *(unsigned long *)(insn & 0xff); + break; + } + } else if (((insn & 0xf000) == 0x4000) || ((insn &0xff00) == 0x5500)) { + /* b**:8 */ + unsigned long dsp; + dsp = (long)(insn && 0xff)+pc+2; + child->thread.debugreg[1] = dsp; + get_user(child->thread.debugreg[5],(unsigned short *)dsp); + put_user(BREAK_INST,(unsigned short *)dsp); + } else if (((insn & 0xff00) == 0x5800) || ((insn &0xff00) == 0x5c00)) { + /* b**:16 */ + unsigned long dsp; + get_user(dsp,(unsigned short *)(pc+2)); + dsp = (long)dsp+pc+4; + child->thread.debugreg[1] = dsp; + get_user(child->thread.debugreg[5],(unsigned short *)dsp); + put_user(BREAK_INST,(unsigned short *)dsp); + } + child->thread.debugreg[0] = next; + get_user(child->thread.debugreg[4],(unsigned short *)next); + put_user(BREAK_INST,(unsigned short *)next); + return 0; +} + +inline +static int read_long(struct task_struct * tsk, unsigned long addr, + unsigned long * result) +{ + *result = *(unsigned long *)addr; + return 0; +} + +void ptrace_disable(struct task_struct *child) +{ + ptrace_cancel_bpt(child); +} + +asmlinkage int sys_ptrace(long request, long pid, long addr, long data) +{ + struct task_struct *child; + int ret; + + lock_kernel(); + ret = -EPERM; + if (request == PTRACE_TRACEME) { + /* are we already being traced? */ + if (current->ptrace & PT_PTRACED) + goto out; + /* set the ptrace bit in the process flags. */ + current->ptrace |= PT_PTRACED; + ret = 0; + goto out; + } + ret = -ESRCH; + read_lock(&tasklist_lock); + child = find_task_by_pid(pid); + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); + if (!child) + goto out; + + ret = -EPERM; + if (pid == 1) /* you may not mess with init */ + goto out_tsk; + + if (request == PTRACE_ATTACH) { + ret = ptrace_attach(child); + goto out_tsk; + } + ret = -ESRCH; + if (!(child->ptrace & PT_PTRACED)) + goto out_tsk; + if (child->state != TASK_STOPPED) { + if (request != PTRACE_KILL) + goto out_tsk; + } + ret = ptrace_check_attach(child, request == PTRACE_KILL); + if (ret < 0) + goto out_tsk; + + switch (request) { + case PTRACE_PEEKTEXT: /* read word at location addr. */ + case PTRACE_PEEKDATA: { + unsigned long tmp; + + ret = read_long(child, addr, &tmp); + if (ret < 0) + break ; + ret = verify_area(VERIFY_WRITE, (void *) data, sizeof(long)); + if (!ret) + put_user(tmp, (unsigned long *) data); + break ; + } + + /* read the word at location addr in the USER area. */ + case PTRACE_PEEKUSR: { + unsigned long tmp; + + if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) + ret = -EIO; + + ret = verify_area(VERIFY_WRITE, (void *) data, + sizeof(long)); + if (ret) + break ; + tmp = 0; /* Default return condition */ + addr = addr >> 2; /* temporary hack. */ + if (addr < 10) + tmp = get_reg(child, addr); + else { + ret = -EIO; + break ; + } + put_user(tmp,(unsigned long *) data); + ret = 0; + break ; + } + + /* when I and D space are separate, this will have to be fixed. */ + case PTRACE_POKETEXT: /* write the word at location addr. */ + case PTRACE_POKEDATA: + ret = 0; + if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data)) + break; + ret = -EIO; + break; + + case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ + if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) { + ret = -EIO; + break ; + } + addr = addr >> 2; /* temporary hack. */ + + if (addr == PT_ORIG_ER0) { + ret = -EIO; + break ; + } + if (addr == PT_CCR) { + data &= SR_MASK; + } + if (addr < 10) { + if (put_reg(child, addr, data)) + ret = -EIO; + else + ret = 0; + break ; + } + ret = -EIO; + break ; + case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ + case PTRACE_CONT: { /* restart after signal. */ + ret = -EIO; + if ((unsigned long) data >= _NSIG) + break ; + if (request == PTRACE_SYSCALL) + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + else + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + child->exit_code = data; + wake_up_process(child); + /* make sure the single step bit is not set. */ + ptrace_cancel_bpt(child); + ret = 0; + } + +/* + * make the child exit. Best I can do is send it a sigkill. + * perhaps it should be put in the status that it wants to + * exit. + */ + case PTRACE_KILL: { + + ret = 0; + if (child->state == TASK_ZOMBIE) /* already dead */ + break; + child->exit_code = SIGKILL; + ptrace_cancel_bpt(child); + wake_up_process(child); + break; + } + + case PTRACE_SINGLESTEP: { /* set the trap flag. */ + ret = -EIO; + if ((unsigned long) data > _NSIG) + break; + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + child->thread.debugreg[0]=-1; + child->exit_code = data; + wake_up_process(child); + ret = 0; + break; + } + + case PTRACE_DETACH: /* detach a process that was attached. */ + ret = ptrace_detach(child, data); + break; + + case PTRACE_GETREGS: { /* Get all gp regs from the child. */ + int i; + unsigned long tmp; + for (i = 0; i < 19; i++) { + tmp = get_reg(child, i); + if (put_user(tmp, (unsigned long *) data)) { + ret = -EFAULT; + break; + } + data += sizeof(long); + } + ret = 0; + break; + } + + case PTRACE_SETREGS: { /* Set all gp regs in the child. */ + int i; + unsigned long tmp; + for (i = 0; i < 10; i++) { + if (get_user(tmp, (unsigned long *) data)) { + ret = -EFAULT; + break; + } + put_reg(child, i, tmp); + data += sizeof(long); + } + ret = 0; + break; + } + + default: + ret = -EIO; + break; + } +out_tsk: + put_task_struct(child); +out: + unlock_kernel(); + return ret; +} + +asmlinkage void syscall_trace(void) +{ + if (!test_thread_flag(TIF_SYSCALL_TRACE)) + return; + if (!(current->ptrace & PT_PTRACED)) + return; + current->exit_code = SIGTRAP; + current->state = TASK_STOPPED; + notify_parent(current, SIGCHLD); + schedule(); + /* + * this isn't the same as continuing with a signal, but it will do + * for normal use. strace only continues with a signal if the + * stopping signal is not SIGTRAP. -brl + */ + if (current->exit_code) { + send_sig(current->exit_code, current, 1); + current->exit_code = 0; + } +} + +asmlinkage void trace_trap(unsigned long bp) +{ + if (current->thread.debugreg[0] == bp || + current->thread.debugreg[1] == bp) { + ptrace_cancel_bpt(current); + force_sig(SIGTRAP,current); + } else + force_sig(SIGILL,current); +} diff --git a/arch/h8300/kernel/semaphore.c b/arch/h8300/kernel/semaphore.c new file mode 100644 index 0000000000000..690efce1e4375 --- /dev/null +++ b/arch/h8300/kernel/semaphore.c @@ -0,0 +1,132 @@ +/* + * Generic semaphore code. Buyer beware. Do your own + * specific changes in + */ + +#include +#include +#include + +#ifndef CONFIG_RMW_INSNS +spinlock_t semaphore_wake_lock; +#endif + +/* + * Semaphores are implemented using a two-way counter: + * The "count" variable is decremented for each process + * that tries to sleep, while the "waking" variable is + * incremented when the "up()" code goes to wake up waiting + * processes. + * + * Notably, the inline "up()" and "down()" functions can + * efficiently test if they need to do any extra work (up + * needs to do something only if count was negative before + * the increment operation. + * + * waking_non_zero() (from asm/semaphore.h) must execute + * atomically. + * + * When __up() is called, the count was negative before + * incrementing it, and we need to wake up somebody. + * + * This routine adds one to the count of processes that need to + * wake up and exit. ALL waiting processes actually wake up but + * only the one that gets to the "waking" field first will gate + * through and acquire the semaphore. The others will go back + * to sleep. + * + * Note that these functions are only called when there is + * contention on the lock, and as such all this is the + * "non-critical" part of the whole semaphore business. The + * critical part is the inline stuff in + * where we want to avoid any extra jumps and calls. + */ +void __up(struct semaphore *sem) +{ + wake_one_more(sem); + wake_up(&sem->wait); +} + +/* + * Perform the "down" function. Return zero for semaphore acquired, + * return negative for signalled out of the function. + * + * If called from __down, the return is ignored and the wait loop is + * not interruptible. This means that a task waiting on a semaphore + * using "down()" cannot be killed until someone does an "up()" on + * the semaphore. + * + * If called from __down_interruptible, the return value gets checked + * upon return. If the return value is negative then the task continues + * with the negative value in the return register (it can be tested by + * the caller). + * + * Either form may be used in conjunction with "up()". + * + */ + + +#define DOWN_HEAD(task_state) \ + \ + \ + current->state = (task_state); \ + add_wait_queue(&sem->wait, &wait); \ + \ + /* \ + * Ok, we're set up. sem->count is known to be less than zero \ + * so we must wait. \ + * \ + * We can let go the lock for purposes of waiting. \ + * We re-acquire it after awaking so as to protect \ + * all semaphore operations. \ + * \ + * If "up()" is called before we call waking_non_zero() then \ + * we will catch it right away. If it is called later then \ + * we will have to go through a wakeup cycle to catch it. \ + * \ + * Multiple waiters contend for the semaphore lock to see \ + * who gets to gate through and who has to wait some more. \ + */ \ + for (;;) { + +#define DOWN_TAIL(task_state) \ + current->state = (task_state); \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&sem->wait, &wait); + +void __down(struct semaphore * sem) +{ + DECLARE_WAITQUEUE(wait, current); + + DOWN_HEAD(TASK_UNINTERRUPTIBLE) + if (waking_non_zero(sem)) + break; + schedule(); + DOWN_TAIL(TASK_UNINTERRUPTIBLE) +} + +int __down_interruptible(struct semaphore * sem) +{ + DECLARE_WAITQUEUE(wait, current); + int ret = 0; + + DOWN_HEAD(TASK_INTERRUPTIBLE) + + ret = waking_non_zero_interruptible(sem, current); + if (ret) + { + if (ret == 1) + /* ret != 0 only if we get interrupted -arca */ + ret = 0; + break; + } + schedule(); + DOWN_TAIL(TASK_INTERRUPTIBLE) + return ret; +} + +int __down_trylock(struct semaphore * sem) +{ + return waking_non_zero_trylock(sem); +} diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c new file mode 100644 index 0000000000000..645db050d95c7 --- /dev/null +++ b/arch/h8300/kernel/setup.c @@ -0,0 +1,231 @@ +/* + * linux/arch/h8300h/kernel/setup.c + * + * Copyleft ()) 2000 James D. Schettine {james@telos-systems.com} + * Copyright (C) 1999,2000 Greg Ungerer (gerg@snapgear.com) + * Copyright (C) 1998,1999 D. Jeff Dionne + * Copyright (C) 1998 Kenneth Albanowski + * Copyright (C) 1995 Hamish Macdonald + * Copyright (C) 2000 Lineo Inc. (www.lineo.com) + * Copyright (C) 2001 Lineo, Inc. + * + * H8/300H porting Yoshinori Sato + */ + +/* + * This file handles the architecture-dependent parts of system setup + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_BLK_DEV_INITRD +#include +#include +#endif + +#if defined(CONFIG_CPU_H8300H) +#define CPU "H8/300H" +#endif + +unsigned long rom_length; +unsigned long memory_start; +unsigned long memory_end; + +struct task_struct *_current_task; + +char command_line[512]; +char saved_command_line[512]; + +extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end; +extern int _ramstart, _ramend; +extern char _target_name[]; + +#if defined(CONFIG_H8300H_SIM) && defined(CONFIG_GDB_MAGICPRINT) +/* printk with gdb service */ +static void gdb_console_output(struct console *c, char *msg, unsigned len) +{ + for (; len > 0; len--) { + asm("mov.w %0,r2\n\t" + "jsr @0xc4"::"r"(*msg++):"er2"); + } +} + +/* + * Setup initial baud/bits/parity. We do two things here: + * - construct a cflag setting for the first rs_open() + * - initialize the serial port + * Return non-zero if we didn't find a serial port. + */ +static int __init gdb_console_setup(struct console *co, char *options) +{ + return 0; +} + +static const struct console gdb_console = { + name: "gdb", + write: gdb_console_output, + device: NULL, + setup: gdb_console_setup, + flags: CON_PRINTBUFFER, + index: -1, +}; +#endif + +void setup_arch(char **cmdline_p) +{ + int bootmap_size; + + memory_start = PAGE_ALIGN((unsigned long)(&_ramstart)); + memory_end = &_ramend; /* by now the stack is part of the init task */ + + init_mm.start_code = (unsigned long) &_stext; + init_mm.end_code = (unsigned long) &_etext; + init_mm.end_data = (unsigned long) &_edata; + init_mm.brk = (unsigned long) 0; + +#if defined(CONFIG_H8300H_SIM) && defined(CONFIG_GDB_MAGICPRINT) + register_console(&gdb_console); +#endif + + printk("\x0F\r\n\nuClinux " CPU "\n"); + printk("Target Hardware: %s\n",_target_name); + printk("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n"); + printk("H8/300H support by Yoshinori Sato \n"); + +#ifdef DEBUG + printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x " + "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext, + (int) &_sdata, (int) &_edata, + (int) &_sbss, (int) &_ebss); + printk("KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x " + "STACK=0x%06x-0x%06x\n", + (int) &_ebss, (int) memory_start, + (int) memory_start, (int) memory_end, + (int) memory_end, (int) &_ramend); +#endif + +#ifdef CONFIG_BLK_DEV_BLKMEM + ROOT_DEV = MKDEV(BLKMEM_MAJOR,0); +#endif + +#ifdef CONFIG_DEFAULT_CMDLINE + /* set from default command line */ + if (*command_line == '\0') + strcpy(command_line,CONFIG_KERNEL_COMMAND); +#endif + /* Keep a copy of command line */ + *cmdline_p = &command_line[0]; + memcpy(saved_command_line, command_line, sizeof(saved_command_line)); + saved_command_line[sizeof(saved_command_line)-1] = 0; + +#ifdef DEBUG + if (strlen(*cmdline_p)) + printk("Command line: '%s'\n", *cmdline_p); +#endif + + /* + * give all the memory to the bootmap allocator, tell it to put the + * boot mem_map at the start of memory + */ + bootmap_size = init_bootmem_node( + NODE_DATA(0), + memory_start >> PAGE_SHIFT, /* map goes here */ + PAGE_OFFSET >> PAGE_SHIFT, /* 0 on coldfire */ + memory_end >> PAGE_SHIFT); + /* + * free the usable memory, we have to make sure we do not free + * the bootmem bitmap so we then reserve it after freeing it :-) + */ + free_bootmem(memory_start, memory_end - memory_start); + reserve_bootmem(memory_start, bootmap_size); + /* + * get kmalloc into gear + */ + paging_init(); +#ifdef DEBUG + printk("Done setup_arch\n"); +#endif +} + +int get_cpuinfo(char * buffer) +{ + char *cpu; + u_long clockfreq; + + cpu = CPU; + + clockfreq = CONFIG_CPU_CLOCK; + + return(sprintf(buffer, "CPU:\t\t%s\n" + "Clock:\t%lu.%1luMHz\n" + "BogoMips:\t%lu.%02lu\n" + "Calibration:\t%lu loops\n", + cpu, + clockfreq/100,clockfreq%100, + (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100, + (loops_per_jiffy*HZ))); + +} + +/* + * Get CPU information for use by the procfs. + */ + +static int show_cpuinfo(struct seq_file *m, void *v) +{ + char *cpu; + u_long clockfreq; + + cpu = CPU; + + clockfreq = CONFIG_CPU_CLOCK; + + seq_printf(m, "CPU:\t\t%s\n" + "Clock:\t%lu.%1luMHz\n" + "BogoMips:\t%lu.%02lu\n" + "Calibration:\t%lu loops\n", + cpu, + clockfreq/100,clockfreq%100, + (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100, + (loops_per_jiffy*HZ)); + + return 0; +} + +static void *c_start(struct seq_file *m, loff_t *pos) +{ + return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL; +} + +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return c_start(m, pos); +} + +static void c_stop(struct seq_file *m, void *v) +{ +} + +struct seq_operations cpuinfo_op = { + start: c_start, + next: c_next, + stop: c_stop, + show: show_cpuinfo, +}; diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c new file mode 100644 index 0000000000000..3b7eee748e62d --- /dev/null +++ b/arch/h8300/kernel/signal.c @@ -0,0 +1,642 @@ +/* + * linux/arch/h8300/kernel/signal.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +/* + * uClinux H8/300 support by Yoshinori Sato + * + * Based on + * Linux/m68k by Hamish Macdonald + */ + +/* + * ++roman (07/09/96): implemented signal stacks (specially for tosemu on + * Atari :-) Current limitation: Only one sigstack can be active at one time. + * If a second signal with SA_ONSTACK set arrives while working on a sigstack, + * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested + * signal handlers! + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + +asmlinkage long sys_wait4(pid_t pid, unsigned int * stat_addr, int options, + struct rusage * ru); +asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); + +/* + * Atomically swap in the new signal mask, and wait for a signal. + */ +asmlinkage int do_sigsuspend(struct pt_regs *regs) +{ + old_sigset_t mask = regs->er3; + sigset_t saveset; + + mask &= _BLOCKABLE; + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + regs->er0 = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(&saveset, regs)) + return -EINTR; + } +} + +asmlinkage int +do_rt_sigsuspend(struct pt_regs *regs) +{ + sigset_t *unewset = (sigset_t *)regs->er1; + size_t sigsetsize = (size_t)regs->er2; + sigset_t saveset, newset; + + /* XXX: Don't preclude handling different sized sigset_t's. */ + if (sigsetsize != sizeof(sigset_t)) + return -EINVAL; + + if (copy_from_user(&newset, unewset, sizeof(newset))) + return -EFAULT; + sigdelsetmask(&newset, ~_BLOCKABLE); + + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + regs->er0 = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(&saveset, regs)) + return -EINTR; + } +} + +asmlinkage int +sys_sigaction(int sig, const struct old_sigaction *act, + struct old_sigaction *oact) +{ + struct k_sigaction new_ka, old_ka; + int ret; + + if (act) { + old_sigset_t mask; + if (verify_area(VERIFY_READ, act, sizeof(*act)) || + __get_user(new_ka.sa.sa_handler, &act->sa_handler) || + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) + return -EFAULT; + __get_user(new_ka.sa.sa_flags, &act->sa_flags); + __get_user(mask, &act->sa_mask); + siginitset(&new_ka.sa.sa_mask, mask); + } + + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + + if (!ret && oact) { + if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) + return -EFAULT; + __put_user(old_ka.sa.sa_flags, &oact->sa_flags); + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); + } + + return ret; +} + +asmlinkage int +sys_sigaltstack(const stack_t *uss, stack_t *uoss) +{ + return do_sigaltstack(uss, uoss, rdusp()); +} + + +/* + * Do a signal return; undo the signal stack. + * + * Keep the return code on the stack quadword aligned! + * That makes the cache flush below easier. + */ + +struct sigframe +{ + char *pretcode; + int sig; + int code; + struct sigcontext *psc; + char retcode[6]; + unsigned long extramask[_NSIG_WORDS-1]; + struct sigcontext sc; +}; + +struct rt_sigframe +{ + char *pretcode; + int sig; + struct siginfo *pinfo; + void *puc; + char retcode[6]; + struct siginfo info; + struct ucontext uc; +}; + + +static inline int +restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp, + int *pd0) +{ + struct sigcontext context; + int err = 0; + + /* get previous context */ + if (copy_from_user(&context, usc, sizeof(context))) + goto badframe; + + /* restore passed registers */ + regs->er1 = context.sc_er1; + regs->er2 = context.sc_er2; + regs->er3 = context.sc_er3; + regs->ccr = (regs->ccr & 0x10)|(context.sc_ccr & 0xef); + regs->pc = context.sc_pc; + regs->orig_er0 = -1; /* disable syscall checks */ + wrusp(context.sc_usp); + + *pd0 = context.sc_er0; + return err; + +badframe: + return 1; +} + +static inline int +rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, + struct ucontext *uc, int *pd0) +{ + int temp; + greg_t *gregs = uc->uc_mcontext.gregs; + unsigned long usp; + int err; + + err = __get_user(temp, &uc->uc_mcontext.version); + if (temp != MCONTEXT_VERSION) + goto badframe; + /* restore passed registers */ + err |= __get_user(regs->er0, &gregs[0]); + err |= __get_user(regs->er1, &gregs[1]); + err |= __get_user(regs->er2, &gregs[2]); + err |= __get_user(regs->er3, &gregs[3]); + err |= __get_user(sw->er4, &gregs[4]); + err |= __get_user(sw->er5, &gregs[5]); + err |= __get_user(sw->er6, &gregs[6]); + err |= __get_user(usp, &gregs[7]); + wrusp(usp); + err |= __get_user(regs->pc, &gregs[8]); + err |= __get_user(temp, &gregs[9]); + regs->ccr = (regs->ccr & 0x10) | (temp & 0xef); + regs->orig_er0 = -1; /* disable syscall checks */ + + if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) + goto badframe; + + *pd0 = regs->er0; + return err; + +badframe: + return 1; +} + +asmlinkage int do_sigreturn(unsigned long __unused,...) +{ + struct switch_stack *sw = (struct switch_stack *) &__unused; + struct pt_regs *regs = (struct pt_regs *) (sw + 1); + unsigned long usp = rdusp(); + struct sigframe *frame = (struct sigframe *)(usp - 4); + sigset_t set; + int er0; + + if (verify_area(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__get_user(set.sig[0], &frame->sc.sc_mask) || + (_NSIG_WORDS > 1 && + __copy_from_user(&set.sig[1], &frame->extramask, + sizeof(frame->extramask)))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + if (restore_sigcontext(regs, &frame->sc, frame + 1, &er0)) + goto badframe; + return er0; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +asmlinkage int do_rt_sigreturn(unsigned long __unused,...) +{ + struct switch_stack *sw = (struct switch_stack *) &__unused; + struct pt_regs *regs = (struct pt_regs *) (sw + 1); + unsigned long usp = rdusp(); + struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4); + sigset_t set; + int er0; + + if (verify_area(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_unlock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_lock_irq(¤t->sighand->siglock); + + if (rt_restore_ucontext(regs, sw, &frame->uc, &er0)) + goto badframe; + return er0; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, + unsigned long mask) +{ + sc->sc_mask = mask; + sc->sc_usp = rdusp(); + sc->sc_er0 = regs->er0; + sc->sc_er1 = regs->er1; + sc->sc_er2 = regs->er2; + sc->sc_er3 = regs->er3; + sc->sc_ccr = regs->ccr; + sc->sc_pc = regs->pc; +} + +static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs) +{ + struct switch_stack *sw = (struct switch_stack *)regs - 1; + greg_t *gregs = uc->uc_mcontext.gregs; + int err = 0; + + err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); + err |= __put_user(regs->er0, &gregs[0]); + err |= __put_user(regs->er1, &gregs[1]); + err |= __put_user(regs->er2, &gregs[2]); + err |= __put_user(regs->er3, &gregs[3]); + err |= __put_user(sw->er4, &gregs[4]); + err |= __put_user(sw->er5, &gregs[5]); + err |= __put_user(sw->er6, &gregs[6]); + err |= __put_user(rdusp(), &gregs[7]); + err |= __put_user(regs->pc, &gregs[8]); + err |= __put_user(regs->ccr, &gregs[9]); + return err; +} + +static inline void * +get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) +{ + unsigned long usp; + + /* Default to using normal stack. */ + usp = rdusp(); + + /* This is the X/Open sanctioned signal stack switching. */ + if (ka->sa.sa_flags & SA_ONSTACK) { + if (!on_sig_stack(usp)) + usp = current->sas_ss_sp + current->sas_ss_size; + } + return (void *)((usp - frame_size) & -8UL); +} + +static void setup_frame (int sig, struct k_sigaction *ka, + sigset_t *set, struct pt_regs *regs) +{ + struct sigframe *frame; + struct sigcontext context; + int err = 0; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + + err |= __put_user((current_thread_info()->exec_domain + && current_thread_info()->exec_domain->signal_invmap + && sig < 32 + ? current_thread_info()->exec_domain->signal_invmap[sig] + : sig), + &frame->sig); + + err |= __put_user(&frame->sc, &frame->psc); + + if (_NSIG_WORDS > 1) + err |= copy_to_user(frame->extramask, &set->sig[1], + sizeof(frame->extramask)); + + setup_sigcontext(&context, regs, set->sig[0]); + err |= copy_to_user (&frame->sc, &context, sizeof(context)); + + /* Set up to return from userspace. */ + err |= __put_user(frame->retcode, &frame->pretcode); + + /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */ + err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff), + (long *)(frame->retcode + 0)); + err |= __put_user(0x5700, (short *)(frame->retcode + 4)); + + + if (err) + goto give_sigsegv; + + /* Set up registers for signal handler */ + wrusp ((unsigned long) frame); + regs->pc = (unsigned long) ka->sa.sa_handler; + + return; + +give_sigsegv: + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); +} + +static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *set, struct pt_regs *regs) +{ + struct rt_sigframe *frame; + int err = 0; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + + err |= __put_user((current_thread_info()->exec_domain + && current_thread_info()->exec_domain->signal_invmap + && sig < 32 + ? current_thread_info()->exec_domain->signal_invmap[sig] + : sig), + &frame->sig); + err |= __put_user(&frame->info, &frame->pinfo); + err |= __put_user(&frame->uc, &frame->puc); + err |= copy_siginfo_to_user(&frame->info, info); + + /* Create the ucontext. */ + err |= __put_user(0, &frame->uc.uc_flags); + err |= __put_user(0, &frame->uc.uc_link); + err |= __put_user((void *)current->sas_ss_sp, + &frame->uc.uc_stack.ss_sp); + err |= __put_user(sas_ss_flags(rdusp()), + &frame->uc.uc_stack.ss_flags); + err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |= rt_setup_ucontext(&frame->uc, regs); + err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); + + /* Set up to return from userspace. */ + err |= __put_user(frame->retcode, &frame->pretcode); + + /* moveq #,d0; notb d0; movea.l #,a5; trap #0 */ + /* sub.l er0,er0; mov.b #__NR_rt_sigreturn,r0l; trapa #0 */ + err != __put_user(0x1a80f800 + (__NR_rt_sigreturn & 0xff), + (long *)(frame->retcode + 0)); + err |= __put_user(0x5700, (short *)(frame->retcode + 4)); + + if (err) + goto give_sigsegv; + + /* Set up registers for signal handler */ + wrusp ((unsigned long) frame); + regs->pc = (unsigned long) ka->sa.sa_handler; + + return; + +give_sigsegv: + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); +} + +static inline void +handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) +{ + switch (regs->er0) { + case -ERESTARTNOHAND: + if (!has_handler) + goto do_restart; + regs->er0 = -EINTR; + break; + + case -ERESTARTSYS: + if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { + regs->er0 = -EINTR; + break; + } + /* fallthrough */ + case -ERESTARTNOINTR: + do_restart: + regs->er0 = regs->orig_er0; + regs->pc -= 2; + break; + } +} + +/* + * OK, we're invoking a handler + */ +static void +handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *oldset, struct pt_regs *regs) +{ + /* are we from a system call? */ + if (regs->orig_er0 >= 0) + /* If so, check system call restarting.. */ + handle_restart(regs, ka, 1); + + /* set up the stack frame */ + if (ka->sa.sa_flags & SA_SIGINFO) + setup_rt_frame(sig, ka, info, oldset, regs); + else + setup_frame(sig, ka, oldset, regs); + + if (ka->sa.sa_flags & SA_ONESHOT) + ka->sa.sa_handler = SIG_DFL; + + if (!(ka->sa.sa_flags & SA_NODEFER)) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + sigaddset(¤t->blocked,sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } +} + +/* + * Note that 'init' is a special process: it doesn't get signals it doesn't + * want to handle. Thus you cannot kill init even with a SIGKILL even by + * mistake. + * + * Note that we go through the signals twice: once to check the signals + * that the kernel can handle, and then we build all the user-level signal + * handling stack-frames in one go after that. + */ +asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) +{ + siginfo_t info; + struct k_sigaction *ka; + + current->thread.esp0 = (unsigned long) regs; + + if (!oldset) + oldset = ¤t->blocked; + + for (;;) { + int signr; + + signr = get_signal_to_deliver(&info, regs, NULL); + + if (!signr) + break; + + if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { + current->exit_code = signr; + current->state = TASK_STOPPED; + + /* Did we come from a system call? */ + if (regs->orig_er0 >= 0) { + /* Restart the system call the same way as + if the process were not traced. */ + struct k_sigaction *ka = + ¤t->sighand->action[signr-1]; + int has_handler = + (ka->sa.sa_handler != SIG_IGN && + ka->sa.sa_handler != SIG_DFL); + handle_restart(regs, ka, has_handler); + } + notify_parent(current, SIGCHLD); + schedule(); + + /* We're back. Did the debugger cancel the sig? */ + if (!(signr = current->exit_code)) { + discard_frame: + continue; + } + current->exit_code = 0; + + /* The debugger continued. Ignore SIGSTOP. */ + if (signr == SIGSTOP) + goto discard_frame; + + /* Update the siginfo structure. Is this good? */ + if (signr != info.si_signo) { + info.si_signo = signr; + info.si_errno = 0; + info.si_code = SI_USER; + info.si_pid = current->parent->pid; + info.si_uid = current->parent->uid; + } + + /* If the (new) signal is now blocked, requeue it. */ + if (sigismember(¤t->blocked, signr)) { + send_sig_info(signr, &info, current); + continue; + } + } + + ka = ¤t->sighand->action[signr-1]; + if (ka->sa.sa_handler == SIG_IGN) { + if (signr != SIGCHLD) + continue; + /* Check for SIGCHLD: it's special. */ + while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) + /* nothing */; + continue; + } + + if (ka->sa.sa_handler == SIG_DFL) { + int exit_code = signr; + + if (current->pid == 1) + continue; + + switch (signr) { + case SIGCONT: case SIGCHLD: + case SIGWINCH: case SIGURG: + continue; + + case SIGTSTP: case SIGTTIN: case SIGTTOU: + if (is_orphaned_pgrp(current->pgrp)) + continue; + /* FALLTHRU */ + + case SIGSTOP: { + struct sighand_struct *sig; + current->state = TASK_STOPPED; + current->exit_code = signr; + sig = current->parent->sighand; + if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags +& SA_NOCLDSTOP)) + notify_parent(current, SIGCHLD); + schedule(); + continue; + } + + case SIGQUIT: case SIGILL: case SIGTRAP: + case SIGIOT: case SIGFPE: case SIGSEGV: + case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: + if (do_coredump(signr, exit_code, regs)) + exit_code |= 0x80; + /* FALLTHRU */ + + default: + sigaddset(¤t->pending.signal, signr); + recalc_sigpending(); + current->flags |= PF_SIGNALED; + do_exit(exit_code); + /* NOTREACHED */ + } + } + + /* Whee! Actually deliver the signal. */ + handle_signal(signr, ka, &info, oldset, regs); + return 1; + } + + /* Did we come from a system call? */ + if (regs->orig_er0 >= 0) + /* Restart the system call - no handlers present */ + handle_restart(regs, NULL, 0); + + return 0; +} diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c new file mode 100644 index 0000000000000..7a19a4b2f3686 --- /dev/null +++ b/arch/h8300/kernel/sys_h8300.c @@ -0,0 +1,289 @@ +/* + * linux/arch/h8300/kernel/sys_h8300.c + * + * This file contains various random system calls that + * have a non-standard calling sequence on the H8/300 + * platform. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way unix traditionally does this, though. + */ +asmlinkage int sys_pipe(unsigned long * fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; +} + +/* common code for old and new mmaps */ +static inline long do_mmap2( + unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + int error = -EBADF; + struct file * file = NULL; + + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + if (!(flags & MAP_ANONYMOUS)) { + file = fget(fd); + if (!file) + goto out; + } + + down_write(¤t->mm->mmap_sem); + error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); + + if (file) + fput(file); +out: + return error; +} + +asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + return do_mmap2(addr, len, prot, flags, fd, pgoff); +} + +/* + * Perform the select(nd, in, out, ex, tv) and mmap() system + * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to + * handle more than 4 system call parameters, so these system calls + * used a memory block for parameter passing.. + */ + +struct mmap_arg_struct { + unsigned long addr; + unsigned long len; + unsigned long prot; + unsigned long flags; + unsigned long fd; + unsigned long offset; +}; + +asmlinkage int old_mmap(struct mmap_arg_struct *arg) +{ + struct mmap_arg_struct a; + int error = -EFAULT; + + if (copy_from_user(&a, arg, sizeof(a))) + goto out; + + error = -EINVAL; + if (a.offset & ~PAGE_MASK) + goto out; + + a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + + error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); +out: + return error; +} + +#if 0 /* DAVIDM - do we want this */ +struct mmap_arg_struct64 { + __u32 addr; + __u32 len; + __u32 prot; + __u32 flags; + __u64 offset; /* 64 bits */ + __u32 fd; +}; + +asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg) +{ + int error = -EFAULT; + struct file * file = NULL; + struct mmap_arg_struct64 a; + unsigned long pgoff; + + if (copy_from_user(&a, arg, sizeof(a))) + return -EFAULT; + + if ((long)a.offset & ~PAGE_MASK) + return -EINVAL; + + pgoff = a.offset >> PAGE_SHIFT; + if ((a.offset >> PAGE_SHIFT) != pgoff) + return -EINVAL; + + if (!(a.flags & MAP_ANONYMOUS)) { + error = -EBADF; + file = fget(a.fd); + if (!file) + goto out; + } + a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + + down_write(¤t->mm->mmap_sem); + error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff); + up_write(¤t->mm->mmap_sem); + if (file) + fput(file); +out: + return error; +} +#endif + +extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); + +struct sel_arg_struct { + unsigned long n; + fd_set *inp, *outp, *exp; + struct timeval *tvp; +}; + +asmlinkage int old_select(struct sel_arg_struct *arg) +{ + struct sel_arg_struct a; + + if (copy_from_user(&a, arg, sizeof(a))) + return -EFAULT; + /* sys_select() does the appropriate kernel locking */ + return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); +} + +/* + * sys_ipc() is the de-multiplexer for the SysV IPC calls.. + * + * This is really horribly ugly. + */ +asmlinkage int sys_ipc (uint call, int first, int second, + int third, void *ptr, long fifth) +{ + int version, ret; + + version = call >> 16; /* hack for backward compatibility */ + call &= 0xffff; + + if (call <= SEMCTL) + switch (call) { + case SEMOP: + return sys_semop (first, (struct sembuf *)ptr, second); + case SEMGET: + return sys_semget (first, second, third); + case SEMCTL: { + union semun fourth; + if (!ptr) + return -EINVAL; + if (get_user(fourth.__pad, (void **) ptr)) + return -EFAULT; + return sys_semctl (first, second, third, fourth); + } + default: + return -EINVAL; + } + if (call <= MSGCTL) + switch (call) { + case MSGSND: + return sys_msgsnd (first, (struct msgbuf *) ptr, + second, third); + case MSGRCV: + switch (version) { + case 0: { + struct ipc_kludge tmp; + if (!ptr) + return -EINVAL; + if (copy_from_user (&tmp, + (struct ipc_kludge *)ptr, + sizeof (tmp))) + return -EFAULT; + return sys_msgrcv (first, tmp.msgp, second, + tmp.msgtyp, third); + } + default: + return sys_msgrcv (first, + (struct msgbuf *) ptr, + second, fifth, third); + } + case MSGGET: + return sys_msgget ((key_t) first, second); + case MSGCTL: + return sys_msgctl (first, second, + (struct msqid_ds *) ptr); + default: + return -EINVAL; + } + if (call <= SHMCTL) + switch (call) { + case SHMAT: + switch (version) { + default: { + ulong raddr; + ret = sys_shmat (first, (char *) ptr, + second, &raddr); + if (ret) + return ret; + return put_user (raddr, (ulong *) third); + } + } + case SHMDT: + return sys_shmdt ((char *)ptr); + case SHMGET: + return sys_shmget (first, second, third); + case SHMCTL: + return sys_shmctl (first, second, + (struct shmid_ds *) ptr); + default: + return -EINVAL; + } + + return -EINVAL; +} + +asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on) +{ + return -ENOSYS; +} + +/* sys_cacheflush -- no support. */ +asmlinkage int +sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) +{ + return -EINVAL; +} + +asmlinkage int sys_getpagesize(void) +{ + return PAGE_SIZE; +} + +#if defined(CONFIG_SYSCALL_PRINT) +asmlinkage void syscall_print(void *dummy,...) +{ + struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy); + unsigned long *usp=rdusp()+8; + printk("call %06x:%d 1:%08x,2:%08x,3:%08x,ret:%08x\n", + ((*usp) & 0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0); +} +#endif diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S new file mode 100644 index 0000000000000..1984319503096 --- /dev/null +++ b/arch/h8300/kernel/syscalls.S @@ -0,0 +1,314 @@ +/* Systemcall Entry Table */ +#include +#include +#include +#include + +.globl SYMBOL_NAME(sys_call_table) + +#if defined(CONFIG_CPU_H8300H) + .h8300h +#endif +#if defined(CONFIG_CPU_H8S) + .h8300s +#endif + .section .text + .align 2 +SYMBOL_NAME_LABEL(sys_call_table) + .long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/ + .long SYMBOL_NAME(sys_exit) + .long SYMBOL_NAME(sys_fork) + .long SYMBOL_NAME(sys_read) + .long SYMBOL_NAME(sys_write) + .long SYMBOL_NAME(sys_open) /* 5 */ + .long SYMBOL_NAME(sys_close) + .long SYMBOL_NAME(sys_waitpid) + .long SYMBOL_NAME(sys_creat) + .long SYMBOL_NAME(sys_link) + .long SYMBOL_NAME(sys_unlink) /* 10 */ + .long SYMBOL_NAME(sys_execve) + .long SYMBOL_NAME(sys_chdir) + .long SYMBOL_NAME(sys_time) + .long SYMBOL_NAME(sys_mknod) + .long SYMBOL_NAME(sys_chmod) /* 15 */ + .long SYMBOL_NAME(sys_chown16) + .long SYMBOL_NAME(sys_ni_syscall) /* old break syscall holder */ + .long SYMBOL_NAME(sys_stat) + .long SYMBOL_NAME(sys_lseek) + .long SYMBOL_NAME(sys_getpid) /* 20 */ + .long SYMBOL_NAME(sys_mount) + .long SYMBOL_NAME(sys_oldumount) + .long SYMBOL_NAME(sys_setuid16) + .long SYMBOL_NAME(sys_getuid16) + .long SYMBOL_NAME(sys_stime) /* 25 */ + .long SYMBOL_NAME(sys_ptrace) + .long SYMBOL_NAME(sys_alarm) + .long SYMBOL_NAME(sys_fstat) + .long SYMBOL_NAME(sys_pause) + .long SYMBOL_NAME(sys_utime) /* 30 */ + .long SYMBOL_NAME(sys_ni_syscall) /* old stty syscall holder */ + .long SYMBOL_NAME(sys_ni_syscall) /* old gtty syscall holder */ + .long SYMBOL_NAME(sys_access) + .long SYMBOL_NAME(sys_nice) + .long SYMBOL_NAME(sys_ni_syscall) /* 35 */ /* old ftime syscall holder */ + .long SYMBOL_NAME(sys_sync) + .long SYMBOL_NAME(sys_kill) + .long SYMBOL_NAME(sys_rename) + .long SYMBOL_NAME(sys_mkdir) + .long SYMBOL_NAME(sys_rmdir) /* 40 */ + .long SYMBOL_NAME(sys_dup) + .long SYMBOL_NAME(sys_pipe) + .long SYMBOL_NAME(sys_times) + .long SYMBOL_NAME(sys_ni_syscall) /* old prof syscall holder */ + .long SYMBOL_NAME(sys_brk) /* 45 */ + .long SYMBOL_NAME(sys_setgid16) + .long SYMBOL_NAME(sys_getgid16) + .long SYMBOL_NAME(sys_signal) + .long SYMBOL_NAME(sys_geteuid16) + .long SYMBOL_NAME(sys_getegid16) /* 50 */ + .long SYMBOL_NAME(sys_acct) + .long SYMBOL_NAME(sys_umount) /* recycled never used phys() */ + .long SYMBOL_NAME(sys_ni_syscall) /* old lock syscall holder */ + .long SYMBOL_NAME(sys_ioctl) + .long SYMBOL_NAME(sys_fcntl) /* 55 */ + .long SYMBOL_NAME(sys_ni_syscall) /* old mpx syscall holder */ + .long SYMBOL_NAME(sys_setpgid) + .long SYMBOL_NAME(sys_ni_syscall) /* old ulimit syscall holder */ + .long SYMBOL_NAME(sys_ni_syscall) + .long SYMBOL_NAME(sys_umask) /* 60 */ + .long SYMBOL_NAME(sys_chroot) + .long SYMBOL_NAME(sys_ustat) + .long SYMBOL_NAME(sys_dup2) + .long SYMBOL_NAME(sys_getppid) + .long SYMBOL_NAME(sys_getpgrp) /* 65 */ + .long SYMBOL_NAME(sys_setsid) + .long SYMBOL_NAME(sys_sigaction) + .long SYMBOL_NAME(sys_sgetmask) + .long SYMBOL_NAME(sys_ssetmask) + .long SYMBOL_NAME(sys_setreuid16) /* 70 */ + .long SYMBOL_NAME(sys_setregid16) + .long SYMBOL_NAME(sys_sigsuspend) + .long SYMBOL_NAME(sys_sigpending) + .long SYMBOL_NAME(sys_sethostname) + .long SYMBOL_NAME(sys_setrlimit) /* 75 */ + .long SYMBOL_NAME(sys_old_getrlimit) + .long SYMBOL_NAME(sys_getrusage) + .long SYMBOL_NAME(sys_gettimeofday) + .long SYMBOL_NAME(sys_settimeofday) + .long SYMBOL_NAME(sys_getgroups16) /* 80 */ + .long SYMBOL_NAME(sys_setgroups16) + .long SYMBOL_NAME(old_select) + .long SYMBOL_NAME(sys_symlink) + .long SYMBOL_NAME(sys_lstat) + .long SYMBOL_NAME(sys_readlink) /* 85 */ + .long SYMBOL_NAME(sys_uselib) + .long SYMBOL_NAME(sys_swapon) + .long SYMBOL_NAME(sys_reboot) + .long SYMBOL_NAME(old_readdir) + .long SYMBOL_NAME(old_mmap) /* 90 */ + .long SYMBOL_NAME(sys_munmap) + .long SYMBOL_NAME(sys_truncate) + .long SYMBOL_NAME(sys_ftruncate) + .long SYMBOL_NAME(sys_fchmod) + .long SYMBOL_NAME(sys_fchown16) /* 95 */ + .long SYMBOL_NAME(sys_getpriority) + .long SYMBOL_NAME(sys_setpriority) + .long SYMBOL_NAME(sys_ni_syscall) /* old profil syscall holder */ + .long SYMBOL_NAME(sys_statfs) + .long SYMBOL_NAME(sys_fstatfs) /* 100 */ + .long SYMBOL_NAME(sys_ioperm) + .long SYMBOL_NAME(sys_socketcall) + .long SYMBOL_NAME(sys_syslog) + .long SYMBOL_NAME(sys_setitimer) + .long SYMBOL_NAME(sys_getitimer) /* 105 */ + .long SYMBOL_NAME(sys_newstat) + .long SYMBOL_NAME(sys_newlstat) + .long SYMBOL_NAME(sys_newfstat) + .long SYMBOL_NAME(sys_ni_syscall) + .long SYMBOL_NAME(sys_ni_syscall) /* iopl for i386 */ /* 110 */ + .long SYMBOL_NAME(sys_vhangup) + .long SYMBOL_NAME(sys_ni_syscall) /* obsolete idle() syscall */ + .long SYMBOL_NAME(sys_ni_syscall) /* vm86old for i386 */ + .long SYMBOL_NAME(sys_wait4) + .long SYMBOL_NAME(sys_swapoff) /* 115 */ + .long SYMBOL_NAME(sys_sysinfo) + .long SYMBOL_NAME(sys_ipc) + .long SYMBOL_NAME(sys_fsync) + .long SYMBOL_NAME(sys_sigreturn) + .long SYMBOL_NAME(sys_clone) /* 120 */ + .long SYMBOL_NAME(sys_setdomainname) + .long SYMBOL_NAME(sys_newuname) + .long SYMBOL_NAME(sys_cacheflush) /* modify_ldt for i386 */ + .long SYMBOL_NAME(sys_adjtimex) + .long SYMBOL_NAME(sys_ni_syscall) /* 125 sys_mprotect */ + .long SYMBOL_NAME(sys_sigprocmask) + .long SYMBOL_NAME(sys_ni_syscall) /* sys_create_module */ + .long SYMBOL_NAME(sys_init_module) + .long SYMBOL_NAME(sys_delete_module) + .long SYMBOL_NAME(sys_ni_syscall) /* 130 sys_get_kernel_syms */ + .long SYMBOL_NAME(sys_quotactl) + .long SYMBOL_NAME(sys_getpgid) + .long SYMBOL_NAME(sys_fchdir) + .long SYMBOL_NAME(sys_bdflush) + .long SYMBOL_NAME(sys_sysfs) /* 135 */ + .long SYMBOL_NAME(sys_personality) + .long SYMBOL_NAME(sys_ni_syscall) /* for afs_syscall */ + .long SYMBOL_NAME(sys_setfsuid16) + .long SYMBOL_NAME(sys_setfsgid16) + .long SYMBOL_NAME(sys_llseek) /* 140 */ + .long SYMBOL_NAME(sys_getdents) + .long SYMBOL_NAME(sys_select) + .long SYMBOL_NAME(sys_flock) + .long SYMBOL_NAME(sys_ni_syscall) /* sys_msync */ + .long SYMBOL_NAME(sys_readv) /* 145 */ + .long SYMBOL_NAME(sys_writev) + .long SYMBOL_NAME(sys_getsid) + .long SYMBOL_NAME(sys_fdatasync) + .long SYMBOL_NAME(sys_sysctl) + .long SYMBOL_NAME(sys_ni_syscall) /* 150 sys_mlock */ + .long SYMBOL_NAME(sys_ni_syscall) /* sys_munlock */ + .long SYMBOL_NAME(sys_ni_syscall) /* sys_mlockall */ + .long SYMBOL_NAME(sys_ni_syscall) /* sys_munlockall */ + .long SYMBOL_NAME(sys_sched_setparam) + .long SYMBOL_NAME(sys_sched_getparam) /* 155 */ + .long SYMBOL_NAME(sys_sched_setscheduler) + .long SYMBOL_NAME(sys_sched_getscheduler) + .long SYMBOL_NAME(sys_sched_yield) + .long SYMBOL_NAME(sys_sched_get_priority_max) + .long SYMBOL_NAME(sys_sched_get_priority_min) /* 160 */ + .long SYMBOL_NAME(sys_sched_rr_get_interval) + .long SYMBOL_NAME(sys_nanosleep) + .long SYMBOL_NAME(sys_ni_syscall) /* sys_mremap */ + .long SYMBOL_NAME(sys_setresuid16) + .long SYMBOL_NAME(sys_getresuid16) /* 165 */ + .long SYMBOL_NAME(sys_ni_syscall) /* for vm86 */ + .long SYMBOL_NAME(sys_ni_syscall) /* sys_query_module */ + .long SYMBOL_NAME(sys_poll) + .long SYMBOL_NAME(sys_nfsservctl) + .long SYMBOL_NAME(sys_setresgid16) /* 170 */ + .long SYMBOL_NAME(sys_getresgid16) + .long SYMBOL_NAME(sys_prctl) + .long SYMBOL_NAME(sys_rt_sigreturn) + .long SYMBOL_NAME(sys_rt_sigaction) + .long SYMBOL_NAME(sys_rt_sigprocmask) /* 175 */ + .long SYMBOL_NAME(sys_rt_sigpending) + .long SYMBOL_NAME(sys_rt_sigtimedwait) + .long SYMBOL_NAME(sys_rt_sigqueueinfo) + .long SYMBOL_NAME(sys_rt_sigsuspend) + .long SYMBOL_NAME(sys_pread64) /* 180 */ + .long SYMBOL_NAME(sys_pwrite64) + .long SYMBOL_NAME(sys_lchown16); + .long SYMBOL_NAME(sys_getcwd) + .long SYMBOL_NAME(sys_capget) + .long SYMBOL_NAME(sys_capset) /* 185 */ + .long SYMBOL_NAME(sys_sigaltstack) + .long SYMBOL_NAME(sys_sendfile) + .long SYMBOL_NAME(sys_ni_syscall) /* streams1 */ + .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */ + .long SYMBOL_NAME(sys_vfork) /* 190 */ + .long SYMBOL_NAME(sys_getrlimit) + .long SYMBOL_NAME(sys_mmap2) + .long SYMBOL_NAME(sys_truncate64) + .long SYMBOL_NAME(sys_ftruncate64) + .long SYMBOL_NAME(sys_stat64) /* 195 */ + .long SYMBOL_NAME(sys_lstat64) + .long SYMBOL_NAME(sys_fstat64) + .long SYMBOL_NAME(sys_chown) + .long SYMBOL_NAME(sys_getuid) + .long SYMBOL_NAME(sys_getgid) /* 200 */ + .long SYMBOL_NAME(sys_geteuid) + .long SYMBOL_NAME(sys_getegid) + .long SYMBOL_NAME(sys_setreuid) + .long SYMBOL_NAME(sys_setregid) + .long SYMBOL_NAME(sys_getgroups) /* 205 */ + .long SYMBOL_NAME(sys_setgroups) + .long SYMBOL_NAME(sys_fchown) + .long SYMBOL_NAME(sys_setresuid) + .long SYMBOL_NAME(sys_getresuid) + .long SYMBOL_NAME(sys_setresgid) /* 210 */ + .long SYMBOL_NAME(sys_getresgid) + .long SYMBOL_NAME(sys_lchown) + .long SYMBOL_NAME(sys_setuid) + .long SYMBOL_NAME(sys_setgid) + .long SYMBOL_NAME(sys_setfsuid) /* 215 */ + .long SYMBOL_NAME(sys_setfsgid) + .long SYMBOL_NAME(sys_pivot_root) + .long SYMBOL_NAME(sys_ni_syscall) + .long SYMBOL_NAME(sys_ni_syscall) + .long SYMBOL_NAME(sys_getdents64) /* 220 */ + .long SYMBOL_NAME(sys_fcntl64) + .long SYMBOL_NAME(sys_ni_syscall) /* reserved for TUX */ + .long SYMBOL_NAME(sys_ni_syscall) + .long SYMBOL_NAME(sys_gettid) + .long SYMBOL_NAME(sys_ni_syscall) /* 225 */ /* sys_readahead */ + .long SYMBOL_NAME(sys_setxattr) + .long SYMBOL_NAME(sys_lsetxattr) + .long SYMBOL_NAME(sys_fsetxattr) + .long SYMBOL_NAME(sys_getxattr) + .long SYMBOL_NAME(sys_lgetxattr) /* 230 */ + .long SYMBOL_NAME(sys_fgetxattr) + .long SYMBOL_NAME(sys_listxattr) + .long SYMBOL_NAME(sys_llistxattr) + .long SYMBOL_NAME(sys_flistxattr) + .long SYMBOL_NAME(sys_removexattr) /* 235 */ + .long SYMBOL_NAME(sys_lremovexattr) + .long SYMBOL_NAME(sys_fremovexattr) + .long SYMBOL_NAME(sys_tkill) + .long SYMBOL_NAME(sys_sendfile64) + .long SYMBOL_NAME(sys_futex) /* 240 */ + .long SYMBOL_NAME(sys_sched_setaffinity) + .long SYMBOL_NAME(sys_sched_getaffinity) + .long SYMBOL_NAME(sys_ni_syscall) /* sys_set_thread_area */ + .long SYMBOL_NAME(sys_ni_syscall) /* sys_get_thread_area */ + .long SYMBOL_NAME(sys_io_setup) /* 245 */ + .long SYMBOL_NAME(sys_io_destroy) + .long SYMBOL_NAME(sys_io_getevents) + .long SYMBOL_NAME(sys_io_submit) + .long SYMBOL_NAME(sys_io_cancel) + .long SYMBOL_NAME(sys_ni_syscall) /* 250 */ /* sys_alloc_hugepages */ + .long SYMBOL_NAME(sys_ni_syscall) /* sys_freec_hugepages */ + .long SYMBOL_NAME(sys_exit_group) + .long SYMBOL_NAME(sys_lookup_dcookie) + .long SYMBOL_NAME(sys_epoll_create) + .long SYMBOL_NAME(sys_epoll_ctl) /* 255 */ + .long SYMBOL_NAME(sys_epoll_wait) + .long SYMBOL_NAME(sys_ni_syscall) /* sys_remap_file_pages */ + .long SYMBOL_NAME(sys_set_tid_address) + .long SYMBOL_NAME(sys_timer_create) + .long SYMBOL_NAME(sys_timer_settime) /* 260 */ + .long SYMBOL_NAME(sys_timer_gettime) + .long SYMBOL_NAME(sys_timer_getoverrun) + .long SYMBOL_NAME(sys_timer_delete) + .long SYMBOL_NAME(sys_clock_settime) + .long SYMBOL_NAME(sys_clock_gettime) /* 265 */ + .long SYMBOL_NAME(sys_clock_getres) + .long SYMBOL_NAME(sys_clock_nanosleep) + + .rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4 + .long SYMBOL_NAME(sys_ni_syscall) + .endr + +SYMBOL_NAME_LABEL(sys_clone) + mov.l #SYMBOL_NAME(h8300_clone),er0 + jmp @SYMBOL_NAME(syscall_trampoline) + +SYMBOL_NAME_LABEL(sys_sigsuspend) + mov.l #SYMBOL_NAME(do_sigsuspend),er0 + jmp @SYMBOL_NAME(syscall_trampoline) + +SYMBOL_NAME_LABEL(sys_rt_sigsuspend) + mov.l #SYMBOL_NAME(do_rt_sigsuspend),er0 + jmp @SYMBOL_NAME(syscall_trampoline) + +SYMBOL_NAME_LABEL(sys_sigreturn) + mov.l #SYMBOL_NAME(do_sigreturn),er0 + jmp @SYMBOL_NAME(syscall_trampoline) + +SYMBOL_NAME_LABEL(sys_rt_sigreturn) + mov.l #SYMBOL_NAME(do_rt_sigreturn),er0 + jmp @SYMBOL_NAME(syscall_trampoline) + +SYMBOL_NAME_LABEL(sys_fork) + mov.l #SYMBOL_NAME(h8300_fork),er0 + jmp @SYMBOL_NAME(syscall_trampoline) + diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c new file mode 100644 index 0000000000000..dacf335b1c4c2 --- /dev/null +++ b/arch/h8300/kernel/time.c @@ -0,0 +1,134 @@ +/* + * linux/arch/h8300/kernel/time.c + * + * Yoshinori Sato + * + * Copied/hacked from: + * + * linux/arch/m68k/kernel/time.c + * + * Copyright (C) 1991, 1992, 1995 Linus Torvalds + * + * This file contains the m68k-specific time handling details. + * Most of the stuff is located in the machine specific files. + * + * 1997-09-10 Updated NTP code according to technical memorandum Jan '96 + * "A Kernel Model for Precision Timekeeping" by Dave Mills + */ + +#include /* CONFIG_HEARTBEAT */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define TICK_SIZE (tick_nsec / 1000) + +u64 jiffies_64; + +static inline void do_profile (unsigned long pc) +{ + if (prof_buffer && current->pid) { + extern int _stext; + pc -= (unsigned long) &_stext; + pc >>= prof_shift; + if (pc < prof_len) + ++prof_buffer[pc]; + else + /* + * Don't ignore out-of-bounds PC values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + ++prof_buffer[prof_len-1]; + } +} + +/* + * timer_interrupt() needs to keep up the real-time clock, + * as well as call the "do_timer()" routine every clocktick + */ +static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs) +{ + /* may need to kick the hardware timer */ + platform_timer_eoi(); + + do_timer(regs); + + if (!user_mode(regs)) + do_profile(regs->pc); + +} + +void time_init(void) +{ + unsigned int year, mon, day, hour, min, sec; + + /* FIX by dqg : Set to zero for platforms that don't have tod */ + /* without this time is undefined and can overflow time_t, causing */ + /* very stange errors */ + year = 1980; + mon = day = 1; + hour = min = sec = 0; + platform_gettod (&year, &mon, &day, &hour, &min, &sec); + + if ((year += 1900) < 1970) + year += 100; + xtime.tv_sec = mktime(year, mon, day, hour, min, sec); + xtime.tv_nsec = 0; + + platform_timer_setup(timer_interrupt); +} + +/* + * This version of gettimeofday has near microsecond resolution. + */ +void do_gettimeofday(struct timeval *tv) +{ + unsigned long flags; + unsigned long usec, sec; + + read_lock_irqsave(&xtime_lock, flags); + usec = 0; + sec = xtime.tv_sec; + usec += (xtime.tv_nsec / 1000); + read_unlock_irqrestore(&xtime_lock, flags); + + while (usec >= 1000000) { + usec -= 1000000; + sec++; + } + + tv->tv_sec = sec; + tv->tv_usec = usec; +} + +void do_settimeofday(struct timeval *tv) +{ + write_lock_irq(&xtime_lock); + /* This is revolting. We need to set the xtime.tv_usec + * correctly. However, the value in this location is + * is value at the last tick. + * Discover what correction gettimeofday + * would have done, and then undo it! + */ + while (tv->tv_usec < 0) { + tv->tv_usec += 1000000; + tv->tv_sec--; + } + + xtime.tv_sec = tv->tv_sec; + xtime.tv_nsec = (tv->tv_usec * 1000); + time_adjust = 0; /* stop active adjtime() */ + time_status |= STA_UNSYNC; + time_maxerror = NTP_PHASE_LIMIT; + time_esterror = NTP_PHASE_LIMIT; + write_unlock_irq(&xtime_lock); +} diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c new file mode 100644 index 0000000000000..ae281c8eb1d03 --- /dev/null +++ b/arch/h8300/kernel/traps.c @@ -0,0 +1,124 @@ +/* + * linux/arch/h8300/boot/traps.c -- general exception handling code + * H8/300 support Yoshinori Sato + * + * Cloned from Linux/m68k. + * + * No original Copyright holder listed, + * Probabily original (C) Roman Zippel (assigned DJD, 1999) + * + * Copyright 1999-2000 D. Jeff Dionne, + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * this must be called very early as the kernel might + * use some instruction that are emulated on the 060 + */ + +void __init base_trap_init(void) +{ +} + +void __init trap_init (void) +{ +} + +asmlinkage void set_esp0 (unsigned long ssp) +{ + current->thread.esp0 = ssp; +} + +/* + * Generic dumping code. Used for panic and debug. + */ + +static void dump(struct pt_regs *fp) +{ + unsigned long *sp; + unsigned char *tp; + int i; + + printk("\nCURRENT PROCESS:\n\n"); +#if 0 +{ + extern int swt_lastjiffies, swt_reference; + printk("WATCHDOG: jiffies=%d lastjiffies=%d [%d] reference=%d\n", + jiffies, swt_lastjiffies, (swt_lastjiffies - jiffies), + swt_reference); +} +#endif + printk("COMM=%s PID=%d\n", current->comm, current->pid); + if (current->mm) { + printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n", + (int) current->mm->start_code, + (int) current->mm->end_code, + (int) current->mm->start_data, + (int) current->mm->end_data, + (int) current->mm->end_data, + (int) current->mm->brk); + printk("USER-STACK=%08x KERNEL-STACK=%08x\n\n", + (int) current->mm->start_stack, + (int) PAGE_SIZE+(unsigned long)current); + } + + printk("PC: %08lx\n", (long)fp->pc); + printk("CCR: %08lx SP: %08lx\n", fp->ccr, (long) fp); + printk("ER0: %08lx ER1: %08lx ER2: %08lx ER3: %08lx\n", + fp->er0, fp->er1, fp->er2, fp->er3); + printk("\nCODE:"); + tp = ((unsigned char *) fp->pc) - 0x20; + for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) { + if ((i % 0x10) == 0) + printk("\n%08x: ", (int) (tp + i)); + printk("%08x ", (int) *sp++); + } + printk("\n"); + + printk("\nKERNEL STACK:"); + tp = ((unsigned char *) fp) - 0x40; + for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) { + if ((i % 0x10) == 0) + printk("\n%08x: ", (int) (tp + i)); + printk("%08x ", (int) *sp++); + } + printk("\n"); + if (STACK_MAGIC != *(unsigned long *)((unsigned long)current+PAGE_SIZE)) + printk("(Possibly corrupted stack page??)\n"); + + printk("\n\n"); +} + +void show_trace_task(struct task_struct *tsk) +{ + /* DAVIDM: we can do better, need a proper stack dump */ + printk("STACK ksp=0x%lx, usp=0x%lx\n", tsk->thread.ksp, tsk->thread.usp); +} + +void die_if_kernel (char *str, struct pt_regs *fp, int nr) +{ + extern int console_loglevel; + + if (!(fp->ccr & PS_S)) + return; + + console_loglevel = 15; + dump(fp); + + do_exit(SIGSEGV); +} diff --git a/arch/h8300/lib/Makefile b/arch/h8300/lib/Makefile new file mode 100644 index 0000000000000..304fd7e1c6c81 --- /dev/null +++ b/arch/h8300/lib/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for H8/300-specific library files.. +# + +.S.o: + $(CC) $(AFLAGS) -D__ASSEMBLY__ -c $< -o $@ + +L_TARGET = lib.a +obj-y = ashrdi3.o checksum.o memcpy.o memset.o abs.o diff --git a/arch/h8300/lib/abs.S b/arch/h8300/lib/abs.S new file mode 100644 index 0000000000000..76ea851141887 --- /dev/null +++ b/arch/h8300/lib/abs.S @@ -0,0 +1,21 @@ +;;; memcpy.S + +#include + +#if defined(__H8300H__) + .h8300h +#endif +#if defined(__H8300S__) + .h8300s +#endif + .text +.global SYMBOL_NAME(abs) + +;;; int abs(int n) +SYMBOL_NAME_LABEL(abs) + mov.l er0,er0 + bpl 1f + neg.l er0 +1: + rts + diff --git a/arch/h8300/lib/ashrdi3.c b/arch/h8300/lib/ashrdi3.c new file mode 100644 index 0000000000000..78efb65e315a9 --- /dev/null +++ b/arch/h8300/lib/ashrdi3.c @@ -0,0 +1,63 @@ +/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */ +/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#define BITS_PER_UNIT 8 + +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int word_type __attribute__ ((mode (__word__))); + +struct DIstruct {SItype high, low;}; + +typedef union +{ + struct DIstruct s; + DItype ll; +} DIunion; + +DItype +__ashrdi3 (DItype u, word_type b) +{ + DIunion w; + word_type bm; + DIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (SItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + /* w.s.high = 1..1 or 0..0 */ + w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1); + w.s.low = uu.s.high >> -bm; + } + else + { + USItype carries = (USItype)uu.s.high << bm; + w.s.high = uu.s.high >> b; + w.s.low = ((USItype)uu.s.low >> b) | carries; + } + + return w.ll; +} diff --git a/arch/h8300/lib/checksum.c b/arch/h8300/lib/checksum.c new file mode 100644 index 0000000000000..6ea20ed7d3846 --- /dev/null +++ b/arch/h8300/lib/checksum.c @@ -0,0 +1,156 @@ +/* + * 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, + * Arnt Gulbrandsen, + * Tom May, + * Andreas Schwab, + * 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 + +static inline unsigned short from32to16(unsigned long x) +{ + /* add up 16-bit and 16-bit for 16+c bit */ + x = (x & 0xffff) + (x >> 16); + /* add up carry.. */ + x = (x & 0xffff) + (x >> 16); + return x; +} + +static unsigned long do_csum(const unsigned char * buff, int len) +{ + int odd, count; + unsigned long result = 0; + + if (len <= 0) + goto out; + odd = 1 & (unsigned long) buff; + if (odd) { + result = *buff; + len--; + buff++; + } + count = len >> 1; /* nr of 16-bit words.. */ + if (count) { + if (2 & (unsigned long) buff) { + result += *(unsigned short *) buff; + count--; + len -= 2; + buff += 2; + } + count >>= 1; /* nr of 32-bit words.. */ + if (count) { + unsigned long carry = 0; + do { + unsigned long w = *(unsigned long *) buff; + count--; + buff += 4; + result += carry; + result += w; + carry = (w > result); + } while (count); + result += carry; + result = (result & 0xffff) + (result >> 16); + } + if (len & 2) { + result += *(unsigned short *) buff; + buff += 2; + } + } + if (len & 1) + result += (*buff << 8); + result = from32to16(result); + if (odd) + result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); +out: + return result; +} + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + */ +unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl) +{ + return ~do_csum(iph,ihl*4); +} + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) +{ + unsigned int result = do_csum(buff, len); + + /* add in old sum, and carry.. */ + result += sum; + /* 16+c bits -> 16 bits */ + result = (result & 0xffff) + (result >> 16); + return result; +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ +unsigned short ip_compute_csum(const unsigned char * buff, int len) +{ + return ~do_csum(buff,len); +} + +/* + * copy from fs while checksumming, otherwise like csum_partial + */ + +unsigned int +csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err) +{ + if (csum_err) *csum_err = 0; + memcpy(dst, src, len); + return csum_partial(dst, len, sum); +} + +/* + * copy from ds while checksumming, otherwise like csum_partial + */ + +unsigned int +csum_partial_copy(const char *src, char *dst, int len, int sum) +{ + memcpy(dst, src, len); + return csum_partial(dst, len, sum); +} diff --git a/arch/h8300/lib/memcpy.S b/arch/h8300/lib/memcpy.S new file mode 100644 index 0000000000000..fdcbc1ee673c9 --- /dev/null +++ b/arch/h8300/lib/memcpy.S @@ -0,0 +1,84 @@ +;;; memcpy.S + +#include + +#if defined(__H8300H__) + .h8300h +#endif +#if defined(__H8300S__) + .h8300s +#endif + + .text +.global SYMBOL_NAME(memcpy) + +;;; void *memcpy(void *to, void *from, size_t n) +SYMBOL_NAME_LABEL(memcpy) + mov.l er2,er2 + bne 1f + rts +1: + ;; address check + bld #0,r0l + bxor #0,r1l + bcs 4f + mov.l er4,@-sp + mov.l er0,@-sp + btst #0,r0l + beq 1f + ;; (aligned even) odd address + mov.b @er1,r3l + mov.b r3l,@er0 + adds #1,er1 + adds #1,er0 + dec.l #1,er2 + beq 3f +1: + ;; n < sizeof(unsigned long) check + sub.l er4,er4 + adds #4,er4 ; loop count check value + cmp.l er4,er2 + blo 2f + ;; unsigned long copy +1: + mov.l @er1,er3 + mov.l er3,@er0 + adds #4,er0 + adds #4,er1 + subs #4,er2 + cmp.l er4,er2 + bcc 1b + ;; rest +2: + mov.l er2,er2 + beq 3f +1: + mov.b @er1,r3l + mov.b r3l,@er0 + adds #1,er1 + adds #1,er0 + dec.l #1,er2 + bne 1b +3: + mov.l @sp+,er0 + mov.l @sp+,er4 + rts + + ;; odd <- even / even <- odd +4: + mov.l er4,er3 + mov.l er2,er4 + mov.l er5,er2 + mov.l er1,er5 + mov.l er6,er1 + mov.l er0,er6 +1: + eepmov.w + mov.w r4,r4 + bne 1b + dec.w #1,e4 + bpl 1b + mov.l er1,er6 + mov.l er2,er5 + mov.l er3,er4 + rts diff --git a/arch/h8300/lib/memset.S b/arch/h8300/lib/memset.S new file mode 100644 index 0000000000000..dda8700698254 --- /dev/null +++ b/arch/h8300/lib/memset.S @@ -0,0 +1,61 @@ +/* memset.S */ + +#include + +#if defined(__H8300H__) + .h8300h +#endif +#if defined(__H8300S__) + .h8300s +#endif + .text + +.global SYMBOL_NAME(memset) + +;;void *memset(*ptr, int c, size_t count) +;; ptr = er0 +;; c = er1(r1l) +;; count = er2 +SYMBOL_NAME_LABEL(memset) + mov.l er2,er2 + beq 7f + mov.l er0,@-sp + btst #0,r0l + beq 2f + + ;; odd address +1: + mov.b r1l,@er0 + adds #1,er0 + dec.l #1,er2 + beq 6f + + ;; even address +2: + mov.l er2,er3 + cmp.l #4,er2 + blo 4f + ;; count>=4 -> count/4 + shlr.l er2 + shlr.l er2 + ;; byte -> long + mov.b r1l,r1h + mov.w r1,e1 +3: + mov.l er1,@er0 + adds #4,er0 + dec.l #1,er2 + bne 3b +4: + ;; count % 4 + and.b #3,r3l + beq 6f +5: + mov.b r1l,@er0 + adds #1,er0 + dec.b r3l + bne 5b +6: + mov.l @sp+,er0 +7: + rts \ No newline at end of file diff --git a/arch/h8300/mm/Makefile b/arch/h8300/mm/Makefile new file mode 100644 index 0000000000000..79c34b1c9872f --- /dev/null +++ b/arch/h8300/mm/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the linux m68k-specific parts of the memory manager. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definition is now in the main makefile... + +obj-y := init.o fault.o memory.o kmap.o extable.o diff --git a/arch/h8300/mm/extable.c b/arch/h8300/mm/extable.c new file mode 100644 index 0000000000000..4f4f885b398f1 --- /dev/null +++ b/arch/h8300/mm/extable.c @@ -0,0 +1,30 @@ +/* + * linux/arch/h8300/mm/extable.c + */ + +#include +#include +#include +#include + +/* Simple binary search */ +const struct exception_table_entry * +search_extable(const struct exception_table_entry *first, + const struct exception_table_entry *last, + unsigned long value) +{ + while (first <= last) { + const struct exception_table_entry *mid; + long diff; + + mid = (last - first) / 2 + first; + diff = mid->insn - value; + if (diff == 0) + return mid; + else if (diff < 0) + first = mid+1; + else + last = mid-1; + } + return NULL; +} diff --git a/arch/h8300/mm/fault.c b/arch/h8300/mm/fault.c new file mode 100644 index 0000000000000..29e9af9f0e6a7 --- /dev/null +++ b/arch/h8300/mm/fault.c @@ -0,0 +1,58 @@ +/* + * linux/arch/h8300/mm/fault.c + * + * Copyright (C) 1998 D. Jeff Dionne , + * Copyright (C) 2000 Lineo, Inc. (www.lineo.com) + * + * Based on: + * + * linux/arch/m68knommu/mm/fault.c + * linux/arch/m68k/mm/fault.c + * + * Copyright (C) 1995 Hamish Macdonald + */ + +#include +#include +#include +#include + +#include +#include + +extern void die_if_kernel(char *, struct pt_regs *, long); + +/* + * This routine handles page faults. It determines the problem, and + * then passes it off to one of the appropriate routines. + * + * error_code: + * bit 0 == 0 means no page found, 1 means protection fault + * bit 1 == 0 means read, 1 means write + * + * If this routine detects a bad access, it returns 1, otherwise it + * returns 0. + */ +asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, + unsigned long error_code) +{ +#ifdef DEBUG + printk ("regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n", + regs->sr, regs->pc, address, error_code); +#endif + +/* + * Oops. The kernel tried to access some bad page. We'll have to + * terminate things with extreme prejudice. + */ + if ((unsigned long) address < PAGE_SIZE) { + printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); + } else + printk(KERN_ALERT "Unable to handle kernel access"); + printk(" at virtual address %08lx\n",address); + die_if_kernel("Oops", regs, error_code); + do_exit(SIGKILL); + + return 1; +} + diff --git a/arch/h8300/mm/init.c b/arch/h8300/mm/init.c new file mode 100644 index 0000000000000..164dc6060f909 --- /dev/null +++ b/arch/h8300/mm/init.c @@ -0,0 +1,235 @@ +/* + * linux/arch/h8300/mm/init.c + * + * Copyright (C) 1998 D. Jeff Dionne , + * Kenneth Albanowski , + * Copyright (C) 2000 Lineo, Inc. (www.lineo.com) + * + * Based on: + * + * linux/arch/m68knommu/mm/init.c + * linux/arch/m68k/mm/init.c + * + * Copyright (C) 1995 Hamish Macdonald + * + * JAN/1999 -- hacked to support ColdFire (gerg@snapgear.com) + * DEC/2000 -- linux 2.4 support + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_BLK_DEV_RAM +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#undef DEBUG + +extern void die_if_kernel(char *,struct pt_regs *,long); +extern void free_initmem(void); + +/* + * BAD_PAGE is the page that is used for page faults when linux + * is out-of-memory. Older versions of linux just did a + * do_exit(), but using this instead means there is less risk + * for a process dying in kernel mode, possibly leaving a inode + * unused etc.. + * + * BAD_PAGETABLE is the accompanying page-table: it is initialized + * to point to BAD_PAGE entries. + * + * ZERO_PAGE is a special page that is used for zero-initialized + * data and COW. + */ +static unsigned long empty_bad_page_table; + +static unsigned long empty_bad_page; + +unsigned long empty_zero_page; + +extern unsigned long rom_length; + +void show_mem(void) +{ + unsigned long i; + int free = 0, total = 0, reserved = 0, shared = 0; + int cached = 0; + + printk("\nMem-info:\n"); + show_free_areas(); + i = max_mapnr; + while (i-- > 0) { + total++; + if (PageReserved(mem_map+i)) + reserved++; + else if (PageSwapCache(mem_map+i)) + cached++; + else if (!page_count(mem_map+i)) + free++; + else + shared += page_count(mem_map+i) - 1; + } + printk("%d pages of RAM\n",total); + printk("%d free pages\n",free); + printk("%d reserved pages\n",reserved); + printk("%d pages shared\n",shared); + printk("%d pages swap cached\n",cached); +} + +extern unsigned long memory_start; +extern unsigned long memory_end; + +/* + * paging_init() continues the virtual memory environment setup which + * was begun by the code in arch/head.S. + * The parameters are pointers to where to stick the starting and ending + * addresses of available kernel virtual memory. + */ +void paging_init(void) +{ + /* + * Make sure start_mem is page aligned, otherwise bootmem and + * page_alloc get different views og the world. + */ +#ifdef DEBUG + unsigned long start_mem = PAGE_ALIGN(memory_start); +#endif + unsigned long end_mem = memory_end & PAGE_MASK; + +#ifdef DEBUG + printk ("start_mem is %#lx\nvirtual_end is %#lx\n", + start_mem, end_mem); +#endif + + /* + * Initialize the bad page table and bad page to point + * to a couple of allocated pages. + */ + empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); + empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); + empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); + memset((void *)empty_zero_page, 0, PAGE_SIZE); + + /* + * Set up SFC/DFC registers (user data space). + */ + set_fs (USER_DS); + +#ifdef DEBUG + printk ("before free_area_init\n"); + + printk ("free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n", + start_mem, end_mem); +#endif + + { + unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; + + zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT; + zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT; +#ifdef CONFIG_HIGHMEM + zones_size[ZONE_HIGHMEM] = 0; +#endif + free_area_init(zones_size); + } +} + +void mem_init(void) +{ + int codek = 0, datak = 0, initk = 0; + /* DAVIDM look at setup memory map generically with reserved area */ + unsigned long tmp; + extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end; + extern unsigned char _ramend, _ramstart; + unsigned long len = &_ramend - &_ramstart; + unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */ + unsigned long end_mem = memory_end; /* DAVIDM - this must not include kernel stack at top */ + +#ifdef DEBUG + printk("Mem_init: start=%lx, end=%lx\n", start_mem, end_mem); +#endif + + end_mem &= PAGE_MASK; + high_memory = (void *) end_mem; + + start_mem = PAGE_ALIGN(start_mem); + max_mapnr = num_physpages = MAP_NR(high_memory); + + /* this will put all memory onto the freelists */ + totalram_pages = free_all_bootmem(); + + codek = (&_etext - &_stext) >> 10; + datak = (&_ebss - &_sdata) >> 10; + initk = (&__init_begin - &__init_end) >> 10; + + tmp = nr_free_pages() << PAGE_SHIFT; + printk("Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n", + tmp >> 10, + len >> 10, + (rom_length > 0) ? ((rom_length >> 10) - codek) : 0, + rom_length >> 10, + codek, + datak + ); +} + + +#ifdef CONFIG_BLK_DEV_INITRD +void free_initrd_mem(unsigned long start, unsigned long end) +{ + int pages = 0; + for (; start < end; start += PAGE_SIZE) { + ClearPageReserved(virt_to_page(start)); + set_page_count(virt_to_page(start), 1); + free_page(start); + totalram_pages++; + pages++; + } + printk ("Freeing initrd memory: %dk freed\n", pages); +} +#endif + +void +free_initmem() +{ +#ifdef CONFIG_RAMKERNEL + unsigned long addr; + extern char __init_begin, __init_end; +/* + * the following code should be cool even if these sections + * are not page aligned. + */ + addr = PAGE_ALIGN((unsigned long)(&__init_begin)); + /* next to check that the page we free is not a partial page */ + for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) { + ClearPageReserved(virt_to_page(addr)); + set_page_count(virt_to_page(addr), 1); + free_page(addr); + totalram_pages++; + } + printk("Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n", + (addr - PAGE_ALIGN((long) &__init_begin)) >> 10, + (int)(PAGE_ALIGN((unsigned long)(&__init_begin))), + (int)(addr - PAGE_SIZE)); +#endif +} + diff --git a/arch/h8300/mm/kmap.c b/arch/h8300/mm/kmap.c new file mode 100644 index 0000000000000..4101ab54fc177 --- /dev/null +++ b/arch/h8300/mm/kmap.c @@ -0,0 +1,59 @@ +/* + * linux/arch/h8300/mm/kmap.c + * + * Based on + * linux/arch/m68knommu/mm/kmap.c + * + * Copyright (C) 2000 Lineo, + * Copyright (C) 2000-2002 David McCullough + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#undef DEBUG + +/* + * Map some physical address range into the kernel address space. + */ +void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) +{ + return (void *)physaddr; +} + +/* + * Unmap a ioremap()ed region again. + */ +void iounmap(void *addr) +{ +} + +/* + * __iounmap unmaps nearly everything, so be careful + * it doesn't free currently pointer/page tables anymore but it + * wans't used anyway and might be added later. + */ +void __iounmap(void *addr, unsigned long size) +{ +} + +/* + * Set new cache mode for some kernel address space. + * The caller must push data for that range itself, if such data may already + * be in the cache. + */ +void kernel_set_cachemode(void *addr, unsigned long size, int cmode) +{ +} diff --git a/arch/h8300/mm/memory.c b/arch/h8300/mm/memory.c new file mode 100644 index 0000000000000..f4ddece3216f9 --- /dev/null +++ b/arch/h8300/mm/memory.c @@ -0,0 +1,70 @@ +/* + * linux/arch/h8300/mm/memory.c + * + * Copyright (C) 2002 Yoshinori Sato , + * + * Based on: + * + * linux/arch/m68knommu/mm/memory.c + * + * Copyright (C) 1998 Kenneth Albanowski , + * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com) + * + * Based on: + * + * linux/arch/m68k/mm/memory.c + * + * Copyright (C) 1995 Hamish Macdonald + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +void cache_clear (unsigned long paddr, int len) +{ +} + + +void cache_push (unsigned long paddr, int len) +{ +} + +void cache_push_v (unsigned long vaddr, int len) +{ +} + +/* Map some physical address range into the kernel address space. The + * code is copied and adapted from map_chunk(). + */ + +unsigned long kernel_map(unsigned long paddr, unsigned long size, + int nocacheflag, unsigned long *memavailp ) +{ + return paddr; +} + +#ifdef MAGIC_ROM_PTR + +int is_in_rom(unsigned long addr) +{ + /* Anything not in operational RAM is returned as in rom! */ + if (addr < _ramstart || addr >= _ramend) + return 1; + else + return 0; +} + +#endif + diff --git a/arch/h8300/platform/h8300h/Makefile b/arch/h8300/platform/h8300h/Makefile new file mode 100644 index 0000000000000..e43f083a25277 --- /dev/null +++ b/arch/h8300/platform/h8300h/Makefile @@ -0,0 +1,22 @@ +# +# Makefile for the linux kernel. +# +# Reuse any files we can from the H8/300H +# + +#VPATH := $(VPATH):$(BOARD) + +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +.S.o: + $(CC) -D__ASSEMBLY__ $(AFLAGS) -I. -c $< -o $*.o + +obj-y := entry.o ints.o + +$(BOARD)/crt0_$(MODEL).o: $(BOARD)/crt0_$(MODEL).S + +entry.o: entry.S + +ints.o: ints.c diff --git a/arch/h8300/platform/h8300h/Rules.make b/arch/h8300/platform/h8300h/Rules.make new file mode 100644 index 0000000000000..84571e7681138 --- /dev/null +++ b/arch/h8300/platform/h8300h/Rules.make @@ -0,0 +1,51 @@ +# +# h8300h/Makefile +# +# This file is included by the global makefile so that you can add your own +# platform-specific flags and dependencies. +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (c) 2001 Lineo, Inc, +# Copyright (c) 2000,2001 D. Jeff Dionne +# Copyright (c) 1998,1999 D. Jeff Dionne +# Copyright (C) 1998 Kenneth Albanowski +# Copyright (C) 1994 Hamish Macdonald +# +# 68VZ328 Fixes By Evan Stawnyczy +# H8/300H Modify By Yoshinori Sato + +CROSS_COMPILE = h8300-elf- + +GCC_DIR = $(shell $(CC) -v 2>&1 | grep specs | sed -e 's/.* \(.*\)specs/\1\./') + +INCGCC = $(GCC_DIR)/include +LIBGCC = $(GCC_DIR)/h8300h/int32/libgcc.a + +CFLAGS := -fno-builtin -DNO_CACHE $(CFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -mh -mint32 -malign-300 -D__ELF__ -DNO_FORGET -DUTS_SYSNAME=\"uClinux\" -D__linux__ -DTARGET=$(BOARD) +AFLAGS := $(AFLAGS) -pipe -DNO_MM -DNO_FPU -DNO_CACHE -mh -D__ELF__ -DUTS_SYSNAME=\"uClinux\" + +LINKFLAGS = -T arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld +LDFLAGS := $(LDFLAGS) -mh8300helf + +HEAD := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o + +SUBDIRS := arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib \ + arch/$(ARCH)/platform/$(PLATFORM) \ + arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD) \ + $(SUBDIRS) + +CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \ + arch/$(ARCH)/platform/$(PLATFORM)/platform.o \ + arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(BOARD).o \ + $(CORE_FILES) + +LIBS += arch/$(ARCH)/lib/lib.a $(LIBGCC) + +linux.bin: linux + $(OBJCOPY) -O binary linux linux.bin + +archclean: + rm -f linux diff --git a/arch/h8300/platform/h8300h/aki3068net/Makefile b/arch/h8300/platform/h8300h/aki3068net/Makefile new file mode 100644 index 0000000000000..ae2c45a25906e --- /dev/null +++ b/arch/h8300/platform/h8300h/aki3068net/Makefile @@ -0,0 +1,16 @@ +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +all: $(BOARD).o +O_TARGET := $(BOARD).o +obj-y := timer.o + +timer.o: timer.c + +clean: + rm -f *.[oa] diff --git a/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S b/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S new file mode 100644 index 0000000000000..582962d279f02 --- /dev/null +++ b/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S @@ -0,0 +1,109 @@ +/* + * linux/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S + * + * Yoshinori Sato + * + * Platform depend startup for uClinux-2.4.x + * Target Archtecture: AE-3068 (aka. aki3068net) + * Memory Layout : RAM + */ + +#define ASSEMBLY + +#include +#include + + .global SYMBOL_NAME(_start) + .global SYMBOL_NAME(command_line) + .global SYMBOL_NAME(_platform_gpio_table) + .global SYMBOL_NAME(_target_name) + + .h8300h + + .section .text + .file "crt0_ram.S" + + /* CPU Reset entry */ +SYMBOL_NAME_LABEL(_start) + mov.l #__ramend,sp + ldc #0x80,ccr + + /* Peripheral Setup */ + + /* .bss clear */ + mov.l #__sbss,er5 + mov.l er5,er6 + inc.l #1,er6 + mov.l #__ebss,er4 + sub.l er5,er4 + sub.w r0,r0 + mov.b r0l,@er5 +1: + eepmov.w + dec.w #1,e4 + bpl 1b + + /* copy kernel commandline */ + mov.l #COMMAND_START,er5 + mov.l #SYMBOL_NAME(command_line),er6 + mov.w #512,r4 + eepmov.w + + /* RAM Interrupt Vector Table Setup */ +#if defined(CONFIG_GDB_DEBUG) + mov.l @SYMBOL_NAME(interrupt_redirect_table)+11*4,er0 +#endif + mov.l #SYMBOL_NAME(_vector_lma),er5 + mov.l #SYMBOL_NAME(interrupt_redirect_table),er6 + mov.w #0x100,r4 + eepmov.w +#if defined(CONFIG_GDB_DEBUG) + mov.l er0,@SYMBOL_NAME(interrupt_redirect_table)+11*4 +#endif + + /* uClinux kernel start */ + ldc #0x90,ccr /* running kernel */ + mov.l #SYMBOL_NAME(init_task_union),sp + mov.l sp,@SYMBOL_NAME(_current_task) + add.l #0x2000,sp + jsr @_start_kernel +_exit: + + jmp _exit + + rts + + /* I/O port assign information */ +__platform_gpio_table: + mov.l #gpio_table,er0 + rts + +gpio_table: + ;; P1DDR + .byte 0xff,0xff + ;; P2DDR + .byte 0xff,0xff + ;; P3DDR + .byte 0xff,0x00 + ;; P4DDR + .byte 0x00,0x00 + ;; P5DDR + .byte 0x01,0x01 + ;; P6DDR + .byte 0x00,0x00 + ;; dummy + .byte 0x00,0x00 + ;; P8DDR + .byte 0x0c,0x0c + ;; P9DDR + .byte 0x00,0x00 + ;; PADDR + .byte 0x00,0x00 + ;; PBDDR + .byte 0x30,0x30 + +__target_name: + .asciz "AE-3068" + + .section .bootvec,"ax" + jmp @SYMBOL_NAME(_start) diff --git a/arch/h8300/platform/h8300h/aki3068net/ram.ld b/arch/h8300/platform/h8300h/aki3068net/ram.ld new file mode 100644 index 0000000000000..e4e79ce07047b --- /dev/null +++ b/arch/h8300/platform/h8300h/aki3068net/ram.ld @@ -0,0 +1,90 @@ +/* AE-3068 (aka. aki3068net) RAM */ + +OUTPUT_ARCH(h8300h) +ENTRY("__start") + +MEMORY + { + ram : ORIGIN = 0x400000, LENGTH = 0x600000-0x400000-0x80000 + disk : ORIGIN = 0x600000-0x80000, LENGTH = 0x60000 + eram : ORIGIN = 0x600000, LENGTH = 0 + iram : ORIGIN = 0xffbf20, LENGTH = 0x4000 + } + +SECTIONS +{ + .bootvec : + { + *(.bootvec) + } > ram + .text : + { + __stext = . ; + *(.text) + . = ALIGN(0x4) ; + *(.text.*) + . = ALIGN(0x4) ; + *(.kstrtab) + . = ALIGN(0x4) ; + *(.rodata*) + . = ALIGN(16); /* Exception table */ + ___start___ex_table = .; + *(__ex_table) + ___stop___ex_table = .; + + ___start___ksymtab = .; /* Kernel symbol table */ + *(__ksymtab) + ___stop___ksymtab = .; + + . = ALIGN(0x4) ; + __etext = . ; + } > ram + .data : + { + __sdata = . ; + ___data_start = . ; + *(.data) + *(.data.*) + *(.exitcall.exit) + + . = ALIGN(0x2000) ; + *(.data.init_task) + . = ALIGN(0x2000) ; + ___init_begin = .; + *(.text.init) + *(.data.init) + . = ALIGN(16); + ___setup_start = .; + *(.setup.init) + ___setup_end = .; + ___initcall_start = .; + *(.initcall.init) + . = ALIGN(4) ; + ___initcall_end = .; + ___init_end = .; + __edata = . ; + . = ALIGN(0x4) ; + __sbss = . ; + *(.bss) + . = ALIGN(0x4) ; + *(COMMON) + . = ALIGN(0x4) ; + __ebss = . ; + __end = . ; + __ramstart = .; + } > ram + .blkimg : + { + __ramend = . ; + __blkimg = . ; + } > disk + .ram_vec : AT(ADDR(.data) + SIZEOF(.data)) + { + *(.int_redirect) + } > iram + __vector_lma = LOADADDR(.ram_vec); + .dummy2 : + { + COMMAND_START = . - 0x200 ; + } > eram +} diff --git a/arch/h8300/platform/h8300h/aki3068net/timer.c b/arch/h8300/platform/h8300h/aki3068net/timer.c new file mode 100644 index 0000000000000..696a6cc16c825 --- /dev/null +++ b/arch/h8300/platform/h8300h/aki3068net/timer.c @@ -0,0 +1,46 @@ +/* + * linux/arch/h8300/platform/h8300h/aki3068net/timer.c + * + * Yoshinori Sato + * + * Platform depend Timer Handler + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define TMR8CMA2 0x00ffff94 +#define TMR8TCSR2 0x00ffff92 +#define TMR8TCNT2 0x00ffff90 +#define CMFA 6 + +int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *)) +{ + outb(CONFIG_CLK_FREQ*10/8192,TMR8CMA2); + outb(0x00,TMR8TCSR2); + request_irq(40,timer_int,0,"timer",0); + outb(0x40|0x08|0x03,TMR8TCNT2); +} + +void platform_timer_eoi(void) +{ + *(unsigned char *)TMR8TCSR2 &= ~(1 << CMFA); +} + +void platform_gettod(int *year, int *mon, int *day, int *hour, + int *min, int *sec) +{ + *year = *mon = *day = *hour = *min = *sec = 0; +} diff --git a/arch/h8300/platform/h8300h/entry.S b/arch/h8300/platform/h8300h/entry.S new file mode 100644 index 0000000000000..00359fa158ff4 --- /dev/null +++ b/arch/h8300/platform/h8300h/entry.S @@ -0,0 +1,357 @@ +/* -*- mode: asm -*- + * + * linux/arch/h8300/platform/h8300h/entry.S + * + * Yoshinori Sato + * + */ + +/* + * entry.S + * include exception/interrupt gateway + * system call entry + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +ENOSYS = 38 + +LSIGTRAP = 5 + +SOFTIRQ_PENDING = 0 + +/* the following macro is used when enabling interrupts */ + +LER3 = 0 +LER2 = 4 +LER1 = 8 +LORIG = 12 +LCCR = 16 +LER0 = 18 +LVEC = 22 +LRET = 24 + + .h8300h + +/* CPU context save/restore macros. */ + + .macro SAVE_ALL + mov.l er0,@-sp + stc ccr,r0l + orc #0x10,ccr + btst #4,r0l + bne 1f + mov.l sp,@SYMBOL_NAME(sw_usp) + mov.l @sp,er0 + mov.l @SYMBOL_NAME(sw_ksp),sp + mov.l er0,@-sp + stc ccr,r0l + and #0xef,r0l + mov.w r0,@-sp + mov.l @(2:16,sp),er0 + bra 2f +1: + mov.l @sp,er0 + stc ccr,@-sp +2: + mov.l er0,@-sp + mov.l er1,@-sp + mov.l er2,@-sp + mov.l er3,@-sp + .endm + + .macro RESTORE_REGS + mov.w @(LCCR:16,sp),r0 + btst #4,r0l + bne 1f + mov.l @SYMBOL_NAME(sw_usp),er0 + mov.l @(LER0:16,sp),er1 + mov.l er1,@er0 + mov.l @sp+,er3 + mov.l @sp+,er2 + mov.l @sp+,er1 + add.l #10,sp + mov.l sp,@SYMBOL_NAME(sw_ksp) + mov.l er0,sp + bra 2f +1: + mov.l @sp+,er3 + mov.l @sp+,er2 + mov.l @sp+,er1 + adds #4,sp + adds #2,sp +2: + mov.l @sp+,er0 + adds #4,sp + .endm + + .macro RESTORE_ALL + RESTORE_REGS + rte + .endm + +#define SWITCH_STACK_SIZE (3*4+12) /* includes return address */ + + .macro SAVE_SWITCH_STACK + mov.l er4,@-sp + mov.l er5,@-sp + mov.l er6,@-sp + .endm + + .macro RESTORE_SWITCH_STACK + mov.l @sp+,er6 + mov.l @sp+,er5 + mov.l @sp+,er4 + .endm + +.globl SYMBOL_NAME(system_call) +.globl SYMBOL_NAME(ret_from_exception) +.globl SYMBOL_NAME(ret_from_signal) +.globl SYMBOL_NAME(ret_from_interrupt), SYMBOL_NAME(bad_interrupt) +.globl SYMBOL_NAME(interrupt_redirect_table) +.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp) +.globl SYMBOL_NAME(resume) +.globl SYMBOL_NAME(sys_vfork) +.globl SYMBOL_NAME(syscall_trampoline) + + .section .int_redirect,"ax" +SYMBOL_NAME_LABEL(interrupt_redirect_table) + .rept 7 + .long 0 + .endr + jsr @interrupt_entry /* NMI */ + jmp @SYMBOL_NAME(system_call) /* TRAPA #0 (System call) */ + .long 0 + .long 0 + jmp @SYMBOL_NAME(trace_break) /* TRAPA #3 (breakpoint) */ + .rept 64-12 + jsr @interrupt_entry + .endr + + .section .text + .align 2 +interrupt_entry: + SAVE_ALL + mov.w @(LCCR,sp),r0 + btst #4,r0l + bne 1f + mov.l @SYMBOL_NAME(sw_usp),er0 + mov.l @(4:16,er0),er0 + bra 2f +1: + mov.l @(LVEC,sp),er0 +2: + sub.l #SYMBOL_NAME(interrupt_redirect_table),er0 + shlr.l er0 + shlr.l er0 + dec.l #1,er0 + mov.l sp,er1 + jsr @SYMBOL_NAME(process_int) + mov.l @SYMBOL_NAME(irq_stat)+SOFTIRQ_PENDING,er0 + beq 1f + jsr @SYMBOL_NAME(do_softirq) +1: + jmp @SYMBOL_NAME(ret_from_exception) + +SYMBOL_NAME_LABEL(system_call) + subs #4,sp + SAVE_ALL + mov.l er0,er3 + mov.l #-ENOSYS,er0 + mov.l er0,@(LER0:16,sp) + + /* save top of frame */ + mov.l sp,er0 + mov.l er3,@-sp + jsr @SYMBOL_NAME(set_esp0) + mov.l @sp+,er3 + cmp.l #NR_syscalls,er3 + bcc SYMBOL_NAME(ret_from_exception):16 + shll.l er3 + shll.l er3 + mov.l #SYMBOL_NAME(sys_call_table),er0 + add.l er3,er0 + mov.l @er0,er0 + mov.l er0,er3 + beq SYMBOL_NAME(ret_from_exception):16 + mov.l @SYMBOL_NAME(_current_task),er2 + mov.b @((TASK_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l + btst #(TIF_SYSCALL_TRACE & 7),r2l + bne 1f + mov.l @(LER1:16,sp),er0 + mov.l @(LER2:16,sp),er1 + mov.l @(LER3:16,sp),er2 + mov.l er5,@-sp + mov.l er4,@-sp + jsr @er3 + adds #4,sp + adds #4,sp + mov.l er0,@(LER0,sp) /* save the return value */ +#if defined(CONFIG_SYSCALL_PRINT) + jsr @SYMBOL_NAME(syscall_print) +#endif + jmp @SYMBOL_NAME(ret_from_exception) +1: + SAVE_SWITCH_STACK + mov.l er3,er5 /* save syscall entry */ + jsr SYMBOL_NAME(syscall_trace) + mov.l er5,er3 + RESTORE_SWITCH_STACK + mov.l @(LER1:16,sp),er0 + mov.l @(LER2:16,sp),er1 + mov.l @(LER3:16,sp),er2 + mov.l er5,@-sp + mov.l er4,@-sp + jsr @er3 + adds #4,sp + adds #4,sp + mov.l er0,@(LER0:16,sp) /* save the return value */ + SAVE_SWITCH_STACK + jsr SYMBOL_NAME(syscall_trace) + +SYMBOL_NAME_LABEL(ret_from_signal) + RESTORE_SWITCH_STACK + +SYMBOL_NAME_LABEL(ret_from_exception) + mov.b @(LCCR+1:16,sp),r0l + btst #4,r0l /* check if returning to kernel */ + bne 3f /* if so, skip resched, signals */ + andc #0x7f,ccr + mov.l @SYMBOL_NAME(_current_task),er0 + mov.l @(TI_FLAGS:16,er2),er1 + and.l #_TIF_WORK_MASK,er1 + bne 1f + mov.l @((TASK_THREAD+THREAD_VFORK):16,er0),er1 + bne Lvfork_return +3: + RESTORE_ALL /* Does RTE */ +1: + mov.l @(TI_FLAGS:16,er2),er1 + btst #TIF_NEED_RESCHED,r1l + bne @SYMBOL_NAME(reschedule):16 + +Lsignal_return: + SAVE_SWITCH_STACK + mov.l sp,er1 + add #12,er1 + mov.l er2,er0 + jsr @SYMBOL_NAME(do_signal) + RESTORE_SWITCH_STACK + mov.l @SYMBOL_NAME(_current_task),er0 + mov.l @((TASK_THREAD+THREAD_VFORK):16,er0),er1 + bne Lvfork_return + RESTORE_ALL + +Lvfork_return: + sub.l er2,er2 + mov.l er2,@((TASK_THREAD+THREAD_VFORK):16,er0) + mov.l @SYMBOL_NAME(sw_usp),er0 + mov.l er1,@(8:16,er0) + RESTORE_ALL + +SYMBOL_NAME_LABEL(reschedule) + /* save top of frame */ + mov.l sp,er0 + jsr @SYMBOL_NAME(set_esp0) + + mov.l #SYMBOL_NAME(ret_from_exception),er0 + mov.l er0,@-sp + jmp @SYMBOL_NAME(schedule) + +SYMBOL_NAME_LABEL(resume) + /* + * Beware - when entering resume, offset of tss is in d1, + * prev (the current task) is in a0, next (the new task) + * is in a1 and d2.b is non-zero if the mm structure is + * shared between the tasks, so don't change these + * registers until their contents are no longer needed. + */ + + /* save sr */ + sub.w r3,r3 + stc ccr,r3l + mov.w r3,@(THREAD_CCR:16,er0) + SAVE_SWITCH_STACK + + /* disable interrupts */ + orc #0x80,ccr + mov.l @SYMBOL_NAME(sw_usp),er3 + mov.l er3,@(THREAD_USP:16,er0) + mov.l sp,@(THREAD_KSP:16,er0) + + /* get pointer to tss struct (a1 contains new task) */ + mov.l er1,@SYMBOL_NAME(_current_task) + + /* Skip address space switching if they are the same. */ + /* FIXME: what did we hack out of here, this does nothing! */ + + mov.l @(THREAD_USP:16,er1),er0 + mov.l er0,@SYMBOL_NAME(sw_usp) + mov.l @(THREAD_KSP:16,er1),sp + RESTORE_SWITCH_STACK + + /* restore status register */ + mov.w @(THREAD_CCR:16,er1),r3 + + ldc r3l,ccr + + rts + +/* Handler for uninitialized and spurious interrupts */ + +SYMBOL_NAME_LABEL(bad_interrupt) + mov.l @SYMBOL_NAME(num_spurious),er0 + inc.l #1,er0 + mov.l er0,@SYMBOL_NAME(num_spurious) + rts + +SYMBOL_NAME_LABEL(trace_break) + subs #4,sp + SAVE_ALL + sub.l er1,er1 + dec.l #1,er1 + mov.l er1,@(LORIG,sp) + mov.l sp,er0 + jsr @SYMBOL_NAME(set_esp0) + mov.l @SYMBOL_NAME(sw_usp),er0 + mov.l @er0,er1 + subs #2,er1 + mov.l er1,@er0 + and.w #0xff,e1 + mov.l er1,er0 + jsr @SYMBOL_NAME(trace_trap) + jmp @SYMBOL_NAME(ret_from_exception) + +SYMBOL_NAME_LABEL(sys_vfork) + SAVE_SWITCH_STACK + mov.l @SYMBOL_NAME(sw_usp),er6 + mov.l @(8:16,er6),er6 + mov.l sp,er0 + add.l #SWITCH_STACK_SIZE,er0 + jsr @SYMBOL_NAME(h8300_vfork) + mov.l @SYMBOL_NAME(_current_task),er5 + mov.l er6,@((TASK_THREAD+THREAD_VFORK):16,er5) + RESTORE_SWITCH_STACK + rts + +SYMBOL_NAME_LABEL(syscall_trampoline) + SAVE_SWITCH_STACK + mov.l er0,er6 + mov.l sp,er0 + add.l #SWITCH_STACK_SIZE,er0 + jsr @er6 + RESTORE_SWITCH_STACK + rts + + .section .bss +SYMBOL_NAME_LABEL(sw_ksp) + .space 4 +SYMBOL_NAME_LABEL(sw_usp) + .space 4 diff --git a/arch/h8300/platform/h8300h/generic/Makefile b/arch/h8300/platform/h8300h/generic/Makefile new file mode 100644 index 0000000000000..48bb288238b72 --- /dev/null +++ b/arch/h8300/platform/h8300h/generic/Makefile @@ -0,0 +1,12 @@ +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +obj-y := timer.o crt0_$(MODEL).o + +clean: + rm -f *.[oa] diff --git a/arch/h8300/platform/h8300h/generic/crt0_rom.S b/arch/h8300/platform/h8300h/generic/crt0_rom.S new file mode 100644 index 0000000000000..7ae53be8cf78a --- /dev/null +++ b/arch/h8300/platform/h8300h/generic/crt0_rom.S @@ -0,0 +1,118 @@ +/* + * linux/arch/h8300/platform/h8300h/generic/crt0_rom.S + * + * Yoshinori Sato + * + * Platform depend startup for uClinux-2.4.x + * Target Archtecture: generic + * Memory Layout : ROM + */ + +#define ASSEMBLY + +#include +#include + + .global SYMBOL_NAME(_start) + .global SYMBOL_NAME(_command_line) + .global SYMBOL_NAME(_platform_gpio_table) + .global SYMBOL_NAME(_target_name) + + .h8300h + .section .text + .file "crt0_rom.S" + + /* CPU Reset entry */ +SYMBOL_NAME_LABEL(_start) + mov.l #__ramend,sp + ldc #0x80,ccr + + /* Peripheral Setup */ + + /* .bss clear */ + mov.l #__sbss,er5 + mov.l er5,er6 + inc.l #1,er6 + mov.l #__ebss,er4 + sub.l er5,er4 + sub.w r0,r0 + mov.b r0l,@er5 +1: + eepmov.w + dec.w #1,e4 + bpl 1b + + /* copy .data */ +#if !defined(CONFIG_H8300H_SIM) + mov.l #__begin_data,er5 + mov.l #__sdata,er6 + mov.l #__edata,er4 + sub.l er6,er4 +1: + eepmov.w + dec.w #1,e4 + bpl 1b +#endif + + /* copy kernel commandline */ + mov.l #COMMAND_START,er5 + mov.l #SYMBOL_NAME(_command_line),er6 + mov.w #512,r4 + eepmov.w + + /* uClinux kernel start */ + ldc #0x90,ccr /* running kernel */ + mov.l #SYMBOL_NAME(init_thread_union),sp + mov.l sp,@SYMBOL_NAME(_current_task) + add.l #0x2000,sp + jsr @_start_kernel +_exit: + + jmp _exit + + rts + + /* I/O port assign information */ +__platform_gpio_table: + mov.l #gpio_table,er0 + rts + +gpio_table: + ;; P1DDR + .byte 0x00,0x00 + ;; P2DDR + .byte 0x00,0x00 + ;; P3DDR + .byte 0x00,0x00 + ;; P4DDR + .byte 0x00,0x00 + ;; P5DDR + .byte 0x00,0x00 + ;; P6DDR + .byte 0x00,0x00 + ;; dummy + .byte 0x00,0x00 + ;; P8DDR + .byte 0x00,0x00 + ;; P9DDR + .byte 0x00,0x00 + ;; PADDR + .byte 0x00,0x00 + ;; PBDDR + .byte 0x00,0x00 + +__target_name: + .asciz "generic" + + .section .bss +__command_line: + .space 512 + + /* interrupt vector */ + .section .vectors,"ax" + .long __start +vector = 1 + .rept 64-1 + .long _interrupt_redirect_table+vector*4 +vector = vector + 1 + .endr diff --git a/arch/h8300/platform/h8300h/generic/ram.ld b/arch/h8300/platform/h8300h/generic/ram.ld new file mode 100644 index 0000000000000..26942a77df2c1 --- /dev/null +++ b/arch/h8300/platform/h8300h/generic/ram.ld @@ -0,0 +1,76 @@ +/* AKI3068NET RAM */ + +OUTPUT_ARCH(h8300h) +ENTRY("__start") + +MEMORY + { + ram : ORIGIN = 0x400000, LENGTH = 0xA0000 +/* rdisk : ORIGIN = 0x4A0000, LENGTH = 0x70000 */ +/* uram : ORIGIN = 0x510000, LENGTH = 0xF0000 */ + uram : ORIGIN = 0x4A0000, LENGTH = 0x160000 + eram : ORIGIN = 0x600000, LENGTH = 0 + iram : ORIGIN = 0xffbf20, LENGTH = 0x4000 + } + +SECTIONS +{ + .bootvec : + { + *(.bootvec) + } > ram + .text : + { + __stext = . ; + *(.text) + __etext = . ; + } > ram + .rodata : + { + ___data_rom_start = ALIGN ( 4 ) ; + } > ram + .erom : + { + __erom = . ; + } > ram + .data : + { + __ramstart = . ; + __sdata = . ; + ___data_start = . ; + *(.data) + __edata = . ; + edata = ALIGN( 0x10 ) ; + ___data_end = ALIGN( 0x10 ) ; + } > ram + .bss : + { + __sbss = . ; + ___bss_start = . ; + *(.bss) + *(COMMON) + __ebss = . ; + ___bss_end = . ; + } > ram +/* + .rootimg : + { + __rootimage = . ; + } > rdisk +*/ + .dummy1 : + { + end = ALIGN( 0x10 ) ; + __end = ALIGN( 0x10 ) ; + } > uram + .ram_vec : AT(___bss_end) + { + __ram_vector = . ; + } > iram + __ram_vector_image = LOADADDR(.ram_vec) ; + .dummy2 : + { + _COMMAND_START = . - 0x200 ; + __ramend = . ; + } > eram +} diff --git a/arch/h8300/platform/h8300h/generic/rom.ld b/arch/h8300/platform/h8300h/generic/rom.ld new file mode 100644 index 0000000000000..5453fe42b5860 --- /dev/null +++ b/arch/h8300/platform/h8300h/generic/rom.ld @@ -0,0 +1,122 @@ +OUTPUT_ARCH(h8300h) +ENTRY("__start") + +/*INPUT(rootimage.o)*/ + +_jiffies = _jiffies_64 + 4; + +MEMORY + { + vector : ORIGIN = 0x000000, LENGTH = 0x000100 + rom : ORIGIN = 0x000100, LENGTH = 0x200000-0x000100 + erom : ORIGIN = 0x200000, LENGTH = 1 + ram : ORIGIN = 0x200000, LENGTH = 0x100000 + eram : ORIGIN = 0x2fa000, LENGTH = 1 + } + +SECTIONS +{ + .vectors : + { + __vector = . ; + *(.vectors*) + } > vector + .text : + { + *(.int_redirect) + __stext = . ; + *(.text) + . = ALIGN(0x4) ; + *(.exit.text) + *(.text.*) + . = ALIGN(0x4) ; + *(.exitcall.exit) + . = ALIGN(0x4) ; + *(.kstrtab) + . = ALIGN(0x4) ; + *(.rodata*) + . = ALIGN(16); /* Exception table */ + ___start___ex_table = .; + *(__ex_table) + ___stop___ex_table = .; + + ___start___ksymtab = .; /* Kernel symbol table */ + *(__ksymtab) + ___stop___ksymtab = .; + + . = ALIGN(0x4) ; + __etext = . ; + } > rom + .data : AT( ADDR(.text)+SIZEOF(.text)) + { + __sdata = . ; + ___data_start = . ; + + . = ALIGN(0x2000) ; + *(.data.init_task) + . = ALIGN(0x4) ; + *(.data) + . = ALIGN(0x4) ; + *(.data.*) + + . = ALIGN(0x4) ; + ___init_begin = .; + *(.init.text) + *(.init.data) + . = ALIGN(0x4) ; + ___setup_start = .; + *(.init.setup) + . = ALIGN(0x4) ; + ___setup_end = .; + ___start___param = .; + *(__param) + ___stop___param = .; + ___initcall_start = .; + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + ___initcall_end = .; + ___con_initcall_start = .; + *(.con_initcall.init) + ___con_initcall_end = .; + . = ALIGN(4); + ___initramfs_start = .; + *(.init.ramfs) + ___initramfs_end = .; + . = ALIGN(0x4) ; + ___init_end = .; + + __edata = . ; + } > ram + __begin_data = LOADADDR(.data) ; + .blkimg : AT( LOADADDR(.data) + SIZEOF(.data)) + { + __blkimg = . ; + *(.rootimg*) + } > rom + .erom : + { + __erom = . ; + } > erom + .bss : + { + . = ALIGN(0x4) ; + __sbss = . ; + *(.bss) + . = ALIGN(0x4) ; + *(COMMON) + . = ALIGN(0x4) ; + __ebss = . ; + __end = . ; + __ramstart = .; + } > ram + .dummy : + { + COMMAND_START = . - 0x200 ; + __ramend = . ; + } > eram +} diff --git a/arch/h8300/platform/h8300h/generic/timer.c b/arch/h8300/platform/h8300h/generic/timer.c new file mode 100644 index 0000000000000..0652e801be71c --- /dev/null +++ b/arch/h8300/platform/h8300h/generic/timer.c @@ -0,0 +1,84 @@ +/* + * linux/arch/h8300/platform/h8300h/generic/timer.c + * + * Yoshinori Sato + * + * Platform depend Timer Handler + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#if defined(CONFIG_H83007) || defined(CONFIG_H83068) +#define TMR8CMA2 0x00ffff94 +#define TMR8TCSR2 0x00ffff92 +#define TMR8TCNT2 0x00ffff90 + +int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *)) +{ + outb(H8300_TIMER_COUNT_DATA,TMR8CMA2); + outb(0x00,TMR8TCSR2); + request_irq(40,timer_int,0,"timer",0); + outb(0x40|0x08|0x03,TMR8TCNT2); + return 0; +} + +void platform_timer_eoi(void) +{ + __asm__("bclr #6,@0xffff92:8"); +} +#endif + +#if defined(H8_3002) || defined(CONFIG_H83048) +#define TSTR 0x00ffff60 +#define TSNC 0x00ffff61 +#define TMDR 0x00ffff62 +#define TFCR 0x00ffff63 +#define TOER 0x00ffff90 +#define TOCR 0x00ffff91 +#define TCR 0x00ffff64 +#define TIOR 0x00ffff65 +#define TIER 0x00ffff66 +#define TSR 0x00ffff67 +#define TCNT 0x00ffff68 +#define GRA 0x00ffff6a +#define GRB 0x00ffff6c + +int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *)) +{ + *(unsigned short *)GRA= H8300_TIMER_COUNT_DATA; + *(unsigned short *)TCNT=0; + outb(0x23,TCR); + outb(0x00,TIOR); + request_irq(26,timer_int,0,"timer",0); + outb(inb(TIER) | 0x01,TIER); + outb(inb(TSNC) & ~0x01,TSNC); + outb(inb(TMDR) & ~0x01,TMDR); + outb(inb(TSTR) | 0x01,TSTR); + return 0; +} + +void platform_timer_eoi(void) +{ + outb(inb(TSR) & ~0x01,TSR); +} +#endif + +void platform_gettod(int *year, int *mon, int *day, int *hour, + int *min, int *sec) +{ + *year = *mon = *day = *hour = *min = *sec = 0; +} diff --git a/arch/h8300/platform/h8300h/h8max/Makefile b/arch/h8300/platform/h8300h/h8max/Makefile new file mode 100644 index 0000000000000..ae2c45a25906e --- /dev/null +++ b/arch/h8300/platform/h8300h/h8max/Makefile @@ -0,0 +1,16 @@ +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +all: $(BOARD).o +O_TARGET := $(BOARD).o +obj-y := timer.o + +timer.o: timer.c + +clean: + rm -f *.[oa] diff --git a/arch/h8300/platform/h8300h/h8max/crt0_ram.S b/arch/h8300/platform/h8300h/h8max/crt0_ram.S new file mode 100644 index 0000000000000..8d64dda268e4a --- /dev/null +++ b/arch/h8300/platform/h8300h/h8max/crt0_ram.S @@ -0,0 +1,109 @@ +/* + * linux/arch/h8300/platform/h8300h/h8max/crt0_ram.S + * + * Yoshinori Sato + * + * Platform depend startup for uClinux-2.4.x + * Target Archtecture: H8MAX + * Memory Layout : RAM + */ + +#define ASSEMBLY + +#include +#include + + .global SYMBOL_NAME(_start) + .global SYMBOL_NAME(command_line) + .global SYMBOL_NAME(_platform_gpio_table) + .global SYMBOL_NAME(_target_name) + + .h8300h + + .section .text + .file "crt0_ram.S" + + /* CPU Reset entry */ +SYMBOL_NAME_LABEL(_start) + mov.l #__ramend,sp + ldc #0x80,ccr + + /* Peripheral Setup */ + + /* .bss clear */ + mov.l #__sbss,er5 + mov.l er5,er6 + inc.l #1,er6 + mov.l #__ebss,er4 + sub.l er5,er4 + sub.w r0,r0 + mov.b r0l,@er5 +1: + eepmov.w + dec.w #1,e4 + bpl 1b + + /* copy kernel commandline */ + mov.l #COMMAND_START,er5 + mov.l #SYMBOL_NAME(command_line),er6 + mov.w #512,r4 + eepmov.w + + /* RAM Interrupt Vector Table Setup */ +#if defined(CONFIG_GDB_DEBUG) + mov.l @SYMBOL_NAME(interrupt_redirect_table)+11*4,er0 +#endif + mov.l #SYMBOL_NAME(_vector_lma),er5 + mov.l #SYMBOL_NAME(interrupt_redirect_table),er6 + mov.w #0x100,r4 + eepmov.w +#if defined(CONFIG_GDB_DEBUG) + mov.l er0,@SYMBOL_NAME(interrupt_redirect_table)+11*4 +#endif + + /* uClinux kernel start */ + ldc #0x90,ccr /* running kernel */ + mov.l #SYMBOL_NAME(init_task_union),sp + mov.l sp,@SYMBOL_NAME(_current_task) + add.l #0x2000,sp + jsr @_start_kernel +_exit: + + jmp _exit + + rts + + /* I/O port assign information */ +__platform_gpio_table: + mov.l #gpio_table,er0 + rts + +gpio_table: + ;; P1DDR + .byte 0xff,0xff + ;; P2DDR + .byte 0xff,0xff + ;; P3DDR + .byte 0x00,0x00 + ;; P4DDR + .byte 0x00,0x00 + ;; P5DDR + .byte 0x01,0x01 + ;; P6DDR + .byte 0xf6,0xf6 + ;; dummy + .byte 0x00,0x00 + ;; P8DDR + .byte 0xee,0xee + ;; P9DDR + .byte 0x00,0x00 + ;; PADDR + .byte 0x00,0x00 + ;; PBDDR + .byte 0x30,0x30 + +__target_name: + .asciz "H8MAX" + + .section .bootvec,"ax" + jmp @SYMBOL_NAME(_start) diff --git a/arch/h8300/platform/h8300h/h8max/ram.ld b/arch/h8300/platform/h8300h/h8max/ram.ld new file mode 100644 index 0000000000000..57d0d6fa33fc4 --- /dev/null +++ b/arch/h8300/platform/h8300h/h8max/ram.ld @@ -0,0 +1,90 @@ +/* H8MAX RAM */ + +OUTPUT_ARCH(h8300h) +ENTRY("__start") + +MEMORY + { + ram : ORIGIN = 0x400000, LENGTH = 0x600000-0x400000-0xc000 + disk : ORIGIN = 0x600000-0xc000, LENGTH = 0xc000 + eram : ORIGIN = 0x600000, LENGTH = 0 + iram : ORIGIN = 0xfffd20, LENGTH = 0x100 + } + +SECTIONS +{ + .bootvec : + { + *(.bootvec) + } > ram + .text : + { + __stext = . ; + *(.text) + . = ALIGN(0x4) ; + *(.text.*) + . = ALIGN(0x4) ; + *(.kstrtab) + . = ALIGN(0x4) ; + *(.rodata*) + . = ALIGN(16); /* Exception table */ + ___start___ex_table = .; + *(__ex_table) + ___stop___ex_table = .; + + ___start___ksymtab = .; /* Kernel symbol table */ + *(__ksymtab) + ___stop___ksymtab = .; + + . = ALIGN(0x4) ; + __etext = . ; + } > ram + .data : + { + __sdata = . ; + ___data_start = . ; + *(.data) + *(.data.*) + *(.exitcall.exit) + + . = ALIGN(0x2000) ; + *(.data.init_task) + . = ALIGN(0x2000) ; + ___init_begin = .; + *(.text.init) + *(.data.init) + . = ALIGN(16); + ___setup_start = .; + *(.setup.init) + ___setup_end = .; + ___initcall_start = .; + *(.initcall.init) + . = ALIGN(4) ; + ___initcall_end = .; + ___init_end = .; + __edata = . ; + . = ALIGN(0x4) ; + __sbss = . ; + *(.bss) + . = ALIGN(0x4) ; + *(COMMON) + . = ALIGN(0x4) ; + __ebss = . ; + __end = . ; + __ramstart = .; + } > ram + .blkimg : + { + __ramend = . ; + __blkimg = . ; + } > disk + .ram_vec : AT(ADDR(.data) + SIZEOF(.data)) + { + *(.int_redirect) + } > iram + __vector_lma = LOADADDR(.ram_vec); + .dummy2 : + { + COMMAND_START = . - 0x200 ; + } > eram +} diff --git a/arch/h8300/platform/h8300h/h8max/timer.c b/arch/h8300/platform/h8300h/h8max/timer.c new file mode 100644 index 0000000000000..47a4a3730ad65 --- /dev/null +++ b/arch/h8300/platform/h8300h/h8max/timer.c @@ -0,0 +1,46 @@ +/* + * linux/arch/h8300/platform/h8300h/h8max/timer.c + * + * Yoshinori Sato + * + * Platform depend Timer Handler + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define TMR8CMA2 0x00ffff94 +#define TMR8TCSR2 0x00ffff92 +#define TMR8TCNT2 0x00ffff90 +#define CMFA 6 + +int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *)) +{ + outb(CONFIG_CLK_FREQ*10/8192,TMR8CMA2); + outb(0x00,TMR8TCSR2); + request_irq(40,timer_int,0,"timer",0); + outb(0x40|0x08|0x03,TMR8TCNT2); +} + +void platform_timer_eoi(void) +{ + *(unsigned char *)TMR8TCSR2 &= ~(1 << CMFA); +} + +void platform_gettod(int *year, int *mon, int *day, int *hour, + int *min, int *sec) +{ + *year = *mon = *day = *hour = *min = *sec = 0; +} diff --git a/arch/h8300/platform/h8300h/ints.c b/arch/h8300/platform/h8300h/ints.c new file mode 100644 index 0000000000000..7bf1c1242de24 --- /dev/null +++ b/arch/h8300/platform/h8300h/ints.c @@ -0,0 +1,252 @@ +/* + * linux/arch/h8300/platform/h8300h/ints.c + * + * Yoshinori Sato + * + * Based on linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Copyright 1996 Roman Zippel + * Copyright 1999 D. Jeff Dionne + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define INTERNAL_IRQS (64) + +#define EXT_IRQ0 12 +#define EXT_IRQ1 13 +#define EXT_IRQ2 14 +#define EXT_IRQ3 15 +#define EXT_IRQ4 16 +#define EXT_IRQ5 17 +#define EXT_IRQ6 18 +#define EXT_IRQ7 19 + +#define WDT_IRQ 20 + +/* table for system interrupt handlers */ +static irq_handler_t irq_list[SYS_IRQS]; + +/* The number of spurious interrupts */ +volatile unsigned int num_spurious; + +/* assembler routines */ +asmlinkage void system_call(void); +asmlinkage void bad_interrupt(void); + +/* irq node variables for the 32 (potential) on chip sources */ +/*static irq_node_t *int_irq_list[INTERNAL_IRQS];*/ +static int int_irq_count[INTERNAL_IRQS]; + +#if 0 +static void int_badint(int irq, void *dev_id, struct pt_regs *fp) +{ + num_spurious += 1; +} +#endif + +void init_IRQ(void) +{ + int i; + + for (i = 0; i < SYS_IRQS; i++) { + irq_list[i].handler = NULL; + irq_list[i].flags = 0; + irq_list[i].devname = NULL; + irq_list[i].dev_id = NULL; + } + +} + +int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + if (irq >= EXT_IRQ0 && irq <= EXT_IRQ3) { + if (H8300_GPIO_RESERVE(H8300_GPIO_P8, 1 << (irq - EXT_IRQ0)) == 0) + return 1; + H8300_GPIO_DDR(H8300_GPIO_P8, (irq - EXT_IRQ0), 0); + } + if (irq >= EXT_IRQ4 && irq <= EXT_IRQ5) { + if (H8300_GPIO_RESERVE(H8300_GPIO_P9, 1 << (irq - EXT_IRQ0)) == 0) + return 1; + H8300_GPIO_DDR(H8300_GPIO_P9, (irq - EXT_IRQ0), 0); + } + irq_list[irq].handler = handler; + irq_list[irq].flags = flags; + irq_list[irq].devname = devname; + irq_list[irq].dev_id = dev_id; + if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5) + *(volatile unsigned char *)IER |= 1 << (irq - EXT_IRQ0); + return 0; +} + +void free_irq(unsigned int irq, void *dev_id) +{ + if (irq_list[irq].dev_id != dev_id) + printk("%s: Removing probably wrong IRQ %d from %s\n", + __FUNCTION__, irq, irq_list[irq].devname); + if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5) + *(volatile unsigned char *)IER &= ~(1 << (irq - EXT_IRQ0)); + irq_list[irq].handler = NULL; + irq_list[irq].flags = 0; + irq_list[irq].dev_id = NULL; + irq_list[irq].devname = NULL; +} + +/* + * Do we need these probe functions on the m68k? + */ +unsigned long probe_irq_on (void) +{ + return 0; +} + +int probe_irq_off (unsigned long irqs) +{ + return 0; +} + +struct int_regs { + unsigned long ier; + unsigned long isr; + unsigned char mask; +}; + +#define REGS_DEF(ier,isr,mask) {ier,isr,mask} + +const struct int_regs interrupt_registers[]= { + REGS_DEF(IER,ISR,0x01), + REGS_DEF(IER,ISR,0x02), + REGS_DEF(IER,ISR,0x04), + REGS_DEF(IER,ISR,0x08), + REGS_DEF(IER,ISR,0x10), + REGS_DEF(IER,ISR,0x20), + REGS_DEF(IER,ISR,0x40), + REGS_DEF(IER,ISR,0x80), + REGS_DEF(TCSR,TCSR,0x20), + REGS_DEF(RTMCSR,RTMCSR,0x40), + REGS_DEF(0,0,0), + REGS_DEF(ADCSR,ADCSR,0x40), + REGS_DEF(TISRA,TISRA,0x10), + REGS_DEF(TISRB,TISRB,0x10), + REGS_DEF(TISRC,TISRC,0x10), + REGS_DEF(0,0,0), + REGS_DEF(TISRA,TISRA,0x20), + REGS_DEF(TISRB,TISRB,0x20), + REGS_DEF(TISRC,TISRC,0x20), + REGS_DEF(0,0,0), + REGS_DEF(TISRA,TISRA,0x40), + REGS_DEF(TISRB,TISRB,0x40), + REGS_DEF(TISRC,TISRC,0x40), + REGS_DEF(0,0,0), + REGS_DEF(_8TCR0,_8TCSR0,0x40), + REGS_DEF(_8TCR0,_8TCSR0,0x80), + REGS_DEF(_8TCR1,_8TCSR1,0xC0), + REGS_DEF(_8TCR0,_8TCSR0,0x20), + REGS_DEF(_8TCR2,_8TCSR2,0x40), + REGS_DEF(_8TCR2,_8TCSR2,0x80), + REGS_DEF(_8TCR3,_8TCSR3,0xC0), + REGS_DEF(_8TCR2,_8TCSR2,0x20), + REGS_DEF(DTCR0A,DTCR0A,0x0), + REGS_DEF(DTCR0B,DTCR0B,0x0), + REGS_DEF(DTCR1A,DTCR1A,0x0), + REGS_DEF(DTCR1B,DTCR1B,0x0), + REGS_DEF(0,0,0), + REGS_DEF(0,0,0), + REGS_DEF(0,0,0), + REGS_DEF(0,0,0), + REGS_DEF(SCR0,SSR0,0x40), + REGS_DEF(SCR0,SSR0,0x40), + REGS_DEF(SCR0,SSR0,0x80), + REGS_DEF(SCR0,SSR0,0x04), + REGS_DEF(SCR1,SSR1,0x40), + REGS_DEF(SCR1,SSR1,0x40), + REGS_DEF(SCR1,SSR1,0x80), + REGS_DEF(SCR1,SSR1,0x04), + REGS_DEF(SCR2,SSR2,0x40), + REGS_DEF(SCR2,SSR2,0x40), + REGS_DEF(SCR2,SSR2,0x80), + REGS_DEF(SCR2,SSR2,0x04) +}; + +void enable_irq(unsigned int irq) +{ + unsigned char ier; + const struct int_regs *regs=&interrupt_registers[irq - 12]; + if (irq == WDT_IRQ) { + ier = ctrl_inb(TCSR); + ier |= 0x20; + ctrl_outb((0xa500 | ier),TCSR); + } else { + if ((irq > 12) && regs->ier) { + ier = ctrl_inb(regs->ier); + ier |= regs->mask; + ctrl_outb(ier, regs->ier); + } else + panic("Unknown interrupt vector"); + } +} + +void disable_irq(unsigned int irq) +{ + unsigned char ier; + const struct int_regs *regs=&interrupt_registers[irq - 12]; + if (irq == WDT_IRQ) { + ier = ctrl_inb(TCSR); + ier &= ~0x20; + ctrl_outb((0xa500 | ier),TCSR); + } else { + if ((irq > 12) && regs->ier) { + ier = ctrl_inb(regs->ier); + ier &= ~(regs->mask); + ctrl_outb(ier, regs->ier); + } else + panic("Unknown interrupt vector"); + } +} + +asmlinkage void process_int(unsigned long vec, struct pt_regs *fp) +{ + irq_enter(); + if (irq_list[vec].handler) { + irq_list[vec].handler(vec, irq_list[vec].dev_id, fp); + int_irq_count[vec]++; + } else + panic("No interrupt handler for %ld\n", vec); + if (vec >= EXT_IRQ0 && vec <= EXT_IRQ5) + *(volatile unsigned char *)ISR &= ~(1 << (vec - EXT_IRQ0)); + irq_exit(); +} + +int show_interrupts(struct seq_file *p, void *v) +{ + int i; + + for (i = 0; i < NR_IRQS; i++) { + seq_printf(p, "%3d: %10u ",i,int_irq_count[i]); + seq_printf(p, "%s\n", irq_list[i].devname); + } + + return 0; +} + +void init_irq_proc(void) +{ +} diff --git a/arch/h8300/vmlinux.lds.S b/arch/h8300/vmlinux.lds.S new file mode 100644 index 0000000000000..23cd933a89fe2 --- /dev/null +++ b/arch/h8300/vmlinux.lds.S @@ -0,0 +1,38 @@ +#include + +#ifdef CONFIG_H8300H_GENERIC +#ifdef CONFIG_ROMKERNEL +#include "platform/h8300h/generic/rom.ld" +#endif +#ifdef CONFIG_RAMKERNEL +#include "platform/h8300h/generic/ram.ld" +#endif +#endif + +#ifdef CONFIG_H8300H_AKI3068NET +#ifdef CONFIG_ROMKERNEL +#include "platform/h8300h/aki3068net/rom.ld" +#endif +#ifdef CONFIG_RAMKERNEL +#include "platform/h8300h/aki3068net/ram.ld" +#endif +#endif + +#ifdef CONFIG_H8300H_H8MAX +#ifdef CONFIG_ROMKERNEL +#include "platform/h8300h/h8max/rom.ld" +#endif +#ifdef CONFIG_RAMKERNEL +#include "platform/h8300h/h8max/ram.ld" +#endif +#endif + +#ifdef CONFIG_H8300H_SIM +#ifdef CONFIG_ROMKERNEL +#include "platform/h8300h/generic/rom.ld" +#endif +#ifdef CONFIG_RAMKERNEL +#include "platform/h8300h/generic/ram.ld" +#endif +#endif + diff --git a/include/asm-h8300/a.out.h b/include/asm-h8300/a.out.h new file mode 100644 index 0000000000000..3c70939f9f003 --- /dev/null +++ b/include/asm-h8300/a.out.h @@ -0,0 +1,26 @@ +#ifndef __H8300_A_OUT_H__ +#define __H8300_A_OUT_H__ + +struct exec +{ + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#ifdef __KERNEL__ + +#define STACK_TOP TASK_SIZE + +#endif + +#endif /* __H8300_A_OUT_H__ */ diff --git a/include/asm-h8300/aki3068net/ne.h b/include/asm-h8300/aki3068net/ne.h new file mode 100644 index 0000000000000..f20bfbc1afa38 --- /dev/null +++ b/include/asm-h8300/aki3068net/ne.h @@ -0,0 +1,23 @@ +/* AE-3068 (aka. aki3068net) RTL8019AS Config */ + +#define NE2000_ADDR CONFIG_NE_BASE +#define NE2000_IRQ 5 +#define NE2000_IRQ_VECTOR (12 + NE2000_IRQ) +#define NE2000_BYTE volatile unsigned short + +#define IER 0xfee015 +#define ISR 0xfee016 +#define IRQ_MASK (1 << NE2000_IRQ) + +#define WCRL 0xfee023 +#define MAR0A 0xffff20 +#define ETCR0A 0xffff24 +#define DTCR0A 0xffff27 +#define MAR0B 0xffff28 +#define DTCR0B 0xffff2f + +#define H8300_INIT_NE() \ +do { \ + wordlength = 1; \ + outb_p(0x48, ioaddr + EN0_DCFG); \ +} while(0) diff --git a/include/asm-h8300/atomic.h b/include/asm-h8300/atomic.h new file mode 100644 index 0000000000000..1b1b2490dd005 --- /dev/null +++ b/include/asm-h8300/atomic.h @@ -0,0 +1,107 @@ +#ifndef __ARCH_H8300_ATOMIC__ +#define __ARCH_H8300_ATOMIC__ + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + */ + +typedef struct { int counter; } atomic_t; +#define ATOMIC_INIT(i) { (i) } + +#define atomic_read(v) ((v)->counter) +#define atomic_set(v, i) (((v)->counter) = i) + +#include +#include + +static __inline__ int atomic_add_return(int i, atomic_t *v) +{ + int ret,flags; + local_irq_save(flags); + ret = v->counter += i; + local_irq_restore(flags); + return ret; +} + +#define atomic_add(i, v) atomic_add_return(i, v) + +static __inline__ int atomic_sub_return(int i, atomic_t *v) +{ + int ret,flags; + local_irq_save(flags); + ret = v->counter -= i; + local_irq_restore(flags); + return ret; +} + +#define atomic_sub(i, v) atomic_sub_return(i, v) + +static __inline__ int atomic_inc_return(atomic_t *v) +{ + int ret,flags; + local_irq_save(flags); + v->counter++; + ret = v->counter; + local_irq_restore(flags); + return ret; +} + +#define atomic_inc(v) atomic_inc_return(v) + +static __inline__ int atomic_dec_return(atomic_t *v) +{ + int ret,flags; + local_irq_save(flags); + --v->counter; + ret = v->counter; + local_irq_restore(flags); + return ret; +} + +#define atomic_dec(v) atomic_dec_return(v) + +static __inline__ int atomic_dec_and_test(atomic_t *v) +{ + int ret,flags; + local_irq_save(flags); + --v->counter; + ret = v->counter; + local_irq_restore(flags); + return ret == 0; +} + +static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *v) +{ + __asm__ __volatile__("stc ccr,r2l\n\t" + "orc #0x80,ccr\n\t" + "mov.l %0,er0\n\t" + "mov.l %1,er1\n\t" + "and.l er1,er0\n\t" + "mov.l er0,%0\n\t" + "ldc r2l,ccr" + : "=m" (*v) : "ir" (~(mask)) :"er0","er1","er2"); +} + +static __inline__ void atomic_set_mask(unsigned long mask, unsigned long *v) +{ + __asm__ __volatile__("stc ccr,r2l\n\t" + "orc #0x80,ccr\n\t" + "mov.l %0,er0\n\t" + "mov.l %1,er1\n\t" + "or.l er1,er0\n\t" + "mov.l er0,%0\n\t" + "ldc r2l,ccr" + : "=m" (*v) : "ir" (mask) :"er0","er1","er2"); +} + +/* Atomic operations are already serializing */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + +#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) +#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) + +#endif /* __ARCH_H8300_ATOMIC __ */ diff --git a/include/asm-h8300/bitops.h b/include/asm-h8300/bitops.h new file mode 100644 index 0000000000000..6366c97b3db32 --- /dev/null +++ b/include/asm-h8300/bitops.h @@ -0,0 +1,480 @@ +#ifndef _H8300_BITOPS_H +#define _H8300_BITOPS_H + +/* + * Copyright 1992, Linus Torvalds. + * Copyright 2002, Yoshinori Sato + */ + +#include +#include +#include +#include /* swab32 */ + +#ifdef __KERNEL__ +/* + * Function prototypes to keep gcc -Wall happy + */ + +/* + * The __ functions are not atomic + */ + +extern void set_bit(int nr, volatile unsigned long* addr); +extern void clear_bit(int nr, volatile unsigned long* addr); +extern void change_bit(int nr, volatile unsigned long* addr); +extern int test_and_set_bit(int nr, volatile unsigned long* addr); +extern int __test_and_set_bit(int nr, volatile unsigned long* addr); +extern int test_and_clear_bit(int nr, volatile unsigned long* addr); +extern int __test_and_clear_bit(int nr, volatile unsigned long* addr); +extern int test_and_change_bit(int nr, volatile unsigned long* addr); +extern int __test_and_change_bit(int nr, volatile unsigned long* addr); +extern int __constant_test_bit(int nr, const volatile unsigned long* addr); +extern int __test_bit(int nr, volatile unsigned long* addr); +extern int find_first_zero_bit(void * addr, unsigned size); +extern int find_next_zero_bit (void * addr, int size, int offset); + +/* + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check against ~0UL first.. + */ +extern __inline__ unsigned long ffz(unsigned long word) +{ + unsigned long result; + + __asm__("sub.l %0,%0\n\t" + "dec.l #1,%0\n" + "1:\n\t" + "shlr.l %1\n\t" + "adds #1,%0\n\t" + "bcs 1b" + : "=r" (result) : "r" (word)); + return result; +} + +extern __inline__ void set_bit(int nr, volatile unsigned long* addr) +{ + unsigned char *a = (unsigned char *) addr; + a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3)); + __asm__("mov.l %0,er0\n\t" + "bset r0l,@%1" + ::"r"(nr & 7),"r"(a):"er0","er1"); +} +/* Bigendian is complexed... */ + +#define __set_bit(nr, addr) set_bit(nr, addr) + +/* + * clear_bit() doesn't provide any barrier for the compiler. + */ +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +extern __inline__ void clear_bit(int nr, volatile unsigned long* addr) +{ + unsigned char *a = (unsigned char *) addr; + a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3)); + __asm__("mov.l %0,er0\n\t" + "bclr r0l,@%1" + ::"r"(nr & 7),"r"(a):"er0"); +} + +#define __clear_bit(nr, addr) clear_bit(nr, addr) + +extern __inline__ void change_bit(int nr, volatile unsigned long* addr) +{ + unsigned char *a = (unsigned char *) addr; + a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3)); + __asm__("mov.l %0,er0\n\t" + "bnot r0l,@%1" + ::"r"(nr & 7),"r"(a):"er0"); +} + +#define __change_bit(nr, addr) change_bit(nr, addr) + +extern __inline__ int test_and_set_bit(int nr, volatile unsigned long* addr) +{ + int retval; + unsigned char *a; + a = (unsigned char *) addr; + + a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3)); + __asm__("mov.l %1,er0\n\t" + "stc ccr,r0h\n\t" + "orc #0x80,ccr\n\t" + "btst r0l,@%2\n\t" + "bset r0l,@%2\n\t" + "stc ccr,r0l\n\t" + "ldc r0h,ccr\n\t" + "btst #2,r0l\n\t" + "bne 1f\n\t" + "sub.l %0,%0\n\t" + "inc.l #1,%0\n" + "bra 2f\n" + "1:\n\t" + "sub.l %0,%0\n" + "2:" + : "=r"(retval) :"r"(nr & 7),"r"(a):"er0"); + return retval; +} + +extern __inline__ int __test_and_set_bit(int nr, volatile unsigned long* addr) +{ + int retval; + unsigned char *a = (unsigned char *) addr; + + a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3)); + __asm__("mov.l %1,er0\n\t" + "btst r0l,@%2\n\t" + "bset r0l,@%2\n\t" + "beq 1f\n\t" + "sub.l %0,%0\n\t" + "inc.l #1,%0\n" + "bra 2f\n" + "1:\n\t" + "sub.l %0,%0\n" + "2:" + : "=r"(retval) :"r"(nr & 7),"r"(a):"er0"); + return retval; +} + +extern __inline__ int test_and_clear_bit(int nr, volatile unsigned long* addr) +{ + int retval; + unsigned char *a = (unsigned char *) addr; + + a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3)); + __asm__("mov.l %1,er0\n\t" + "stc ccr,r0h\n\t" + "orc #0x80,ccr\n\t" + "btst r0l,@%2\n\t" + "bclr r0l,@%2\n\t" + "stc ccr,r0l\n\t" + "ldc r0h,ccr\n\t" + "btst #2,r0l\n\t" + "bne 1f\n\t" + "sub.l %0,%0\n\t" + "inc.l #1,%0\n" + "bra 2f\n" + "1:\n\t" + "sub.l %0,%0\n" + "2:" + : "=r"(retval) :"r"(nr & 7),"r"(a):"er0"); + return retval; +} + +extern __inline__ int __test_and_clear_bit(int nr, volatile unsigned long* addr) +{ + int retval; + unsigned char *a = (unsigned char *) addr; + + a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3)); + __asm__("mov.l %1,er0\n\t" + "btst r0l,@%2\n\t" + "bclr r0l,@%2\n\t" + "beq 1f\n\t" + "sub.l %0,%0\n\t" + "inc.l #1,%0\n" + "bra 2f\n" + "1:\n\t" + "sub.l %0,%0\n" + "2:" + : "=r"(retval) :"r"(nr & 7),"r"(a):"er0"); + return retval; +} + +extern __inline__ int test_and_change_bit(int nr, volatile unsigned long* addr) +{ + int retval; + unsigned char *a = (unsigned char *) addr; + + a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3)); + __asm__("mov.l %1,er0\n\t" + "stc ccr,r0h\n\t" + "orc #0x80,ccr\n\t" + "btst r0l,@%2\n\t" + "bnot r0l,@%2\n\t" + "stc ccr,r0l\n\t" + "ldc r0h,ccr\n\t" + "btst #2,r0l\n\t" + "bne 1f\n\t" + "sub.l %0,%0\n\t" + "inc.l #1,%0\n" + "bra 2f\n" + "1:\n\t" + "sub.l %0,%0\n" + "2:" + : "=r"(retval) :"r"(nr & 7),"r"(a):"er0"); + return retval; +} + +extern __inline__ int __test_and_change_bit(int nr, volatile unsigned long* addr) +{ + int retval; + unsigned char *a = (unsigned char *) addr; + + a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3)); + __asm__("mov.l %1,er0\n\t" + "btst r0l,@%2\n\t" + "bnot r0l,@%2\n\t" + "beq 1f\n\t" + "sub.l %0,%0\n\t" + "inc.l #1,%0\n" + "bra 2f\n" + "1:\n\t" + "sub.l %0,%0\n" + "2:" + : "=r"(retval) :"r"(nr & 7),"r"(a):"er0"); + return retval; +} + +/* + * This routine doesn't need to be atomic. + */ +extern __inline__ int __constant_test_bit(int nr, const volatile unsigned long* addr) +{ + return ((1UL << (nr & 7)) & + (((const volatile unsigned char *) addr) + [((nr >> 3) & ~3) + 3 - ((nr >> 3) & 3)])) != 0; +} + +extern __inline__ int __test_bit(int nr, volatile unsigned long* addr) +{ + int retval; + unsigned char *a = (unsigned char *) addr; + + a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3)); + __asm__("mov.l %1,er0\n\t" + "btst r0l,@%2\n\t" + "beq 1f\n\t" + "sub.l %0,%0\n\t" + "inc.l #1,%0\n" + "bra 2f\n" + "1:\n\t" + "sub.l %0,%0\n" + "2:" + : "=r"(retval) :"r"(nr & 7),"r"(a):"er0"); + return retval; +} + +#define test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + __constant_test_bit((nr),(addr)) : \ + __test_bit((nr),(addr))) + + +#define find_first_zero_bit(addr, size) \ + find_next_zero_bit((addr), (size), 0) + +extern __inline__ int find_next_zero_bit (void * addr, int size, int offset) +{ + unsigned long *p = ((unsigned long *) addr) + (offset >> 5); + unsigned long result = offset & ~31UL; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if (offset) { + tmp = *(p++); + tmp |= ~0UL >> (32-offset); + if (size < 32) + goto found_first; + if (~tmp) + goto found_middle; + size -= 32; + result += 32; + } + while (size & ~31UL) { + if (~(tmp = *(p++))) + goto found_middle; + result += 32; + size -= 32; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp |= ~0UL >> size; +found_middle: + return result + ffz(tmp); +} + +extern __inline__ unsigned long ffs(unsigned long word) +{ + unsigned long result; + + __asm__("sub.l er0,er0\n\t" + "dec.l #1,er0\n" + "1:\n\t" + "shlr.l %1\n\t" + "adds #1,er0\n\t" + "bcc 1b\n\t" + "mov.l er0,%0" + : "=r" (result) : "r"(word) : "er0"); + return result; +} + +#define __ffs(x) ffs(x) + +/* + * fls: find last bit set. + */ +#define fls(x) generic_fls(x) + +/* + * Every architecture must define this function. It's the fastest + * way of searching a 140-bit bitmap where the first 100 bits are + * unlikely to be set. It's guaranteed that at least one of the 140 + * bits is cleared. + */ +static inline int sched_find_first_bit(unsigned long *b) +{ + if (unlikely(b[0])) + return __ffs(b[0]); + if (unlikely(b[1])) + return __ffs(b[1]) + 32; + if (unlikely(b[2])) + return __ffs(b[2]) + 64; + if (b[3]) + return __ffs(b[3]) + 96; + return __ffs(b[4]) + 128; +} + +/* + * hweightN: returns the hamming weight (i.e. the number + * of bits set) of a N-bit word + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +extern __inline__ int ext2_set_bit(int nr, volatile void *addr) +{ + unsigned char *a = (unsigned char *) addr; + register unsigned short r __asm__("er0"); + a += nr >> 3; + __asm__("mov.l %1,er0\n\t" + "sub.w e0,e0\n\t" + "btst r0l,@%2\n\t" + "bset r0l,@%2\n\t" + "beq 1f\n\t" + "inc.w #1,e0\n" + "1:\n\t" + "mov.w e0,r0\n\t" + "sub.w e0,e0" + :"=r"(r):"r"(nr & 7),"r"(a)); + return r; +} + +extern __inline__ int ext2_clear_bit(int nr, volatile void *addr) +{ + unsigned char *a = (unsigned char *) addr; + register unsigned short r __asm__("er0"); + a += nr >> 3; + __asm__("mov.l %1,er0\n\t" + "sub.w e0,e0\n\t" + "btst r0l,@%2\n\t" + "bclr r0l,@%2\n\t" + "beq 1f\n\t" + "inc.w #1,e0\n" + "1:\n\t" + "mov.w e0,r0\n\t" + "sub.w e0,e0" + :"=r"(r):"r"(nr & 7),"r"(a)); + return r; +} + +extern __inline__ int ext2_test_bit(int nr, volatile void *addr) +{ + unsigned char *a = (unsigned char *) addr; + int ret; + a += nr >> 3; + __asm__("mov.l %1,er0\n\t" + "sub.l %0,%0\n\t" + "btst r0l,@%2\n\t" + "beq 1f\n\t" + "inc.l #1,%0\n" + "1:" + : "=r"(ret) :"r"(nr & 7),"r"(a):"er0","er1"); + return ret; +} + + +#define ext2_find_first_zero_bit(addr, size) \ + ext2_find_next_zero_bit((addr), (size), 0) + +extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) +{ + unsigned long *p = ((unsigned long *) addr) + (offset >> 5); + unsigned long result = offset & ~31UL; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if(offset) { + /* We hold the little endian value in tmp, but then the + * shift is illegal. So we could keep a big endian value + * in tmp, like this: + * + * tmp = __swab32(*(p++)); + * tmp |= ~0UL >> (32-offset); + * + * but this would decrease performance, so we change the + * shift: + */ + tmp = *(p++); + tmp |= __swab32(~0UL >> (32-offset)); + if(size < 32) + goto found_first; + if(~tmp) + goto found_middle; + size -= 32; + result += 32; + } + while(size & ~31UL) { + if(~(tmp = *(p++))) + goto found_middle; + result += 32; + size -= 32; + } + if(!size) + return result; + tmp = *p; + +found_first: + /* tmp is little endian, so we would have to swab the shift, + * see above. But then we have to swab tmp below for ffz, so + * we might as well do this here. + */ + return result + ffz(__swab32(tmp) | (~0UL << size)); +found_middle: + return result + ffz(__swab32(tmp)); +} + +/* Bitmap functions for the minix filesystem. */ +#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr) +#define minix_set_bit(nr,addr) set_bit(nr,addr) +#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr) +#define minix_test_bit(nr,addr) test_bit(nr,addr) +#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) + +/** + * hweightN - returns the hamming weight of a N-bit word + * @x: the word to weigh + * + * The Hamming Weight of a number is the total number of bits set in it. + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +#endif /* __KERNEL__ */ + +#endif /* _H8300_BITOPS_H */ diff --git a/include/asm-h8300/bootinfo.h b/include/asm-h8300/bootinfo.h new file mode 100644 index 0000000000000..5bed7e7aac0ac --- /dev/null +++ b/include/asm-h8300/bootinfo.h @@ -0,0 +1,2 @@ + +/* Nothing for h8300 */ diff --git a/include/asm-h8300/bug.h b/include/asm-h8300/bug.h new file mode 100644 index 0000000000000..1412c9d3ec075 --- /dev/null +++ b/include/asm-h8300/bug.h @@ -0,0 +1,12 @@ +#ifndef _H8300_BUG_H +#define _H8300_BUG_H + +#define BUG() do { \ + printk("%s(%d): kernel BUG!\n", __FILE__, __LINE__); \ +} while (0) + +#define PAGE_BUG(page) do { \ + BUG(); \ +} while (0) + +#endif diff --git a/include/asm-h8300/bugs.h b/include/asm-h8300/bugs.h new file mode 100644 index 0000000000000..1cb4afba6eb16 --- /dev/null +++ b/include/asm-h8300/bugs.h @@ -0,0 +1,16 @@ +/* + * include/asm-h8300/bugs.h + * + * Copyright (C) 1994 Linus Torvalds + */ + +/* + * This is included by init/main.c to check for architecture-dependent bugs. + * + * Needs: + * void check_bugs(void); + */ + +static void check_bugs(void) +{ +} diff --git a/include/asm-h8300/byteorder.h b/include/asm-h8300/byteorder.h new file mode 100644 index 0000000000000..36e597d616195 --- /dev/null +++ b/include/asm-h8300/byteorder.h @@ -0,0 +1,13 @@ +#ifndef _H8300_BYTEORDER_H +#define _H8300_BYTEORDER_H + +#include + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __BYTEORDER_HAS_U64__ +# define __SWAB_64_THRU_32__ +#endif + +#include + +#endif /* _H8300_BYTEORDER_H */ diff --git a/include/asm-h8300/cache.h b/include/asm-h8300/cache.h new file mode 100644 index 0000000000000..c6350283649d4 --- /dev/null +++ b/include/asm-h8300/cache.h @@ -0,0 +1,12 @@ +#ifndef __ARCH_H8300_CACHE_H +#define __ARCH_H8300_CACHE_H + +/* bytes per L1 cache line */ +#define L1_CACHE_BYTES 4 + +/* m68k-elf-gcc 2.95.2 doesn't like these */ + +#define __cacheline_aligned +#define ____cacheline_aligned + +#endif diff --git a/include/asm-h8300/cachectl.h b/include/asm-h8300/cachectl.h new file mode 100644 index 0000000000000..c464022d8e266 --- /dev/null +++ b/include/asm-h8300/cachectl.h @@ -0,0 +1,14 @@ +#ifndef _H8300_CACHECTL_H +#define _H8300_CACHECTL_H + +/* Definitions for the cacheflush system call. */ + +#define FLUSH_SCOPE_LINE 0 /* Flush a cache line */ +#define FLUSH_SCOPE_PAGE 0 /* Flush a page */ +#define FLUSH_SCOPE_ALL 0 /* Flush the whole cache -- superuser only */ + +#define FLUSH_CACHE_DATA 0 /* Writeback and flush data cache */ +#define FLUSH_CACHE_INSN 0 /* Flush instruction cache */ +#define FLUSH_CACHE_BOTH 0 /* Flush both caches */ + +#endif /* _H8300_CACHECTL_H */ diff --git a/include/asm-h8300/cacheflush.h b/include/asm-h8300/cacheflush.h new file mode 100644 index 0000000000000..6cd61c3a358cc --- /dev/null +++ b/include/asm-h8300/cacheflush.h @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2002, Yoshinori Sato + */ + +#ifndef _ASM_H8300_CACHEFLUSH_H +#define _AMS_H8300_CACHEFLUSH_H + +/* + * Cache handling functions + * No Cache memory all dummy functions + */ + +#define flush_cache_all() +#define flush_cache_all() +#define flush_cache_mm(mm) +#define flush_cache_range(vma,a,b) +#define flush_cache_page(vma,p) +#define flush_page_to_ram(page) +#define flush_dcache_page(page) +#define flush_icache() +#define flush_icache_page(vma,page) +#define flush_icache_range(start,len) +#define cache_push_v(vaddr,len) +#define cache_push(paddr,len) +#define cache_clear(paddr,len) + +#define flush_dcache_range(a,b) + +#define flush_icache_user_range(vma,page,addr,len) + +#endif /* _ASM_H8300_CACHEFLUSH_H */ diff --git a/include/asm-h8300/checksum.h b/include/asm-h8300/checksum.h new file mode 100644 index 0000000000000..120c36d4aea34 --- /dev/null +++ b/include/asm-h8300/checksum.h @@ -0,0 +1,105 @@ +#ifndef _H8300_CHECKSUM_H +#define _H8300_CHECKSUM_H + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum); + + +/* + * the same as csum_partial_copy, but copies from user space. + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +extern unsigned int csum_partial_copy_from_user(const char *src, char *dst, + int len, int sum, int *csum_err); + +#define csum_partial_copy_nocheck(src, dst, len, sum) \ + csum_partial_copy((src), (dst), (len), (sum)) + +unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl); + + +/* + * Fold a partial checksum + */ + +static inline unsigned int csum_fold(unsigned int sum) +{ + __asm__("mov.l %0,er0\n\t" + "sub.w r1,r1\n\t" + "add.w e0,r0\n\t" + "addx #0,r1l\n\t" + "add.w r1,r0\n\t" + "sub.w e0,e0\n\t" + "mov.l er0,%0" + : "=r"(sum) + : "0"(sum) + : "er0","er1"); + return ~sum; +} + + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ + +static inline unsigned int +csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len, + unsigned short proto, unsigned int sum) +{ + __asm__ ("sub.l er0,er0\n\t" + "add.l %2,%0\n\t" + "addx #0,r0l\n\t" + "add.l %3,%0\n\t" + "addx #0,r0l\n\t" + "add.l %4,%0\n\t" + "addx #0,r0l\n\t" + "add.l er0,%0\n\t" + "bcc 1f\n\t" + "inc.l #1,%0\n" + "1:" + : "=&r" (sum) + : "0" (sum), "r" (daddr), "r" (saddr), "r" (len + proto) + :"er0"); + return sum; +} + +static inline unsigned short int +csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len, + unsigned short proto, unsigned int sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +extern unsigned short ip_compute_csum(const unsigned char * buff, int len); + +#endif /* _H8300_CHECKSUM_H */ diff --git a/include/asm-h8300/current.h b/include/asm-h8300/current.h new file mode 100644 index 0000000000000..57d74ee55a147 --- /dev/null +++ b/include/asm-h8300/current.h @@ -0,0 +1,25 @@ +#ifndef _H8300_CURRENT_H +#define _H8300_CURRENT_H +/* + * current.h + * (C) Copyright 2000, Lineo, David McCullough + * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) + * + * rather than dedicate a register (as the m68k source does), we + * just keep a global, we should probably just change it all to be + * current and lose _current_task. + */ + +#include +#include + +struct task_struct; + +static inline struct task_struct *get_current(void) +{ + return(current_thread_info()->task); +} + +#define current get_current() + +#endif /* _H8300_CURRENT_H */ diff --git a/include/asm-h8300/dbg.h b/include/asm-h8300/dbg.h new file mode 100644 index 0000000000000..2c6d1cbcf736d --- /dev/null +++ b/include/asm-h8300/dbg.h @@ -0,0 +1,2 @@ +#define DEBUG 1 +#define BREAK asm volatile ("trap #3") diff --git a/include/asm-h8300/delay.h b/include/asm-h8300/delay.h new file mode 100644 index 0000000000000..7183e7e16f43e --- /dev/null +++ b/include/asm-h8300/delay.h @@ -0,0 +1,39 @@ +#ifndef _H8300_DELAY_H +#define _H8300_DELAY_H + +#include + +/* + * Copyright (C) 2002 Yoshinori Sato + * + * Delay routines, using a pre-computed "loops_per_second" value. + */ + +extern __inline__ void __delay(unsigned long loops) +{ + __asm__ __volatile__ ("mov.l %0,er0\n\t" + "1:\n\t" + "dec.l #1,er0\n\t" + "bne 1b" + ::"r" (loops):"er0"); +} + +/* + * Use only for very small delays ( < 1 msec). Should probably use a + * lookup table, really, as the multiplications take much too long with + * short delays. This is a "reasonable" implementation, though (and the + * first constant multiplications gets optimized away if the delay is + * a constant) + */ + +extern unsigned long loops_per_jiffy; + +extern __inline__ void udelay(unsigned long usecs) +{ + usecs *= 4295; /* 2**32 / 1000000 */ + usecs /= (loops_per_jiffy*HZ); + if (usecs) + __delay(usecs); +} + +#endif /* _H8300_DELAY_H */ diff --git a/include/asm-h8300/div64.h b/include/asm-h8300/div64.h new file mode 100644 index 0000000000000..df5634def9dc7 --- /dev/null +++ b/include/asm-h8300/div64.h @@ -0,0 +1,13 @@ +#ifndef H8300_DIV64_H +#define H8300_DIV64_H + +/* n = n / base; return rem; */ + +#define do_div(n,base) ({ \ + int __res; \ + __res = ((unsigned long) n) % (unsigned) base; \ + n = ((unsigned long) n) / (unsigned) base; \ + __res; \ +}) + +#endif /* _H8300_DIV64_H */ diff --git a/include/asm-h8300/dma.h b/include/asm-h8300/dma.h new file mode 100644 index 0000000000000..3708681b7ddcf --- /dev/null +++ b/include/asm-h8300/dma.h @@ -0,0 +1,16 @@ +#ifndef _H8300_DMA_H +#define _H8300_DMA_H + +#include + +/* + * Set number of channels of DMA on ColdFire for different implementations. + */ +#define MAX_DMA_CHANNELS 0 +#define MAX_DMA_ADDRESS PAGE_OFFSET + +/* These are in kernel/dma.c: */ +extern int request_dma(unsigned int dmanr, const char *device_id); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ + +#endif /* _H8300_DMA_H */ diff --git a/include/asm-h8300/elf.h b/include/asm-h8300/elf.h new file mode 100644 index 0000000000000..8af8df06f23ca --- /dev/null +++ b/include/asm-h8300/elf.h @@ -0,0 +1,57 @@ +#ifndef __ASMH8300_ELF_H +#define __ASMH8300_ELF_H + +/* + * ELF register definitions.. + */ + +#include +#include +#include + +typedef unsigned long elf_greg_t; + +#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef struct user_m68kfp_struct elf_fpregset_t; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ((x)->e_machine == EM_68K) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2MSB +#define ELF_ARCH EM_H8_300H + +#define ELF_PLAT_INIT(_r) _r->er1 = 0 + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 +#endif + +/* This is the location that an ET_DYN program is loaded if exec'ed. Typical + use of this is to invoke "./ld.so someprog" to test out a new version of + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +#define ELF_ET_DYN_BASE 0xD0000000UL + +/* This yields a mask that user programs can use to figure out what + instruction set this cpu supports. */ + +#define ELF_HWCAP (0) + +/* This yields a string that ld.so will use to load implementation + specific libraries for optimization. This is more specific in + intent than poking at uname or /proc/cpuinfo. */ + +#define ELF_PLATFORM (NULL) + +#ifdef __KERNEL__ +#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX) +#endif diff --git a/include/asm-h8300/errno.h b/include/asm-h8300/errno.h new file mode 100644 index 0000000000000..db092a534d43e --- /dev/null +++ b/include/asm-h8300/errno.h @@ -0,0 +1,132 @@ +#ifndef _H8300_ERRNO_H +#define _H8300_ERRNO_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ + +#endif /* _H8300_ERRNO_H */ diff --git a/include/asm-h8300/fcntl.h b/include/asm-h8300/fcntl.h new file mode 100644 index 0000000000000..a7e7ac01d0d76 --- /dev/null +++ b/include/asm-h8300/fcntl.h @@ -0,0 +1,86 @@ +#ifndef _H8300_FCNTL_H +#define _H8300_FCNTL_H + +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files + located on an ext2 file system */ +#define O_ACCMODE 0003 +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 0100 /* not fcntl */ +#define O_EXCL 0200 /* not fcntl */ +#define O_NOCTTY 0400 /* not fcntl */ +#define O_TRUNC 01000 /* not fcntl */ +#define O_APPEND 02000 +#define O_NONBLOCK 04000 +#define O_NDELAY O_NONBLOCK +#define O_SYNC 010000 +#define FASYNC 020000 /* fcntl, for BSD compatibility */ +#define O_DIRECTORY 040000 /* must be a directory */ +#define O_NOFOLLOW 0100000 /* don't follow links */ +#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */ +#define O_LARGEFILE 0400000 + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get close_on_exec */ +#define F_SETFD 2 /* set/clear close_on_exec */ +#define F_GETFL 3 /* get file->f_flags */ +#define F_SETFL 4 /* set file->f_flags */ +#define F_GETLK 5 +#define F_SETLK 6 +#define F_SETLKW 7 + +#define F_SETOWN 8 /* for sockets. */ +#define F_GETOWN 9 /* for sockets. */ +#define F_SETSIG 10 /* for sockets. */ +#define F_GETSIG 11 /* for sockets. */ + +#define F_GETLK64 12 /* using 'struct flock64' */ +#define F_SETLK64 13 +#define F_SETLKW64 14 + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* for posix fcntl() and lockf() */ +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 + +/* for old implementation of bsd flock () */ +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ + +/* for leases */ +#define F_INPROGRESS 16 + +/* operations for bsd flock(), also used by the kernel implementation */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +#define LOCK_UN 8 /* remove lock */ + +#define LOCK_MAND 32 /* This is a mandatory flock */ +#define LOCK_READ 64 /* ... Which allows concurrent read operations */ +#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */ +#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */ + +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; +}; + +struct flock64 { + short l_type; + short l_whence; + loff_t l_start; + loff_t l_len; + pid_t l_pid; +}; + +#define F_LINUX_SPECIFIC_BASE 1024 +#endif /* _H8300_FCNTL_H */ diff --git a/include/asm-h8300/flat.h b/include/asm-h8300/flat.h new file mode 100644 index 0000000000000..ac3f50610f543 --- /dev/null +++ b/include/asm-h8300/flat.h @@ -0,0 +1,10 @@ +/* + * include/asm-h8300/flat.h -- uClinux flat-format executables + */ + +#ifndef __H8300_FLAT_H__ +#define __H8300_FLAT_H__ + +#define flat_argvp_envp_on_stack() 1 + +#endif /* __H8300_FLAT_H__ */ diff --git a/include/asm-h8300/fpu.h b/include/asm-h8300/fpu.h new file mode 100644 index 0000000000000..4fc416e80bef0 --- /dev/null +++ b/include/asm-h8300/fpu.h @@ -0,0 +1 @@ +/* Nothing do */ diff --git a/include/asm-h8300/generic/timer_rate.h b/include/asm-h8300/generic/timer_rate.h new file mode 100644 index 0000000000000..48c87ab781338 --- /dev/null +++ b/include/asm-h8300/generic/timer_rate.h @@ -0,0 +1,11 @@ +#include + +#if defined(CONFIG_H83007) || defined(CONFIG_H83068) +#define H8300_TIMER_COUNT_DATA CONFIG_CPU_CLOCK*10/8192 +#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 +#endif + +#if defined(H8_3002) || defined(CONFIG_H83048) +#define H8300_TIMER_COUNT_DATA CONFIG_CPU_CLOCK*10/8 +#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8 +#endif diff --git a/include/asm-h8300/gpio.h b/include/asm-h8300/gpio.h new file mode 100644 index 0000000000000..d43c2ab525cf6 --- /dev/null +++ b/include/asm-h8300/gpio.h @@ -0,0 +1,46 @@ +#ifndef _H8300_GPIO_H +#define _H8300_GPIO_H + +#define H8300_GPIO_P1 0 +#define H8300_GPIO_P2 1 +#define H8300_GPIO_P3 2 +#define H8300_GPIO_P4 3 +#define H8300_GPIO_P5 4 +#define H8300_GPIO_P6 5 +/*#define H8300_GPIO_P7 6*/ +#define H8300_GPIO_P8 7 +#define H8300_GPIO_P9 8 +#define H8300_GPIO_PA 9 +#define H8300_GPIO_PB 10 + +#define H8300_GPIO_B7 0x80 +#define H8300_GPIO_B6 0x40 +#define H8300_GPIO_B5 0x20 +#define H8300_GPIO_B4 0x10 +#define H8300_GPIO_B3 0x08 +#define H8300_GPIO_B2 0x04 +#define H8300_GPIO_B1 0x02 +#define H8300_GPIO_B0 0x01 + +#define H8300_GPIO_INPUT 0 +#define H8300_GPIO_OUTPUT 1 + +#define H8300_GPIO_RESERVE(port, bits) \ + h8300_reserved_gpio(port, bits) + +#define H8300_GPIO_FREE(port, bits) \ + h8300_free_gpio(port, bits) + +#define H8300_GPIO_DDR(port, bit, dir) \ + h8300_set_gpio_dir(((port) << 8) | bit, dir) + +#define H8300_GPIO_GETDIR(port, bit) \ + h8300_get_gpio_dir(((port) << 8) | bit) + +extern int h8300_reserved_gpio(int port, int bits); +extern int h8300_free_gpio(int port, int bits); +extern int h8300_set_gpio_dir(int port_bit, int dir); +extern int h8300_get_gpio_dir(int port_bit); +extern int h8300_init_gpio(void); + +#endif diff --git a/include/asm-h8300/h8300_ne.h b/include/asm-h8300/h8300_ne.h new file mode 100644 index 0000000000000..debef6ae71404 --- /dev/null +++ b/include/asm-h8300/h8300_ne.h @@ -0,0 +1,19 @@ +/****************************************************************************/ + +/* + * h8300_ne.h -- NE2000 in H8/300H Evalution Board. + * + * (C) Copyright 2002, Yoshinori Sato + */ + +/****************************************************************************/ +#ifndef h8300ne_h +#define h8300ne_h +/****************************************************************************/ + +/* Such a description is OK ? */ +#define DEPEND_HEADER(target) +#include DEPEND_HEADER(TARGET) + +/****************************************************************************/ +#endif /* h8300ne_h */ diff --git a/include/asm-h8300/h8max/ide.h b/include/asm-h8300/h8max/ide.h new file mode 100644 index 0000000000000..e7d75ac579745 --- /dev/null +++ b/include/asm-h8300/h8max/ide.h @@ -0,0 +1,60 @@ +/* H8MAX IDE I/F Config */ + +#define H8300_IDE_BASE 0x200000 +#define H8300_IDE_CTRL 0x60000c +#define H8300_IDE_IRQ 5 +#define H8300_IDE_REG_OFFSET 2 + +#undef outb +#undef inb +#undef outb_p +#undef inb_p +#undef outsw +#undef insw + +#define outb(d,a) h8max_outb(d,(unsigned short *)a) +#define inb(a) h8max_inb((unsigned char *)a) +#define outb_p(d,a) h8max_outb(d,(unsigned short *)a) +#define inb_p(a) h8max_inb((unsigned char *)a) +#define outsw(addr,buf,len) h8max_outsw(addr,buf,len); +#define insw(addr,buf,len) h8max_insw(addr,buf,len); + +static inline void h8max_outb(unsigned short d,unsigned short *a) +{ + *a = d; +} + +static inline unsigned char h8max_inb(unsigned char *a) +{ + return *(a+1); +} + +static inline void h8max_outsw(void *addr, void *buf, int len) +{ + unsigned volatile short *ap = (unsigned volatile short *)addr; + unsigned short *bp = (unsigned short *)buf; + unsigned short d; + while(len--) { + d = *bp++; + *ap = (d >> 8) | (d << 8); + } +} + +static inline void h8max_insw(void *addr, void *buf, int len) +{ + unsigned volatile short *ap = (unsigned volatile short *)addr; + unsigned short *bp = (unsigned short *)buf; + unsigned short d; + while(len--) { + d = *ap; + *bp++ = (d >> 8) | (d << 8); + } +} + +static inline void target_ide_fix_driveid(struct hd_driveid *id) +{ + int c; + unsigned short *p = (unsigned short *)id; + for (c = 0; c < SECTOR_WORDS; c++, p++) + *p = (*p >> 8) | (*p << 8); +} diff --git a/include/asm-h8300/h8max/ne.h b/include/asm-h8300/h8max/ne.h new file mode 100644 index 0000000000000..ab5538dfeb364 --- /dev/null +++ b/include/asm-h8300/h8max/ne.h @@ -0,0 +1,71 @@ +/* H8MAX RTL8019AS Config */ + +#define NE2000_ADDR 0x800600 +#define NE2000_IRQ 4 +#define NE2000_IRQ_VECTOR (12 + NE2000_IRQ) +#define NE2000_BYTE volatile unsigned short + +#define IER 0xfee015 +#define ISR 0xfee016 +#define IRQ_MASK (1 << NE2000_IRQ) +/* sorry quick hack */ +#if defined(outb) +# undef outb +#endif +#define outb(d,a) h8max_outb((d),(a) - NE2000_ADDR) +#if defined(inb) +# undef inb +#endif +#define inb(a) h8max_inb((a) - NE2000_ADDR) +#if defined(outb_p) +# undef outb_p +#endif +#define outb_p(d,a) h8max_outb((d),(a) - NE2000_ADDR) +#if defined(inb_p) +# undef inb_p +#endif +#define inb_p(a) h8max_inb((a) - NE2000_ADDR) +#if defined(outsw) +# undef outsw +#endif +#define outsw(a,p,l) h8max_outsw((a) - NE2000_ADDR,(unsigned short *)p,l) +#if defined(insw) +# undef insw +#endif +#define insw(a,p,l) h8max_insw((a) - NE2000_ADDR,(unsigned short *)p,l) + +#define H8300_INIT_NE() \ +do { \ + wordlength = 2; \ + h8max_outb(0x49, ioaddr + EN0_DCFG); \ + SA_prom[14] = SA_prom[15] = 0x57;\ +} while(0) + +static inline void h8max_outb(unsigned char d,unsigned char a) +{ + *(unsigned short *)(NE2000_ADDR + (a << 1)) = d; +} + +static inline unsigned char h8max_inb(unsigned char a) +{ + return *(unsigned char *)(NE2000_ADDR + (a << 1) +1); +} + +static inline void h8max_outsw(unsigned char a,unsigned short *p,unsigned long l) +{ + unsigned short d; + for (; l != 0; --l, p++) { + d = (((*p) >> 8) & 0xff) | ((*p) << 8); + *(unsigned short *)(NE2000_ADDR + (a << 1)) = d; + } +} + +static inline void h8max_insw(unsigned char a,unsigned short *p,unsigned long l) +{ + unsigned short d; + for (; l != 0; --l, p++) { + d = *(unsigned short *)(NE2000_ADDR + (a << 1)); + *p = (d << 8)|((d >> 8) & 0xff); + } +} + diff --git a/include/asm-h8300/hardirq.h b/include/asm-h8300/hardirq.h new file mode 100644 index 0000000000000..964e681be7337 --- /dev/null +++ b/include/asm-h8300/hardirq.h @@ -0,0 +1,105 @@ +#ifndef __H8300_HARDIRQ_H +#define __H8300_HARDIRQ_H + +#include +#include +#include +#include +#include + +typedef struct { + unsigned int __softirq_pending; + unsigned int __syscall_count; + struct task_struct * __ksoftirqd_task; +} ____cacheline_aligned irq_cpustat_t; + +#include /* Standard mappings for irq_cpustat_t above */ + +/* + * We put the hardirq and softirq counter into the preemption + * counter. The bitmask has the following meaning: + * + * - bits 0-7 are the preemption count (max preemption depth: 256) + * - bits 8-15 are the softirq count (max # of softirqs: 256) + * - bits 16-23 are the hardirq count (max # of hardirqs: 256) + * + * - ( bit 26 is the PREEMPT_ACTIVE flag. ) + * + * PREEMPT_MASK: 0x000000ff + * HARDIRQ_MASK: 0x0000ff00 + * SOFTIRQ_MASK: 0x00ff0000 + */ + +#define PREEMPT_BITS 8 +#define SOFTIRQ_BITS 8 +#define HARDIRQ_BITS 8 + +#define PREEMPT_SHIFT 0 +#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) +#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) + +#define __MASK(x) ((1UL << (x))-1) + +#define PREEMPT_MASK (__MASK(PREEMPT_BITS) << PREEMPT_SHIFT) +#define HARDIRQ_MASK (__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) +#define SOFTIRQ_MASK (__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) + +#define hardirq_count() (preempt_count() & HARDIRQ_MASK) +#define softirq_count() (preempt_count() & SOFTIRQ_MASK) +#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK)) + +#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) +#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) +#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) + +/* + * The hardirq mask has to be large enough to have + * space for potentially all IRQ sources in the system + * nesting on a single CPU: + */ +#if (1 << HARDIRQ_BITS) < NR_IRQS +# error HARDIRQ_BITS is too low! +#endif + +/* + * Are we doing bottom half or hardware interrupt processing? + * Are we in a softirq context? Interrupt context? + */ +#define in_irq() (hardirq_count()) +#define in_softirq() (softirq_count()) +#define in_interrupt() (irq_count()) + +#define hardirq_trylock() (!in_interrupt()) +#define hardirq_endlock() do { } while (0) + +#define irq_enter() (preempt_count() += HARDIRQ_OFFSET) + +#if CONFIG_PREEMPT +# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) +#else +# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET +#endif + +#if CONFIG_PREEMPT +# define in_atomic() (preempt_count() != kernel_locked()) +# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) +#else +# define in_atomic() (preempt_count() != 0) +# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET +#endif + +#define irq_exit() \ +do { \ + preempt_count() -= IRQ_EXIT_OFFSET; \ + if (!in_interrupt() && softirq_pending(smp_processor_id())) \ + do_softirq(); \ + preempt_enable_no_resched(); \ +} while (0) + +#ifndef CONFIG_SMP +# define synchronize_irq(irq) barrier() +#else +# error h8300 SMP is not available +#endif /* CONFIG_SMP */ + +#endif diff --git a/include/asm-h8300/hdreg.h b/include/asm-h8300/hdreg.h new file mode 100644 index 0000000000000..f98b5cde57204 --- /dev/null +++ b/include/asm-h8300/hdreg.h @@ -0,0 +1,13 @@ +/* + * linux/include/asm-h8300/hdreg.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + */ + +#ifndef _H8300_HDREG_H +#define _H8300_HDREG_H + +typedef unsigned int q40ide_ioreg_t; +typedef unsigned char * ide_ioreg_t; + +#endif /* _H8300_HDREG_H */ diff --git a/include/asm-h8300/hw_irq.h b/include/asm-h8300/hw_irq.h new file mode 100644 index 0000000000000..d75a5a1119e84 --- /dev/null +++ b/include/asm-h8300/hw_irq.h @@ -0,0 +1 @@ +/* Do Nothing */ diff --git a/include/asm-h8300/ide.h b/include/asm-h8300/ide.h new file mode 100644 index 0000000000000..3ebf8e2623249 --- /dev/null +++ b/include/asm-h8300/ide.h @@ -0,0 +1,161 @@ +/****************************************************************************/ + +/* + * linux/include/asm-h8300/ide.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + * Copyright (C) 2001 Lineo Inc., davidm@snapgear.com + * Copyright (C) 2002 Greg Ungerer (gerg@snapgear.com) + * Copyright (C) 2002 Yoshinori Sato (ysato@users.sourceforge.jp) + */ + +/****************************************************************************/ +#ifndef _H8300_IDE_H +#define _H8300_IDE_H +/****************************************************************************/ +#ifdef __KERNEL__ +/****************************************************************************/ + +#include +#include + +#include +#include +#include + +/* + * Some coldfire specifics. + */ + +/* + * Save some space, only have 1 interface. + */ +#define MAX_HWIFS 1 + +/* + * Fix up things that may not have been provided. + */ + +#undef SUPPORT_SLOW_DATA_PORTS +#define SUPPORT_SLOW_DATA_PORTS 0 + +#undef SUPPORT_VLB_SYNC +#define SUPPORT_VLB_SYNC 0 + +/* this definition is used only on startup .. */ +#undef HD_DATA +#define HD_DATA NULL + +#define DBGIDE(fmt,a...) +// #define DBGIDE(fmt,a...) printk(fmt, ##a) +#define IDE_INLINE __inline__ +// #define IDE_INLINE + +#define ide__sti() __sti() + +/****************************************************************************/ + +typedef union { + unsigned all : 8; /* all of the bits together */ + struct { + unsigned bit7 : 1; /* always 1 */ + unsigned lba : 1; /* using LBA instead of CHS */ + unsigned bit5 : 1; /* always 1 */ + unsigned unit : 1; /* drive select number, 0 or 1 */ + unsigned head : 4; /* always zeros here */ + } b; +} select_t; + +/* + * Our list of ports/irq's for different boards. + */ + +/* Such a description is OK ? */ +#define DEPEND_HEADER(target) +#include DEPEND_HEADER(TARGET) + +/****************************************************************************/ + +static IDE_INLINE int ide_default_irq(ide_ioreg_t base) +{ + return H8300_IDE_IRQ+12; +} + +static IDE_INLINE ide_ioreg_t ide_default_io_base(int index) +{ + return (ide_ioreg_t)H8300_IDE_BASE; +} + +/* + * Set up a hw structure for a specified data port, control port and IRQ. + * This should follow whatever the default interface uses. + */ +static IDE_INLINE void ide_init_hwif_ports( + hw_regs_t *hw, + ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, + int *irq) +{ + ide_ioreg_t reg = data_port; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += H8300_IDE_REG_OFFSET; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t)H8300_IDE_CTRL; + } +} + + +/* + * This registers the standard ports for this architecture with the IDE + * driver. + */ +static IDE_INLINE void ide_init_default_hwifs(void) +{ + hw_regs_t hw; + ide_ioreg_t base; + int index; + + for (index = 0; index < MAX_HWIFS; index++) { + base = ide_default_io_base(index); + if (!base) + continue; + memset(&hw, 0, sizeof(hw)); + ide_init_hwif_ports(&hw, base, 0, NULL); + hw.irq = ide_default_irq(base); + ide_register_hw(&hw, NULL); + } +} + +#define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id)) +#define ide_free_irq(irq,dev_id) free_irq((irq), (dev_id)) +#define ide_check_region(from,extent) (0) +#define ide_request_region(from,extent,name) do {} while(0) +#define ide_release_region(from,extent) do {} while(0) + +/* + * The following are not needed for the non-m68k ports + */ +#define ide_ack_intr(hwif) (1) +#define ide_fix_driveid(id) target_ide_fix_driveid(id) +#define ide_release_lock(lock) do {} while (0) +#define ide_get_lock(lock, hdlr, data) do {} while (0) + +static IDE_INLINE void ide_print_resource(char *name,hw_regs_t *hw) +{ + printk("%s at 0x%08x-0x%08x,0x%08x on irq %d", name, + (unsigned int)hw->io_ports[IDE_DATA_OFFSET], + (unsigned int)hw->io_ports[IDE_DATA_OFFSET]+(8*H8300_IDE_REG_OFFSET)-1, + (unsigned int)hw->io_ports[IDE_CONTROL_OFFSET], + hw->irq); +} + +/****************************************************************************/ +#endif /* __KERNEL__ */ +#endif /* _H8300_IDE_H */ +/****************************************************************************/ diff --git a/include/asm-h8300/init.h b/include/asm-h8300/init.h new file mode 100644 index 0000000000000..6c908048fd1ac --- /dev/null +++ b/include/asm-h8300/init.h @@ -0,0 +1,11 @@ +#ifndef _H8300_INIT_H +#define _H8300_INIT_H + +#define __init __attribute__ ((__section__ (".text.init"))) +#define __initdata __attribute__ ((__section__ (".data.init"))) +/* For assembly routines */ +#define __INIT .section ".text.init",#alloc,#execinstr +#define __FINIT .previous +#define __INITDATA .section ".data.init",#alloc,#write + +#endif diff --git a/include/asm-h8300/io.h b/include/asm-h8300/io.h new file mode 100644 index 0000000000000..66559c756649c --- /dev/null +++ b/include/asm-h8300/io.h @@ -0,0 +1,234 @@ +#ifndef _H8300_IO_H +#define _H8300_IO_H + +#ifdef __KERNEL__ + +#include +#include + +/* + * These are for ISA/PCI shared memory _only_ and should never be used + * on any other type of memory, including Zorro memory. They are meant to + * access the bus in the bus byte order which is little-endian!. + * + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the m68k architecture, we just read/write the + * memory location directly. + */ +/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates + * two accesses to memory, which may be undesireable for some devices. + */ + +/* + * swap functions are sometimes needed to interface little-endian hardware + */ + +/* + * CHANGES + * + * 020325 Added some #define's for the COBRA5272 board + * (hede) + */ +static inline unsigned short _swapw(volatile unsigned short v) +{ + return ((v << 8) | (v >> 8)); +} + +static inline unsigned int _swapl(volatile unsigned long v) +{ + return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24)); +} + +#define readb(addr) \ + ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; }) +#define readw(addr) \ + ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; }) +#define readl(addr) \ + ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; }) + +#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b)) +#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b)) +#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) + +/* + * The following are some defines we need for MTD with our + * COBRA5272 board. + * Because I don't know if they break something I have + * #ifdef'd them. + * (020325 - hede) + */ +#ifdef CONFIG_senTec +#define __raw_readb readb +#define __raw_readw readw +#define __raw_readl readl +#define __raw_writeb writeb +#define __raw_writew writew +#define __raw_writel writel +#endif /* CONFIG_senTec */ + +static inline void io_outsb(unsigned int addr, void *buf, int len) +{ + volatile unsigned char *ap = (volatile unsigned char *) addr; + unsigned char *bp = (unsigned char *) buf; + while (len--) + *ap = *bp++; +} + +static inline void io_outsw(unsigned int addr, void *buf, int len) +{ + volatile unsigned short *ap = (volatile unsigned short *) addr; + unsigned short *bp = (unsigned short *) buf; + while (len--) + *ap = _swapw(*bp++); +} + +static inline void io_outsl(unsigned int addr, void *buf, int len) +{ + volatile unsigned int *ap = (volatile unsigned int *) addr; + unsigned int *bp = (unsigned int *) buf; + while (len--) + *ap = _swapl(*bp++); +} + +static inline void io_insb(unsigned int addr, void *buf, int len) +{ + volatile unsigned char *ap = (volatile unsigned char *) addr; + unsigned char *bp = (unsigned char *) buf; + while (len--) + *bp++ = *ap; +} + +static inline void io_insw(unsigned int addr, void *buf, int len) +{ + volatile unsigned short *ap = (volatile unsigned short *) addr; + unsigned short *bp = (unsigned short *) buf; + while (len--) + *bp++ = _swapw(*ap); +} + +static inline void io_insl(unsigned int addr, void *buf, int len) +{ + volatile unsigned int *ap = (volatile unsigned int *) addr; + unsigned int *bp = (unsigned int *) buf; + while (len--) + *bp++ = _swapl(*ap); +} + +/* + * make the short names macros so specific devices + * can override them as required + */ + +#define memset_io(a,b,c) memset((void *)(a),(b),(c)) +#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) +#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) + +#define inb(addr) readb(addr) +#define inw(addr) readw(addr) +#define inl(addr) readl(addr) +#define outb(x,addr) ((void) writeb(x,addr)) +#define outw(x,addr) ((void) writew(x,addr)) +#define outl(x,addr) ((void) writel(x,addr)) + +#define inb_p(addr) inb(addr) +#define inw_p(addr) inw(addr) +#define inl_p(addr) inl(addr) +#define outb_p(x,addr) outb(x,addr) +#define outw_p(x,addr) outw(x,addr) +#define outl_p(x,addr) outl(x,addr) + +#define outsb(a,b,l) io_outsb(a,b,l) +#define outsw(a,b,l) io_outsw(a,b,l) +#define outsl(a,b,l) io_outsl(a,b,l) + +#define insb(a,b,l) io_insb(a,b,l) +#define insw(a,b,l) io_insw(a,b,l) +#define insl(a,b,l) io_insl(a,b,l) + +#define IO_SPACE_LIMIT 0xffff + + +/* Values for nocacheflag and cmode */ +#define IOMAP_FULL_CACHING 0 +#define IOMAP_NOCACHE_SER 1 +#define IOMAP_NOCACHE_NONSER 2 +#define IOMAP_WRITETHROUGH 3 + +extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag); +extern void __iounmap(void *addr, unsigned long size); + +extern inline void *ioremap(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} +extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} +extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); +} +extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_FULL_CACHING); +} + +extern void iounmap(void *addr); + +/* Nothing to do */ + +#define dma_cache_inv(_start,_size) do { } while (0) +#define dma_cache_wback(_start,_size) do { } while (0) +#define dma_cache_wback_inv(_start,_size) do { } while (0) + +/* H8/300 internal I/O functions */ +static __inline__ unsigned char ctrl_inb(unsigned long addr) +{ + return *(volatile unsigned char*)addr; +} + +static __inline__ unsigned short ctrl_inw(unsigned long addr) +{ + return *(volatile unsigned short*)addr; +} + +static __inline__ unsigned int ctrl_inl(unsigned long addr) +{ + return *(volatile unsigned long*)addr; +} + +static __inline__ void ctrl_outb(unsigned char b, unsigned long addr) +{ + *(volatile unsigned char*)addr = b; +} + +static __inline__ void ctrl_outw(unsigned short b, unsigned long addr) +{ + *(volatile unsigned short*)addr = b; +} + +static __inline__ void ctrl_outl(unsigned int b, unsigned long addr) +{ + *(volatile unsigned long*)addr = b; +} + +/* Pages to physical address... */ +#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) +#define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT) + +/* + * Macros used for converting between virtual and physical mappings. + */ +#define mm_ptov(vaddr) ((void *) (vaddr)) +#define mm_vtop(vaddr) ((unsigned long) (vaddr)) +#define phys_to_virt(vaddr) ((void *) (vaddr)) +#define virt_to_phys(vaddr) ((unsigned long) (vaddr)) + +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +#endif /* __KERNEL__ */ + +#endif /* _H8300_IO_H */ diff --git a/include/asm-h8300/ioctl.h b/include/asm-h8300/ioctl.h new file mode 100644 index 0000000000000..031c623478b31 --- /dev/null +++ b/include/asm-h8300/ioctl.h @@ -0,0 +1,80 @@ +/* $Id: ioctl.h,v 1.1 2002/11/19 02:09:26 gerg Exp $ + * + * linux/ioctl.h for Linux by H.H. Bergman. + */ + +#ifndef _H8300_IOCTL_H +#define _H8300_IOCTL_H + +/* ioctl command encoding: 32 bits total, command in lower 16 bits, + * size of the parameter structure in the lower 14 bits of the + * upper 16 bits. + * Encoding the size of the parameter structure in the ioctl request + * is useful for catching programs compiled with old versions + * and to avoid overwriting user space outside the user buffer area. + * The highest 2 bits are reserved for indicating the ``access mode''. + * NOTE: This limits the max parameter size to 16kB -1 ! + */ + +/* + * I don't really have any idea about what this should look like, so + * for the time being, this is heavily based on the PC definitions. + */ + +/* + * The following is for compatibility across the various Linux + * platforms. The i386 ioctl numbering scheme doesn't really enforce + * a type field. De facto, however, the top 8 bits of the lower 16 + * bits are indeed used as a type field, so we might just as well make + * this explicit here. Please be sure to use the decoding macros + * below from now on. + */ +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 14 +#define _IOC_DIRBITS 2 + +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) + +/* + * Direction bits. + */ +#define _IOC_NONE 0U +#define _IOC_WRITE 1U +#define _IOC_READ 2U + +#define _IOC(dir,type,nr,size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +/* used to create numbers */ +#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) + +/* used to decode ioctl numbers.. */ +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) + +/* ...and for the drivers/sound files... */ + +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) + +#endif /* _H8300_IOCTL_H */ diff --git a/include/asm-h8300/ioctls.h b/include/asm-h8300/ioctls.h new file mode 100644 index 0000000000000..ac20457e5978d --- /dev/null +++ b/include/asm-h8300/ioctls.h @@ -0,0 +1,81 @@ +#ifndef __ARCH_H8300_IOCTLS_H__ +#define __ARCH_H8300_IOCTLS_H__ + +#include + +/* 0x54 is just a magic number to make these relatively unique ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ +#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ + +#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ +#define FIOCLEX 0x5451 +#define FIOASYNC 0x5452 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ +#define FIOQSIZE 0x545E + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#endif /* __ARCH_H8300_IOCTLS_H__ */ diff --git a/include/asm-h8300/ipc.h b/include/asm-h8300/ipc.h new file mode 100644 index 0000000000000..6219d8a90e552 --- /dev/null +++ b/include/asm-h8300/ipc.h @@ -0,0 +1,31 @@ +#ifndef __H8300_IPC_H__ +#define __H8300_IPC_H__ + +/* + * These are used to wrap system calls on H8/300. + * + * See arch/h8300/kernel/sys_h8300.c for ugly details.. + */ +struct ipc_kludge { + struct msgbuf *msgp; + long msgtyp; +}; + +#define SEMOP 1 +#define SEMGET 2 +#define SEMCTL 3 +#define MSGSND 11 +#define MSGRCV 12 +#define MSGGET 13 +#define MSGCTL 14 +#define SHMAT 21 +#define SHMDT 22 +#define SHMGET 23 +#define SHMCTL 24 + +/* Used by the DIPC package, try and avoid reusing it */ +#define DIPC 25 + +#define IPCCALL(version,op) ((version)<<16 | (op)) + +#endif diff --git a/include/asm-h8300/ipcbuf.h b/include/asm-h8300/ipcbuf.h new file mode 100644 index 0000000000000..2cd1ebcc109db --- /dev/null +++ b/include/asm-h8300/ipcbuf.h @@ -0,0 +1,29 @@ +#ifndef __H8300_IPCBUF_H__ +#define __H8300_IPCBUF_H__ + +/* + * The user_ipc_perm structure for H8/300 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 32-bit mode_t and seq + * - 2 miscellaneous 32-bit values + */ + +struct ipc64_perm +{ + __kernel_key_t key; + __kernel_uid32_t uid; + __kernel_gid32_t gid; + __kernel_uid32_t cuid; + __kernel_gid32_t cgid; + __kernel_mode_t mode; + unsigned short __pad1; + unsigned short seq; + unsigned short __pad2; + unsigned long __unused1; + unsigned long __unused2; +}; + +#endif /* __H8300_IPCBUF_H__ */ diff --git a/include/asm-h8300/irq.h b/include/asm-h8300/irq.h new file mode 100644 index 0000000000000..9202f2a6e52da --- /dev/null +++ b/include/asm-h8300/irq.h @@ -0,0 +1,56 @@ +#ifndef _H8300_IRQ_H_ +#define _H8300_IRQ_H_ + +#define SYS_IRQS 64 + +#define NR_IRQS 64 + +#include + +/* + * "Generic" interrupt sources + */ + +#define IRQ_SCHED_TIMER (40) /* interrupt source for scheduling timer */ + +static __inline__ int irq_cannonicalize(int irq) +{ + return irq; +} + +extern void enable_irq(unsigned int); +extern void disable_irq(unsigned int); + +extern int sys_request_irq(unsigned int, + void (*)(int, void *, struct pt_regs *), + unsigned long, const char *, void *); +extern void sys_free_irq(unsigned int, void *); + +typedef struct irq_node { + void (*handler)(int, void *, struct pt_regs *); + unsigned long flags; + void *dev_id; + const char *devname; + struct irq_node *next; +} irq_node_t; + +/* + * This structure has only 4 elements for speed reasons + */ +typedef struct irq_handler { + void (*handler)(int, void *, struct pt_regs *); + unsigned long flags; + void *dev_id; + const char *devname; +} irq_handler_t; + +/* count of spurious interrupts */ +extern volatile unsigned int num_spurious; + +/* + * Some drivers want these entry points + */ +#define enable_irq_nosync(x) enable_irq(x) +#define disable_irq_nosync(x) disable_irq(x) + +#endif /* _H8300_IRQ_H_ */ diff --git a/include/asm-h8300/keyboard.h b/include/asm-h8300/keyboard.h new file mode 100644 index 0000000000000..b05d11387ae52 --- /dev/null +++ b/include/asm-h8300/keyboard.h @@ -0,0 +1,33 @@ +/* + * linux/include/asm-h8300/keyboard.h + * Created 04 Dec 2001 by Khaled Hassounah + * This file contains the Dragonball architecture specific keyboard definitions + */ + +#ifndef _H8300_KEYBOARD_H +#define _H8300_KEYBOARD_H + +#include + +/* dummy i.e. no real keyboard */ +#define kbd_setkeycode(x...) (-ENOSYS) +#define kbd_getkeycode(x...) (-ENOSYS) +#define kbd_translate(x...) (0) +#define kbd_unexpected_up(x...) (1) +#define kbd_leds(x...) do {;} while (0) +#define kbd_init_hw(x...) do {;} while (0) +#define kbd_enable_irq(x...) do {;} while (0) +#define kbd_disable_irq(x...) do {;} while (0) + + +/* needed if MAGIC_SYSRQ is enabled for serial console */ +#ifndef SYSRQ_KEY +#define SYSRQ_KEY ((unsigned char)(-1)) +#define kbd_sysrq_xlate ((unsigned char *)NULL) +#endif + + +#endif /* _H8300_KEYBOARD_H */ + + + diff --git a/include/asm-h8300/kmap_types.h b/include/asm-h8300/kmap_types.h new file mode 100644 index 0000000000000..82431edeb2a10 --- /dev/null +++ b/include/asm-h8300/kmap_types.h @@ -0,0 +1,19 @@ +#ifndef _ASM_KMAP_TYPES_H +#define _ASM_KMAP_TYPES_H + +enum km_type { + KM_BOUNCE_READ, + KM_SKB_SUNRPC_DATA, + KM_SKB_DATA_SOFTIRQ, + KM_USER0, + KM_USER1, + KM_BIO_SRC_IRQ, + KM_BIO_DST_IRQ, + KM_PTE0, + KM_PTE1, + KM_IRQ0, + KM_IRQ1, + KM_TYPE_NR +}; + +#endif diff --git a/include/asm-h8300/linkage.h b/include/asm-h8300/linkage.h new file mode 100644 index 0000000000000..6f4df7d461808 --- /dev/null +++ b/include/asm-h8300/linkage.h @@ -0,0 +1,8 @@ +#ifndef _H8300_LINKAGE_H +#define _H8300_LINKAGE_H + +#undef SYMBOL_NAME_LABEL +#undef SYMBOL_NAME +#define SYMBOL_NAME_LABEL(_name_) _##_name_##: +#define SYMBOL_NAME(_name_) _##_name_ +#endif diff --git a/include/asm-h8300/linux_logo.h b/include/asm-h8300/linux_logo.h new file mode 100644 index 0000000000000..9c22ccb9051b3 --- /dev/null +++ b/include/asm-h8300/linux_logo.h @@ -0,0 +1,11 @@ +/* + * include/asm-h8300/linux_logo.h: This is a linux logo + * to be displayed on boot. + */ + +#include +#include +#include + +#define linux_logo_banner "Linux/m68knommu version " UTS_RELEASE + diff --git a/include/asm-h8300/mc146818rtc.h b/include/asm-h8300/mc146818rtc.h new file mode 100644 index 0000000000000..ab9d9646d2416 --- /dev/null +++ b/include/asm-h8300/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/include/asm-h8300/md.h b/include/asm-h8300/md.h new file mode 100644 index 0000000000000..1a47dc6691fb3 --- /dev/null +++ b/include/asm-h8300/md.h @@ -0,0 +1,13 @@ +/* $Id: md.h,v 1.1 2002/11/19 02:09:26 gerg Exp $ + * md.h: High speed xor_block operation for RAID4/5 + * + */ + +#ifndef __ASM_MD_H +#define __ASM_MD_H + +/* #define HAVE_ARCH_XORBLOCK */ + +#define MD_XORBLOCK_ALIGNMENT sizeof(long) + +#endif /* __ASM_MD_H */ diff --git a/include/asm-h8300/mman.h b/include/asm-h8300/mman.h new file mode 100644 index 0000000000000..5c3fc5898bccd --- /dev/null +++ b/include/asm-h8300/mman.h @@ -0,0 +1,38 @@ +#ifndef __H8300_MMAN_H__ +#define __H8300_MMAN_H__ + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_NONE 0x0 /* page can not be accessed */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping */ +#define MAP_FIXED 0x10 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x20 /* don't use a file */ + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ +#define MAP_LOCKED 0x2000 /* pages are locked */ +#define MAP_NORESERVE 0x4000 /* don't check for reservations */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate the caches */ +#define MS_SYNC 4 /* synchronous memory sync */ + +#define MCL_CURRENT 1 /* lock all current mappings */ +#define MCL_FUTURE 2 /* lock all future mappings */ + +#define MADV_NORMAL 0x0 /* default page-in behavior */ +#define MADV_RANDOM 0x1 /* page-in minimum required */ +#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ +#define MADV_WILLNEED 0x3 /* pre-fault pages */ +#define MADV_DONTNEED 0x4 /* discard these pages */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __H8300_MMAN_H__ */ diff --git a/include/asm-h8300/mmu.h b/include/asm-h8300/mmu.h new file mode 100644 index 0000000000000..0bbcac5a84b04 --- /dev/null +++ b/include/asm-h8300/mmu.h @@ -0,0 +1,22 @@ +#ifndef __MMU_H +#define __MMU_H + +/* Copyright (C) 2002, David McCullough */ + +struct mm_rblock_struct { + int size; + int refcount; + void *kblock; +}; + +struct mm_tblock_struct { + struct mm_rblock_struct *rblock; + struct mm_tblock_struct *next; +}; + +typedef struct { + struct mm_tblock_struct tblock; + unsigned long end_brk; +} mm_context_t; + +#endif diff --git a/include/asm-h8300/mmu_context.h b/include/asm-h8300/mmu_context.h new file mode 100644 index 0000000000000..ffdf723191cfb --- /dev/null +++ b/include/asm-h8300/mmu_context.h @@ -0,0 +1,32 @@ +#ifndef __H8300_MMU_CONTEXT_H +#define __H8300_MMU_CONTEXT_H + +#include +#include +#include +#include + +static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu) +{ +} + +extern inline int +init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + // mm->context = virt_to_phys(mm->pgd); + return(0); +} + +#define destroy_context(mm) do { } while(0) +#define deactivate_mm(tsk,mm) do { } while(0) + +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu) +{ +} + +extern inline void activate_mm(struct mm_struct *prev_mm, + struct mm_struct *next_mm) +{ +} + +#endif diff --git a/include/asm-h8300/module.h b/include/asm-h8300/module.h new file mode 100644 index 0000000000000..2f4086195bb57 --- /dev/null +++ b/include/asm-h8300/module.h @@ -0,0 +1,12 @@ +#ifndef _ASM_H8300_MODULE_H +#define _ASM_H8300_MODULE_H +/* + * This file contains the H8/300 architecture specific module code. + */ + +#define module_map(x) vmalloc(x) +#define module_unmap(x) vfree(x) +#define module_arch_init(x) (0) +#define arch_init_modules(x) do { } while (0) + +#endif /* _ASM_H8/300_MODULE_H */ diff --git a/include/asm-h8300/msgbuf.h b/include/asm-h8300/msgbuf.h new file mode 100644 index 0000000000000..6b148cd09aa51 --- /dev/null +++ b/include/asm-h8300/msgbuf.h @@ -0,0 +1,31 @@ +#ifndef _H8300_MSGBUF_H +#define _H8300_MSGBUF_H + +/* + * The msqid64_ds structure for H8/300 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct msqid64_ds { + struct ipc64_perm msg_perm; + __kernel_time_t msg_stime; /* last msgsnd time */ + unsigned long __unused1; + __kernel_time_t msg_rtime; /* last msgrcv time */ + unsigned long __unused2; + __kernel_time_t msg_ctime; /* last change time */ + unsigned long __unused3; + unsigned long msg_cbytes; /* current number of bytes on queue */ + unsigned long msg_qnum; /* number of messages in queue */ + unsigned long msg_qbytes; /* max number of bytes on queue */ + __kernel_pid_t msg_lspid; /* pid of last msgsnd */ + __kernel_pid_t msg_lrpid; /* last receive pid */ + unsigned long __unused4; + unsigned long __unused5; +}; + +#endif /* _H8300_MSGBUF_H */ diff --git a/include/asm-h8300/namei.h b/include/asm-h8300/namei.h new file mode 100644 index 0000000000000..ab6f196db6e05 --- /dev/null +++ b/include/asm-h8300/namei.h @@ -0,0 +1,17 @@ +/* + * linux/include/asm-h8300/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __H8300_NAMEI_H +#define __H8300_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif diff --git a/include/asm-h8300/page.h b/include/asm-h8300/page.h new file mode 100644 index 0000000000000..b82c8292e061f --- /dev/null +++ b/include/asm-h8300/page.h @@ -0,0 +1,101 @@ +#ifndef _H8300NOMMU_PAGE_H +#define _H8300NOMMU_PAGE_H + +#include + +/* PAGE_SHIFT determines the page size */ + +#define PAGE_SHIFT (12) +#define PAGE_SIZE (4096) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifdef __KERNEL__ + +#include + +#if !defined(CONFIG_SMALL_TASKS) && PAGE_SHIFT < 13 +#define KTHREAD_SIZE (8192) +#else +#define KTHREAD_SIZE PAGE_SIZE +#endif + +#ifndef __ASSEMBLY__ + +#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) +#define free_user_page(page, addr) free_page(addr) + +#define clear_page(page) memset((page), 0, PAGE_SIZE) +#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) + +#define clear_user_page(page, vaddr, pg) clear_page(page) +#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) + +/* + * These are used to make use of C type-checking.. + */ +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pmd[16]; } pmd_t; +typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; + +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((&x)->pmd[0]) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +/* Pure 2^n version of get_order */ +extern __inline__ int get_order(unsigned long size) +{ + int order; + + size = (size-1) >> (PAGE_SHIFT-1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + +extern unsigned long memory_start; +extern unsigned long memory_end; + +#endif /* !__ASSEMBLY__ */ + +#include + +#define PAGE_OFFSET (PAGE_OFFSET_RAW) + +#ifndef __ASSEMBLY__ + +#define __pa(vaddr) virt_to_phys((void *)vaddr) +#define __va(paddr) phys_to_virt((unsigned long)paddr) + +#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) +#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) + +#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT) +#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)) +#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)) +#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET) +#define VALID_PAGE(page) ((page - mem_map) < max_mapnr) + +#define pfn_to_page(pfn) virt_to_page(pfn_to_virt(pfn)) +#define page_to_pfn(page) virt_to_pfn(page_to_virt(page)) + +#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \ + ((void *)(kaddr) < (void *)memory_end)) + +#endif /* __ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + +#endif /* _H8300NOMMU_PAGE_H */ diff --git a/include/asm-h8300/page_offset.h b/include/asm-h8300/page_offset.h new file mode 100644 index 0000000000000..8cc6e17218a80 --- /dev/null +++ b/include/asm-h8300/page_offset.h @@ -0,0 +1,4 @@ + +#include +#define PAGE_OFFSET_RAW 0x00000000 + diff --git a/include/asm-h8300/param.h b/include/asm-h8300/param.h new file mode 100644 index 0000000000000..73ae4696bc413 --- /dev/null +++ b/include/asm-h8300/param.h @@ -0,0 +1,27 @@ +#ifndef _H8300_PARAM_H +#define _H8300_PARAM_H + +#include + +#ifndef HZ +#define HZ 100 +#endif + +#ifdef __KERNEL__ +#define USER_HZ HZ +#define CLOCKS_PER_SEC (USER_HZ) +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NGROUPS +#define NGROUPS 32 +#endif + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif /* _H8300_PARAM_H */ diff --git a/include/asm-h8300/pci.h b/include/asm-h8300/pci.h new file mode 100644 index 0000000000000..9c183edba5e02 --- /dev/null +++ b/include/asm-h8300/pci.h @@ -0,0 +1,25 @@ +#ifndef _ASM_H8300_PCI_H +#define _ASM_H8300_PCI_H + +/* + * asm-h8300/pci.h - H8/300 specific PCI declarations. + * + * Yoshinori Sato + */ + +#define pcibios_assign_all_busses() 0 + +extern inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} + +extern inline void pcibios_penalize_isa_irq(int irq) +{ + /* We don't do dynamic PCI IRQ allocation */ +} + +/* Return the index of the PCI controller for device PDEV. */ +#define pci_controller_num(PDEV) (0) + +#endif /* _ASM_H8300_PCI_H */ diff --git a/include/asm-h8300/percpu.h b/include/asm-h8300/percpu.h new file mode 100644 index 0000000000000..72c03e3666d88 --- /dev/null +++ b/include/asm-h8300/percpu.h @@ -0,0 +1,6 @@ +#ifndef __ARCH_H8300_PERCPU__ +#define __ARCH_H8300_PERCPU__ + +#include + +#endif /* __ARCH_H8300_PERCPU__ */ diff --git a/include/asm-h8300/pgalloc.h b/include/asm-h8300/pgalloc.h new file mode 100644 index 0000000000000..c2e89a286d238 --- /dev/null +++ b/include/asm-h8300/pgalloc.h @@ -0,0 +1,8 @@ +#ifndef _H8300_PGALLOC_H +#define _H8300_PGALLOC_H + +#include + +#define check_pgt_cache() do { } while (0) + +#endif /* _H8300_PGALLOC_H */ diff --git a/include/asm-h8300/pgtable.h b/include/asm-h8300/pgtable.h new file mode 100644 index 0000000000000..4c09bed3a29bb --- /dev/null +++ b/include/asm-h8300/pgtable.h @@ -0,0 +1,52 @@ +#ifndef _H8300_PGTABLE_H +#define _H8300_PGTABLE_H + +#include +#include +#include +#include +#include + +typedef pte_t *pte_addr_t; + +#define pgd_present(pgd) (1) /* pages are always present on NO_MM */ +#define pgd_none(pgd) (0) +#define pgd_bad(pgd) (0) +#define pgd_clear(pgdp) +#define kern_addr_valid(addr) (1) +#define pmd_offset(a, b) ((void *)0) + +#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_COPY __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_READONLY __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_KERNEL __pgprot(0) /* these mean nothing to NO_MM */ + +extern void paging_init(void); +#define swapper_pg_dir ((pgd_t *) 0) + +#define __swp_type(x) (0) +#define __swp_offset(x) (0) +#define __swp_entry(typ,off) ((swp_entry_t) { ((typ) | ((off) << 7)) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +#define ZERO_PAGE(vaddr) (virt_to_page(0)) + +/* + * These would be in other places but having them here reduces the diffs. + */ +extern unsigned int kobjsize(const void *objp); +extern int is_in_rom(unsigned long); + +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) +#define io_remap_page_range remap_page_range + +#endif /* _H8300_PGTABLE_H */ diff --git a/include/asm-h8300/poll.h b/include/asm-h8300/poll.h new file mode 100644 index 0000000000000..bf49ab8ad6da1 --- /dev/null +++ b/include/asm-h8300/poll.h @@ -0,0 +1,22 @@ +#ifndef __H8300_POLL_H +#define __H8300_POLL_H + +#define POLLIN 1 +#define POLLPRI 2 +#define POLLOUT 4 +#define POLLERR 8 +#define POLLHUP 16 +#define POLLNVAL 32 +#define POLLRDNORM 64 +#define POLLWRNORM POLLOUT +#define POLLRDBAND 128 +#define POLLWRBAND 256 +#define POLLMSG 0x0400 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif diff --git a/include/asm-h8300/posix_types.h b/include/asm-h8300/posix_types.h new file mode 100644 index 0000000000000..77c22770a5ba4 --- /dev/null +++ b/include/asm-h8300/posix_types.h @@ -0,0 +1,65 @@ +#ifndef __ARCH_H8300_POSIX_TYPES_H +#define __ARCH_H8300_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) + +#undef __FD_CLR +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) + +#undef __FD_ISSET +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + +#endif diff --git a/include/asm-h8300/processor.h b/include/asm-h8300/processor.h new file mode 100644 index 0000000000000..00553660c8ba4 --- /dev/null +++ b/include/asm-h8300/processor.h @@ -0,0 +1,121 @@ +/* + * 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 +#include +#include +#include +#include + +extern inline unsigned long rdusp(void) { + extern unsigned int sw_usp; + return(sw_usp); +} + +extern inline void wrusp(unsigned long usp) { + extern unsigned int sw_usp; + sw_usp = usp; +} + +/* + * User space process size: 3.75GB. This is hardcoded into a few places, + * so don't change it unless you know what you are doing. + */ +#define TASK_SIZE (0xFFFFFFFFUL) + +/* + * This decides where the kernel will search for a free chunk of vm + * space during mmap's. We won't be using it + */ +#define TASK_UNMAPPED_BASE 0 + +/* + * Bus types + */ +#define EISA_bus 0 +#define MCA_bus 0 + +struct thread_struct { + unsigned long ksp; /* kernel stack pointer */ + unsigned long usp; /* user stack pointer */ + unsigned short ccr; /* saved status register */ + unsigned long esp0; /* points to SR of stack frame */ + unsigned long vfork_ret; + unsigned long debugreg[8]; /* debug info */ +} __attribute__((aligned(2),packed)); + +#define INIT_THREAD { \ + sizeof(init_stack) + (unsigned long) init_stack, 0, \ + PS_S, 0, 0, \ +} + +/* + * Do necessary setup to start up a newly executed thread. + * + * pass the data segment into user programs if it exists, + * it can't hurt anything as far as I can tell + */ +#define start_thread(_regs, _pc, _usp) \ +do { \ + (_regs)->pc = (_pc); \ + (_regs)->ccr &= ~0x10; \ + *((unsigned long *)(_usp)-1) = _pc; \ + wrusp((unsigned long)(_usp) - sizeof(unsigned long)*3); \ +} while(0) + +/* Forward declaration, a strange C thing */ +struct task_struct; + +/* Free all resources held by a thread. */ +static inline void release_thread(struct task_struct *dead_task) +{ +} + +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + +#define copy_segments(tsk, mm) do { } while (0) +#define release_segments(mm) do { } while (0) +#define forget_segments() do { } while (0) +#define prepare_to_copy(tsk) do { } while (0) + +/* + * Free current thread data structures etc.. + */ +static inline void exit_thread(void) +{ +} + +/* + * Return saved PC of a blocked thread. + */ +unsigned long thread_saved_pc(struct task_struct *tsk); +unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) \ + ({ \ + unsigned long eip = 0; \ + if ((tsk)->thread.esp0 > PAGE_SIZE && \ + MAP_NR((tsk)->thread.esp0) < max_mapnr) \ + eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ + eip; }) +#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) + +#define cpu_relax() do { } while (0) + +#endif diff --git a/include/asm-h8300/ptrace.h b/include/asm-h8300/ptrace.h new file mode 100644 index 0000000000000..85dc0642df44b --- /dev/null +++ b/include/asm-h8300/ptrace.h @@ -0,0 +1,56 @@ +#ifndef _H8300_PTRACE_H +#define _H8300_PTRACE_H + +#ifndef __ASSEMBLY__ + +#define PT_ER1 0 +#define PT_ER2 1 +#define PT_ER3 2 +#define PT_ER4 3 +#define PT_ER5 4 +#define PT_ER6 5 +#define PT_ER0 6 +#define PT_ORIG_ER0 7 +#define PT_CCR 8 +#define PT_PC 9 +#define PT_USP 10 + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long er3; + long er2; + long er1; + long orig_er0; + unsigned short ccr; + long er0; + long vector; + unsigned long pc; +} __attribute__((aligned(2),packed)); + +/* + * This is the extended stack used by signal handlers and the context + * switcher: it's pushed after the normal "struct pt_regs". + */ +struct switch_stack { + unsigned long er6; + unsigned long er5; + unsigned long er4; + unsigned long retpc; +}; + +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 + +#ifdef __KERNEL__ +#ifndef PS_S +#define PS_S (0x10) +#endif + +#define user_mode(regs) (!((regs)->ccr & PS_S)) +#define instruction_pointer(regs) ((regs)->pc) +extern void show_regs(struct pt_regs *); +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ +#endif /* _H8300_PTRACE_H */ diff --git a/include/asm-h8300/regs306x.h b/include/asm-h8300/regs306x.h new file mode 100644 index 0000000000000..c20c4915c60f9 --- /dev/null +++ b/include/asm-h8300/regs306x.h @@ -0,0 +1,212 @@ +/* internal Peripherals Register address define */ +/* CPU: H8/306x */ + +#if !defined(__REGS_H8306x__) +#define __REGS_H8306x__ + +#if defined(__KERNEL__) + +#define DASTCR *(volatile unsigned char *)0xFEE01A +#define DADR0 0xFEE09C +#define DADR1 0xFEE09D +#define DACR 0xFEE09E + +#define ADDRAH 0xFFFFE0 +#define ADDRAL 0xFFFFE1 +#define ADDRBH 0xFFFFE2 +#define ADDRBL 0xFFFFE3 +#define ADDRCH 0xFFFFE4 +#define ADDRCL 0xFFFFE5 +#define ADDRDH 0xFFFFE6 +#define ADDRDL 0xFFFFE7 +#define ADCSR 0xFFFFE8 +#define ADCR 0xFFFFE9 + +#define BRCR 0xFEE013 +#define ADRCR 0xFEE01E +#define CSCR 0xFEE01F +#define ABWCR 0xFEE020 +#define ASTCR 0xFEE021 +#define WCRH 0xFEE022 +#define WCRL 0xFEE023 +#define BCR 0xFEE024 +#define DRCRA 0xFEE026 +#define DRCRB 0xFEE027 +#define RTMCSR 0xFEE028 +#define RTCNT 0xFEE029 +#define RTCOR 0xFEE02A + +#define MAR0AR 0xFFFF20 +#define MAR0AE 0xFFFF21 +#define MAR0AH 0xFFFF22 +#define MAR0AL 0xFFFF23 +#define ETCR0AL 0xFFFF24 +#define ETCR0AH 0xFFFF25 +#define IOAR0A 0xFFFF26 +#define DTCR0A 0xFFFF27 +#define MAR0BR 0xFFFF28 +#define MAR0BE 0xFFFF29 +#define MAR0BH 0xFFFF2A +#define MAR0BL 0xFFFF2B +#define ETCR0BL 0xFFFF2C +#define ETCR0BH 0xFFFF2D +#define IOAR0B 0xFFFF2E +#define DTCR0B 0xFFFF2F +#define MAR1AR 0xFFFF30 +#define MAR1AE 0xFFFF31 +#define MAR1AH 0xFFFF32 +#define MAR1AL 0xFFFF33 +#define ETCR1AL 0xFFFF34 +#define ETCR1AH 0xFFFF35 +#define IOAR1A 0xFFFF36 +#define DTCR1A 0xFFFF37 +#define MAR1BR 0xFFFF38 +#define MAR1BE 0xFFFF39 +#define MAR1BH 0xFFFF3A +#define MAR1BL 0xFFFF3B +#define ETCR1BL 0xFFFF3C +#define ETCR1BH 0xFFFF3D +#define IOAR1B 0xFFFF3E +#define DTCR1B 0xFFFF3F + +#define ISCR 0xFEE014 +#define IER 0xFEE015 +#define ISR 0xFEE016 +#define IPRA 0xFEE018 +#define IPRB 0xFEE019 + +#define P1DDR 0xFEE000 +#define P2DDR 0xFEE001 +#define P3DDR 0xFEE002 +#define P4DDR 0xFEE003 +#define P5DDR 0xFEE004 +#define P6DDR 0xFEE005 +/*#define P7DDR 0xFEE006*/ +#define P8DDR 0xFEE007 +#define P9DDR 0xFEE008 +#define PADDR 0xFEE009 +#define PBDDR 0xFEE00A + +#define P1DR 0xFFFFD0 +#define P2DR 0xFFFFD1 +#define P3DR 0xFFFFD2 +#define P4DR 0xFFFFD3 +#define P5DR 0xFFFFD4 +#define P6DR 0xFFFFD5 +/*#define P7DR 0xFFFFD6*/ +#define P8DR 0xFFFFD7 +#define P9DR 0xFFFFD8 +#define PADR 0xFFFFD9 +#define PBDR 0xFFFFDA + +#define P2CR 0xFEE03C +#define P4CR 0xFEE03E +#define P5CR 0xFEE03F + +#define SMR0 0xFFFFB0 +#define BRR0 0xFFFFB1 +#define SCR0 0xFFFFB2 +#define TDR0 0xFFFFB3 +#define SSR0 0xFFFFB4 +#define RDR0 0xFFFFB5 +#define SCMR0 0xFFFFB6 +#define SMR1 0xFFFFB8 +#define BRR1 0xFFFFB9 +#define SCR1 0xFFFFBA +#define TDR1 0xFFFFBB +#define SSR1 0xFFFFBC +#define RDR1 0xFFFFBD +#define SCMR1 0xFFFFBE +#define SMR2 0xFFFFC0 +#define BRR2 0xFFFFC1 +#define SCR2 0xFFFFC2 +#define TDR2 0xFFFFC3 +#define SSR2 0xFFFFC4 +#define RDR2 0xFFFFC5 +#define SCMR2 0xFFFFC6 + +#define MDCR 0xFEE000 +#define SYSCR 0xFEE001 +#define DIVCR 0xFEE01B +#define MSTCRH 0xFEE01C +#define MSTCRL 0xFEE01D +#define FLMCR1 0xFEE030 +#define FLMCR2 0xFEE031 +#define EBR1 0xFEE032 +#define EBR2 0xFEE033 +#define RAMCR 0xFEE077 + +#define TSTR 0xFFFF60 +#define TSNC 0XFFFF61 +#define TMDR 0xFFFF62 +#define TOLR 0xFFFF63 +#define TISRA 0xFFFF64 +#define TISRB 0xFFFF65 +#define TISRC 0xFFFF66 +#define TCR0 0xFFFF68 +#define TIOR0 0xFFFF69 +#define TCNT0H 0xFFFF6A +#define TCNT0L 0xFFFF6B +#define GRA0H 0xFFFF6C +#define GRA0L 0xFFFF6D +#define GRB0H 0xFFFF6E +#define GRB0L 0xFFFF6F +#define TCR1 0xFFFF70 +#define TIOR1 0xFFFF71 +#define TCNT1H 0xFFFF72 +#define TCNT1L 0xFFFF73 +#define GRA1H 0xFFFF74 +#define GRA1L 0xFFFF75 +#define GRB1H 0xFFFF76 +#define GRB1L 0xFFFF77 +#define TCR3 0xFFFF78 +#define TIOR3 0xFFFF79 +#define TCNT3H 0xFFFF7A +#define TCNT3L 0xFFFF7B +#define GRA3H 0xFFFF7C +#define GRA3L 0xFFFF7D +#define GRB3H 0xFFFF7E +#define GRB3L 0xFFFF7F + +#define _8TCR0 0xFFFF80 +#define _8TCR1 0xFFFF81 +#define _8TCSR0 0xFFFF82 +#define _8TCSR1 0xFFFF83 +#define TCORA0 0xFFFF84 +#define TCORA1 0xFFFF85 +#define TCORB0 0xFFFF86 +#define TCORB1 0xFFFF87 +#define _8TCNT0 0xFFFF88 +#define _8TCNT1 0xFFFF89 + +#define _8TCR2 0xFFFF90 +#define _8TCR3 0xFFFF91 +#define _8TCSR2 0xFFFF92 +#define _8TCSR3 0xFFFF93 +#define TCORA2 0xFFFF94 +#define TCORA3 0xFFFF95 +#define TCORB2 0xFFFF96 +#define TCORB3 0xFFFF97 +#define _8TCNT2 0xFFFF98 +#define _8TCNT3 0xFFFF99 + +#define TCSR 0xFFFF8C +#define TCNT 0xFFFF8D +#define RSTCSR 0xFFFF8F + +#define TPMR 0xFFFFA0 +#define TPCR 0xFFFFA1 +#define NDERB 0xFFFFA2 +#define NDERA 0xFFFFA3 +#define NDRB1 0xFFFFA4 +#define NDRA1 0xFFFFA5 +#define NDRB2 0xFFFFA6 +#define NDRA2 0xFFFFA7 + +#define TCSR 0xFFFF8C +#define TCNT 0xFFFF8D +#define RSTCSRW 0xFFFF8E +#define RSTCSRR 0xFFFF8F + +#endif /* __KERNEL__ */ +#endif /* __REGS_H8306x__ */ diff --git a/include/asm-h8300/resource.h b/include/asm-h8300/resource.h new file mode 100644 index 0000000000000..38b8e942afa54 --- /dev/null +++ b/include/asm-h8300/resource.h @@ -0,0 +1,47 @@ +#ifndef _H8300_RESOURCE_H +#define _H8300_RESOURCE_H + +/* + * Resource limits + */ + +#define RLIMIT_CPU 0 /* CPU time in ms */ +#define RLIMIT_FSIZE 1 /* Maximum filesize */ +#define RLIMIT_DATA 2 /* max data size */ +#define RLIMIT_STACK 3 /* max stack size */ +#define RLIMIT_CORE 4 /* max core file size */ +#define RLIMIT_RSS 5 /* max resident set size */ +#define RLIMIT_NPROC 6 /* max number of processes */ +#define RLIMIT_NOFILE 7 /* max number of open files */ +#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ +#define RLIMIT_AS 9 /* address space limit */ +#define RLIMIT_LOCKS 10 /* maximum file locks held */ + +#define RLIM_NLIMITS 11 + +/* + * SuS says limits have to be unsigned. + * Which makes a ton more sense anyway. + */ +#define RLIM_INFINITY (~0UL) + +#ifdef __KERNEL__ + +#define INIT_RLIMITS \ +{ \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { _STK_LIM, RLIM_INFINITY }, \ + { 0, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ + { INR_OPEN, INR_OPEN }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ +} + +#endif /* __KERNEL__ */ + +#endif /* _H8300_RESOURCE_H */ diff --git a/include/asm-h8300/scatterlist.h b/include/asm-h8300/scatterlist.h new file mode 100644 index 0000000000000..7627f0cd1a2f4 --- /dev/null +++ b/include/asm-h8300/scatterlist.h @@ -0,0 +1,13 @@ +#ifndef _H8300_SCATTERLIST_H +#define _H8300_SCATTERLIST_H + +struct scatterlist { + struct page *page; + unsigned int offset; + dma_addr_t dma_address; + unsigned int length; +}; + +#define ISA_DMA_THRESHOLD (0xffffffff) + +#endif /* !(_H8300_SCATTERLIST_H) */ diff --git a/include/asm-h8300/segment.h b/include/asm-h8300/segment.h new file mode 100644 index 0000000000000..b79a82d0f99d9 --- /dev/null +++ b/include/asm-h8300/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/include/asm-h8300/semaphore-helper.h b/include/asm-h8300/semaphore-helper.h new file mode 100644 index 0000000000000..29e0fbf1acb70 --- /dev/null +++ b/include/asm-h8300/semaphore-helper.h @@ -0,0 +1,86 @@ +#ifndef _H8300_SEMAPHORE_HELPER_H +#define _H8300_SEMAPHORE_HELPER_H + +/* + * SMP- and interrupt-safe semaphores helper functions. + * + * (C) Copyright 1996 Linus Torvalds + * + * based on + * m68k version by Andreas Schwab + */ + +#include +#include + +/* + * These two _must_ execute atomically wrt each other. + */ +static inline void wake_one_more(struct semaphore * sem) +{ + atomic_inc((atomic_t *)&sem->sleepers); +} + +static inline int waking_non_zero(struct semaphore *sem) +{ + int ret; + unsigned long flags; + + spin_lock_irqsave(&semaphore_wake_lock, flags); + ret = 0; + if (sem->sleepers > 0) { + sem->sleepers--; + ret = 1; + } + spin_unlock_irqrestore(&semaphore_wake_lock, flags); + return ret; +} + +/* + * waking_non_zero_interruptible: + * 1 got the lock + * 0 go to sleep + * -EINTR interrupted + */ +static inline int waking_non_zero_interruptible(struct semaphore *sem, + struct task_struct *tsk) +{ + int ret; + unsigned long flags; + + spin_lock_irqsave(&semaphore_wake_lock, flags); + ret = 0; + if (sem->sleepers > 0) { + sem->sleepers--; + ret = 1; + } else if (signal_pending(tsk)) { + atomic_inc(&sem->count); + ret = -EINTR; + } + spin_unlock_irqrestore(&semaphore_wake_lock, flags); + return ret; +} + +/* + * waking_non_zero_trylock: + * 1 failed to lock + * 0 got the lock + */ +static inline int waking_non_zero_trylock(struct semaphore *sem) +{ + int ret; + unsigned long flags; + + spin_lock_irqsave(&semaphore_wake_lock, flags); + ret = 1; + if (sem->sleepers <= 0) + atomic_inc(&sem->count); + else { + sem->sleepers--; + ret = 0; + } + spin_unlock_irqrestore(&semaphore_wake_lock, flags); + return ret; +} + +#endif diff --git a/include/asm-h8300/semaphore.h b/include/asm-h8300/semaphore.h new file mode 100644 index 0000000000000..e39a85ed75dc2 --- /dev/null +++ b/include/asm-h8300/semaphore.h @@ -0,0 +1,206 @@ +#ifndef _H8300_SEMAPHORE_H +#define _H8300_SEMAPHORE_H + +#define RW_LOCK_BIAS 0x01000000 + +#ifndef __ASSEMBLY__ + +#include +#include +#include +#include + +#include +#include + +/* + * Interrupt-safe semaphores.. + * + * (C) Copyright 1996 Linus Torvalds + * + * H8/300 version by Yoshinori Sato + */ + + +struct semaphore { + atomic_t count; + int sleepers; + wait_queue_head_t wait; +#if WAITQUEUE_DEBUG + long __magic; +#endif +}; + +#if WAITQUEUE_DEBUG +# define __SEM_DEBUG_INIT(name) \ + , (long)&(name).__magic +#else +# define __SEM_DEBUG_INIT(name) +#endif + +#define __SEMAPHORE_INITIALIZER(name,count) \ +{ ATOMIC_INIT(count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ + __SEM_DEBUG_INIT(name) } + +#define __MUTEX_INITIALIZER(name) \ + __SEMAPHORE_INITIALIZER(name,1) + +#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ + struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) + +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) + +extern inline void sema_init (struct semaphore *sem, int val) +{ + *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val); +} + +static inline void init_MUTEX (struct semaphore *sem) +{ + sema_init(sem, 1); +} + +static inline void init_MUTEX_LOCKED (struct semaphore *sem) +{ + sema_init(sem, 0); +} + +asmlinkage void __down_failed(void /* special register calling convention */); +asmlinkage int __down_failed_interruptible(void /* params in registers */); +asmlinkage int __down_failed_trylock(void /* params in registers */); +asmlinkage void __up_wakeup(void /* special register calling convention */); + +asmlinkage void __down(struct semaphore * sem); +asmlinkage int __down_interruptible(struct semaphore * sem); +asmlinkage int __down_trylock(struct semaphore * sem); +asmlinkage void __up(struct semaphore * sem); + +extern spinlock_t semaphore_wake_lock; + +/* + * This is ugly, but we want the default case to fall through. + * "down_failed" is a special asm handler that calls the C + * routine that actually waits. See arch/m68k/lib/semaphore.S + */ +extern inline void down(struct semaphore * sem) +{ +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + + __asm__ __volatile__( + "stc ccr,r4l\n\t" + "orc #0x80,ccr\n\t" + "mov.l @%0, er0\n\t" + "dec.l #1,er0\n\t" + "mov.l er0,@%0\n\t" + "bpl 1f\n\t" + "ldc r4l,ccr\n\t" + "mov.l %0,er0\n\t" + "jsr @___down\n" + "1:\n\t" + "ldc r4l,ccr" + : /* no outputs */ + : "r" (&(sem->count)) + : "cc", "er0", "er1", "er2", "er3", "er4", "memory"); +} + +extern inline int down_interruptible(struct semaphore * sem) +{ + register int ret __asm__("er0"); + +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + + __asm__ __volatile__( + "stc ccr,r1l\n\t" + "orc #0x80,ccr\n\t" + "mov.l @%1, er2\n\t" + "dec.l #1,er2\n\t" + "mov.l er2,@%1\n\t" + "bpl 1f\n\t" + "ldc r1l,ccr\n\t" + "mov.l %1,er0\n\t" + "jsr @___down_interruptible\n\t" + "bra 2f\n" + "1:\n\t" + "ldc r1l,ccr\n\t" + "sub.l %0,%0\n\t" + "2:\n\t" + : "=r" (ret) + : "r" (&(sem->count)) + : "cc", "er1", "er2", "er3", "memory"); + return ret; +} + +extern inline int down_trylock(struct semaphore * sem) +{ + register int result; + +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + + __asm__ __volatile__( + "stc ccr,r4l\n\t" + "orc #0x80,ccr\n\t" + "mov.l @%1,er0\n\t" + "dec.l #1,er0\n\t" + "mov.l er0,@%1\n\t" + "bpl 1f\n\t" + "ldc r4l,ccr\n\t" + "jmp @3f\n" + "1:\n\t" + "ldc r4l,ccr\n\t" + "sub.l %0,%0\n" + "2:\n" + ".section .text.lock,\"ax\"\n" + ".align 2\n" + "3:\n\t" + "mov.l %1,er0\n\t" + "jsr @___down_trylock\n" + "mov.l er0,%0\n\t" + "jmp @2b\n\t" + ".previous" + : "=r" (result) + : "r" (&(sem->count)) + : "cc", "er0","er4", "memory"); + return result; +} + +/* + * Note! This is subtle. We jump to wake people up only if + * the semaphore was negative (== somebody was waiting on it). + * The default case (no contention) will result in NO + * jumps for both down() and up(). + */ +extern inline void up(struct semaphore * sem) +{ +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + + __asm__ __volatile__( + "stc ccr,r4l\n\t" + "orc #0x80,ccr\n\t" + "mov.l @%0,er0\n\t" + "inc.l #1,er0\n\t" + "mov.l er0,@%0\n\t" + "bmi 1f\n\t" + "bne 2f\n\t" + "1:\n\t" + "ldc r4l,ccr\n\t" + "mov.l %0,er0\n\t" + "jsr @___up\n" + "2:\n\t" + "ldc r4l,ccr" + : /* no outputs */ + : "r" (&(sem->count)) + : "cc", "er0", "er4", "memory"); +} + +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/include/asm-h8300/sembuf.h b/include/asm-h8300/sembuf.h new file mode 100644 index 0000000000000..e04a3ec0cb926 --- /dev/null +++ b/include/asm-h8300/sembuf.h @@ -0,0 +1,25 @@ +#ifndef _H8300_SEMBUF_H +#define _H8300_SEMBUF_H + +/* + * The semid64_ds structure for m68k architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct semid64_ds { + struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ + __kernel_time_t sem_otime; /* last semop time */ + unsigned long __unused1; + __kernel_time_t sem_ctime; /* last change time */ + unsigned long __unused2; + unsigned long sem_nsems; /* no. of semaphores in array */ + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _H8300_SEMBUF_H */ diff --git a/include/asm-h8300/setup.h b/include/asm-h8300/setup.h new file mode 100644 index 0000000000000..4fc416e80bef0 --- /dev/null +++ b/include/asm-h8300/setup.h @@ -0,0 +1 @@ +/* Nothing do */ diff --git a/include/asm-h8300/sh_bios.h b/include/asm-h8300/sh_bios.h new file mode 100644 index 0000000000000..b6bb6e58295cf --- /dev/null +++ b/include/asm-h8300/sh_bios.h @@ -0,0 +1,29 @@ +/* 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/include/asm-h8300/shm.h b/include/asm-h8300/shm.h new file mode 100644 index 0000000000000..bec7585248394 --- /dev/null +++ b/include/asm-h8300/shm.h @@ -0,0 +1,32 @@ +#ifndef _H8300_SHM_H +#define _H8300_SHM_H + +#include + +/* format of page table entries that correspond to shared memory pages + currently out in swap space (see also mm/swap.c): + bits 0-1 (PAGE_PRESENT) is = 0 + bits 8..2 (SWP_TYPE) are = SHM_SWP_TYPE + bits 31..9 are used like this: + bits 15..9 (SHM_ID) the id of the shared memory segment + bits 30..16 (SHM_IDX) the index of the page within the shared memory segment + (actually only bits 25..16 get used since SHMMAX is so low) + bit 31 (SHM_READ_ONLY) flag whether the page belongs to a read-only attach +*/ +/* on the m68k both bits 0 and 1 must be zero */ +/* format on the sun3 is similar, but bits 30, 31 are set to zero and all + others are reduced by 2. --m */ + +#ifndef CONFIG_SUN3 +#define SHM_ID_SHIFT 9 +#else +#define SHM_ID_SHIFT 7 +#endif +#define _SHM_ID_BITS 7 +#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) + +#define SHM_IDX_SHIFT (SHM_ID_SHIFT+_SHM_ID_BITS) +#define _SHM_IDX_BITS 15 +#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) + +#endif /* _H8300_SHM_H */ diff --git a/include/asm-h8300/shmbuf.h b/include/asm-h8300/shmbuf.h new file mode 100644 index 0000000000000..64e77993a7a90 --- /dev/null +++ b/include/asm-h8300/shmbuf.h @@ -0,0 +1,42 @@ +#ifndef _H8300_SHMBUF_H +#define _H8300_SHMBUF_H + +/* + * The shmid64_ds structure for m68k architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct shmid64_ds { + struct ipc64_perm shm_perm; /* operation perms */ + size_t shm_segsz; /* size of segment (bytes) */ + __kernel_time_t shm_atime; /* last attach time */ + unsigned long __unused1; + __kernel_time_t shm_dtime; /* last detach time */ + unsigned long __unused2; + __kernel_time_t shm_ctime; /* last change time */ + unsigned long __unused3; + __kernel_pid_t shm_cpid; /* pid of creator */ + __kernel_pid_t shm_lpid; /* pid of last operator */ + unsigned long shm_nattch; /* no. of current attaches */ + unsigned long __unused4; + unsigned long __unused5; +}; + +struct shminfo64 { + unsigned long shmmax; + unsigned long shmmin; + unsigned long shmmni; + unsigned long shmseg; + unsigned long shmall; + unsigned long __unused1; + unsigned long __unused2; + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _H8300_SHMBUF_H */ diff --git a/include/asm-h8300/shmparam.h b/include/asm-h8300/shmparam.h new file mode 100644 index 0000000000000..d1863953ec643 --- /dev/null +++ b/include/asm-h8300/shmparam.h @@ -0,0 +1,6 @@ +#ifndef _H8300_SHMPARAM_H +#define _H8300_SHMPARAM_H + +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ + +#endif /* _H8300_SHMPARAM_H */ diff --git a/include/asm-h8300/sigcontext.h b/include/asm-h8300/sigcontext.h new file mode 100644 index 0000000000000..acd04dee4e81e --- /dev/null +++ b/include/asm-h8300/sigcontext.h @@ -0,0 +1,15 @@ +#ifndef _ASM_H8300_SIGCONTEXT_H +#define _ASM_H8300_SIGCONTEXT_H + +struct sigcontext { + unsigned long sc_mask; /* old sigmask */ + unsigned long sc_usp; /* old user stack pointer */ + unsigned long sc_er0; + unsigned long sc_er1; + unsigned long sc_er2; + unsigned long sc_er3; + unsigned short sc_ccr; + unsigned long sc_pc; +}; + +#endif diff --git a/include/asm-h8300/siginfo.h b/include/asm-h8300/siginfo.h new file mode 100644 index 0000000000000..bc8fbea931a55 --- /dev/null +++ b/include/asm-h8300/siginfo.h @@ -0,0 +1,6 @@ +#ifndef _H8300_SIGINFO_H +#define _H8300_SIGINFO_H + +#include + +#endif diff --git a/include/asm-h8300/signal.h b/include/asm-h8300/signal.h new file mode 100644 index 0000000000000..460d8a6f69f4a --- /dev/null +++ b/include/asm-h8300/signal.h @@ -0,0 +1,183 @@ +#ifndef _H8300_SIGNAL_H +#define _H8300_SIGNAL_H + +#include + +/* Avoid too many header ordering problems. */ +struct siginfo; + +#ifdef __KERNEL__ +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define _NSIG 64 +#define _NSIG_BPW 32 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +#define NSIG 32 +typedef unsigned long sigset_t; + +#endif /* __KERNEL__ */ + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX (_NSIG-1) + +/* + * SA_FLAGS values: + * + * SA_ONSTACK indicates that a registered stack_t will be used. + * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_SIGINFO 0x00000004 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND +#define SA_INTERRUPT 0x20000000 /* dummy -- ignored */ + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 + +#ifdef __KERNEL__ +/* + * These values of sa_flags are used only by the kernel as part of the + * irq handling routines. + * + * SA_INTERRUPT is also used by the irq handling routines. + * SA_SHIRQ is for shared interrupt support on PCI and EISA. + */ +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#define SA_SHIRQ 0x04000000 +#endif + +#define SIG_BLOCK 0 /* for blocking signals */ +#define SIG_UNBLOCK 1 /* for unblocking signals */ +#define SIG_SETMASK 2 /* for setting the signal mask */ + +/* Type of a signal handler. */ +typedef void (*__sighandler_t)(int); + +#define SIG_DFL ((__sighandler_t)0) /* default signal handling */ +#define SIG_IGN ((__sighandler_t)1) /* ignore signal */ +#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ + +#ifdef __KERNEL__ +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +#endif /* __KERNEL__ */ + +typedef struct sigaltstack { + void *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ + +#include +#undef __HAVE_ARCH_SIG_BITOPS + +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + +#endif /* __KERNEL__ */ + +#endif /* _H8300_SIGNAL_H */ diff --git a/include/asm-h8300/smp.h b/include/asm-h8300/smp.h new file mode 100644 index 0000000000000..9e9bd7e589221 --- /dev/null +++ b/include/asm-h8300/smp.h @@ -0,0 +1 @@ +/* nothing required here yet */ diff --git a/include/asm-h8300/smplock.h b/include/asm-h8300/smplock.h new file mode 100644 index 0000000000000..96565069c9887 --- /dev/null +++ b/include/asm-h8300/smplock.h @@ -0,0 +1,51 @@ +/* + * + * + * Default SMP lock implementation + */ +#include +#include + +extern spinlock_t kernel_flag; + +#define kernel_locked() spin_is_locked(&kernel_flag) + +/* + * Release global kernel lock and global interrupt lock + */ +#define release_kernel_lock(task, cpu) \ +do { \ + if (task->lock_depth >= 0) \ + spin_unlock(&kernel_flag); \ + release_irqlock(cpu); \ + __sti(); \ +} while (0) + +/* + * Re-acquire the kernel lock + */ +#define reacquire_kernel_lock(task) \ +do { \ + if (task->lock_depth >= 0) \ + spin_lock(&kernel_flag); \ +} while (0) + + +/* + * Getting the big kernel lock. + * + * This cannot happen asynchronously, + * so we only need to worry about other + * CPU's. + */ +extern __inline__ void lock_kernel(void) +{ + if (!++current->lock_depth) + spin_lock(&kernel_flag); +} + +extern __inline__ void unlock_kernel(void) +{ + if (--current->lock_depth < 0) + spin_unlock(&kernel_flag); +} diff --git a/include/asm-h8300/socket.h b/include/asm-h8300/socket.h new file mode 100644 index 0000000000000..a328c84b9f239 --- /dev/null +++ b/include/asm-h8300/socket.h @@ -0,0 +1,64 @@ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include + +/* For setsockoptions(2) */ +#define SOL_SOCKET 1 + +#define SO_DEBUG 1 +#define SO_REUSEADDR 2 +#define SO_TYPE 3 +#define SO_ERROR 4 +#define SO_DONTROUTE 5 +#define SO_BROADCAST 6 +#define SO_SNDBUF 7 +#define SO_RCVBUF 8 +#define SO_KEEPALIVE 9 +#define SO_OOBINLINE 10 +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_LINGER 13 +#define SO_BSDCOMPAT 14 +/* To add :#define SO_REUSEPORT 15 */ +#define SO_PASSCRED 16 +#define SO_PEERCRED 17 +#define SO_RCVLOWAT 18 +#define SO_SNDLOWAT 19 +#define SO_RCVTIMEO 20 +#define SO_SNDTIMEO 21 + +/* Security levels - as per NRL IPv6 - don't actually do anything */ +#define SO_SECURITY_AUTHENTICATION 22 +#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 +#define SO_SECURITY_ENCRYPTION_NETWORK 24 + +#define SO_BINDTODEVICE 25 + +/* Socket filtering */ +#define SO_ATTACH_FILTER 26 +#define SO_DETACH_FILTER 27 + +#define SO_PEERNAME 28 +#define SO_TIMESTAMP 29 +#define SCM_TIMESTAMP SO_TIMESTAMP + +#define SO_ACCEPTCONN 30 + +/* Nast libc5 fixup - bletch */ +#if defined(__KERNEL__) +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#define SOCK_MAX (SOCK_PACKET+1) +#endif + +#endif /* _ASM_SOCKET_H */ diff --git a/include/asm-h8300/sockios.h b/include/asm-h8300/sockios.h new file mode 100644 index 0000000000000..d005d9594cc60 --- /dev/null +++ b/include/asm-h8300/sockios.h @@ -0,0 +1,12 @@ +#ifndef __ARCH_H8300_SOCKIOS__ +#define __ARCH_H8300_SOCKIOS__ + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp */ + +#endif /* __ARCH_H8300_SOCKIOS__ */ diff --git a/include/asm-h8300/softirq.h b/include/asm-h8300/softirq.h new file mode 100644 index 0000000000000..d944be956a25a --- /dev/null +++ b/include/asm-h8300/softirq.h @@ -0,0 +1,20 @@ +#ifndef __ASM_SOFTIRQ_H +#define __ASM_SOFTIRQ_H + +#include +#include + +#define local_bh_disable() \ + do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0) +#define __local_bh_enable() \ + do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0) + +#define local_bh_enable() \ +do { \ + __local_bh_enable(); \ + if (unlikely(!in_interrupt() && softirq_pending(smp_processor_id()))) \ + do_softirq(); \ + preempt_check_resched(); \ +} while (0) + +#endif /* __ASM_SOFTIRQ_H */ diff --git a/include/asm-h8300/spinlock.h b/include/asm-h8300/spinlock.h new file mode 100644 index 0000000000000..d5407fa173e4f --- /dev/null +++ b/include/asm-h8300/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/include/asm-h8300/stat.h b/include/asm-h8300/stat.h new file mode 100644 index 0000000000000..7c71b3231d93f --- /dev/null +++ b/include/asm-h8300/stat.h @@ -0,0 +1,80 @@ +#ifndef _H8300_STAT_H +#define _H8300_STAT_H + +struct __old_kernel_stat { + unsigned short st_dev; + unsigned short st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned long st_size; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; +}; + +struct stat { + unsigned short st_dev; + unsigned short __pad1; + unsigned long st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned short __pad2; + unsigned long st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long __unused1; + unsigned long st_mtime; + unsigned long __unused2; + unsigned long st_ctime; + unsigned long __unused3; + unsigned long __unused4; + unsigned long __unused5; +}; + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat64 { + unsigned char __pad0[6]; + unsigned short st_dev; + unsigned char __pad1[2]; + +#define STAT64_HAS_BROKEN_ST_INO 1 + unsigned long __st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned char __pad2[6]; + unsigned short st_rdev; + unsigned char __pad3[2]; + + long long st_size; + unsigned long st_blksize; + + unsigned long __pad4; /* future possible st_blocks high bits */ + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + + unsigned long st_atime; + unsigned long st_atime_nsec; + + unsigned long st_mtime; + unsigned long st_mtime_nsec; + + unsigned long st_ctime; + unsigned long st_ctime_nsec; + + unsigned long long st_ino; +}; + +#endif /* _H8300_STAT_H */ diff --git a/include/asm-h8300/statfs.h b/include/asm-h8300/statfs.h new file mode 100644 index 0000000000000..9e3be68f0c07c --- /dev/null +++ b/include/asm-h8300/statfs.h @@ -0,0 +1,25 @@ +#ifndef _H8300_STATFS_H +#define _H8300_STATFS_H + +#ifndef __KERNEL_STRICT_NAMES + +#include + +typedef __kernel_fsid_t fsid_t; + +#endif + +struct statfs { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_spare[6]; +}; + +#endif /* _H8300_STATFS_H */ diff --git a/include/asm-h8300/string.h b/include/asm-h8300/string.h new file mode 100644 index 0000000000000..ca5034897d872 --- /dev/null +++ b/include/asm-h8300/string.h @@ -0,0 +1,44 @@ +#ifndef _H8300_STRING_H_ +#define _H8300_STRING_H_ + +#ifdef __KERNEL__ /* only set these up for kernel code */ + +#include +#include + +#define __HAVE_ARCH_MEMSET +extern void * memset(void * s, int c, size_t count); + +#define __HAVE_ARCH_MEMCPY +extern void * memcpy(void *d, const void *s, size_t count); + +#else /* KERNEL */ + +/* + * let user libraries deal with these, + * IMHO the kernel has no place defining these functions for user apps + */ + +#define __HAVE_ARCH_STRCPY 1 +#define __HAVE_ARCH_STRNCPY 1 +#define __HAVE_ARCH_STRCAT 1 +#define __HAVE_ARCH_STRNCAT 1 +#define __HAVE_ARCH_STRCMP 1 +#define __HAVE_ARCH_STRNCMP 1 +#define __HAVE_ARCH_STRNICMP 1 +#define __HAVE_ARCH_STRCHR 1 +#define __HAVE_ARCH_STRRCHR 1 +#define __HAVE_ARCH_STRSTR 1 +#define __HAVE_ARCH_STRLEN 1 +#define __HAVE_ARCH_STRNLEN 1 +#define __HAVE_ARCH_MEMSET 1 +#define __HAVE_ARCH_MEMCPY 1 +#define __HAVE_ARCH_MEMMOVE 1 +#define __HAVE_ARCH_MEMSCAN 1 +#define __HAVE_ARCH_MEMCMP 1 +#define __HAVE_ARCH_MEMCHR 1 +#define __HAVE_ARCH_STRTOK 1 + +#endif /* KERNEL */ + +#endif /* _M68K_STRING_H_ */ diff --git a/include/asm-h8300/system.h b/include/asm-h8300/system.h new file mode 100644 index 0000000000000..0b0ce43759f87 --- /dev/null +++ b/include/asm-h8300/system.h @@ -0,0 +1,156 @@ +#ifndef _H8300_SYSTEM_H +#define _H8300_SYSTEM_H + +#include /* get configuration macros */ +#include +#include + +#define prepare_to_switch() do { } while(0) + +/* + * switch_to(n) should switch tasks to task ptr, first checking that + * ptr isn't the current task, in which case it does nothing. This + * also clears the TS-flag if the task we switched to has used the + * math co-processor latest. + */ +/* + * switch_to() saves the extra registers, that are not saved + * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and + * a0-a1. Some of these are used by schedule() and its predecessors + * and so we might get see unexpected behaviors when a task returns + * with unexpected register values. + * + * syscall stores these registers itself and none of them are used + * by syscall after the function in the syscall has been called. + * + * Beware that resume now expects *next to be in d1 and the offset of + * tss to be in a1. This saves a few instructions as we no longer have + * to push them onto the stack and read them back right after. + * + * 02/17/96 - Jes Sorensen (jds@kom.auc.dk) + * + * Changed 96/09/19 by Andreas Schwab + * pass prev in a0, next in a1, offset of tss in d1, and whether + * the mm structures are shared in d2 (to avoid atc flushing). + * + * H8/300 Porting 2002/09/04 Yoshinori Sato + */ +asmlinkage void resume(void); +#define switch_to(prev,next,last) { \ + void *_last; \ + __asm__ __volatile__( \ + "mov.l %1, er0\n\t" \ + "mov.l %2, er1\n\t" \ + "jsr @_resume" \ + : "=r" (_last) \ + : "r" (&(prev->thread)), \ + "r" (&(next->thread)) \ + : "cc", "er0", "er1", "er2", "er3"); \ + (last) = _last; \ +} + +#if defined(__H8300H__) +#define __sti() asm volatile ("andc #0x7f,ccr") +#define __cli() asm volatile ("orc #0x80,ccr") + +#define __save_flags(x) \ + asm volatile ("sub.l er0,er0\n\tstc ccr,r0l\n\tmov.l er0,%0":"=r" (x) : : "er0") + +#define __restore_flags(x) \ + asm volatile ("mov.l %0,er0\n\tldc r0l,ccr": :"r" (x) : "er0") +#endif +#if defined(__H8300S__) +#define __sti() asm volatile ("andc #0xf8,exr") +#define __cli() asm volatile ("orc #0x07,exr") + +#define __save_flags(x) \ + asm volatile ("sub.l er0,er0\n\tstc exr,r0l\n\tmov.l er0,%0":"=r" (x) : : "er0") + +#define __restore_flags(x) \ + asm volatile ("mov.l %0,er0\n\tldc r0l,exr": :"r" (x) : "er0") +#endif + +#define irqs_disabled() \ +({ \ + unsigned long flags; \ + __save_flags(flags); \ + ((flags & 0x80) == 0x80); \ +}) + +#define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc") + +/* For spinlocks etc */ +#define local_irq_disable() asm volatile ("orc #0x80,ccr") +#define local_irq_enable() asm volatile ("andc #0x7f,ccr") +#define local_irq_save(x) ({ __save_flags(x); local_irq_disable(); }) +#define local_irq_restore(x) __restore_flags(x) +#define local_save_flags(x) __save_flags(x) + +/* + * Force strict CPU ordering. + * Not really required on m68k... + */ +#define nop() asm volatile ("nop"::) +#define mb() asm volatile ("" : : :"memory") +#define rmb() asm volatile ("" : : :"memory") +#define wmb() asm volatile ("" : : :"memory") +#define set_rmb(var, value) do { xchg(&var, value); } while (0) +#define set_mb(var, value) set_rmb(var, value) +#define set_wmb(var, value) do { var = value; wmb(); } while (0) + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#define smp_rmb() rmb() +#define smp_wmb() wmb() +#define smp_read_barrier_depends() read_barrier_depends() +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() do { } while(0) +#endif + +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) (xchg((ptr),1)) + +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((volatile struct __xchg_dummy *)(x)) + +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) +{ + unsigned long tmp, flags; + + local_irq_save(flags); + + switch (size) { + case 1: + __asm__ __volatile__ + ("mov.b %2,%0\n\t" + "mov.b %1,%2" + : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "er0","memory"); + break; + case 2: + __asm__ __volatile__ + ("mov.w %2,%0\n\t" + "mov.w %1,%2" + : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 4: + __asm__ __volatile__ + ("mov.l %2,%0\n\t" + "mov.l %1,%2" + : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)) : "memory"); + break; + default: + tmp = 0; + } + local_irq_restore(flags); + return tmp; +} + +#define HARD_RESET_NOW() ({ \ + local_irq_disable(); \ + asm("jmp @@0"); \ +}) + +#endif /* _H8300_SYSTEM_H */ diff --git a/include/asm-h8300/target_time.h b/include/asm-h8300/target_time.h new file mode 100644 index 0000000000000..3c46294844456 --- /dev/null +++ b/include/asm-h8300/target_time.h @@ -0,0 +1,4 @@ +extern int platform_timer_setup(void (*timer_int)(int, void *, struct pt_regs *)); +extern void platform_timer_eoi(void); +extern void platfrom_gettod(unsigned int *year, unsigned int *mon, unsigned int *day, + unsigned int *hour, unsigned int *min, unsigned int *sec); diff --git a/include/asm-h8300/termbits.h b/include/asm-h8300/termbits.h new file mode 100644 index 0000000000000..45c635080a3e8 --- /dev/null +++ b/include/asm-h8300/termbits.h @@ -0,0 +1,174 @@ +#ifndef __ARCH_H8300_TERMBITS_H__ +#define __ARCH_H8300_TERMBITS_H__ + +#include + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define B500000 0010005 +#define B576000 0010006 +#define B921600 0010007 +#define B1000000 0010010 +#define B1152000 0010011 +#define B1500000 0010012 +#define B2000000 0010013 +#define B2500000 0010014 +#define B3000000 0010015 +#define B3500000 0010016 +#define B4000000 0010017 +#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CMSPAR 010000000000 /* mark or space (stick) parity */ +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* __ARCH_H8300_TERMBITS_H__ */ diff --git a/include/asm-h8300/termios.h b/include/asm-h8300/termios.h new file mode 100644 index 0000000000000..e2319f992af29 --- /dev/null +++ b/include/asm-h8300/termios.h @@ -0,0 +1,108 @@ +#ifndef _H8300_TERMIOS_H +#define _H8300_TERMIOS_H + +#include +#include + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#ifdef __KERNEL__ +/* intr=^C quit=^| erase=del kill=^U + eof=^D vtime=\0 vmin=\1 sxtc=\0 + start=^Q stop=^S susp=^Z eol=\0 + reprint=^R discard=^U werase=^W lnext=^V + eol2=\0 +*/ +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" +#endif + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ + +/* line disciplines */ +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 +#define N_STRIP 4 +#define N_AX25 5 +#define N_X25 6 /* X.25 async */ +#define N_6PACK 7 +#define N_MASC 8 /* Reserved for Mobitex module */ +#define N_R3964 9 /* Reserved for Simatic R3964 module */ +#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ +#define N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */ +#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ +#define N_HDLC 13 /* synchronous HDLC */ +#define N_SYNC_PPP 14 +#define N_HCI 15 /* Bluetooth HCI UART */ + +#ifdef __KERNEL__ + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +#define user_termio_to_kernel_termios(termios, termio) \ +({ \ + unsigned short tmp; \ + get_user(tmp, &(termio)->c_iflag); \ + (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \ + get_user(tmp, &(termio)->c_oflag); \ + (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \ + get_user(tmp, &(termio)->c_cflag); \ + (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \ + get_user(tmp, &(termio)->c_lflag); \ + (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \ + get_user((termios)->c_line, &(termio)->c_line); \ + copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ +}) + +/* + * Translate a "termios" structure into a "termio". Ugh. + */ +#define kernel_termios_to_user_termio(termio, termios) \ +({ \ + put_user((termios)->c_iflag, &(termio)->c_iflag); \ + put_user((termios)->c_oflag, &(termio)->c_oflag); \ + put_user((termios)->c_cflag, &(termio)->c_cflag); \ + put_user((termios)->c_lflag, &(termio)->c_lflag); \ + put_user((termios)->c_line, &(termio)->c_line); \ + copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ +}) + +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) + +#endif /* __KERNEL__ */ + +#endif /* _H8300_TERMIOS_H */ diff --git a/include/asm-h8300/thread_info.h b/include/asm-h8300/thread_info.h new file mode 100644 index 0000000000000..1c9b5b9570217 --- /dev/null +++ b/include/asm-h8300/thread_info.h @@ -0,0 +1,106 @@ +/* thread_info.h: h8300 low-level thread information + * adapted from the i386 and PPC versions by Yoshinori Sato + * + * Copyright (C) 2002 David Howells (dhowells@redhat.com) + * - Incorporating suggestions made by Linus Torvalds and Dave Miller + */ + +#ifndef _ASM_THREAD_INFO_H +#define _ASM_THREAD_INFO_H + +#include + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ + +/* + * low level task data. + * If you change this, change the TI_* offsets below to match. + */ +struct thread_info { + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + unsigned long flags; /* low level flags */ + int cpu; /* cpu we're on */ + int preempt_count; /* 0 => preemptable, <0 => BUG*/ + struct restart_block restart_block; +}; + +/* + * macros/functions for gaining access to the thread information structure + */ +#define INIT_THREAD_INFO(tsk) \ +{ \ + task: &tsk, \ + exec_domain: &default_exec_domain, \ + flags: 0, \ + cpu: 0, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} + +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) + + +/* + * Size of kernel stack for each process. This must be a power of 2... + */ +#define THREAD_SIZE 8192 /* 2 pages */ + + +/* how to get the thread information struct from C */ +static inline struct thread_info *current_thread_info(void) +{ + struct thread_info *ti; + __asm__( + "mov.l sp, %0 \n\t" + "and.l %1, %0" + : "=&r"(ti) + : "r" (~(THREAD_SIZE-1)) + ); + return ti; +} + +/* thread information allocation */ +#define alloc_thread_info() ((struct thread_info *) \ + __get_free_pages(GFP_KERNEL, 1)) +#define free_thread_info(ti) free_pages((unsigned long) (ti), 1) +#define get_thread_info(ti) get_task_struct((ti)->task) +#define put_thread_info(ti) put_task_struct((ti)->task) +#endif /* __ASSEMBLY__ */ + +/* + * Offsets in thread_info structure, used in assembly code + */ +#define TI_TASK 0 +#define TI_EXECDOMAIN 4 +#define TI_FLAGS 8 +#define TI_CPU 12 + +#define PREEMPT_ACTIVE 0x4000000 + +/* + * thread information flag bit numbers + */ +#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ +#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ +#define TIF_SIGPENDING 2 /* signal pending */ +#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ +#define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling + TIF_NEED_RESCHED */ + +/* as above, but as bit values */ +#define _TIF_SYSCALL_TRACE (1< +#include TIMEX_DEPEND_HEADER(TARGET) + +#define CLOCK_TICK_RATE H8300_TIMER_FREQ +#define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ +#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \ + (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \ + << (SHIFT_SCALE-SHIFT_HZ)) / HZ) + +typedef unsigned long cycles_t; +extern short h8300_timer_count; + +static inline cycles_t get_cycles(void) +{ + return 0; +} + +#endif diff --git a/include/asm-h8300/tlb.h b/include/asm-h8300/tlb.h new file mode 100644 index 0000000000000..69c0faa931945 --- /dev/null +++ b/include/asm-h8300/tlb.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-h8300/tlbflush.h b/include/asm-h8300/tlbflush.h new file mode 100644 index 0000000000000..bbdffbeeedef9 --- /dev/null +++ b/include/asm-h8300/tlbflush.h @@ -0,0 +1,61 @@ +#ifndef _H8300_TLBFLUSH_H +#define _H8300_TLBFLUSH_H + +/* + * Copyright (C) 2000 Lineo, David McCullough + * Copyright (C) 2000-2002, Greg Ungerer + */ + +#include + +/* + * flush all user-space atc entries. + */ +static inline void __flush_tlb(void) +{ + BUG(); +} + +static inline void __flush_tlb_one(unsigned long addr) +{ + BUG(); +} + +#define flush_tlb() __flush_tlb() + +/* + * flush all atc entries (both kernel and user-space entries). + */ +static inline void flush_tlb_all(void) +{ + BUG(); +} + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + BUG(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) +{ + BUG(); +} + +static inline void flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + BUG(); +} + +extern inline void flush_tlb_kernel_page(unsigned long addr) +{ + BUG(); +} + +extern inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + BUG(); +} + +#endif /* _H8300_TLBFLUSH_H */ diff --git a/include/asm-h8300/topology.h b/include/asm-h8300/topology.h new file mode 100644 index 0000000000000..fdc121924d4c9 --- /dev/null +++ b/include/asm-h8300/topology.h @@ -0,0 +1,6 @@ +#ifndef _ASM_H8300_TOPOLOGY_H +#define _ASM_H8300_TOPOLOGY_H + +#include + +#endif /* _ASM_H8300_TOPOLOGY_H */ diff --git a/include/asm-h8300/traps.h b/include/asm-h8300/traps.h new file mode 100644 index 0000000000000..7d8867eb4fc1e --- /dev/null +++ b/include/asm-h8300/traps.h @@ -0,0 +1,207 @@ +/* + * linux/include/asm/traps.h + * + * Copyright (C) 1993 Hamish Macdonald + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef _H8300_TRAPS_H +#define _H8300_TRAPS_H + +#if 0 +#ifndef __ASSEMBLY__ + +typedef void (*e_vector)(void); + +extern e_vector vectors[]; + +#endif + +#define VEC_BUSERR (2) +#define VEC_ADDRERR (3) +#define VEC_ILLEGAL (4) +#define VEC_ZERODIV (5) +#define VEC_CHK (6) +#define VEC_TRAP (7) +#define VEC_PRIV (8) +#define VEC_TRACE (9) +#define VEC_LINE10 (10) +#define VEC_LINE11 (11) +#define VEC_RESV1 (12) +#define VEC_COPROC (13) +#define VEC_FORMAT (14) +#define VEC_UNINT (15) +#define VEC_SPUR (24) +#define VEC_INT1 (25) +#define VEC_INT2 (26) +#define VEC_INT3 (27) +#define VEC_INT4 (28) +#define VEC_INT5 (29) +#define VEC_INT6 (30) +#define VEC_INT7 (31) +#define VEC_SYS (32) +#define VEC_TRAP1 (33) +#define VEC_TRAP2 (34) +#define VEC_TRAP3 (35) +#define VEC_TRAP4 (36) +#define VEC_TRAP5 (37) +#define VEC_TRAP6 (38) +#define VEC_TRAP7 (39) +#define VEC_TRAP8 (40) +#define VEC_TRAP9 (41) +#define VEC_TRAP10 (42) +#define VEC_TRAP11 (43) +#define VEC_TRAP12 (44) +#define VEC_TRAP13 (45) +#define VEC_TRAP14 (46) +#define VEC_TRAP15 (47) +#define VEC_FPBRUC (48) +#define VEC_FPIR (49) +#define VEC_FPDIVZ (50) +#define VEC_FPUNDER (51) +#define VEC_FPOE (52) +#define VEC_FPOVER (53) +#define VEC_FPNAN (54) +#define VEC_FPUNSUP (55) +#define VEC_UNIMPEA (60) +#define VEC_UNIMPII (61) +#define VEC_USER (64) + +#define VECOFF(vec) ((vec)<<2) + +#ifndef __ASSEMBLY__ + +/* Status register bits */ +#define PS_T (0x8000) +#define PS_S (0x2000) +#define PS_M (0x1000) +#define PS_C (0x0001) + +/* bits for 68020/68030 special status word */ + +#define FC (0x8000) +#define FB (0x4000) +#define RC (0x2000) +#define RB (0x1000) +#define DF (0x0100) +#define RM (0x0080) +#define RW (0x0040) +#define SZ (0x0030) +#define DFC (0x0007) + +/* bits for 68030 MMU status register (mmusr,psr) */ + +#define MMU_B (0x8000) /* bus error */ +#define MMU_L (0x4000) /* limit violation */ +#define MMU_S (0x2000) /* supervisor violation */ +#define MMU_WP (0x0800) /* write-protected */ +#define MMU_I (0x0400) /* invalid descriptor */ +#define MMU_M (0x0200) /* ATC entry modified */ +#define MMU_T (0x0040) /* transparent translation */ +#define MMU_NUM (0x0007) /* number of levels traversed */ + + +/* bits for 68040 special status word */ +#define CP_040 (0x8000) +#define CU_040 (0x4000) +#define CT_040 (0x2000) +#define CM_040 (0x1000) +#define MA_040 (0x0800) +#define ATC_040 (0x0400) +#define LK_040 (0x0200) +#define RW_040 (0x0100) +#define SIZ_040 (0x0060) +#define TT_040 (0x0018) +#define TM_040 (0x0007) + +/* bits for 68040 write back status word */ +#define WBV_040 (0x80) +#define WBSIZ_040 (0x60) +#define WBBYT_040 (0x20) +#define WBWRD_040 (0x40) +#define WBLNG_040 (0x00) +#define WBTT_040 (0x18) +#define WBTM_040 (0x07) + +/* bus access size codes */ +#define BA_SIZE_BYTE (0x20) +#define BA_SIZE_WORD (0x40) +#define BA_SIZE_LONG (0x00) +#define BA_SIZE_LINE (0x60) + +/* bus access transfer type codes */ +#define BA_TT_MOVE16 (0x08) + +/* structure for stack frames */ + +struct frame { + struct pt_regs ptregs; + union { + struct { + unsigned long iaddr; /* instruction address */ + } fmt2; + struct { + unsigned long effaddr; /* effective address */ + } fmt3; + struct { + unsigned long effaddr; /* effective address */ + unsigned long pc; /* pc of faulted instr */ + } fmt4; + struct { + unsigned long effaddr; /* effective address */ + unsigned short ssw; /* special status word */ + unsigned short wb3s; /* write back 3 status */ + unsigned short wb2s; /* write back 2 status */ + unsigned short wb1s; /* write back 1 status */ + unsigned long faddr; /* fault address */ + unsigned long wb3a; /* write back 3 address */ + unsigned long wb3d; /* write back 3 data */ + unsigned long wb2a; /* write back 2 address */ + unsigned long wb2d; /* write back 2 data */ + unsigned long wb1a; /* write back 1 address */ + unsigned long wb1dpd0; /* write back 1 data/push data 0*/ + unsigned long pd1; /* push data 1*/ + unsigned long pd2; /* push data 2*/ + unsigned long pd3; /* push data 3*/ + } fmt7; + struct { + unsigned long iaddr; /* instruction address */ + unsigned short int1[4]; /* internal registers */ + } fmt9; + struct { + unsigned short int1; + unsigned short ssw; /* special status word */ + unsigned short isc; /* instruction stage c */ + unsigned short isb; /* instruction stage b */ + unsigned long daddr; /* data cycle fault address */ + unsigned short int2[2]; + unsigned long dobuf; /* data cycle output buffer */ + unsigned short int3[2]; + } fmta; + struct { + unsigned short int1; + unsigned short ssw; /* special status word */ + unsigned short isc; /* instruction stage c */ + unsigned short isb; /* instruction stage b */ + unsigned long daddr; /* data cycle fault address */ + unsigned short int2[2]; + unsigned long dobuf; /* data cycle output buffer */ + unsigned short int3[4]; + unsigned long baddr; /* stage B address */ + unsigned short int4[2]; + unsigned long dibuf; /* data cycle input buffer */ + unsigned short int5[3]; + unsigned ver : 4; /* stack frame version # */ + unsigned int6:12; + unsigned short int7[18]; + } fmtb; + } un; +}; + +#endif /* __ASSEMBLY__ */ +#endif + +#endif /* _H8300_TRAPS_H */ diff --git a/include/asm-h8300/types.h b/include/asm-h8300/types.h new file mode 100644 index 0000000000000..18a43a95a1d30 --- /dev/null +++ b/include/asm-h8300/types.h @@ -0,0 +1,58 @@ +#ifndef _H8300_TYPES_H +#define _H8300_TYPES_H + +/* + * This file is never included by application software unless + * explicitly requested (e.g., via linux/types.h) in which case the + * application is Linux specific so (user-) name space pollution is + * not a major issue. However, for interoperability, libraries still + * need to be careful to avoid a name clashes. + */ + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#define BITS_PER_LONG 32 + +/* Dma addresses are 32-bits wide. */ + +typedef u32 dma_addr_t; + +#endif /* __KERNEL__ */ + +#endif /* _H8300_TYPES_H */ diff --git a/include/asm-h8300/uaccess.h b/include/asm-h8300/uaccess.h new file mode 100644 index 0000000000000..24a0b92b13ee3 --- /dev/null +++ b/include/asm-h8300/uaccess.h @@ -0,0 +1,165 @@ +#ifndef __H8300_UACCESS_H +#define __H8300_UACCESS_H + +/* + * User space memory access functions + */ +#include +#include +#include + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +/* We let the MMU do all checking */ +extern inline int access_ok(int type, const void * addr, unsigned long size) +{ +#define RANGE_CHECK_OK(addr, size, lower, upper) \ + (((addr) >= (lower)) && (((addr) + (size)) < (upper))) + + extern unsigned long _ramend; + return(RANGE_CHECK_OK((unsigned long) addr, size, 0L, (unsigned long)&_ramend)); +} + +extern inline int verify_area(int type, const void * addr, unsigned long size) +{ + return access_ok(type,addr,size)?0:-EFAULT; +} + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +/* Returns 0 if exception not found and fixup otherwise. */ +extern unsigned long search_exception_table(unsigned long); + + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + */ + +#define put_user(x, ptr) \ +({ \ + int __pu_err = 0; \ + typeof(*(ptr)) __pu_val = (x); \ + switch (sizeof (*(ptr))) { \ + case 1: \ + case 2: \ + case 4: \ + *(ptr) = (__pu_val); \ + break; \ + case 8: \ + memcpy(ptr, &__pu_val, sizeof (*(ptr))); \ + break; \ + default: \ + __pu_err = __put_user_bad(); \ + break; \ + } \ + __pu_err; \ +}) +#define __put_user(x, ptr) put_user(x, ptr) + +extern int __put_user_bad(void); + +/* + * Tell gcc we read from memory instead of writing: this is because + * we do not write to any memory gcc knows about, so there are no + * aliasing issues. + */ + +#define __ptr(x) ((unsigned long *)(x)) + +/* + * Tell gcc we read from memory instead of writing: this is because + * we do not write to any memory gcc knows about, so there are no + * aliasing issues. + */ + +#define get_user(x, ptr) \ +({ \ + int __gu_err = 0; \ + typeof(*(ptr)) __gu_val = 0; \ + switch (sizeof(*(ptr))) { \ + case 1: \ + case 2: \ + case 4: \ + __gu_val = *(ptr); \ + break; \ + case 8: \ + memcpy(&__gu_val, ptr, sizeof (*(ptr))); \ + break; \ + default: \ + __gu_val = 0; \ + __gu_err = __get_user_bad(); \ + break; \ + } \ + (x) = __gu_val; \ + __gu_err; \ +}) +#define __get_user(x, ptr) get_user(x, ptr) + +extern int __get_user_bad(void); + +#define copy_from_user(to, from, n) (memcpy(to, from, n), 0) +#define copy_to_user(to, from, n) (memcpy(to, from, n), 0) + +#define __copy_from_user(to, from, n) copy_from_user(to, from, n) +#define __copy_to_user(to, from, n) copy_to_user(to, from, n) + +#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; }) + +#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; }) + +/* + * Copy a null terminated string from userspace. + */ + +static inline long +strncpy_from_user(char *dst, const char *src, long count) +{ + char *tmp; + strncpy(dst, src, count); + for (tmp = dst; *tmp && count > 0; tmp++, count--) + ; + return(tmp - dst); /* DAVIDM should we count a NUL ? check getname */ +} + +/* + * Return the size of a string (including the ending 0) + * + * Return 0 on exception, a value greater than N if too long + */ +static inline long strnlen_user(const char *src, long n) +{ + return(strlen(src) + 1); /* DAVIDM make safer */ +} + +#define strlen_user(str) strnlen_user(str, 32767) + +/* + * Zero Userspace + */ + +static inline unsigned long +clear_user(void *to, unsigned long n) +{ + memset(to, 0, n); + return(0); +} + +#endif /* _H8300_UACCESS_H */ diff --git a/include/asm-h8300/ucontext.h b/include/asm-h8300/ucontext.h new file mode 100644 index 0000000000000..7987d6c062459 --- /dev/null +++ b/include/asm-h8300/ucontext.h @@ -0,0 +1,23 @@ +#ifndef _H8300_UCONTEXT_H +#define _H8300_UCONTEXT_H + +typedef int greg_t; +#define NGREG 10 +typedef greg_t gregset_t[NGREG]; + +struct mcontext { + int version; + gregset_t gregs; +}; + +#define MCONTEXT_VERSION 1 + +struct ucontext { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + struct mcontext uc_mcontext; + sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +#endif diff --git a/include/asm-h8300/unaligned.h b/include/asm-h8300/unaligned.h new file mode 100644 index 0000000000000..8a93961173c3e --- /dev/null +++ b/include/asm-h8300/unaligned.h @@ -0,0 +1,16 @@ +#ifndef __H8300_UNALIGNED_H +#define __H8300_UNALIGNED_H + +#include + +/* Use memmove here, so gcc does not insert a __builtin_memcpy. */ + +#define get_unaligned(ptr) \ + ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; }) + +#define put_unaligned(val, ptr) \ + ({ __typeof__(*(ptr)) __tmp = (val); \ + memmove((ptr), &__tmp, sizeof(*(ptr))); \ + (void)0; }) + +#endif diff --git a/include/asm-h8300/unistd.h b/include/asm-h8300/unistd.h new file mode 100644 index 0000000000000..5ed2416f307dd --- /dev/null +++ b/include/asm-h8300/unistd.h @@ -0,0 +1,461 @@ +#ifndef _ASM_H8300_UNISTD_H_ +#define _ASM_H8300_UNISTD_H_ + +/* + * This file contains the system call numbers. + */ + +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_umount2 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl /* 110 */ not supported +#define __NR_vhangup 111 +#define __NR_idle /* 112 */ Obsolete +#define __NR_vm86 /* 113 */ not supported +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_cacheflush 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 +#define __NR_getpagesize 166 +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 +#define __NR_setresgid 170 +#define __NR_getresgid 171 +#define __NR_prctl 172 +#define __NR_rt_sigreturn 173 +#define __NR_rt_sigaction 174 +#define __NR_rt_sigprocmask 175 +#define __NR_rt_sigpending 176 +#define __NR_rt_sigtimedwait 177 +#define __NR_rt_sigqueueinfo 178 +#define __NR_rt_sigsuspend 179 +#define __NR_pread64 180 +#define __NR_pwrite64 181 +#define __NR_lchown 182 +#define __NR_getcwd 183 +#define __NR_capget 184 +#define __NR_capset 185 +#define __NR_sigaltstack 186 +#define __NR_sendfile 187 +#define __NR_getpmsg 188 /* some people actually want streams */ +#define __NR_putpmsg 189 /* some people actually want streams */ +#define __NR_vfork 190 +#define __NR_ugetrlimit 191 +#define __NR_mmap2 192 +#define __NR_truncate64 193 +#define __NR_ftruncate64 194 +#define __NR_stat64 195 +#define __NR_lstat64 196 +#define __NR_fstat64 197 +#define __NR_chown32 198 +#define __NR_getuid32 199 +#define __NR_getgid32 200 +#define __NR_geteuid32 201 +#define __NR_getegid32 202 +#define __NR_setreuid32 203 +#define __NR_setregid32 204 +#define __NR_getgroups32 205 +#define __NR_setgroups32 206 +#define __NR_fchown32 207 +#define __NR_setresuid32 208 +#define __NR_getresuid32 209 +#define __NR_setresgid32 210 +#define __NR_getresgid32 211 +#define __NR_lchown32 212 +#define __NR_setuid32 213 +#define __NR_setgid32 214 +#define __NR_setfsuid32 215 +#define __NR_setfsgid32 216 +#define __NR_pivot_root 217 +#define __NR_getdents64 220 +#define __NR_fcntl64 221 +#define __NR_security 223 +#define __NR_gettid 224 +#define __NR_readahead 225 +#define __NR_setxattr 226 +#define __NR_lsetxattr 227 +#define __NR_fsetxattr 228 +#define __NR_getxattr 229 +#define __NR_lgetxattr 230 +#define __NR_fgetxattr 231 +#define __NR_listxattr 232 +#define __NR_llistxattr 233 +#define __NR_flistxattr 234 +#define __NR_removexattr 235 +#define __NR_lremovexattr 236 +#define __NR_fremovexattr 237 +#define __NR_tkill 238 +#define __NR_sendfile64 239 +#define __NR_futex 240 +#define __NR_sched_setaffinity 241 +#define __NR_sched_getaffinity 242 +#define __NR_set_thread_area 243 +#define __NR_get_thread_area 244 +#define __NR_io_setup 245 +#define __NR_io_destroy 246 +#define __NR_io_getevents 247 +#define __NR_io_submit 248 +#define __NR_io_cancel 249 +#define __NR_alloc_hugepages 250 +#define __NR_free_hugepages 251 +#define __NR_exit_group 252 +#define __NR_lookup_dcookie 253 +#define __NR_sys_epoll_create 254 +#define __NR_sys_epoll_ctl 255 +#define __NR_sys_epoll_wait 256 +#define __NR_remap_file_pages 257 +#define __NR_set_tid_address 258 +#define __NR_timer_create 259 +#define __NR_timer_settime (__NR_timer_create+1) +#define __NR_timer_gettime (__NR_timer_create+2) +#define __NR_timer_getoverrun (__NR_timer_create+3) +#define __NR_timer_delete (__NR_timer_create+4) +#define __NR_clock_settime (__NR_timer_create+5) +#define __NR_clock_gettime (__NR_timer_create+6) +#define __NR_clock_getres (__NR_timer_create+7) +#define __NR_clock_nanosleep (__NR_timer_create+8) + +#define NR_syscalls 268 + + +/* user-visible error numbers are in the range -1 - -122: see + */ + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-125)) { \ + /* avoid using res which is declared to be in register d0; \ + errno might expand to a function call and clobber it. */ \ + int __err = -(res); \ + errno = __err; \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +#define _syscall0(type, name) \ +type name(void) \ +{ \ + register long __res __asm__("er0"); \ + __asm__ __volatile__ ("mov.l %1,er0\n\t" \ + "trapa #0\n\t" \ + : "=r" (__res) \ + : "ir" (__NR_##name) \ + : "cc"); \ + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ + errno = -__res; \ + __res = -1; \ + } \ + return (type)__res; \ +} + +#define _syscall1(type, name, atype, a) \ +type name(atype a) \ +{ \ + register long __res __asm__("er0"); \ + __asm__ __volatile__ ("mov.l %2, er1\n\t" \ + "mov.l %1, er0\n\t" \ + "trapa #0\n\t" \ + : "=r" (__res) \ + : "ir" (__NR_##name), \ + "g" ((long)a) \ + : "cc", "er1"); \ + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ + errno = -__res; \ + __res = -1; \ + } \ + return (type)__res; \ +} + +#define _syscall2(type, name, atype, a, btype, b) \ +type name(atype a, btype b) \ +{ \ + register long __res __asm__("er0"); \ + __asm__ __volatile__ ("mov.l %3, er2\n\t" \ + "mov.l %2, er1\n\t" \ + "mov.l %1, er0\n\t" \ + "trapa #0\n\t" \ + : "=r" (__res) \ + : "ir" (__NR_##name), \ + "g" ((long)a), \ + "g" ((long)b) \ + : "cc", "er1", "er2"); \ + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ + errno = -__res; \ + __res = -1; \ + } \ + return (type)__res; \ +} + +#define _syscall3(type, name, atype, a, btype, b, ctype, c) \ +type name(atype a, btype b, ctype c) \ +{ \ + register long __res __asm__("er0"); \ + __asm__ __volatile__ ("mov.l %4, er3\n\t" \ + "mov.l %3, er2\n\t" \ + "mov.l %2, er1\n\t" \ + "mov.l %1, er0\n\t" \ + "trapa #0\n\t" \ + : "=r" (__res) \ + : "ir" (__NR_##name), \ + "g" ((long)a), \ + "g" ((long)b), \ + "g" ((long)c) \ + : "cc", "er1", "er2", "er3"); \ + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ + errno = -__res; \ + __res = -1; \ + } \ + return (type)__res; \ +} + +#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d) \ +type name(atype a, btype b, ctype c, dtype d) \ +{ \ + register long __res __asm__("er0"); \ + __asm__ __volatile__ ("mov.l %5, er4\n\t" \ + "mov.l %4, er3\n\t" \ + "mov.l %3, er2\n\t" \ + "mov.l %2, er1\n\t" \ + "mov.l %1, er0\n\t" \ + "trapa #0\n\t" \ + : "=r" (__res) \ + : "ir" (__NR_##name), \ + "g" ((long)a), \ + "g" ((long)b), \ + "g" ((long)c), \ + "g" ((long)d) \ + : "cc", "er1", "er2", "er3", "er4"); \ + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ + errno = -__res; \ + __res = -1; \ + } \ + return (type)__res; \ +} + +#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e) \ +type name(atype a, btype b, ctype c, dtype d, etype e) \ +{ \ + register long __res __asm__("er0"); \ + __asm__ __volatile__ ("mov.l %6, er5\n\t" \ + "mov.l %5, er4\n\t" \ + "mov.l %4, er3\n\t" \ + "mov.l %3, er2\n\t" \ + "mov.l %2, er1\n\t" \ + "mov.l %1, er0\n\t" \ + "trapa #0\n\t" \ + : "=r" (__res) \ + : "ir" (__NR_##name), \ + "g" ((long)a), \ + "g" ((long)b), \ + "g" ((long)c), \ + "g" ((long)d), \ + "g" ((long)e) \ + : "cc", "er1", "er2", "er3", "er4"); \ + if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ + errno = -__res; \ + __res = -1; \ + } \ + return (type)__res; \ +} + + +#ifdef __KERNEL_SYSCALLS__ + +/* + * we need this inline - forking from kernel space will result + * in NO COPY ON WRITE (!!!), until an execve is executed. This + * is no problem, but for the stack. This is handled by not letting + * main() use the stack at all after fork(). Thus, no function + * calls - which means inline code for fork too, as otherwise we + * would use the stack upon exit from 'fork()'. + * + * Actually only pause and fork are needed inline, so that there + * won't be any messing with the stack from main(), but we define + * some others too. + */ +#define __NR__exit __NR_exit +static inline _syscall0(int,pause) +static inline _syscall0(int,sync) +static inline _syscall0(pid_t,setsid) +static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) +static inline _syscall3(int,read,int,fd,char *,buf,off_t,count) +static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count) +static inline _syscall1(int,dup,int,fd) +static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) +static inline _syscall3(int,open,const char *,file,int,flag,int,mode) +static inline _syscall1(int,close,int,fd) +static inline _syscall1(int,_exit,int,exitcode) +static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) +static inline _syscall1(int,delete_module,const char *,name) + +static inline pid_t wait(int * wait_stat) +{ + return waitpid(-1,wait_stat,0); +} + +#endif + +/* + * "Conditional" syscalls + */ +#define cond_syscall(name) \ + asm (".weak\t_" #name "\n" \ + ".set\t_" #name ",_sys_ni_syscall"); + +#endif /* _ASM_H8300_UNISTD_H_ */ diff --git a/include/asm-h8300/user.h b/include/asm-h8300/user.h new file mode 100644 index 0000000000000..6c64f99af3e15 --- /dev/null +++ b/include/asm-h8300/user.h @@ -0,0 +1,76 @@ +#ifndef _H8300_USER_H +#define _H8300_USER_H + +#include + +/* Core file format: The core file is written in such a way that gdb + can understand it and provide useful information to the user (under + linux we use the 'trad-core' bfd). There are quite a number of + obstacles to being able to view the contents of the floating point + registers, and until these are solved you will not be able to view the + contents of them. Actually, you can read in the core file and look at + the contents of the user struct to find out what the floating point + registers contain. + The actual file contents are as follows: + UPAGE: 1 page consisting of a user struct that tells gdb what is present + in the file. Directly after this is a copy of the task_struct, which + is currently not used by gdb, but it may come in useful at some point. + All of the registers are stored as part of the upage. The upage should + always be only one page. + DATA: The data area is stored. We use current->end_text to + current->brk to pick up all of the user variables, plus any memory + that may have been malloced. No attempt is made to determine if a page + is demand-zero or if a page is totally unused, we just cover the entire + range. All of the addresses are rounded in such a way that an integral + number of pages is written. + STACK: We need the stack information in order to get a meaningful + backtrace. We need to write the data from (esp) to + current->start_stack, so we round each of these off in order to be able + to write an integer number of pages. + The minimum core file size is 3 pages, or 12288 bytes. +*/ + +/* This is the old layout of "struct pt_regs" as of Linux 1.x, and + is still the layout used by user (the new pt_regs doesn't have + all registers). */ +struct user_regs_struct { + long er1,er2,er3,er4,er5,er6; + long er0; + long usp; + long orig_er0; + short ccr; + long pc; +}; + + +/* When the kernel dumps core, it starts by dumping the user struct - + this will be used by gdb to figure out where the data and stack segments + are within the file, and what virtual addresses to use. */ +struct user{ +/* We start with the registers, to mimic the way that "memory" is returned + from the ptrace(3,...) function. */ + struct user_regs_struct regs; /* Where the registers are actually stored */ +/* ptrace does not yet supply these. Someday.... */ +/* The rest of this junk is to help gdb figure out what goes where */ + unsigned long int u_tsize; /* Text segment size (pages). */ + unsigned long int u_dsize; /* Data segment size (pages). */ + unsigned long int u_ssize; /* Stack segment size (pages). */ + unsigned long start_code; /* Starting virtual address of text. */ + unsigned long start_stack; /* Starting virtual address of stack area. + This is actually the bottom of the stack, + the top of the stack is always found in the + esp register. */ + long int signal; /* Signal that caused the core dump. */ + int reserved; /* No longer used */ + struct user_regs_struct *u_ar0; + /* Used by gdb to help find the values for */ + /* the registers. */ + unsigned long magic; /* To uniquely identify a core file */ + char u_comm[32]; /* User command that was responsible */ +}; +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif diff --git a/include/asm-h8300/virtconvert.h b/include/asm-h8300/virtconvert.h new file mode 100644 index 0000000000000..3b344c1dfe0f3 --- /dev/null +++ b/include/asm-h8300/virtconvert.h @@ -0,0 +1,23 @@ +#ifndef __H8300_VIRT_CONVERT__ +#define __H8300_VIRT_CONVERT__ + +/* + * Macros used for converting between virtual and physical mappings. + */ + +#ifdef __KERNEL__ + +#include +#include +#include + +#define mm_ptov(vaddr) ((void *) (vaddr)) +#define mm_vtop(vaddr) ((unsigned long) (vaddr)) +#define phys_to_virt(vaddr) ((void *) (vaddr)) +#define virt_to_phys(vaddr) ((unsigned long) (vaddr)) + +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +#endif +#endif -- 2.53.0