mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-08 01:08:03 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
9
arch/sparc/Kbuild
Normal file
9
arch/sparc/Kbuild
Normal file
|
@ -0,0 +1,9 @@
|
|||
#
|
||||
# core part of the sparc kernel
|
||||
#
|
||||
|
||||
obj-y += kernel/
|
||||
obj-y += mm/
|
||||
obj-y += math-emu/
|
||||
obj-y += net/
|
||||
obj-y += crypto/
|
564
arch/sparc/Kconfig
Normal file
564
arch/sparc/Kconfig
Normal file
|
@ -0,0 +1,564 @@
|
|||
config 64BIT
|
||||
bool "64-bit kernel" if ARCH = "sparc"
|
||||
default ARCH = "sparc64"
|
||||
help
|
||||
SPARC is a family of RISC microprocessors designed and marketed by
|
||||
Sun Microsystems, incorporated. They are very widely found in Sun
|
||||
workstations and clones.
|
||||
|
||||
Say yes to build a 64-bit kernel - formerly known as sparc64
|
||||
Say no to build a 32-bit kernel - formerly known as sparc
|
||||
|
||||
config SPARC
|
||||
bool
|
||||
default y
|
||||
select ARCH_MIGHT_HAVE_PC_PARPORT if SPARC64 && PCI
|
||||
select ARCH_MIGHT_HAVE_PC_SERIO
|
||||
select OF
|
||||
select OF_PROMTREE
|
||||
select HAVE_IDE
|
||||
select HAVE_OPROFILE
|
||||
select HAVE_ARCH_KGDB if !SMP || SPARC64
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select SYSCTL_EXCEPTION_TRACE
|
||||
select ARCH_WANT_OPTIONAL_GPIOLIB
|
||||
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
|
||||
select RTC_CLASS
|
||||
select RTC_DRV_M48T59
|
||||
select HAVE_DMA_ATTRS
|
||||
select HAVE_DMA_API_DEBUG
|
||||
select HAVE_ARCH_JUMP_LABEL if SPARC64
|
||||
select GENERIC_IRQ_SHOW
|
||||
select ARCH_WANT_IPC_PARSE_VERSION
|
||||
select GENERIC_PCI_IOMAP
|
||||
select HAVE_NMI_WATCHDOG if SPARC64
|
||||
select HAVE_BPF_JIT
|
||||
select HAVE_DEBUG_BUGVERBOSE
|
||||
select GENERIC_SMP_IDLE_THREAD
|
||||
select GENERIC_CMOS_UPDATE
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_STRNCPY_FROM_USER
|
||||
select GENERIC_STRNLEN_USER
|
||||
select MODULES_USE_ELF_RELA
|
||||
select ODD_RT_SIGACTION
|
||||
select OLD_SIGSUSPEND
|
||||
select ARCH_HAS_SG_CHAIN
|
||||
|
||||
config SPARC32
|
||||
def_bool !64BIT
|
||||
select GENERIC_ATOMIC64
|
||||
select CLZ_TAB
|
||||
select HAVE_UID16
|
||||
select OLD_SIGACTION
|
||||
|
||||
config SPARC64
|
||||
def_bool 64BIT
|
||||
select HAVE_FUNCTION_TRACER
|
||||
select HAVE_FUNCTION_GRAPH_TRACER
|
||||
select HAVE_FUNCTION_GRAPH_FP_TEST
|
||||
select HAVE_KRETPROBES
|
||||
select HAVE_KPROBES
|
||||
select HAVE_RCU_TABLE_FREE if SMP
|
||||
select HAVE_MEMBLOCK
|
||||
select HAVE_MEMBLOCK_NODE_MAP
|
||||
select HAVE_ARCH_TRANSPARENT_HUGEPAGE
|
||||
select HAVE_DYNAMIC_FTRACE
|
||||
select HAVE_FTRACE_MCOUNT_RECORD
|
||||
select HAVE_SYSCALL_TRACEPOINTS
|
||||
select HAVE_CONTEXT_TRACKING
|
||||
select HAVE_DEBUG_KMEMLEAK
|
||||
select SPARSE_IRQ
|
||||
select RTC_DRV_CMOS
|
||||
select RTC_DRV_BQ4802
|
||||
select RTC_DRV_SUN4V
|
||||
select RTC_DRV_STARFIRE
|
||||
select HAVE_PERF_EVENTS
|
||||
select PERF_USE_VMALLOC
|
||||
select IRQ_PREFLOW_FASTEOI
|
||||
select ARCH_HAVE_NMI_SAFE_CMPXCHG
|
||||
select HAVE_C_RECORDMCOUNT
|
||||
select NO_BOOTMEM
|
||||
select HAVE_ARCH_AUDITSYSCALL
|
||||
select ARCH_SUPPORTS_ATOMIC_RMW
|
||||
|
||||
config ARCH_DEFCONFIG
|
||||
string
|
||||
default "arch/sparc/configs/sparc32_defconfig" if SPARC32
|
||||
default "arch/sparc/configs/sparc64_defconfig" if SPARC64
|
||||
|
||||
config IOMMU_HELPER
|
||||
bool
|
||||
default y if SPARC64
|
||||
|
||||
config STACKTRACE_SUPPORT
|
||||
bool
|
||||
default y if SPARC64
|
||||
|
||||
config LOCKDEP_SUPPORT
|
||||
bool
|
||||
default y if SPARC64
|
||||
|
||||
config HAVE_LATENCYTOP_SUPPORT
|
||||
bool
|
||||
default y if SPARC64
|
||||
|
||||
config ARCH_HIBERNATION_POSSIBLE
|
||||
def_bool y if SPARC64
|
||||
|
||||
config AUDIT_ARCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config HAVE_SETUP_PER_CPU_AREA
|
||||
def_bool y if SPARC64
|
||||
|
||||
config NEED_PER_CPU_EMBED_FIRST_CHUNK
|
||||
def_bool y if SPARC64
|
||||
|
||||
config NEED_PER_CPU_PAGE_FIRST_CHUNK
|
||||
def_bool y if SPARC64
|
||||
|
||||
config MMU
|
||||
bool
|
||||
default y
|
||||
|
||||
config HIGHMEM
|
||||
bool
|
||||
default y if SPARC32
|
||||
|
||||
config ZONE_DMA
|
||||
bool
|
||||
default y if SPARC32
|
||||
|
||||
config NEED_DMA_MAP_STATE
|
||||
def_bool y
|
||||
|
||||
config NEED_SG_DMA_LENGTH
|
||||
def_bool y
|
||||
|
||||
config GENERIC_ISA_DMA
|
||||
bool
|
||||
default y if SPARC32
|
||||
|
||||
config ARCH_SUPPORTS_DEBUG_PAGEALLOC
|
||||
def_bool y if SPARC64
|
||||
|
||||
source "init/Kconfig"
|
||||
|
||||
source "kernel/Kconfig.freezer"
|
||||
|
||||
menu "Processor type and features"
|
||||
|
||||
config SMP
|
||||
bool "Symmetric multi-processing support"
|
||||
---help---
|
||||
This enables support for systems with more than one CPU. If you have
|
||||
a system with only one CPU, say N. If you have a system with more
|
||||
than one CPU, say Y.
|
||||
|
||||
If you say N here, the kernel will run on uni- and multiprocessor
|
||||
machines, but will use only one CPU of a multiprocessor machine. If
|
||||
you say Y here, the kernel will run on many, but not all,
|
||||
uniprocessor machines. On a uniprocessor machine, the kernel
|
||||
will run faster if you say N here.
|
||||
|
||||
People using multiprocessor machines who say Y here should also say
|
||||
Y to "Enhanced Real Time Clock Support", below. The "Advanced Power
|
||||
Management" code will be disabled if you say Y here.
|
||||
|
||||
See also <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO
|
||||
available at <http://www.tldp.org/docs.html#howto>.
|
||||
|
||||
If you don't know what to do here, say N.
|
||||
|
||||
config NR_CPUS
|
||||
int "Maximum number of CPUs"
|
||||
depends on SMP
|
||||
range 2 32 if SPARC32
|
||||
range 2 1024 if SPARC64
|
||||
default 32 if SPARC32
|
||||
default 64 if SPARC64
|
||||
|
||||
source kernel/Kconfig.hz
|
||||
|
||||
config RWSEM_GENERIC_SPINLOCK
|
||||
bool
|
||||
default y if SPARC32
|
||||
|
||||
config RWSEM_XCHGADD_ALGORITHM
|
||||
bool
|
||||
default y if SPARC64
|
||||
|
||||
config GENERIC_HWEIGHT
|
||||
bool
|
||||
default y
|
||||
|
||||
config GENERIC_CALIBRATE_DELAY
|
||||
bool
|
||||
default y
|
||||
|
||||
config ARCH_MAY_HAVE_PC_FDC
|
||||
bool
|
||||
default y
|
||||
|
||||
config EMULATED_CMPXCHG
|
||||
bool
|
||||
default y if SPARC32
|
||||
help
|
||||
Sparc32 does not have a CAS instruction like sparc64. cmpxchg()
|
||||
is emulated, and therefore it is not completely atomic.
|
||||
|
||||
# Makefile helpers
|
||||
config SPARC32_SMP
|
||||
bool
|
||||
default y
|
||||
depends on SPARC32 && SMP
|
||||
|
||||
config SPARC64_SMP
|
||||
bool
|
||||
default y
|
||||
depends on SPARC64 && SMP
|
||||
|
||||
config EARLYFB
|
||||
bool "Support for early boot text console"
|
||||
default y
|
||||
depends on SPARC64
|
||||
help
|
||||
Say Y here to enable a faster early framebuffer boot console.
|
||||
|
||||
config SECCOMP
|
||||
bool "Enable seccomp to safely compute untrusted bytecode"
|
||||
depends on SPARC64 && PROC_FS
|
||||
default y
|
||||
help
|
||||
This kernel feature is useful for number crunching applications
|
||||
that may need to compute untrusted bytecode during their
|
||||
execution. By using pipes or other transports made available to
|
||||
the process as file descriptors supporting the read/write
|
||||
syscalls, it's possible to isolate those applications in
|
||||
their own address space using seccomp. Once seccomp is
|
||||
enabled via /proc/<pid>/seccomp, it cannot be disabled
|
||||
and the task is only allowed to execute a few safe syscalls
|
||||
defined by each seccomp mode.
|
||||
|
||||
If unsure, say Y. Only embedded should say N here.
|
||||
|
||||
config HOTPLUG_CPU
|
||||
bool "Support for hot-pluggable CPUs"
|
||||
depends on SPARC64 && SMP
|
||||
help
|
||||
Say Y here to experiment with turning CPUs off and on. CPUs
|
||||
can be controlled through /sys/devices/system/cpu/cpu#.
|
||||
Say N if you want to disable CPU hotplug.
|
||||
|
||||
if SPARC64
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
endif
|
||||
|
||||
config US3_MC
|
||||
tristate "UltraSPARC-III Memory Controller driver"
|
||||
depends on SPARC64
|
||||
default y
|
||||
help
|
||||
This adds a driver for the UltraSPARC-III memory controller.
|
||||
Loading this driver allows exact mnemonic strings to be
|
||||
printed in the event of a memory error, so that the faulty DIMM
|
||||
on the motherboard can be matched to the error.
|
||||
|
||||
If in doubt, say Y, as this information can be very useful.
|
||||
|
||||
# Global things across all Sun machines.
|
||||
config GENERIC_LOCKBREAK
|
||||
bool
|
||||
default y
|
||||
depends on SPARC64 && SMP && PREEMPT
|
||||
|
||||
config NUMA
|
||||
bool "NUMA support"
|
||||
depends on SPARC64 && SMP
|
||||
|
||||
config NODES_SHIFT
|
||||
int
|
||||
default "4"
|
||||
depends on NEED_MULTIPLE_NODES
|
||||
|
||||
# Some NUMA nodes have memory ranges that span
|
||||
# other nodes. Even though a pfn is valid and
|
||||
# between a node's start and end pfns, it may not
|
||||
# reside on that node. See memmap_init_zone()
|
||||
# for details.
|
||||
config NODES_SPAN_OTHER_NODES
|
||||
def_bool y
|
||||
depends on NEED_MULTIPLE_NODES
|
||||
|
||||
config ARCH_SELECT_MEMORY_MODEL
|
||||
def_bool y if SPARC64
|
||||
|
||||
config ARCH_SPARSEMEM_ENABLE
|
||||
def_bool y if SPARC64
|
||||
select SPARSEMEM_VMEMMAP_ENABLE
|
||||
|
||||
config ARCH_SPARSEMEM_DEFAULT
|
||||
def_bool y if SPARC64
|
||||
|
||||
source "mm/Kconfig"
|
||||
|
||||
if SPARC64
|
||||
source "kernel/power/Kconfig"
|
||||
endif
|
||||
|
||||
config SCHED_SMT
|
||||
bool "SMT (Hyperthreading) scheduler support"
|
||||
depends on SPARC64 && SMP
|
||||
default y
|
||||
help
|
||||
SMT scheduler support improves the CPU scheduler's decision making
|
||||
when dealing with SPARC cpus at a cost of slightly increased overhead
|
||||
in some places. If unsure say N here.
|
||||
|
||||
config SCHED_MC
|
||||
bool "Multi-core scheduler support"
|
||||
depends on SPARC64 && SMP
|
||||
default y
|
||||
help
|
||||
Multi-core scheduler support improves the CPU scheduler's decision
|
||||
making when dealing with multi-core CPU chips at a cost of slightly
|
||||
increased overhead in some places. If unsure say N here.
|
||||
|
||||
source "kernel/Kconfig.preempt"
|
||||
|
||||
config CMDLINE_BOOL
|
||||
bool "Default bootloader kernel arguments"
|
||||
depends on SPARC64
|
||||
|
||||
config CMDLINE
|
||||
string "Initial kernel command string"
|
||||
depends on CMDLINE_BOOL
|
||||
default "console=ttyS0,9600 root=/dev/sda1"
|
||||
help
|
||||
Say Y here if you want to be able to pass default arguments to
|
||||
the kernel. This will be overridden by the bootloader, if you
|
||||
use one (such as SILO). This is most useful if you want to boot
|
||||
a kernel from TFTP, and want default options to be available
|
||||
with having them passed on the command line.
|
||||
|
||||
NOTE: This option WILL override the PROM bootargs setting!
|
||||
|
||||
config SUN_PM
|
||||
bool
|
||||
default y if SPARC32
|
||||
help
|
||||
Enable power management and CPU standby features on supported
|
||||
SPARC platforms.
|
||||
|
||||
config SPARC_LED
|
||||
tristate "Sun4m LED driver"
|
||||
depends on SPARC32
|
||||
help
|
||||
This driver toggles the front-panel LED on sun4m systems
|
||||
in a user-specifiable manner. Its state can be probed
|
||||
by reading /proc/led and its blinking mode can be changed
|
||||
via writes to /proc/led
|
||||
|
||||
config SERIAL_CONSOLE
|
||||
bool
|
||||
depends on SPARC32
|
||||
default 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 (silo) about how to pass options to the kernel at
|
||||
boot time.)
|
||||
|
||||
If you don't have a graphics 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 SPARC_LEON
|
||||
bool "Sparc Leon processor family"
|
||||
depends on SPARC32
|
||||
select USB_EHCI_BIG_ENDIAN_MMIO
|
||||
select USB_EHCI_BIG_ENDIAN_DESC
|
||||
---help---
|
||||
If you say Y here if you are running on a SPARC-LEON processor.
|
||||
The LEON processor is a synthesizable VHDL model of the
|
||||
SPARC-v8 standard. LEON is part of the GRLIB collection of
|
||||
IP cores that are distributed under GPL. GRLIB can be downloaded
|
||||
from www.gaisler.com. You can download a sparc-linux cross-compilation
|
||||
toolchain at www.gaisler.com.
|
||||
|
||||
if SPARC_LEON
|
||||
menu "U-Boot options"
|
||||
|
||||
config UBOOT_LOAD_ADDR
|
||||
hex "uImage Load Address"
|
||||
default 0x40004000
|
||||
---help---
|
||||
U-Boot kernel load address, the address in physical address space
|
||||
where u-boot will place the Linux kernel before booting it.
|
||||
This address is normally the base address of main memory + 0x4000.
|
||||
|
||||
config UBOOT_FLASH_ADDR
|
||||
hex "uImage.o Load Address"
|
||||
default 0x00080000
|
||||
---help---
|
||||
Optional setting only affecting the uImage.o ELF-image used to
|
||||
download the uImage file to the target using a ELF-loader other than
|
||||
U-Boot. It may for example be used to download an uImage to FLASH with
|
||||
the GRMON utility before even starting u-boot.
|
||||
|
||||
config UBOOT_ENTRY_ADDR
|
||||
hex "uImage Entry Address"
|
||||
default 0xf0004000
|
||||
---help---
|
||||
Do not change this unless you know what you're doing. This is
|
||||
hardcoded by the SPARC32 and LEON port.
|
||||
|
||||
This is the virtual address u-boot jumps to when booting the Linux
|
||||
Kernel.
|
||||
|
||||
endmenu
|
||||
endif
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Bus options (PCI etc.)"
|
||||
config SBUS
|
||||
bool
|
||||
default y
|
||||
|
||||
config SBUSCHAR
|
||||
bool
|
||||
default y
|
||||
|
||||
config SUN_LDOMS
|
||||
bool "Sun Logical Domains support"
|
||||
depends on SPARC64
|
||||
help
|
||||
Say Y here is you want to support virtual devices via
|
||||
Logical Domains.
|
||||
|
||||
config PCI
|
||||
bool "Support for PCI and PS/2 keyboard/mouse"
|
||||
help
|
||||
Find out whether your system includes a PCI bus. PCI is the name of
|
||||
a bus system, i.e. the way the CPU talks to the other stuff inside
|
||||
your box. If you say Y here, the kernel will include drivers and
|
||||
infrastructure code to support PCI bus devices.
|
||||
|
||||
CONFIG_PCI is needed for all JavaStation's (including MrCoffee),
|
||||
CP-1200, JavaEngine-1, Corona, Red October, and Serengeti SGSC.
|
||||
All of these platforms are extremely obscure, so say N if unsure.
|
||||
|
||||
config PCI_DOMAINS
|
||||
def_bool PCI if SPARC64
|
||||
|
||||
config PCI_SYSCALL
|
||||
def_bool PCI
|
||||
|
||||
config PCIC_PCI
|
||||
bool
|
||||
depends on PCI && SPARC32 && !SPARC_LEON
|
||||
default y
|
||||
|
||||
config LEON_PCI
|
||||
bool
|
||||
depends on PCI && SPARC_LEON
|
||||
default y
|
||||
|
||||
config SPARC_GRPCI1
|
||||
bool "GRPCI Host Bridge Support"
|
||||
depends on LEON_PCI
|
||||
default y
|
||||
help
|
||||
Say Y here to include the GRPCI Host Bridge Driver. The GRPCI
|
||||
PCI host controller is typically found in GRLIB SPARC32/LEON
|
||||
systems. The driver has one property (all_pci_errors) controlled
|
||||
from the bootloader that makes the GRPCI to generate interrupts
|
||||
on detected PCI Parity and System errors.
|
||||
|
||||
config SPARC_GRPCI2
|
||||
bool "GRPCI2 Host Bridge Support"
|
||||
depends on LEON_PCI
|
||||
default y
|
||||
help
|
||||
Say Y here to include the GRPCI2 Host Bridge Driver.
|
||||
|
||||
source "drivers/pci/Kconfig"
|
||||
|
||||
source "drivers/pcmcia/Kconfig"
|
||||
|
||||
config SUN_OPENPROMFS
|
||||
tristate "Openprom tree appears in /proc/openprom"
|
||||
help
|
||||
If you say Y, the OpenPROM device tree will be available as a
|
||||
virtual file system, which you can mount to /proc/openprom by "mount
|
||||
-t openpromfs none /proc/openprom".
|
||||
|
||||
To compile the /proc/openprom support as a module, choose M here: the
|
||||
module will be called openpromfs.
|
||||
|
||||
Only choose N if you know in advance that you will not need to modify
|
||||
OpenPROM settings on the running system.
|
||||
|
||||
# Makefile helpers
|
||||
config SPARC64_PCI
|
||||
bool
|
||||
default y
|
||||
depends on SPARC64 && PCI
|
||||
|
||||
config SPARC64_PCI_MSI
|
||||
bool
|
||||
default y
|
||||
depends on SPARC64_PCI && PCI_MSI
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Executable file formats"
|
||||
|
||||
source "fs/Kconfig.binfmt"
|
||||
|
||||
config COMPAT
|
||||
bool
|
||||
depends on SPARC64
|
||||
default y
|
||||
select COMPAT_BINFMT_ELF
|
||||
select HAVE_UID16
|
||||
select ARCH_WANT_OLD_COMPAT_IPC
|
||||
select COMPAT_OLD_SIGACTION
|
||||
|
||||
config SYSVIPC_COMPAT
|
||||
bool
|
||||
depends on COMPAT && SYSVIPC
|
||||
default y
|
||||
|
||||
config KEYS_COMPAT
|
||||
def_bool y if COMPAT && KEYS
|
||||
|
||||
endmenu
|
||||
|
||||
source "net/Kconfig"
|
||||
|
||||
source "drivers/Kconfig"
|
||||
|
||||
source "drivers/sbus/char/Kconfig"
|
||||
|
||||
source "fs/Kconfig"
|
||||
|
||||
source "arch/sparc/Kconfig.debug"
|
||||
|
||||
source "security/Kconfig"
|
||||
|
||||
source "crypto/Kconfig"
|
||||
|
||||
source "lib/Kconfig"
|
24
arch/sparc/Kconfig.debug
Normal file
24
arch/sparc/Kconfig.debug
Normal file
|
@ -0,0 +1,24 @@
|
|||
menu "Kernel hacking"
|
||||
|
||||
config TRACE_IRQFLAGS_SUPPORT
|
||||
bool
|
||||
default y
|
||||
|
||||
source "lib/Kconfig.debug"
|
||||
|
||||
config DEBUG_DCFLUSH
|
||||
bool "D-cache flush debugging"
|
||||
depends on SPARC64 && DEBUG_KERNEL
|
||||
|
||||
config MCOUNT
|
||||
bool
|
||||
depends on SPARC64
|
||||
depends on FUNCTION_TRACER
|
||||
default y
|
||||
|
||||
config FRAME_POINTER
|
||||
bool
|
||||
depends on MCOUNT
|
||||
default y
|
||||
|
||||
endmenu
|
95
arch/sparc/Makefile
Normal file
95
arch/sparc/Makefile
Normal file
|
@ -0,0 +1,95 @@
|
|||
#
|
||||
# sparc/Makefile
|
||||
#
|
||||
# Makefile for the architecture dependent flags and dependencies on the
|
||||
# Sparc and sparc64.
|
||||
#
|
||||
# Copyright (C) 1994,1996,1998 David S. Miller (davem@caip.rutgers.edu)
|
||||
# Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
|
||||
|
||||
# We are not yet configured - so test on arch
|
||||
ifeq ($(ARCH),sparc)
|
||||
KBUILD_DEFCONFIG := sparc32_defconfig
|
||||
else
|
||||
KBUILD_DEFCONFIG := sparc64_defconfig
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SPARC32),y)
|
||||
#####
|
||||
# sparc32
|
||||
#
|
||||
|
||||
CHECKFLAGS += -D__sparc__
|
||||
LDFLAGS := -m elf32_sparc
|
||||
export BITS := 32
|
||||
UTS_MACHINE := sparc
|
||||
|
||||
KBUILD_CFLAGS += -m32 -mcpu=v8 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
|
||||
KBUILD_AFLAGS += -m32 -Wa,-Av8
|
||||
|
||||
else
|
||||
#####
|
||||
# sparc64
|
||||
#
|
||||
|
||||
CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -D__arch64__ -m64
|
||||
LDFLAGS := -m elf64_sparc
|
||||
export BITS := 64
|
||||
UTS_MACHINE := sparc64
|
||||
|
||||
KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow
|
||||
KBUILD_CFLAGS += -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare
|
||||
KBUILD_CFLAGS += -Wa,--undeclared-regs
|
||||
KBUILD_CFLAGS += $(call cc-option,-mtune=ultrasparc3)
|
||||
KBUILD_AFLAGS += -m64 -mcpu=ultrasparc -Wa,--undeclared-regs
|
||||
|
||||
ifeq ($(CONFIG_MCOUNT),y)
|
||||
KBUILD_CFLAGS += -pg
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
head-y := arch/sparc/kernel/head_$(BITS).o
|
||||
|
||||
# See arch/sparc/Kbuild for the core part of the kernel
|
||||
core-y += arch/sparc/
|
||||
|
||||
libs-y += arch/sparc/prom/
|
||||
libs-y += arch/sparc/lib/
|
||||
|
||||
drivers-$(CONFIG_PM) += arch/sparc/power/
|
||||
drivers-$(CONFIG_OPROFILE) += arch/sparc/oprofile/
|
||||
|
||||
boot := arch/sparc/boot
|
||||
|
||||
# Default target
|
||||
all: zImage
|
||||
|
||||
image zImage uImage tftpboot.img vmlinux.aout: vmlinux
|
||||
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
||||
|
||||
install:
|
||||
$(Q)$(MAKE) $(build)=$(boot) $@
|
||||
|
||||
archclean:
|
||||
$(Q)$(MAKE) $(clean)=$(boot)
|
||||
|
||||
# This is the image used for packaging
|
||||
KBUILD_IMAGE := $(boot)/zImage
|
||||
|
||||
# Don't use tabs in echo arguments.
|
||||
ifeq ($(ARCH),sparc)
|
||||
define archhelp
|
||||
echo '* image - kernel image ($(boot)/image)'
|
||||
echo '* zImage - stripped kernel image ($(boot)/zImage)'
|
||||
echo ' uImage - U-Boot SPARC32 Image (only for LEON)'
|
||||
echo ' tftpboot.img - image prepared for tftp'
|
||||
endef
|
||||
else
|
||||
define archhelp
|
||||
echo '* vmlinux - standard sparc64 kernel'
|
||||
echo '* zImage - stripped and compressed sparc64 kernel ($(boot)/zImage)'
|
||||
echo ' vmlinux.aout - a.out kernel for sparc64'
|
||||
echo ' tftpboot.img - image prepared for tftp'
|
||||
endef
|
||||
endif
|
75
arch/sparc/boot/Makefile
Normal file
75
arch/sparc/boot/Makefile
Normal file
|
@ -0,0 +1,75 @@
|
|||
# Makefile for the Sparc boot stuff.
|
||||
#
|
||||
# Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
# Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz)
|
||||
|
||||
ROOT_IMG := /usr/src/root.img
|
||||
ELFTOAOUT := elftoaout
|
||||
|
||||
hostprogs-y := piggyback
|
||||
targets := tftpboot.img image zImage vmlinux.aout
|
||||
clean-files := System.map
|
||||
|
||||
quiet_cmd_elftoaout = ELFTOAOUT $@
|
||||
cmd_elftoaout = $(ELFTOAOUT) $(obj)/image -o $@
|
||||
quiet_cmd_piggy = PIGGY $@
|
||||
cmd_piggy = $(obj)/piggyback $(BITS) $@ System.map $(ROOT_IMG)
|
||||
quiet_cmd_strip = STRIP $@
|
||||
cmd_strip = $(STRIP) -R .comment -R .note -K sun4u_init -K _end -K _start $< -o $@
|
||||
|
||||
ifeq ($(CONFIG_SPARC64),y)
|
||||
|
||||
# Actual linking
|
||||
|
||||
$(obj)/zImage: $(obj)/image
|
||||
$(call if_changed,gzip)
|
||||
@echo ' kernel: $@ is ready'
|
||||
|
||||
$(obj)/vmlinux.aout: vmlinux FORCE
|
||||
$(call if_changed,elftoaout)
|
||||
@echo ' kernel: $@ is ready'
|
||||
else
|
||||
|
||||
$(obj)/zImage: $(obj)/image
|
||||
$(call if_changed,strip)
|
||||
@echo ' kernel: $@ is ready'
|
||||
|
||||
# The following lines make a readable image for U-Boot.
|
||||
# uImage - Binary file read by U-boot
|
||||
# uImage.o - object file of uImage for loading with a
|
||||
# flash programmer understanding ELF.
|
||||
|
||||
OBJCOPYFLAGS_image.bin := -S -O binary -R .note -R .comment
|
||||
$(obj)/image.bin: $(obj)/image FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
$(obj)/image.gz: $(obj)/image.bin
|
||||
$(call if_changed,gzip)
|
||||
|
||||
UIMAGE_LOADADDR = $(CONFIG_UBOOT_LOAD_ADDR)
|
||||
UIMAGE_ENTRYADDR = $(CONFIG_UBOOT_ENTRY_ADDR)
|
||||
UIMAGE_COMPRESSION = gzip
|
||||
|
||||
quiet_cmd_uimage.o = UIMAGE.O $@
|
||||
cmd_uimage.o = $(LD) -Tdata $(CONFIG_UBOOT_FLASH_ADDR) \
|
||||
-r -b binary $@ -o $@.o
|
||||
|
||||
targets += uImage
|
||||
$(obj)/uImage: $(obj)/image.gz
|
||||
$(call if_changed,uimage)
|
||||
$(call if_changed,uimage.o)
|
||||
@echo ' Image $@ is ready'
|
||||
|
||||
endif
|
||||
|
||||
$(obj)/image: vmlinux FORCE
|
||||
$(call if_changed,strip)
|
||||
@echo ' kernel: $@ is ready'
|
||||
|
||||
$(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback System.map $(ROOT_IMG) FORCE
|
||||
$(call if_changed,elftoaout)
|
||||
$(call if_changed,piggy)
|
||||
|
||||
install:
|
||||
sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(obj)/zImage \
|
||||
System.map "$(INSTALL_PATH)"
|
50
arch/sparc/boot/install.sh
Normal file
50
arch/sparc/boot/install.sh
Normal file
|
@ -0,0 +1,50 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# 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) 1995 by Linus Torvalds
|
||||
#
|
||||
# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
|
||||
#
|
||||
# "make install" script for SPARC architecture
|
||||
#
|
||||
# Arguments:
|
||||
# $1 - kernel version
|
||||
# $2 - kernel image file
|
||||
# $3 - kernel map file
|
||||
# $4 - default install path (blank if root directory)
|
||||
#
|
||||
|
||||
verify () {
|
||||
if [ ! -f "$1" ]; then
|
||||
echo "" 1>&2
|
||||
echo " *** Missing file: $1" 1>&2
|
||||
echo ' *** You need to run "make" before "make install".' 1>&2
|
||||
echo "" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Make sure the files actually exist
|
||||
verify "$2"
|
||||
verify "$3"
|
||||
|
||||
# User may have a custom install script
|
||||
|
||||
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
|
||||
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
|
||||
|
||||
# Default install - same as make zlilo
|
||||
|
||||
if [ -f $4/vmlinuz ]; then
|
||||
mv $4/vmlinuz $4/vmlinuz.old
|
||||
fi
|
||||
|
||||
if [ -f $4/System.map ]; then
|
||||
mv $4/System.map $4/System.old
|
||||
fi
|
||||
|
||||
cat $2 > $4/vmlinuz
|
||||
cp $3 $4/System.map
|
272
arch/sparc/boot/piggyback.c
Normal file
272
arch/sparc/boot/piggyback.c
Normal file
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
Simple utility to make a single-image install kernel with initial ramdisk
|
||||
for Sparc tftpbooting without need to set up nfs.
|
||||
|
||||
Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
|
||||
Pete Zaitcev <zaitcev@yahoo.com> endian fixes for cross-compiles, 2000.
|
||||
Copyright (C) 2011 Sam Ravnborg <sam@ravnborg.org>
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/*
|
||||
* Note: run this on an a.out kernel (use elftoaout for it),
|
||||
* as PROM looks for a.out image only.
|
||||
*/
|
||||
|
||||
#define AOUT_TEXT_OFFSET 32
|
||||
|
||||
static int is64bit = 0;
|
||||
|
||||
/* align to power-of-two size */
|
||||
static int align(int n)
|
||||
{
|
||||
if (is64bit)
|
||||
return (n + 0x1fff) & ~0x1fff;
|
||||
else
|
||||
return (n + 0xfff) & ~0xfff;
|
||||
}
|
||||
|
||||
/* read two bytes as big endian */
|
||||
static unsigned short ld2(char *p)
|
||||
{
|
||||
return (p[0] << 8) | p[1];
|
||||
}
|
||||
|
||||
/* save 4 bytes as big endian */
|
||||
static void st4(char *p, unsigned int x)
|
||||
{
|
||||
p[0] = x >> 24;
|
||||
p[1] = x >> 16;
|
||||
p[2] = x >> 8;
|
||||
p[3] = x;
|
||||
}
|
||||
|
||||
static void die(const char *str)
|
||||
{
|
||||
perror(str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
/* fs_img.gz is an image of initial ramdisk. */
|
||||
fprintf(stderr, "Usage: piggyback bits vmlinux.aout System.map fs_img.gz\n");
|
||||
fprintf(stderr, "\tKernel image will be modified in place.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int start_line(const char *line)
|
||||
{
|
||||
if (strcmp(line + 10, " _start\n") == 0)
|
||||
return 1;
|
||||
else if (strcmp(line + 18, " _start\n") == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int end_line(const char *line)
|
||||
{
|
||||
if (strcmp(line + 10, " _end\n") == 0)
|
||||
return 1;
|
||||
else if (strcmp (line + 18, " _end\n") == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find address for start and end in System.map.
|
||||
* The file looks like this:
|
||||
* f0004000 ... _start
|
||||
* f0379f79 ... _end
|
||||
* 1234567890123456
|
||||
* ^coloumn 1
|
||||
* There is support for 64 bit addresses too.
|
||||
*
|
||||
* Return 0 if either start or end is not found
|
||||
*/
|
||||
static int get_start_end(const char *filename, unsigned int *start,
|
||||
unsigned int *end)
|
||||
{
|
||||
FILE *map;
|
||||
char buffer[1024];
|
||||
|
||||
*start = 0;
|
||||
*end = 0;
|
||||
map = fopen(filename, "r");
|
||||
if (!map)
|
||||
die(filename);
|
||||
while (fgets(buffer, 1024, map)) {
|
||||
if (start_line(buffer))
|
||||
*start = strtoul(buffer, NULL, 16);
|
||||
else if (end_line(buffer))
|
||||
*end = strtoul(buffer, NULL, 16);
|
||||
}
|
||||
fclose (map);
|
||||
|
||||
if (*start == 0 || *end == 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define LOOKBACK (128 * 4)
|
||||
#define BUFSIZE 1024
|
||||
/*
|
||||
* Find the HdrS entry from head_32/head_64.
|
||||
* We check if it is at the beginning of the file (sparc64 case)
|
||||
* and if not we search for it.
|
||||
* When we search do so in steps of 4 as HdrS is on a 4-byte aligned
|
||||
* address (it is on same alignment as sparc instructions)
|
||||
* Return the offset to the HdrS entry (as off_t)
|
||||
*/
|
||||
static off_t get_hdrs_offset(int kernelfd, const char *filename)
|
||||
{
|
||||
char buffer[BUFSIZE];
|
||||
off_t offset;
|
||||
int i;
|
||||
|
||||
if (lseek(kernelfd, 0, SEEK_SET) < 0)
|
||||
die("lseek");
|
||||
if (read(kernelfd, buffer, BUFSIZE) != BUFSIZE)
|
||||
die(filename);
|
||||
|
||||
if (buffer[40] == 'H' && buffer[41] == 'd' &&
|
||||
buffer[42] == 'r' && buffer[43] == 'S') {
|
||||
return 40;
|
||||
} else {
|
||||
/* Find the gokernel label */
|
||||
/* Decode offset from branch instruction */
|
||||
offset = ld2(buffer + AOUT_TEXT_OFFSET + 2) << 2;
|
||||
/* Go back 512 bytes so we do not miss HdrS */
|
||||
offset -= LOOKBACK;
|
||||
/* skip a.out header */
|
||||
offset += AOUT_TEXT_OFFSET;
|
||||
if (lseek(kernelfd, offset, SEEK_SET) < 0)
|
||||
die("lseek");
|
||||
if (read(kernelfd, buffer, BUFSIZE) != BUFSIZE)
|
||||
die(filename);
|
||||
|
||||
for (i = 0; i < LOOKBACK; i += 4) {
|
||||
if (buffer[i + 0] == 'H' && buffer[i + 1] == 'd' &&
|
||||
buffer[i + 2] == 'r' && buffer[i + 3] == 'S') {
|
||||
return offset + i;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf (stderr, "Couldn't find headers signature in %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
static char aout_magic[] = { 0x01, 0x03, 0x01, 0x07 };
|
||||
char buffer[1024];
|
||||
unsigned int i, start, end;
|
||||
off_t offset;
|
||||
struct stat s;
|
||||
int image, tail;
|
||||
|
||||
if (argc != 5)
|
||||
usage();
|
||||
if (strcmp(argv[1], "64") == 0)
|
||||
is64bit = 1;
|
||||
if (stat (argv[4], &s) < 0)
|
||||
die(argv[4]);
|
||||
|
||||
if (!get_start_end(argv[3], &start, &end)) {
|
||||
fprintf(stderr, "Could not determine start and end from %s\n",
|
||||
argv[3]);
|
||||
exit(1);
|
||||
}
|
||||
if ((image = open(argv[2], O_RDWR)) < 0)
|
||||
die(argv[2]);
|
||||
if (read(image, buffer, 512) != 512)
|
||||
die(argv[2]);
|
||||
if (memcmp(buffer, aout_magic, 4) != 0) {
|
||||
fprintf (stderr, "Not a.out. Don't blame me.\n");
|
||||
exit(1);
|
||||
}
|
||||
/*
|
||||
* We need to fill in values for
|
||||
* sparc_ramdisk_image + sparc_ramdisk_size
|
||||
* To locate these symbols search for the "HdrS" text which appear
|
||||
* in the image a little before the gokernel symbol.
|
||||
* See definition of these in init_32.S
|
||||
*/
|
||||
|
||||
offset = get_hdrs_offset(image, argv[2]);
|
||||
/* skip HdrS + LINUX_VERSION_CODE + HdrS version */
|
||||
offset += 10;
|
||||
|
||||
if (lseek(image, offset, 0) < 0)
|
||||
die("lseek");
|
||||
|
||||
/*
|
||||
* root_flags = 0
|
||||
* root_dev = 1 (RAMDISK_MAJOR)
|
||||
* ram_flags = 0
|
||||
* sparc_ramdisk_image = "PAGE aligned address after _end")
|
||||
* sparc_ramdisk_size = size of image
|
||||
*/
|
||||
st4(buffer, 0);
|
||||
st4(buffer + 4, 0x01000000);
|
||||
st4(buffer + 8, align(end + 32));
|
||||
st4(buffer + 12, s.st_size);
|
||||
|
||||
if (write(image, buffer + 2, 14) != 14)
|
||||
die(argv[2]);
|
||||
|
||||
/* For sparc64 update a_text and clear a_data + a_bss */
|
||||
if (is64bit)
|
||||
{
|
||||
if (lseek(image, 4, 0) < 0)
|
||||
die("lseek");
|
||||
/* a_text */
|
||||
st4(buffer, align(end + 32 + 8191) - (start & ~0x3fffffUL) +
|
||||
s.st_size);
|
||||
/* a_data */
|
||||
st4(buffer + 4, 0);
|
||||
/* a_bss */
|
||||
st4(buffer + 8, 0);
|
||||
if (write(image, buffer, 12) != 12)
|
||||
die(argv[2]);
|
||||
}
|
||||
|
||||
/* seek page aligned boundary in the image file and add boot image */
|
||||
if (lseek(image, AOUT_TEXT_OFFSET - start + align(end + 32), 0) < 0)
|
||||
die("lseek");
|
||||
if ((tail = open(argv[4], O_RDONLY)) < 0)
|
||||
die(argv[4]);
|
||||
while ((i = read(tail, buffer, 1024)) > 0)
|
||||
if (write(image, buffer, i) != i)
|
||||
die(argv[2]);
|
||||
if (close(image) < 0)
|
||||
die("close");
|
||||
if (close(tail) < 0)
|
||||
die("close");
|
||||
return 0;
|
||||
}
|
105
arch/sparc/configs/sparc32_defconfig
Normal file
105
arch/sparc/configs/sparc32_defconfig
Normal file
|
@ -0,0 +1,105 @@
|
|||
CONFIG_EXPERIMENTAL=y
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
CONFIG_SYSFS_DEPRECATED_V2=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
||||
CONFIG_SLAB=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
CONFIG_PCI=y
|
||||
CONFIG_SUN_OPENPROMFS=m
|
||||
CONFIG_BINFMT_MISC=m
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=m
|
||||
CONFIG_NET_KEY=m
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_INET_AH=y
|
||||
CONFIG_INET_ESP=y
|
||||
CONFIG_INET_IPCOMP=y
|
||||
# CONFIG_INET_LRO is not set
|
||||
CONFIG_IPV6_PRIVACY=y
|
||||
CONFIG_INET6_AH=m
|
||||
CONFIG_INET6_ESP=m
|
||||
CONFIG_INET6_IPCOMP=m
|
||||
CONFIG_IPV6_TUNNEL=m
|
||||
CONFIG_NET_PKTGEN=m
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_BLK_DEV_LOOP=m
|
||||
CONFIG_BLK_DEV_CRYPTOLOOP=m
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_DEV_SR=m
|
||||
CONFIG_CHR_DEV_SG=m
|
||||
CONFIG_SCSI_QLOGICPTI=m
|
||||
CONFIG_SCSI_SUNESP=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_DUMMY=m
|
||||
CONFIG_NET_ETHERNET=y
|
||||
CONFIG_MII=m
|
||||
CONFIG_SUNLANCE=y
|
||||
CONFIG_HAPPYMEAL=m
|
||||
CONFIG_SUNBMAC=m
|
||||
CONFIG_SUNQE=m
|
||||
# CONFIG_WLAN is not set
|
||||
CONFIG_INPUT_JOYDEV=m
|
||||
CONFIG_INPUT_EVDEV=m
|
||||
CONFIG_INPUT_EVBUG=m
|
||||
CONFIG_KEYBOARD_ATKBD=m
|
||||
CONFIG_KEYBOARD_SUNKBD=m
|
||||
CONFIG_MOUSE_PS2=m
|
||||
CONFIG_MOUSE_SERIAL=m
|
||||
CONFIG_SERIO=m
|
||||
# CONFIG_SERIO_I8042 is not set
|
||||
CONFIG_SERIAL_SUNZILOG=y
|
||||
CONFIG_SERIAL_SUNZILOG_CONSOLE=y
|
||||
CONFIG_SERIAL_SUNSU=y
|
||||
CONFIG_SERIAL_SUNSU_CONSOLE=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_XILINX=m
|
||||
CONFIG_SPI_XILINX_PLTFM=m
|
||||
CONFIG_SUN_OPENPROMIO=m
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||
CONFIG_EXT2_FS_SECURITY=y
|
||||
CONFIG_AUTOFS_FS=m
|
||||
CONFIG_AUTOFS4_FS=m
|
||||
CONFIG_ISO9660_FS=m
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_ROMFS_FS=m
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_ROOT_NFS=y
|
||||
CONFIG_RPCSEC_GSS_KRB5=m
|
||||
CONFIG_NLS=y
|
||||
# CONFIG_ENABLE_WARN_DEPRECATED is not set
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
|
||||
CONFIG_KGDB=y
|
||||
CONFIG_KGDB_TESTS=y
|
||||
CONFIG_CRYPTO_NULL=m
|
||||
CONFIG_CRYPTO_ECB=m
|
||||
CONFIG_CRYPTO_PCBC=m
|
||||
CONFIG_CRYPTO_MD4=y
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_SHA256=m
|
||||
CONFIG_CRYPTO_SHA512=m
|
||||
CONFIG_CRYPTO_AES=m
|
||||
CONFIG_CRYPTO_ARC4=m
|
||||
CONFIG_CRYPTO_BLOWFISH=m
|
||||
CONFIG_CRYPTO_CAST5=m
|
||||
CONFIG_CRYPTO_CAST6=m
|
||||
CONFIG_CRYPTO_SERPENT=m
|
||||
CONFIG_CRYPTO_TWOFISH=m
|
||||
# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_LIBCRC32C=m
|
243
arch/sparc/configs/sparc64_defconfig
Normal file
243
arch/sparc/configs/sparc64_defconfig
Normal file
|
@ -0,0 +1,243 @@
|
|||
CONFIG_64BIT=y
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_LOG_BUF_SHIFT=18
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_PERF_EVENTS=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_SLAB=y
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_OPROFILE=m
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SRCVERSION_ALL=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_HOTPLUG_CPU=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_NUMA=y
|
||||
CONFIG_DEFAULT_MMAP_MIN_ADDR=8192
|
||||
CONFIG_PREEMPT_VOLUNTARY=y
|
||||
CONFIG_SUN_LDOMS=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCI_MSI=y
|
||||
CONFIG_SUN_OPENPROMFS=m
|
||||
CONFIG_BINFMT_MISC=m
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=m
|
||||
CONFIG_NET_KEY=m
|
||||
CONFIG_NET_KEY_MIGRATE=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_NET_IPIP=m
|
||||
CONFIG_NET_IPGRE=m
|
||||
CONFIG_NET_IPGRE_BROADCAST=y
|
||||
CONFIG_IP_MROUTE=y
|
||||
CONFIG_IP_PIMSM_V1=y
|
||||
CONFIG_IP_PIMSM_V2=y
|
||||
CONFIG_ARPD=y
|
||||
CONFIG_SYN_COOKIES=y
|
||||
CONFIG_INET_AH=y
|
||||
CONFIG_INET_ESP=y
|
||||
CONFIG_INET_IPCOMP=y
|
||||
CONFIG_IPV6_PRIVACY=y
|
||||
CONFIG_IPV6_ROUTER_PREF=y
|
||||
CONFIG_IPV6_ROUTE_INFO=y
|
||||
CONFIG_IPV6_OPTIMISTIC_DAD=y
|
||||
CONFIG_INET6_AH=m
|
||||
CONFIG_INET6_ESP=m
|
||||
CONFIG_INET6_IPCOMP=m
|
||||
CONFIG_IPV6_TUNNEL=m
|
||||
CONFIG_VLAN_8021Q=m
|
||||
CONFIG_NET_PKTGEN=m
|
||||
CONFIG_NET_TCPPROBE=m
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
|
||||
CONFIG_CONNECTOR=m
|
||||
CONFIG_BLK_DEV_LOOP=m
|
||||
CONFIG_BLK_DEV_CRYPTOLOOP=m
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_CDROM_PKTCDVD=m
|
||||
CONFIG_CDROM_PKTCDVD_WCACHE=y
|
||||
CONFIG_ATA_OVER_ETH=m
|
||||
CONFIG_SUNVDC=m
|
||||
CONFIG_IDE=y
|
||||
CONFIG_BLK_DEV_IDECD=y
|
||||
CONFIG_BLK_DEV_ALI15X3=y
|
||||
CONFIG_RAID_ATTRS=m
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_DEV_SR=m
|
||||
CONFIG_BLK_DEV_SR_VENDOR=y
|
||||
CONFIG_CHR_DEV_SG=m
|
||||
CONFIG_SCSI_MULTI_LUN=y
|
||||
CONFIG_SCSI_CONSTANTS=y
|
||||
CONFIG_SCSI_SPI_ATTRS=y
|
||||
CONFIG_SCSI_FC_ATTRS=y
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_MD=m
|
||||
CONFIG_MD_LINEAR=m
|
||||
CONFIG_MD_RAID0=m
|
||||
CONFIG_MD_RAID1=m
|
||||
CONFIG_MD_RAID10=m
|
||||
CONFIG_MD_RAID456=m
|
||||
CONFIG_MD_MULTIPATH=m
|
||||
CONFIG_BLK_DEV_DM=m
|
||||
CONFIG_DM_CRYPT=m
|
||||
CONFIG_DM_SNAPSHOT=m
|
||||
CONFIG_DM_MIRROR=m
|
||||
CONFIG_DM_ZERO=m
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_NET_ETHERNET=y
|
||||
CONFIG_MII=m
|
||||
CONFIG_SUNLANCE=m
|
||||
CONFIG_HAPPYMEAL=m
|
||||
CONFIG_SUNGEM=m
|
||||
CONFIG_SUNVNET=m
|
||||
CONFIG_NET_PCI=y
|
||||
CONFIG_E1000=m
|
||||
CONFIG_E1000E=m
|
||||
CONFIG_TIGON3=m
|
||||
CONFIG_BNX2=m
|
||||
CONFIG_NIU=m
|
||||
# CONFIG_WLAN is not set
|
||||
CONFIG_PPP=m
|
||||
CONFIG_PPP_MULTILINK=y
|
||||
CONFIG_PPP_FILTER=y
|
||||
CONFIG_PPP_ASYNC=m
|
||||
CONFIG_PPP_SYNC_TTY=m
|
||||
CONFIG_PPP_DEFLATE=m
|
||||
CONFIG_PPP_BSDCOMP=m
|
||||
CONFIG_PPP_MPPE=m
|
||||
CONFIG_PPPOE=m
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_KEYBOARD_LKKBD=m
|
||||
CONFIG_KEYBOARD_SUNKBD=y
|
||||
CONFIG_MOUSE_SERIAL=y
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_SPARCSPKR=y
|
||||
# CONFIG_SERIO_SERPORT is not set
|
||||
CONFIG_SERIO_PCIPS2=m
|
||||
CONFIG_SERIO_RAW=m
|
||||
# CONFIG_DEVKMEM is not set
|
||||
CONFIG_SERIAL_SUNSU=y
|
||||
CONFIG_SERIAL_SUNSU_CONSOLE=y
|
||||
CONFIG_SERIAL_SUNSAB=y
|
||||
CONFIG_SERIAL_SUNSAB_CONSOLE=y
|
||||
CONFIG_SERIAL_SUNHV=y
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_TILEBLITTING=y
|
||||
CONFIG_FB_SBUS=y
|
||||
CONFIG_FB_CG6=y
|
||||
CONFIG_FB_FFB=y
|
||||
CONFIG_FB_XVR500=y
|
||||
CONFIG_FB_XVR2500=y
|
||||
CONFIG_FB_XVR1000=y
|
||||
CONFIG_FB_RADEON=y
|
||||
# CONFIG_FB_RADEON_BACKLIGHT is not set
|
||||
CONFIG_FB_ATY=y
|
||||
CONFIG_FB_ATY_GX=y
|
||||
# CONFIG_FB_ATY_BACKLIGHT is not set
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||
CONFIG_FONTS=y
|
||||
CONFIG_FONT_SUN8x16=y
|
||||
CONFIG_LOGO=y
|
||||
# CONFIG_LOGO_LINUX_MONO is not set
|
||||
# CONFIG_LOGO_LINUX_VGA16 is not set
|
||||
# CONFIG_LOGO_LINUX_CLUT224 is not set
|
||||
CONFIG_SOUND=m
|
||||
CONFIG_SND=m
|
||||
CONFIG_SND_SEQUENCER=m
|
||||
CONFIG_SND_SEQ_DUMMY=m
|
||||
CONFIG_SND_MIXER_OSS=m
|
||||
CONFIG_SND_PCM_OSS=m
|
||||
CONFIG_SND_SEQUENCER_OSS=y
|
||||
CONFIG_SND_DUMMY=m
|
||||
CONFIG_SND_VIRMIDI=m
|
||||
CONFIG_SND_MTPAV=m
|
||||
CONFIG_SND_ALI5451=m
|
||||
CONFIG_SND_SUN_CS4231=m
|
||||
CONFIG_USB_HIDDEV=y
|
||||
CONFIG_HID_DRAGONRISE=y
|
||||
CONFIG_HID_GYRATION=y
|
||||
CONFIG_HID_TWINHAN=y
|
||||
CONFIG_HID_NTRIG=y
|
||||
CONFIG_HID_ORTEK=y
|
||||
CONFIG_HID_PANTHERLORD=y
|
||||
CONFIG_HID_PETALYNX=y
|
||||
CONFIG_HID_SAMSUNG=y
|
||||
CONFIG_HID_SONY=y
|
||||
CONFIG_HID_SUNPLUS=y
|
||||
CONFIG_HID_GREENASIA=y
|
||||
CONFIG_HID_SMARTJOYPLUS=y
|
||||
CONFIG_HID_TOPSEED=y
|
||||
CONFIG_HID_THRUSTMASTER=y
|
||||
CONFIG_HID_ZEROPLUS=y
|
||||
CONFIG_USB=y
|
||||
# CONFIG_USB_DEVICE_CLASS is not set
|
||||
CONFIG_USB_EHCI_HCD=m
|
||||
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_UHCI_HCD=m
|
||||
CONFIG_USB_STORAGE=m
|
||||
CONFIG_SUN_OPENPROMIO=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||
CONFIG_EXT2_FS_SECURITY=y
|
||||
CONFIG_EXT3_FS=y
|
||||
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
|
||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||
CONFIG_EXT3_FS_SECURITY=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
# CONFIG_ENABLE_WARN_DEPRECATED is not set
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
CONFIG_SCHEDSTATS=y
|
||||
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
|
||||
CONFIG_SYSCTL_SYSCALL_CHECK=y
|
||||
CONFIG_BLK_DEV_IO_TRACE=y
|
||||
CONFIG_KEYS=y
|
||||
CONFIG_CRYPTO_NULL=m
|
||||
CONFIG_CRYPTO_TEST=m
|
||||
CONFIG_CRYPTO_LRW=m
|
||||
CONFIG_CRYPTO_PCBC=m
|
||||
CONFIG_CRYPTO_XTS=m
|
||||
CONFIG_CRYPTO_XCBC=y
|
||||
CONFIG_CRYPTO_MD4=y
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_SHA256=m
|
||||
CONFIG_CRYPTO_SHA512=m
|
||||
CONFIG_CRYPTO_TGR192=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_AES=m
|
||||
CONFIG_CRYPTO_ANUBIS=m
|
||||
CONFIG_CRYPTO_BLOWFISH=m
|
||||
CONFIG_CRYPTO_CAMELLIA=m
|
||||
CONFIG_CRYPTO_CAST5=m
|
||||
CONFIG_CRYPTO_CAST6=m
|
||||
CONFIG_CRYPTO_FCRYPT=m
|
||||
CONFIG_CRYPTO_KHAZAD=m
|
||||
CONFIG_CRYPTO_SEED=m
|
||||
CONFIG_CRYPTO_SERPENT=m
|
||||
CONFIG_CRYPTO_TEA=m
|
||||
CONFIG_CRYPTO_TWOFISH=m
|
||||
# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
CONFIG_CRC16=m
|
||||
CONFIG_LIBCRC32C=m
|
25
arch/sparc/crypto/Makefile
Normal file
25
arch/sparc/crypto/Makefile
Normal file
|
@ -0,0 +1,25 @@
|
|||
#
|
||||
# Arch-specific CryptoAPI modules.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_CRYPTO_SHA1_SPARC64) += sha1-sparc64.o
|
||||
obj-$(CONFIG_CRYPTO_SHA256_SPARC64) += sha256-sparc64.o
|
||||
obj-$(CONFIG_CRYPTO_SHA512_SPARC64) += sha512-sparc64.o
|
||||
obj-$(CONFIG_CRYPTO_MD5_SPARC64) += md5-sparc64.o
|
||||
|
||||
obj-$(CONFIG_CRYPTO_AES_SPARC64) += aes-sparc64.o
|
||||
obj-$(CONFIG_CRYPTO_DES_SPARC64) += des-sparc64.o
|
||||
obj-$(CONFIG_CRYPTO_DES_SPARC64) += camellia-sparc64.o
|
||||
|
||||
obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o
|
||||
|
||||
sha1-sparc64-y := sha1_asm.o sha1_glue.o
|
||||
sha256-sparc64-y := sha256_asm.o sha256_glue.o
|
||||
sha512-sparc64-y := sha512_asm.o sha512_glue.o
|
||||
md5-sparc64-y := md5_asm.o md5_glue.o
|
||||
|
||||
aes-sparc64-y := aes_asm.o aes_glue.o
|
||||
des-sparc64-y := des_asm.o des_glue.o
|
||||
camellia-sparc64-y := camellia_asm.o camellia_glue.o
|
||||
|
||||
crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o
|
1543
arch/sparc/crypto/aes_asm.S
Normal file
1543
arch/sparc/crypto/aes_asm.S
Normal file
File diff suppressed because it is too large
Load diff
504
arch/sparc/crypto/aes_glue.c
Normal file
504
arch/sparc/crypto/aes_glue.c
Normal file
|
@ -0,0 +1,504 @@
|
|||
/* Glue code for AES encryption optimized for sparc64 crypto opcodes.
|
||||
*
|
||||
* This is based largely upon arch/x86/crypto/aesni-intel_glue.c
|
||||
*
|
||||
* Copyright (C) 2008, Intel Corp.
|
||||
* Author: Huang Ying <ying.huang@intel.com>
|
||||
*
|
||||
* Added RFC4106 AES-GCM support for 128-bit keys under the AEAD
|
||||
* interface for 64-bit kernels.
|
||||
* Authors: Adrian Hoban <adrian.hoban@intel.com>
|
||||
* Gabriele Paoloni <gabriele.paoloni@intel.com>
|
||||
* Tadeusz Struk (tadeusz.struk@intel.com)
|
||||
* Aidan O'Mahony (aidan.o.mahony@intel.com)
|
||||
* Copyright (c) 2010, Intel Corporation.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/types.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/aes.h>
|
||||
|
||||
#include <asm/fpumacro.h>
|
||||
#include <asm/pstate.h>
|
||||
#include <asm/elf.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
struct aes_ops {
|
||||
void (*encrypt)(const u64 *key, const u32 *input, u32 *output);
|
||||
void (*decrypt)(const u64 *key, const u32 *input, u32 *output);
|
||||
void (*load_encrypt_keys)(const u64 *key);
|
||||
void (*load_decrypt_keys)(const u64 *key);
|
||||
void (*ecb_encrypt)(const u64 *key, const u64 *input, u64 *output,
|
||||
unsigned int len);
|
||||
void (*ecb_decrypt)(const u64 *key, const u64 *input, u64 *output,
|
||||
unsigned int len);
|
||||
void (*cbc_encrypt)(const u64 *key, const u64 *input, u64 *output,
|
||||
unsigned int len, u64 *iv);
|
||||
void (*cbc_decrypt)(const u64 *key, const u64 *input, u64 *output,
|
||||
unsigned int len, u64 *iv);
|
||||
void (*ctr_crypt)(const u64 *key, const u64 *input, u64 *output,
|
||||
unsigned int len, u64 *iv);
|
||||
};
|
||||
|
||||
struct crypto_sparc64_aes_ctx {
|
||||
struct aes_ops *ops;
|
||||
u64 key[AES_MAX_KEYLENGTH / sizeof(u64)];
|
||||
u32 key_length;
|
||||
u32 expanded_key_length;
|
||||
};
|
||||
|
||||
extern void aes_sparc64_encrypt_128(const u64 *key, const u32 *input,
|
||||
u32 *output);
|
||||
extern void aes_sparc64_encrypt_192(const u64 *key, const u32 *input,
|
||||
u32 *output);
|
||||
extern void aes_sparc64_encrypt_256(const u64 *key, const u32 *input,
|
||||
u32 *output);
|
||||
|
||||
extern void aes_sparc64_decrypt_128(const u64 *key, const u32 *input,
|
||||
u32 *output);
|
||||
extern void aes_sparc64_decrypt_192(const u64 *key, const u32 *input,
|
||||
u32 *output);
|
||||
extern void aes_sparc64_decrypt_256(const u64 *key, const u32 *input,
|
||||
u32 *output);
|
||||
|
||||
extern void aes_sparc64_load_encrypt_keys_128(const u64 *key);
|
||||
extern void aes_sparc64_load_encrypt_keys_192(const u64 *key);
|
||||
extern void aes_sparc64_load_encrypt_keys_256(const u64 *key);
|
||||
|
||||
extern void aes_sparc64_load_decrypt_keys_128(const u64 *key);
|
||||
extern void aes_sparc64_load_decrypt_keys_192(const u64 *key);
|
||||
extern void aes_sparc64_load_decrypt_keys_256(const u64 *key);
|
||||
|
||||
extern void aes_sparc64_ecb_encrypt_128(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len);
|
||||
extern void aes_sparc64_ecb_encrypt_192(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len);
|
||||
extern void aes_sparc64_ecb_encrypt_256(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len);
|
||||
|
||||
extern void aes_sparc64_ecb_decrypt_128(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len);
|
||||
extern void aes_sparc64_ecb_decrypt_192(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len);
|
||||
extern void aes_sparc64_ecb_decrypt_256(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len);
|
||||
|
||||
extern void aes_sparc64_cbc_encrypt_128(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len,
|
||||
u64 *iv);
|
||||
|
||||
extern void aes_sparc64_cbc_encrypt_192(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len,
|
||||
u64 *iv);
|
||||
|
||||
extern void aes_sparc64_cbc_encrypt_256(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len,
|
||||
u64 *iv);
|
||||
|
||||
extern void aes_sparc64_cbc_decrypt_128(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len,
|
||||
u64 *iv);
|
||||
|
||||
extern void aes_sparc64_cbc_decrypt_192(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len,
|
||||
u64 *iv);
|
||||
|
||||
extern void aes_sparc64_cbc_decrypt_256(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len,
|
||||
u64 *iv);
|
||||
|
||||
extern void aes_sparc64_ctr_crypt_128(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len,
|
||||
u64 *iv);
|
||||
extern void aes_sparc64_ctr_crypt_192(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len,
|
||||
u64 *iv);
|
||||
extern void aes_sparc64_ctr_crypt_256(const u64 *key, const u64 *input,
|
||||
u64 *output, unsigned int len,
|
||||
u64 *iv);
|
||||
|
||||
static struct aes_ops aes128_ops = {
|
||||
.encrypt = aes_sparc64_encrypt_128,
|
||||
.decrypt = aes_sparc64_decrypt_128,
|
||||
.load_encrypt_keys = aes_sparc64_load_encrypt_keys_128,
|
||||
.load_decrypt_keys = aes_sparc64_load_decrypt_keys_128,
|
||||
.ecb_encrypt = aes_sparc64_ecb_encrypt_128,
|
||||
.ecb_decrypt = aes_sparc64_ecb_decrypt_128,
|
||||
.cbc_encrypt = aes_sparc64_cbc_encrypt_128,
|
||||
.cbc_decrypt = aes_sparc64_cbc_decrypt_128,
|
||||
.ctr_crypt = aes_sparc64_ctr_crypt_128,
|
||||
};
|
||||
|
||||
static struct aes_ops aes192_ops = {
|
||||
.encrypt = aes_sparc64_encrypt_192,
|
||||
.decrypt = aes_sparc64_decrypt_192,
|
||||
.load_encrypt_keys = aes_sparc64_load_encrypt_keys_192,
|
||||
.load_decrypt_keys = aes_sparc64_load_decrypt_keys_192,
|
||||
.ecb_encrypt = aes_sparc64_ecb_encrypt_192,
|
||||
.ecb_decrypt = aes_sparc64_ecb_decrypt_192,
|
||||
.cbc_encrypt = aes_sparc64_cbc_encrypt_192,
|
||||
.cbc_decrypt = aes_sparc64_cbc_decrypt_192,
|
||||
.ctr_crypt = aes_sparc64_ctr_crypt_192,
|
||||
};
|
||||
|
||||
static struct aes_ops aes256_ops = {
|
||||
.encrypt = aes_sparc64_encrypt_256,
|
||||
.decrypt = aes_sparc64_decrypt_256,
|
||||
.load_encrypt_keys = aes_sparc64_load_encrypt_keys_256,
|
||||
.load_decrypt_keys = aes_sparc64_load_decrypt_keys_256,
|
||||
.ecb_encrypt = aes_sparc64_ecb_encrypt_256,
|
||||
.ecb_decrypt = aes_sparc64_ecb_decrypt_256,
|
||||
.cbc_encrypt = aes_sparc64_cbc_encrypt_256,
|
||||
.cbc_decrypt = aes_sparc64_cbc_decrypt_256,
|
||||
.ctr_crypt = aes_sparc64_ctr_crypt_256,
|
||||
};
|
||||
|
||||
extern void aes_sparc64_key_expand(const u32 *in_key, u64 *output_key,
|
||||
unsigned int key_len);
|
||||
|
||||
static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
||||
unsigned int key_len)
|
||||
{
|
||||
struct crypto_sparc64_aes_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
u32 *flags = &tfm->crt_flags;
|
||||
|
||||
switch (key_len) {
|
||||
case AES_KEYSIZE_128:
|
||||
ctx->expanded_key_length = 0xb0;
|
||||
ctx->ops = &aes128_ops;
|
||||
break;
|
||||
|
||||
case AES_KEYSIZE_192:
|
||||
ctx->expanded_key_length = 0xd0;
|
||||
ctx->ops = &aes192_ops;
|
||||
break;
|
||||
|
||||
case AES_KEYSIZE_256:
|
||||
ctx->expanded_key_length = 0xf0;
|
||||
ctx->ops = &aes256_ops;
|
||||
break;
|
||||
|
||||
default:
|
||||
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
aes_sparc64_key_expand((const u32 *)in_key, &ctx->key[0], key_len);
|
||||
ctx->key_length = key_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||
{
|
||||
struct crypto_sparc64_aes_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
ctx->ops->encrypt(&ctx->key[0], (const u32 *) src, (u32 *) dst);
|
||||
}
|
||||
|
||||
static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||
{
|
||||
struct crypto_sparc64_aes_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
ctx->ops->decrypt(&ctx->key[0], (const u32 *) src, (u32 *) dst);
|
||||
}
|
||||
|
||||
#define AES_BLOCK_MASK (~(AES_BLOCK_SIZE-1))
|
||||
|
||||
static int ecb_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct crypto_sparc64_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
ctx->ops->load_encrypt_keys(&ctx->key[0]);
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
unsigned int block_len = nbytes & AES_BLOCK_MASK;
|
||||
|
||||
if (likely(block_len)) {
|
||||
ctx->ops->ecb_encrypt(&ctx->key[0],
|
||||
(const u64 *)walk.src.virt.addr,
|
||||
(u64 *) walk.dst.virt.addr,
|
||||
block_len);
|
||||
}
|
||||
nbytes &= AES_BLOCK_SIZE - 1;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
fprs_write(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ecb_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct crypto_sparc64_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
u64 *key_end;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
ctx->ops->load_decrypt_keys(&ctx->key[0]);
|
||||
key_end = &ctx->key[ctx->expanded_key_length / sizeof(u64)];
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
unsigned int block_len = nbytes & AES_BLOCK_MASK;
|
||||
|
||||
if (likely(block_len)) {
|
||||
ctx->ops->ecb_decrypt(key_end,
|
||||
(const u64 *) walk.src.virt.addr,
|
||||
(u64 *) walk.dst.virt.addr, block_len);
|
||||
}
|
||||
nbytes &= AES_BLOCK_SIZE - 1;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
fprs_write(0);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cbc_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct crypto_sparc64_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
ctx->ops->load_encrypt_keys(&ctx->key[0]);
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
unsigned int block_len = nbytes & AES_BLOCK_MASK;
|
||||
|
||||
if (likely(block_len)) {
|
||||
ctx->ops->cbc_encrypt(&ctx->key[0],
|
||||
(const u64 *)walk.src.virt.addr,
|
||||
(u64 *) walk.dst.virt.addr,
|
||||
block_len, (u64 *) walk.iv);
|
||||
}
|
||||
nbytes &= AES_BLOCK_SIZE - 1;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
fprs_write(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cbc_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct crypto_sparc64_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
u64 *key_end;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
ctx->ops->load_decrypt_keys(&ctx->key[0]);
|
||||
key_end = &ctx->key[ctx->expanded_key_length / sizeof(u64)];
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
unsigned int block_len = nbytes & AES_BLOCK_MASK;
|
||||
|
||||
if (likely(block_len)) {
|
||||
ctx->ops->cbc_decrypt(key_end,
|
||||
(const u64 *) walk.src.virt.addr,
|
||||
(u64 *) walk.dst.virt.addr,
|
||||
block_len, (u64 *) walk.iv);
|
||||
}
|
||||
nbytes &= AES_BLOCK_SIZE - 1;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
fprs_write(0);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void ctr_crypt_final(struct crypto_sparc64_aes_ctx *ctx,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
u8 *ctrblk = walk->iv;
|
||||
u64 keystream[AES_BLOCK_SIZE / sizeof(u64)];
|
||||
u8 *src = walk->src.virt.addr;
|
||||
u8 *dst = walk->dst.virt.addr;
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
|
||||
ctx->ops->ecb_encrypt(&ctx->key[0], (const u64 *)ctrblk,
|
||||
keystream, AES_BLOCK_SIZE);
|
||||
crypto_xor((u8 *) keystream, src, nbytes);
|
||||
memcpy(dst, keystream, nbytes);
|
||||
crypto_inc(ctrblk, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
static int ctr_crypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct crypto_sparc64_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE);
|
||||
desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
ctx->ops->load_encrypt_keys(&ctx->key[0]);
|
||||
while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) {
|
||||
unsigned int block_len = nbytes & AES_BLOCK_MASK;
|
||||
|
||||
if (likely(block_len)) {
|
||||
ctx->ops->ctr_crypt(&ctx->key[0],
|
||||
(const u64 *)walk.src.virt.addr,
|
||||
(u64 *) walk.dst.virt.addr,
|
||||
block_len, (u64 *) walk.iv);
|
||||
}
|
||||
nbytes &= AES_BLOCK_SIZE - 1;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
if (walk.nbytes) {
|
||||
ctr_crypt_final(ctx, &walk);
|
||||
err = blkcipher_walk_done(desc, &walk, 0);
|
||||
}
|
||||
fprs_write(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct crypto_alg algs[] = { {
|
||||
.cra_name = "aes",
|
||||
.cra_driver_name = "aes-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct crypto_sparc64_aes_ctx),
|
||||
.cra_alignmask = 3,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.cipher = {
|
||||
.cia_min_keysize = AES_MIN_KEY_SIZE,
|
||||
.cia_max_keysize = AES_MAX_KEY_SIZE,
|
||||
.cia_setkey = aes_set_key,
|
||||
.cia_encrypt = aes_encrypt,
|
||||
.cia_decrypt = aes_decrypt
|
||||
}
|
||||
}
|
||||
}, {
|
||||
.cra_name = "ecb(aes)",
|
||||
.cra_driver_name = "ecb-aes-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct crypto_sparc64_aes_ctx),
|
||||
.cra_alignmask = 7,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = AES_MIN_KEY_SIZE,
|
||||
.max_keysize = AES_MAX_KEY_SIZE,
|
||||
.setkey = aes_set_key,
|
||||
.encrypt = ecb_encrypt,
|
||||
.decrypt = ecb_decrypt,
|
||||
},
|
||||
},
|
||||
}, {
|
||||
.cra_name = "cbc(aes)",
|
||||
.cra_driver_name = "cbc-aes-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct crypto_sparc64_aes_ctx),
|
||||
.cra_alignmask = 7,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = AES_MIN_KEY_SIZE,
|
||||
.max_keysize = AES_MAX_KEY_SIZE,
|
||||
.setkey = aes_set_key,
|
||||
.encrypt = cbc_encrypt,
|
||||
.decrypt = cbc_decrypt,
|
||||
},
|
||||
},
|
||||
}, {
|
||||
.cra_name = "ctr(aes)",
|
||||
.cra_driver_name = "ctr-aes-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = 1,
|
||||
.cra_ctxsize = sizeof(struct crypto_sparc64_aes_ctx),
|
||||
.cra_alignmask = 7,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = AES_MIN_KEY_SIZE,
|
||||
.max_keysize = AES_MAX_KEY_SIZE,
|
||||
.setkey = aes_set_key,
|
||||
.encrypt = ctr_crypt,
|
||||
.decrypt = ctr_crypt,
|
||||
},
|
||||
},
|
||||
} };
|
||||
|
||||
static bool __init sparc64_has_aes_opcode(void)
|
||||
{
|
||||
unsigned long cfr;
|
||||
|
||||
if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
|
||||
return false;
|
||||
|
||||
__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
|
||||
if (!(cfr & CFR_AES))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __init aes_sparc64_mod_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(algs); i++)
|
||||
INIT_LIST_HEAD(&algs[i].cra_list);
|
||||
|
||||
if (sparc64_has_aes_opcode()) {
|
||||
pr_info("Using sparc64 aes opcodes optimized AES implementation\n");
|
||||
return crypto_register_algs(algs, ARRAY_SIZE(algs));
|
||||
}
|
||||
pr_info("sparc64 aes opcodes not available.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void __exit aes_sparc64_mod_fini(void)
|
||||
{
|
||||
crypto_unregister_algs(algs, ARRAY_SIZE(algs));
|
||||
}
|
||||
|
||||
module_init(aes_sparc64_mod_init);
|
||||
module_exit(aes_sparc64_mod_fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated");
|
||||
|
||||
MODULE_ALIAS_CRYPTO("aes");
|
||||
|
||||
#include "crop_devid.c"
|
563
arch/sparc/crypto/camellia_asm.S
Normal file
563
arch/sparc/crypto/camellia_asm.S
Normal file
|
@ -0,0 +1,563 @@
|
|||
#include <linux/linkage.h>
|
||||
#include <asm/visasm.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
#define CAMELLIA_6ROUNDS(KEY_BASE, I0, I1) \
|
||||
CAMELLIA_F(KEY_BASE + 0, I1, I0, I1) \
|
||||
CAMELLIA_F(KEY_BASE + 2, I0, I1, I0) \
|
||||
CAMELLIA_F(KEY_BASE + 4, I1, I0, I1) \
|
||||
CAMELLIA_F(KEY_BASE + 6, I0, I1, I0) \
|
||||
CAMELLIA_F(KEY_BASE + 8, I1, I0, I1) \
|
||||
CAMELLIA_F(KEY_BASE + 10, I0, I1, I0)
|
||||
|
||||
#define CAMELLIA_6ROUNDS_FL_FLI(KEY_BASE, I0, I1) \
|
||||
CAMELLIA_6ROUNDS(KEY_BASE, I0, I1) \
|
||||
CAMELLIA_FL(KEY_BASE + 12, I0, I0) \
|
||||
CAMELLIA_FLI(KEY_BASE + 14, I1, I1)
|
||||
|
||||
.data
|
||||
|
||||
.align 8
|
||||
SIGMA: .xword 0xA09E667F3BCC908B
|
||||
.xword 0xB67AE8584CAA73B2
|
||||
.xword 0xC6EF372FE94F82BE
|
||||
.xword 0x54FF53A5F1D36F1C
|
||||
.xword 0x10E527FADE682D1D
|
||||
.xword 0xB05688C2B3E6C1FD
|
||||
|
||||
.text
|
||||
|
||||
.align 32
|
||||
ENTRY(camellia_sparc64_key_expand)
|
||||
/* %o0=in_key, %o1=encrypt_key, %o2=key_len, %o3=decrypt_key */
|
||||
VISEntry
|
||||
ld [%o0 + 0x00], %f0 ! i0, k[0]
|
||||
ld [%o0 + 0x04], %f1 ! i1, k[1]
|
||||
ld [%o0 + 0x08], %f2 ! i2, k[2]
|
||||
ld [%o0 + 0x0c], %f3 ! i3, k[3]
|
||||
std %f0, [%o1 + 0x00] ! k[0, 1]
|
||||
fsrc2 %f0, %f28
|
||||
std %f2, [%o1 + 0x08] ! k[2, 3]
|
||||
cmp %o2, 16
|
||||
be 10f
|
||||
fsrc2 %f2, %f30
|
||||
|
||||
ld [%o0 + 0x10], %f0
|
||||
ld [%o0 + 0x14], %f1
|
||||
std %f0, [%o1 + 0x20] ! k[8, 9]
|
||||
cmp %o2, 24
|
||||
fone %f10
|
||||
be,a 1f
|
||||
fxor %f10, %f0, %f2
|
||||
ld [%o0 + 0x18], %f2
|
||||
ld [%o0 + 0x1c], %f3
|
||||
1:
|
||||
std %f2, [%o1 + 0x28] ! k[10, 11]
|
||||
fxor %f28, %f0, %f0
|
||||
fxor %f30, %f2, %f2
|
||||
|
||||
10:
|
||||
sethi %hi(SIGMA), %g3
|
||||
or %g3, %lo(SIGMA), %g3
|
||||
ldd [%g3 + 0x00], %f16
|
||||
ldd [%g3 + 0x08], %f18
|
||||
ldd [%g3 + 0x10], %f20
|
||||
ldd [%g3 + 0x18], %f22
|
||||
ldd [%g3 + 0x20], %f24
|
||||
ldd [%g3 + 0x28], %f26
|
||||
CAMELLIA_F(16, 2, 0, 2)
|
||||
CAMELLIA_F(18, 0, 2, 0)
|
||||
fxor %f28, %f0, %f0
|
||||
fxor %f30, %f2, %f2
|
||||
CAMELLIA_F(20, 2, 0, 2)
|
||||
CAMELLIA_F(22, 0, 2, 0)
|
||||
|
||||
#define ROTL128(S01, S23, TMP1, TMP2, N) \
|
||||
srlx S01, (64 - N), TMP1; \
|
||||
sllx S01, N, S01; \
|
||||
srlx S23, (64 - N), TMP2; \
|
||||
sllx S23, N, S23; \
|
||||
or S01, TMP2, S01; \
|
||||
or S23, TMP1, S23
|
||||
|
||||
cmp %o2, 16
|
||||
bne 1f
|
||||
nop
|
||||
/* 128-bit key */
|
||||
std %f0, [%o1 + 0x10] ! k[ 4, 5]
|
||||
std %f2, [%o1 + 0x18] ! k[ 6, 7]
|
||||
MOVDTOX_F0_O4
|
||||
MOVDTOX_F2_O5
|
||||
ROTL128(%o4, %o5, %g2, %g3, 15)
|
||||
stx %o4, [%o1 + 0x30] ! k[12, 13]
|
||||
stx %o5, [%o1 + 0x38] ! k[14, 15]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 15)
|
||||
stx %o4, [%o1 + 0x40] ! k[16, 17]
|
||||
stx %o5, [%o1 + 0x48] ! k[18, 19]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 15)
|
||||
stx %o4, [%o1 + 0x60] ! k[24, 25]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 15)
|
||||
stx %o4, [%o1 + 0x70] ! k[28, 29]
|
||||
stx %o5, [%o1 + 0x78] ! k[30, 31]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 34)
|
||||
stx %o4, [%o1 + 0xa0] ! k[40, 41]
|
||||
stx %o5, [%o1 + 0xa8] ! k[42, 43]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 17)
|
||||
stx %o4, [%o1 + 0xc0] ! k[48, 49]
|
||||
stx %o5, [%o1 + 0xc8] ! k[50, 51]
|
||||
|
||||
ldx [%o1 + 0x00], %o4 ! k[ 0, 1]
|
||||
ldx [%o1 + 0x08], %o5 ! k[ 2, 3]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 15)
|
||||
stx %o4, [%o1 + 0x20] ! k[ 8, 9]
|
||||
stx %o5, [%o1 + 0x28] ! k[10, 11]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 30)
|
||||
stx %o4, [%o1 + 0x50] ! k[20, 21]
|
||||
stx %o5, [%o1 + 0x58] ! k[22, 23]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 15)
|
||||
stx %o5, [%o1 + 0x68] ! k[26, 27]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 17)
|
||||
stx %o4, [%o1 + 0x80] ! k[32, 33]
|
||||
stx %o5, [%o1 + 0x88] ! k[34, 35]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 17)
|
||||
stx %o4, [%o1 + 0x90] ! k[36, 37]
|
||||
stx %o5, [%o1 + 0x98] ! k[38, 39]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 17)
|
||||
stx %o4, [%o1 + 0xb0] ! k[44, 45]
|
||||
stx %o5, [%o1 + 0xb8] ! k[46, 47]
|
||||
|
||||
ba,pt %xcc, 2f
|
||||
mov (3 * 16 * 4), %o0
|
||||
|
||||
1:
|
||||
/* 192-bit or 256-bit key */
|
||||
std %f0, [%o1 + 0x30] ! k[12, 13]
|
||||
std %f2, [%o1 + 0x38] ! k[14, 15]
|
||||
ldd [%o1 + 0x20], %f4 ! k[ 8, 9]
|
||||
ldd [%o1 + 0x28], %f6 ! k[10, 11]
|
||||
fxor %f0, %f4, %f0
|
||||
fxor %f2, %f6, %f2
|
||||
CAMELLIA_F(24, 2, 0, 2)
|
||||
CAMELLIA_F(26, 0, 2, 0)
|
||||
std %f0, [%o1 + 0x10] ! k[ 4, 5]
|
||||
std %f2, [%o1 + 0x18] ! k[ 6, 7]
|
||||
MOVDTOX_F0_O4
|
||||
MOVDTOX_F2_O5
|
||||
ROTL128(%o4, %o5, %g2, %g3, 30)
|
||||
stx %o4, [%o1 + 0x50] ! k[20, 21]
|
||||
stx %o5, [%o1 + 0x58] ! k[22, 23]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 30)
|
||||
stx %o4, [%o1 + 0xa0] ! k[40, 41]
|
||||
stx %o5, [%o1 + 0xa8] ! k[42, 43]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 51)
|
||||
stx %o4, [%o1 + 0x100] ! k[64, 65]
|
||||
stx %o5, [%o1 + 0x108] ! k[66, 67]
|
||||
ldx [%o1 + 0x20], %o4 ! k[ 8, 9]
|
||||
ldx [%o1 + 0x28], %o5 ! k[10, 11]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 15)
|
||||
stx %o4, [%o1 + 0x20] ! k[ 8, 9]
|
||||
stx %o5, [%o1 + 0x28] ! k[10, 11]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 15)
|
||||
stx %o4, [%o1 + 0x40] ! k[16, 17]
|
||||
stx %o5, [%o1 + 0x48] ! k[18, 19]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 30)
|
||||
stx %o4, [%o1 + 0x90] ! k[36, 37]
|
||||
stx %o5, [%o1 + 0x98] ! k[38, 39]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 34)
|
||||
stx %o4, [%o1 + 0xd0] ! k[52, 53]
|
||||
stx %o5, [%o1 + 0xd8] ! k[54, 55]
|
||||
ldx [%o1 + 0x30], %o4 ! k[12, 13]
|
||||
ldx [%o1 + 0x38], %o5 ! k[14, 15]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 15)
|
||||
stx %o4, [%o1 + 0x30] ! k[12, 13]
|
||||
stx %o5, [%o1 + 0x38] ! k[14, 15]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 30)
|
||||
stx %o4, [%o1 + 0x70] ! k[28, 29]
|
||||
stx %o5, [%o1 + 0x78] ! k[30, 31]
|
||||
srlx %o4, 32, %g2
|
||||
srlx %o5, 32, %g3
|
||||
stw %o4, [%o1 + 0xc0] ! k[48]
|
||||
stw %g3, [%o1 + 0xc4] ! k[49]
|
||||
stw %o5, [%o1 + 0xc8] ! k[50]
|
||||
stw %g2, [%o1 + 0xcc] ! k[51]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 49)
|
||||
stx %o4, [%o1 + 0xe0] ! k[56, 57]
|
||||
stx %o5, [%o1 + 0xe8] ! k[58, 59]
|
||||
ldx [%o1 + 0x00], %o4 ! k[ 0, 1]
|
||||
ldx [%o1 + 0x08], %o5 ! k[ 2, 3]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 45)
|
||||
stx %o4, [%o1 + 0x60] ! k[24, 25]
|
||||
stx %o5, [%o1 + 0x68] ! k[26, 27]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 15)
|
||||
stx %o4, [%o1 + 0x80] ! k[32, 33]
|
||||
stx %o5, [%o1 + 0x88] ! k[34, 35]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 17)
|
||||
stx %o4, [%o1 + 0xb0] ! k[44, 45]
|
||||
stx %o5, [%o1 + 0xb8] ! k[46, 47]
|
||||
ROTL128(%o4, %o5, %g2, %g3, 34)
|
||||
stx %o4, [%o1 + 0xf0] ! k[60, 61]
|
||||
stx %o5, [%o1 + 0xf8] ! k[62, 63]
|
||||
mov (4 * 16 * 4), %o0
|
||||
2:
|
||||
add %o1, %o0, %o1
|
||||
ldd [%o1 + 0x00], %f0
|
||||
ldd [%o1 + 0x08], %f2
|
||||
std %f0, [%o3 + 0x00]
|
||||
std %f2, [%o3 + 0x08]
|
||||
add %o3, 0x10, %o3
|
||||
1:
|
||||
sub %o1, (16 * 4), %o1
|
||||
ldd [%o1 + 0x38], %f0
|
||||
ldd [%o1 + 0x30], %f2
|
||||
ldd [%o1 + 0x28], %f4
|
||||
ldd [%o1 + 0x20], %f6
|
||||
ldd [%o1 + 0x18], %f8
|
||||
ldd [%o1 + 0x10], %f10
|
||||
std %f0, [%o3 + 0x00]
|
||||
std %f2, [%o3 + 0x08]
|
||||
std %f4, [%o3 + 0x10]
|
||||
std %f6, [%o3 + 0x18]
|
||||
std %f8, [%o3 + 0x20]
|
||||
std %f10, [%o3 + 0x28]
|
||||
|
||||
ldd [%o1 + 0x08], %f0
|
||||
ldd [%o1 + 0x00], %f2
|
||||
std %f0, [%o3 + 0x30]
|
||||
std %f2, [%o3 + 0x38]
|
||||
subcc %o0, (16 * 4), %o0
|
||||
bne,pt %icc, 1b
|
||||
add %o3, (16 * 4), %o3
|
||||
|
||||
std %f2, [%o3 - 0x10]
|
||||
std %f0, [%o3 - 0x08]
|
||||
|
||||
retl
|
||||
VISExit
|
||||
ENDPROC(camellia_sparc64_key_expand)
|
||||
|
||||
.align 32
|
||||
ENTRY(camellia_sparc64_crypt)
|
||||
/* %o0=key, %o1=input, %o2=output, %o3=key_len */
|
||||
VISEntry
|
||||
|
||||
ld [%o1 + 0x00], %f0
|
||||
ld [%o1 + 0x04], %f1
|
||||
ld [%o1 + 0x08], %f2
|
||||
ld [%o1 + 0x0c], %f3
|
||||
|
||||
ldd [%o0 + 0x00], %f4
|
||||
ldd [%o0 + 0x08], %f6
|
||||
|
||||
cmp %o3, 16
|
||||
fxor %f4, %f0, %f0
|
||||
be 1f
|
||||
fxor %f6, %f2, %f2
|
||||
|
||||
ldd [%o0 + 0x10], %f8
|
||||
ldd [%o0 + 0x18], %f10
|
||||
ldd [%o0 + 0x20], %f12
|
||||
ldd [%o0 + 0x28], %f14
|
||||
ldd [%o0 + 0x30], %f16
|
||||
ldd [%o0 + 0x38], %f18
|
||||
ldd [%o0 + 0x40], %f20
|
||||
ldd [%o0 + 0x48], %f22
|
||||
add %o0, 0x40, %o0
|
||||
|
||||
CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2)
|
||||
|
||||
1:
|
||||
ldd [%o0 + 0x10], %f8
|
||||
ldd [%o0 + 0x18], %f10
|
||||
ldd [%o0 + 0x20], %f12
|
||||
ldd [%o0 + 0x28], %f14
|
||||
ldd [%o0 + 0x30], %f16
|
||||
ldd [%o0 + 0x38], %f18
|
||||
ldd [%o0 + 0x40], %f20
|
||||
ldd [%o0 + 0x48], %f22
|
||||
ldd [%o0 + 0x50], %f24
|
||||
ldd [%o0 + 0x58], %f26
|
||||
ldd [%o0 + 0x60], %f28
|
||||
ldd [%o0 + 0x68], %f30
|
||||
ldd [%o0 + 0x70], %f32
|
||||
ldd [%o0 + 0x78], %f34
|
||||
ldd [%o0 + 0x80], %f36
|
||||
ldd [%o0 + 0x88], %f38
|
||||
ldd [%o0 + 0x90], %f40
|
||||
ldd [%o0 + 0x98], %f42
|
||||
ldd [%o0 + 0xa0], %f44
|
||||
ldd [%o0 + 0xa8], %f46
|
||||
ldd [%o0 + 0xb0], %f48
|
||||
ldd [%o0 + 0xb8], %f50
|
||||
ldd [%o0 + 0xc0], %f52
|
||||
ldd [%o0 + 0xc8], %f54
|
||||
|
||||
CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2)
|
||||
CAMELLIA_6ROUNDS_FL_FLI(24, 0, 2)
|
||||
CAMELLIA_6ROUNDS(40, 0, 2)
|
||||
fxor %f52, %f2, %f2
|
||||
fxor %f54, %f0, %f0
|
||||
|
||||
st %f2, [%o2 + 0x00]
|
||||
st %f3, [%o2 + 0x04]
|
||||
st %f0, [%o2 + 0x08]
|
||||
st %f1, [%o2 + 0x0c]
|
||||
|
||||
retl
|
||||
VISExit
|
||||
ENDPROC(camellia_sparc64_crypt)
|
||||
|
||||
.align 32
|
||||
ENTRY(camellia_sparc64_load_keys)
|
||||
/* %o0=key, %o1=key_len */
|
||||
VISEntry
|
||||
ldd [%o0 + 0x00], %f4
|
||||
ldd [%o0 + 0x08], %f6
|
||||
ldd [%o0 + 0x10], %f8
|
||||
ldd [%o0 + 0x18], %f10
|
||||
ldd [%o0 + 0x20], %f12
|
||||
ldd [%o0 + 0x28], %f14
|
||||
ldd [%o0 + 0x30], %f16
|
||||
ldd [%o0 + 0x38], %f18
|
||||
ldd [%o0 + 0x40], %f20
|
||||
ldd [%o0 + 0x48], %f22
|
||||
ldd [%o0 + 0x50], %f24
|
||||
ldd [%o0 + 0x58], %f26
|
||||
ldd [%o0 + 0x60], %f28
|
||||
ldd [%o0 + 0x68], %f30
|
||||
ldd [%o0 + 0x70], %f32
|
||||
ldd [%o0 + 0x78], %f34
|
||||
ldd [%o0 + 0x80], %f36
|
||||
ldd [%o0 + 0x88], %f38
|
||||
ldd [%o0 + 0x90], %f40
|
||||
ldd [%o0 + 0x98], %f42
|
||||
ldd [%o0 + 0xa0], %f44
|
||||
ldd [%o0 + 0xa8], %f46
|
||||
ldd [%o0 + 0xb0], %f48
|
||||
ldd [%o0 + 0xb8], %f50
|
||||
ldd [%o0 + 0xc0], %f52
|
||||
retl
|
||||
ldd [%o0 + 0xc8], %f54
|
||||
ENDPROC(camellia_sparc64_load_keys)
|
||||
|
||||
.align 32
|
||||
ENTRY(camellia_sparc64_ecb_crypt_3_grand_rounds)
|
||||
/* %o0=input, %o1=output, %o2=len, %o3=key */
|
||||
1: ldd [%o0 + 0x00], %f0
|
||||
ldd [%o0 + 0x08], %f2
|
||||
add %o0, 0x10, %o0
|
||||
fxor %f4, %f0, %f0
|
||||
fxor %f6, %f2, %f2
|
||||
CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2)
|
||||
CAMELLIA_6ROUNDS_FL_FLI(24, 0, 2)
|
||||
CAMELLIA_6ROUNDS(40, 0, 2)
|
||||
fxor %f52, %f2, %f2
|
||||
fxor %f54, %f0, %f0
|
||||
std %f2, [%o1 + 0x00]
|
||||
std %f0, [%o1 + 0x08]
|
||||
subcc %o2, 0x10, %o2
|
||||
bne,pt %icc, 1b
|
||||
add %o1, 0x10, %o1
|
||||
retl
|
||||
nop
|
||||
ENDPROC(camellia_sparc64_ecb_crypt_3_grand_rounds)
|
||||
|
||||
.align 32
|
||||
ENTRY(camellia_sparc64_ecb_crypt_4_grand_rounds)
|
||||
/* %o0=input, %o1=output, %o2=len, %o3=key */
|
||||
1: ldd [%o0 + 0x00], %f0
|
||||
ldd [%o0 + 0x08], %f2
|
||||
add %o0, 0x10, %o0
|
||||
fxor %f4, %f0, %f0
|
||||
fxor %f6, %f2, %f2
|
||||
CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2)
|
||||
ldd [%o3 + 0xd0], %f8
|
||||
ldd [%o3 + 0xd8], %f10
|
||||
ldd [%o3 + 0xe0], %f12
|
||||
ldd [%o3 + 0xe8], %f14
|
||||
ldd [%o3 + 0xf0], %f16
|
||||
ldd [%o3 + 0xf8], %f18
|
||||
ldd [%o3 + 0x100], %f20
|
||||
ldd [%o3 + 0x108], %f22
|
||||
CAMELLIA_6ROUNDS_FL_FLI(24, 0, 2)
|
||||
CAMELLIA_6ROUNDS_FL_FLI(40, 0, 2)
|
||||
CAMELLIA_F(8, 2, 0, 2)
|
||||
CAMELLIA_F(10, 0, 2, 0)
|
||||
ldd [%o3 + 0x10], %f8
|
||||
ldd [%o3 + 0x18], %f10
|
||||
CAMELLIA_F(12, 2, 0, 2)
|
||||
CAMELLIA_F(14, 0, 2, 0)
|
||||
ldd [%o3 + 0x20], %f12
|
||||
ldd [%o3 + 0x28], %f14
|
||||
CAMELLIA_F(16, 2, 0, 2)
|
||||
CAMELLIA_F(18, 0, 2, 0)
|
||||
ldd [%o3 + 0x30], %f16
|
||||
ldd [%o3 + 0x38], %f18
|
||||
fxor %f20, %f2, %f2
|
||||
fxor %f22, %f0, %f0
|
||||
ldd [%o3 + 0x40], %f20
|
||||
ldd [%o3 + 0x48], %f22
|
||||
std %f2, [%o1 + 0x00]
|
||||
std %f0, [%o1 + 0x08]
|
||||
subcc %o2, 0x10, %o2
|
||||
bne,pt %icc, 1b
|
||||
add %o1, 0x10, %o1
|
||||
retl
|
||||
nop
|
||||
ENDPROC(camellia_sparc64_ecb_crypt_4_grand_rounds)
|
||||
|
||||
.align 32
|
||||
ENTRY(camellia_sparc64_cbc_encrypt_3_grand_rounds)
|
||||
/* %o0=input, %o1=output, %o2=len, %o3=key, %o4=IV */
|
||||
ldd [%o4 + 0x00], %f60
|
||||
ldd [%o4 + 0x08], %f62
|
||||
1: ldd [%o0 + 0x00], %f0
|
||||
ldd [%o0 + 0x08], %f2
|
||||
add %o0, 0x10, %o0
|
||||
fxor %f60, %f0, %f0
|
||||
fxor %f62, %f2, %f2
|
||||
fxor %f4, %f0, %f0
|
||||
fxor %f6, %f2, %f2
|
||||
CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2)
|
||||
CAMELLIA_6ROUNDS_FL_FLI(24, 0, 2)
|
||||
CAMELLIA_6ROUNDS(40, 0, 2)
|
||||
fxor %f52, %f2, %f60
|
||||
fxor %f54, %f0, %f62
|
||||
std %f60, [%o1 + 0x00]
|
||||
std %f62, [%o1 + 0x08]
|
||||
subcc %o2, 0x10, %o2
|
||||
bne,pt %icc, 1b
|
||||
add %o1, 0x10, %o1
|
||||
std %f60, [%o4 + 0x00]
|
||||
retl
|
||||
std %f62, [%o4 + 0x08]
|
||||
ENDPROC(camellia_sparc64_cbc_encrypt_3_grand_rounds)
|
||||
|
||||
.align 32
|
||||
ENTRY(camellia_sparc64_cbc_encrypt_4_grand_rounds)
|
||||
/* %o0=input, %o1=output, %o2=len, %o3=key, %o4=IV */
|
||||
ldd [%o4 + 0x00], %f60
|
||||
ldd [%o4 + 0x08], %f62
|
||||
1: ldd [%o0 + 0x00], %f0
|
||||
ldd [%o0 + 0x08], %f2
|
||||
add %o0, 0x10, %o0
|
||||
fxor %f60, %f0, %f0
|
||||
fxor %f62, %f2, %f2
|
||||
fxor %f4, %f0, %f0
|
||||
fxor %f6, %f2, %f2
|
||||
CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2)
|
||||
ldd [%o3 + 0xd0], %f8
|
||||
ldd [%o3 + 0xd8], %f10
|
||||
ldd [%o3 + 0xe0], %f12
|
||||
ldd [%o3 + 0xe8], %f14
|
||||
ldd [%o3 + 0xf0], %f16
|
||||
ldd [%o3 + 0xf8], %f18
|
||||
ldd [%o3 + 0x100], %f20
|
||||
ldd [%o3 + 0x108], %f22
|
||||
CAMELLIA_6ROUNDS_FL_FLI(24, 0, 2)
|
||||
CAMELLIA_6ROUNDS_FL_FLI(40, 0, 2)
|
||||
CAMELLIA_F(8, 2, 0, 2)
|
||||
CAMELLIA_F(10, 0, 2, 0)
|
||||
ldd [%o3 + 0x10], %f8
|
||||
ldd [%o3 + 0x18], %f10
|
||||
CAMELLIA_F(12, 2, 0, 2)
|
||||
CAMELLIA_F(14, 0, 2, 0)
|
||||
ldd [%o3 + 0x20], %f12
|
||||
ldd [%o3 + 0x28], %f14
|
||||
CAMELLIA_F(16, 2, 0, 2)
|
||||
CAMELLIA_F(18, 0, 2, 0)
|
||||
ldd [%o3 + 0x30], %f16
|
||||
ldd [%o3 + 0x38], %f18
|
||||
fxor %f20, %f2, %f60
|
||||
fxor %f22, %f0, %f62
|
||||
ldd [%o3 + 0x40], %f20
|
||||
ldd [%o3 + 0x48], %f22
|
||||
std %f60, [%o1 + 0x00]
|
||||
std %f62, [%o1 + 0x08]
|
||||
subcc %o2, 0x10, %o2
|
||||
bne,pt %icc, 1b
|
||||
add %o1, 0x10, %o1
|
||||
std %f60, [%o4 + 0x00]
|
||||
retl
|
||||
std %f62, [%o4 + 0x08]
|
||||
ENDPROC(camellia_sparc64_cbc_encrypt_4_grand_rounds)
|
||||
|
||||
.align 32
|
||||
ENTRY(camellia_sparc64_cbc_decrypt_3_grand_rounds)
|
||||
/* %o0=input, %o1=output, %o2=len, %o3=key, %o4=IV */
|
||||
ldd [%o4 + 0x00], %f60
|
||||
ldd [%o4 + 0x08], %f62
|
||||
1: ldd [%o0 + 0x00], %f56
|
||||
ldd [%o0 + 0x08], %f58
|
||||
add %o0, 0x10, %o0
|
||||
fxor %f4, %f56, %f0
|
||||
fxor %f6, %f58, %f2
|
||||
CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2)
|
||||
CAMELLIA_6ROUNDS_FL_FLI(24, 0, 2)
|
||||
CAMELLIA_6ROUNDS(40, 0, 2)
|
||||
fxor %f52, %f2, %f2
|
||||
fxor %f54, %f0, %f0
|
||||
fxor %f60, %f2, %f2
|
||||
fxor %f62, %f0, %f0
|
||||
fsrc2 %f56, %f60
|
||||
fsrc2 %f58, %f62
|
||||
std %f2, [%o1 + 0x00]
|
||||
std %f0, [%o1 + 0x08]
|
||||
subcc %o2, 0x10, %o2
|
||||
bne,pt %icc, 1b
|
||||
add %o1, 0x10, %o1
|
||||
std %f60, [%o4 + 0x00]
|
||||
retl
|
||||
std %f62, [%o4 + 0x08]
|
||||
ENDPROC(camellia_sparc64_cbc_decrypt_3_grand_rounds)
|
||||
|
||||
.align 32
|
||||
ENTRY(camellia_sparc64_cbc_decrypt_4_grand_rounds)
|
||||
/* %o0=input, %o1=output, %o2=len, %o3=key, %o4=IV */
|
||||
ldd [%o4 + 0x00], %f60
|
||||
ldd [%o4 + 0x08], %f62
|
||||
1: ldd [%o0 + 0x00], %f56
|
||||
ldd [%o0 + 0x08], %f58
|
||||
add %o0, 0x10, %o0
|
||||
fxor %f4, %f56, %f0
|
||||
fxor %f6, %f58, %f2
|
||||
CAMELLIA_6ROUNDS_FL_FLI( 8, 0, 2)
|
||||
ldd [%o3 + 0xd0], %f8
|
||||
ldd [%o3 + 0xd8], %f10
|
||||
ldd [%o3 + 0xe0], %f12
|
||||
ldd [%o3 + 0xe8], %f14
|
||||
ldd [%o3 + 0xf0], %f16
|
||||
ldd [%o3 + 0xf8], %f18
|
||||
ldd [%o3 + 0x100], %f20
|
||||
ldd [%o3 + 0x108], %f22
|
||||
CAMELLIA_6ROUNDS_FL_FLI(24, 0, 2)
|
||||
CAMELLIA_6ROUNDS_FL_FLI(40, 0, 2)
|
||||
CAMELLIA_F(8, 2, 0, 2)
|
||||
CAMELLIA_F(10, 0, 2, 0)
|
||||
ldd [%o3 + 0x10], %f8
|
||||
ldd [%o3 + 0x18], %f10
|
||||
CAMELLIA_F(12, 2, 0, 2)
|
||||
CAMELLIA_F(14, 0, 2, 0)
|
||||
ldd [%o3 + 0x20], %f12
|
||||
ldd [%o3 + 0x28], %f14
|
||||
CAMELLIA_F(16, 2, 0, 2)
|
||||
CAMELLIA_F(18, 0, 2, 0)
|
||||
ldd [%o3 + 0x30], %f16
|
||||
ldd [%o3 + 0x38], %f18
|
||||
fxor %f20, %f2, %f2
|
||||
fxor %f22, %f0, %f0
|
||||
ldd [%o3 + 0x40], %f20
|
||||
ldd [%o3 + 0x48], %f22
|
||||
fxor %f60, %f2, %f2
|
||||
fxor %f62, %f0, %f0
|
||||
fsrc2 %f56, %f60
|
||||
fsrc2 %f58, %f62
|
||||
std %f2, [%o1 + 0x00]
|
||||
std %f0, [%o1 + 0x08]
|
||||
subcc %o2, 0x10, %o2
|
||||
bne,pt %icc, 1b
|
||||
add %o1, 0x10, %o1
|
||||
std %f60, [%o4 + 0x00]
|
||||
retl
|
||||
std %f62, [%o4 + 0x08]
|
||||
ENDPROC(camellia_sparc64_cbc_decrypt_4_grand_rounds)
|
327
arch/sparc/crypto/camellia_glue.c
Normal file
327
arch/sparc/crypto/camellia_glue.c
Normal file
|
@ -0,0 +1,327 @@
|
|||
/* Glue code for CAMELLIA encryption optimized for sparc64 crypto opcodes.
|
||||
*
|
||||
* Copyright (C) 2012 David S. Miller <davem@davemloft.net>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/types.h>
|
||||
#include <crypto/algapi.h>
|
||||
|
||||
#include <asm/fpumacro.h>
|
||||
#include <asm/pstate.h>
|
||||
#include <asm/elf.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
#define CAMELLIA_MIN_KEY_SIZE 16
|
||||
#define CAMELLIA_MAX_KEY_SIZE 32
|
||||
#define CAMELLIA_BLOCK_SIZE 16
|
||||
#define CAMELLIA_TABLE_BYTE_LEN 272
|
||||
|
||||
struct camellia_sparc64_ctx {
|
||||
u64 encrypt_key[CAMELLIA_TABLE_BYTE_LEN / sizeof(u64)];
|
||||
u64 decrypt_key[CAMELLIA_TABLE_BYTE_LEN / sizeof(u64)];
|
||||
int key_len;
|
||||
};
|
||||
|
||||
extern void camellia_sparc64_key_expand(const u32 *in_key, u64 *encrypt_key,
|
||||
unsigned int key_len, u64 *decrypt_key);
|
||||
|
||||
static int camellia_set_key(struct crypto_tfm *tfm, const u8 *_in_key,
|
||||
unsigned int key_len)
|
||||
{
|
||||
struct camellia_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
const u32 *in_key = (const u32 *) _in_key;
|
||||
u32 *flags = &tfm->crt_flags;
|
||||
|
||||
if (key_len != 16 && key_len != 24 && key_len != 32) {
|
||||
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx->key_len = key_len;
|
||||
|
||||
camellia_sparc64_key_expand(in_key, &ctx->encrypt_key[0],
|
||||
key_len, &ctx->decrypt_key[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void camellia_sparc64_crypt(const u64 *key, const u32 *input,
|
||||
u32 *output, unsigned int key_len);
|
||||
|
||||
static void camellia_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||
{
|
||||
struct camellia_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
camellia_sparc64_crypt(&ctx->encrypt_key[0],
|
||||
(const u32 *) src,
|
||||
(u32 *) dst, ctx->key_len);
|
||||
}
|
||||
|
||||
static void camellia_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||
{
|
||||
struct camellia_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
camellia_sparc64_crypt(&ctx->decrypt_key[0],
|
||||
(const u32 *) src,
|
||||
(u32 *) dst, ctx->key_len);
|
||||
}
|
||||
|
||||
extern void camellia_sparc64_load_keys(const u64 *key, unsigned int key_len);
|
||||
|
||||
typedef void ecb_crypt_op(const u64 *input, u64 *output, unsigned int len,
|
||||
const u64 *key);
|
||||
|
||||
extern ecb_crypt_op camellia_sparc64_ecb_crypt_3_grand_rounds;
|
||||
extern ecb_crypt_op camellia_sparc64_ecb_crypt_4_grand_rounds;
|
||||
|
||||
#define CAMELLIA_BLOCK_MASK (~(CAMELLIA_BLOCK_SIZE - 1))
|
||||
|
||||
static int __ecb_crypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes, bool encrypt)
|
||||
{
|
||||
struct camellia_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
ecb_crypt_op *op;
|
||||
const u64 *key;
|
||||
int err;
|
||||
|
||||
op = camellia_sparc64_ecb_crypt_3_grand_rounds;
|
||||
if (ctx->key_len != 16)
|
||||
op = camellia_sparc64_ecb_crypt_4_grand_rounds;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
if (encrypt)
|
||||
key = &ctx->encrypt_key[0];
|
||||
else
|
||||
key = &ctx->decrypt_key[0];
|
||||
camellia_sparc64_load_keys(key, ctx->key_len);
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
unsigned int block_len = nbytes & CAMELLIA_BLOCK_MASK;
|
||||
|
||||
if (likely(block_len)) {
|
||||
const u64 *src64;
|
||||
u64 *dst64;
|
||||
|
||||
src64 = (const u64 *)walk.src.virt.addr;
|
||||
dst64 = (u64 *) walk.dst.virt.addr;
|
||||
op(src64, dst64, block_len, key);
|
||||
}
|
||||
nbytes &= CAMELLIA_BLOCK_SIZE - 1;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
fprs_write(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ecb_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
return __ecb_crypt(desc, dst, src, nbytes, true);
|
||||
}
|
||||
|
||||
static int ecb_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
return __ecb_crypt(desc, dst, src, nbytes, false);
|
||||
}
|
||||
|
||||
typedef void cbc_crypt_op(const u64 *input, u64 *output, unsigned int len,
|
||||
const u64 *key, u64 *iv);
|
||||
|
||||
extern cbc_crypt_op camellia_sparc64_cbc_encrypt_3_grand_rounds;
|
||||
extern cbc_crypt_op camellia_sparc64_cbc_encrypt_4_grand_rounds;
|
||||
extern cbc_crypt_op camellia_sparc64_cbc_decrypt_3_grand_rounds;
|
||||
extern cbc_crypt_op camellia_sparc64_cbc_decrypt_4_grand_rounds;
|
||||
|
||||
static int cbc_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct camellia_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
cbc_crypt_op *op;
|
||||
const u64 *key;
|
||||
int err;
|
||||
|
||||
op = camellia_sparc64_cbc_encrypt_3_grand_rounds;
|
||||
if (ctx->key_len != 16)
|
||||
op = camellia_sparc64_cbc_encrypt_4_grand_rounds;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
key = &ctx->encrypt_key[0];
|
||||
camellia_sparc64_load_keys(key, ctx->key_len);
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
unsigned int block_len = nbytes & CAMELLIA_BLOCK_MASK;
|
||||
|
||||
if (likely(block_len)) {
|
||||
const u64 *src64;
|
||||
u64 *dst64;
|
||||
|
||||
src64 = (const u64 *)walk.src.virt.addr;
|
||||
dst64 = (u64 *) walk.dst.virt.addr;
|
||||
op(src64, dst64, block_len, key,
|
||||
(u64 *) walk.iv);
|
||||
}
|
||||
nbytes &= CAMELLIA_BLOCK_SIZE - 1;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
fprs_write(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cbc_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct camellia_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
cbc_crypt_op *op;
|
||||
const u64 *key;
|
||||
int err;
|
||||
|
||||
op = camellia_sparc64_cbc_decrypt_3_grand_rounds;
|
||||
if (ctx->key_len != 16)
|
||||
op = camellia_sparc64_cbc_decrypt_4_grand_rounds;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
key = &ctx->decrypt_key[0];
|
||||
camellia_sparc64_load_keys(key, ctx->key_len);
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
unsigned int block_len = nbytes & CAMELLIA_BLOCK_MASK;
|
||||
|
||||
if (likely(block_len)) {
|
||||
const u64 *src64;
|
||||
u64 *dst64;
|
||||
|
||||
src64 = (const u64 *)walk.src.virt.addr;
|
||||
dst64 = (u64 *) walk.dst.virt.addr;
|
||||
op(src64, dst64, block_len, key,
|
||||
(u64 *) walk.iv);
|
||||
}
|
||||
nbytes &= CAMELLIA_BLOCK_SIZE - 1;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
fprs_write(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct crypto_alg algs[] = { {
|
||||
.cra_name = "camellia",
|
||||
.cra_driver_name = "camellia-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
|
||||
.cra_blocksize = CAMELLIA_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct camellia_sparc64_ctx),
|
||||
.cra_alignmask = 3,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.cipher = {
|
||||
.cia_min_keysize = CAMELLIA_MIN_KEY_SIZE,
|
||||
.cia_max_keysize = CAMELLIA_MAX_KEY_SIZE,
|
||||
.cia_setkey = camellia_set_key,
|
||||
.cia_encrypt = camellia_encrypt,
|
||||
.cia_decrypt = camellia_decrypt
|
||||
}
|
||||
}
|
||||
}, {
|
||||
.cra_name = "ecb(camellia)",
|
||||
.cra_driver_name = "ecb-camellia-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = CAMELLIA_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct camellia_sparc64_ctx),
|
||||
.cra_alignmask = 7,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = CAMELLIA_MIN_KEY_SIZE,
|
||||
.max_keysize = CAMELLIA_MAX_KEY_SIZE,
|
||||
.setkey = camellia_set_key,
|
||||
.encrypt = ecb_encrypt,
|
||||
.decrypt = ecb_decrypt,
|
||||
},
|
||||
},
|
||||
}, {
|
||||
.cra_name = "cbc(camellia)",
|
||||
.cra_driver_name = "cbc-camellia-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = CAMELLIA_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct camellia_sparc64_ctx),
|
||||
.cra_alignmask = 7,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = CAMELLIA_MIN_KEY_SIZE,
|
||||
.max_keysize = CAMELLIA_MAX_KEY_SIZE,
|
||||
.setkey = camellia_set_key,
|
||||
.encrypt = cbc_encrypt,
|
||||
.decrypt = cbc_decrypt,
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
static bool __init sparc64_has_camellia_opcode(void)
|
||||
{
|
||||
unsigned long cfr;
|
||||
|
||||
if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
|
||||
return false;
|
||||
|
||||
__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
|
||||
if (!(cfr & CFR_CAMELLIA))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __init camellia_sparc64_mod_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(algs); i++)
|
||||
INIT_LIST_HEAD(&algs[i].cra_list);
|
||||
|
||||
if (sparc64_has_camellia_opcode()) {
|
||||
pr_info("Using sparc64 camellia opcodes optimized CAMELLIA implementation\n");
|
||||
return crypto_register_algs(algs, ARRAY_SIZE(algs));
|
||||
}
|
||||
pr_info("sparc64 camellia opcodes not available.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void __exit camellia_sparc64_mod_fini(void)
|
||||
{
|
||||
crypto_unregister_algs(algs, ARRAY_SIZE(algs));
|
||||
}
|
||||
|
||||
module_init(camellia_sparc64_mod_init);
|
||||
module_exit(camellia_sparc64_mod_fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated");
|
||||
|
||||
MODULE_ALIAS_CRYPTO("aes");
|
||||
|
||||
#include "crop_devid.c"
|
20
arch/sparc/crypto/crc32c_asm.S
Normal file
20
arch/sparc/crypto/crc32c_asm.S
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include <linux/linkage.h>
|
||||
#include <asm/visasm.h>
|
||||
#include <asm/asi.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
ENTRY(crc32c_sparc64)
|
||||
/* %o0=crc32p, %o1=data_ptr, %o2=len */
|
||||
VISEntryHalf
|
||||
lda [%o0] ASI_PL, %f1
|
||||
1: ldd [%o1], %f2
|
||||
CRC32C(0,2,0)
|
||||
subcc %o2, 8, %o2
|
||||
bne,pt %icc, 1b
|
||||
add %o1, 0x8, %o1
|
||||
sta %f1, [%o0] ASI_PL
|
||||
VISExitHalf
|
||||
2: retl
|
||||
nop
|
||||
ENDPROC(crc32c_sparc64)
|
181
arch/sparc/crypto/crc32c_glue.c
Normal file
181
arch/sparc/crypto/crc32c_glue.c
Normal file
|
@ -0,0 +1,181 @@
|
|||
/* Glue code for CRC32C optimized for sparc64 crypto opcodes.
|
||||
*
|
||||
* This is based largely upon arch/x86/crypto/crc32c-intel.c
|
||||
*
|
||||
* Copyright (C) 2008 Intel Corporation
|
||||
* Authors: Austin Zhang <austin_zhang@linux.intel.com>
|
||||
* Kent Liu <kent.liu@intel.com>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/crc32.h>
|
||||
|
||||
#include <crypto/internal/hash.h>
|
||||
|
||||
#include <asm/pstate.h>
|
||||
#include <asm/elf.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
/*
|
||||
* Setting the seed allows arbitrary accumulators and flexible XOR policy
|
||||
* If your algorithm starts with ~0, then XOR with ~0 before you set
|
||||
* the seed.
|
||||
*/
|
||||
static int crc32c_sparc64_setkey(struct crypto_shash *hash, const u8 *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
u32 *mctx = crypto_shash_ctx(hash);
|
||||
|
||||
if (keylen != sizeof(u32)) {
|
||||
crypto_shash_set_flags(hash, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
*(__le32 *)mctx = le32_to_cpup((__le32 *)key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crc32c_sparc64_init(struct shash_desc *desc)
|
||||
{
|
||||
u32 *mctx = crypto_shash_ctx(desc->tfm);
|
||||
u32 *crcp = shash_desc_ctx(desc);
|
||||
|
||||
*crcp = *mctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void crc32c_sparc64(u32 *crcp, const u64 *data, unsigned int len);
|
||||
|
||||
static void crc32c_compute(u32 *crcp, const u64 *data, unsigned int len)
|
||||
{
|
||||
unsigned int asm_len;
|
||||
|
||||
asm_len = len & ~7U;
|
||||
if (asm_len) {
|
||||
crc32c_sparc64(crcp, data, asm_len);
|
||||
data += asm_len / 8;
|
||||
len -= asm_len;
|
||||
}
|
||||
if (len)
|
||||
*crcp = __crc32c_le(*crcp, (const unsigned char *) data, len);
|
||||
}
|
||||
|
||||
static int crc32c_sparc64_update(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len)
|
||||
{
|
||||
u32 *crcp = shash_desc_ctx(desc);
|
||||
|
||||
crc32c_compute(crcp, (const u64 *) data, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __crc32c_sparc64_finup(u32 *crcp, const u8 *data, unsigned int len,
|
||||
u8 *out)
|
||||
{
|
||||
u32 tmp = *crcp;
|
||||
|
||||
crc32c_compute(&tmp, (const u64 *) data, len);
|
||||
|
||||
*(__le32 *) out = ~cpu_to_le32(tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crc32c_sparc64_finup(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len, u8 *out)
|
||||
{
|
||||
return __crc32c_sparc64_finup(shash_desc_ctx(desc), data, len, out);
|
||||
}
|
||||
|
||||
static int crc32c_sparc64_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
u32 *crcp = shash_desc_ctx(desc);
|
||||
|
||||
*(__le32 *) out = ~cpu_to_le32p(crcp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crc32c_sparc64_digest(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len, u8 *out)
|
||||
{
|
||||
return __crc32c_sparc64_finup(crypto_shash_ctx(desc->tfm), data, len,
|
||||
out);
|
||||
}
|
||||
|
||||
static int crc32c_sparc64_cra_init(struct crypto_tfm *tfm)
|
||||
{
|
||||
u32 *key = crypto_tfm_ctx(tfm);
|
||||
|
||||
*key = ~0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CHKSUM_BLOCK_SIZE 1
|
||||
#define CHKSUM_DIGEST_SIZE 4
|
||||
|
||||
static struct shash_alg alg = {
|
||||
.setkey = crc32c_sparc64_setkey,
|
||||
.init = crc32c_sparc64_init,
|
||||
.update = crc32c_sparc64_update,
|
||||
.final = crc32c_sparc64_final,
|
||||
.finup = crc32c_sparc64_finup,
|
||||
.digest = crc32c_sparc64_digest,
|
||||
.descsize = sizeof(u32),
|
||||
.digestsize = CHKSUM_DIGEST_SIZE,
|
||||
.base = {
|
||||
.cra_name = "crc32c",
|
||||
.cra_driver_name = "crc32c-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_blocksize = CHKSUM_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(u32),
|
||||
.cra_alignmask = 7,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_init = crc32c_sparc64_cra_init,
|
||||
}
|
||||
};
|
||||
|
||||
static bool __init sparc64_has_crc32c_opcode(void)
|
||||
{
|
||||
unsigned long cfr;
|
||||
|
||||
if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
|
||||
return false;
|
||||
|
||||
__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
|
||||
if (!(cfr & CFR_CRC32C))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __init crc32c_sparc64_mod_init(void)
|
||||
{
|
||||
if (sparc64_has_crc32c_opcode()) {
|
||||
pr_info("Using sparc64 crc32c opcode optimized CRC32C implementation\n");
|
||||
return crypto_register_shash(&alg);
|
||||
}
|
||||
pr_info("sparc64 crc32c opcode not available.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void __exit crc32c_sparc64_mod_fini(void)
|
||||
{
|
||||
crypto_unregister_shash(&alg);
|
||||
}
|
||||
|
||||
module_init(crc32c_sparc64_mod_init);
|
||||
module_exit(crc32c_sparc64_mod_fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated");
|
||||
|
||||
MODULE_ALIAS_CRYPTO("crc32c");
|
||||
|
||||
#include "crop_devid.c"
|
14
arch/sparc/crypto/crop_devid.c
Normal file
14
arch/sparc/crypto/crop_devid.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
/* This is a dummy device table linked into all of the crypto
|
||||
* opcode drivers. It serves to trigger the module autoloading
|
||||
* mechanisms in userspace which scan the OF device tree and
|
||||
* load any modules which have device table entries that
|
||||
* match OF device nodes.
|
||||
*/
|
||||
static const struct of_device_id crypto_opcode_match[] = {
|
||||
{ .name = "cpu", .compatible = "sun4v", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, crypto_opcode_match);
|
419
arch/sparc/crypto/des_asm.S
Normal file
419
arch/sparc/crypto/des_asm.S
Normal file
|
@ -0,0 +1,419 @@
|
|||
#include <linux/linkage.h>
|
||||
#include <asm/visasm.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
.align 32
|
||||
ENTRY(des_sparc64_key_expand)
|
||||
/* %o0=input_key, %o1=output_key */
|
||||
VISEntryHalf
|
||||
ld [%o0 + 0x00], %f0
|
||||
ld [%o0 + 0x04], %f1
|
||||
DES_KEXPAND(0, 0, 0)
|
||||
DES_KEXPAND(0, 1, 2)
|
||||
DES_KEXPAND(2, 3, 6)
|
||||
DES_KEXPAND(2, 2, 4)
|
||||
DES_KEXPAND(6, 3, 10)
|
||||
DES_KEXPAND(6, 2, 8)
|
||||
DES_KEXPAND(10, 3, 14)
|
||||
DES_KEXPAND(10, 2, 12)
|
||||
DES_KEXPAND(14, 1, 16)
|
||||
DES_KEXPAND(16, 3, 20)
|
||||
DES_KEXPAND(16, 2, 18)
|
||||
DES_KEXPAND(20, 3, 24)
|
||||
DES_KEXPAND(20, 2, 22)
|
||||
DES_KEXPAND(24, 3, 28)
|
||||
DES_KEXPAND(24, 2, 26)
|
||||
DES_KEXPAND(28, 1, 30)
|
||||
std %f0, [%o1 + 0x00]
|
||||
std %f2, [%o1 + 0x08]
|
||||
std %f4, [%o1 + 0x10]
|
||||
std %f6, [%o1 + 0x18]
|
||||
std %f8, [%o1 + 0x20]
|
||||
std %f10, [%o1 + 0x28]
|
||||
std %f12, [%o1 + 0x30]
|
||||
std %f14, [%o1 + 0x38]
|
||||
std %f16, [%o1 + 0x40]
|
||||
std %f18, [%o1 + 0x48]
|
||||
std %f20, [%o1 + 0x50]
|
||||
std %f22, [%o1 + 0x58]
|
||||
std %f24, [%o1 + 0x60]
|
||||
std %f26, [%o1 + 0x68]
|
||||
std %f28, [%o1 + 0x70]
|
||||
std %f30, [%o1 + 0x78]
|
||||
retl
|
||||
VISExitHalf
|
||||
ENDPROC(des_sparc64_key_expand)
|
||||
|
||||
.align 32
|
||||
ENTRY(des_sparc64_crypt)
|
||||
/* %o0=key, %o1=input, %o2=output */
|
||||
VISEntry
|
||||
ldd [%o1 + 0x00], %f32
|
||||
ldd [%o0 + 0x00], %f0
|
||||
ldd [%o0 + 0x08], %f2
|
||||
ldd [%o0 + 0x10], %f4
|
||||
ldd [%o0 + 0x18], %f6
|
||||
ldd [%o0 + 0x20], %f8
|
||||
ldd [%o0 + 0x28], %f10
|
||||
ldd [%o0 + 0x30], %f12
|
||||
ldd [%o0 + 0x38], %f14
|
||||
ldd [%o0 + 0x40], %f16
|
||||
ldd [%o0 + 0x48], %f18
|
||||
ldd [%o0 + 0x50], %f20
|
||||
ldd [%o0 + 0x58], %f22
|
||||
ldd [%o0 + 0x60], %f24
|
||||
ldd [%o0 + 0x68], %f26
|
||||
ldd [%o0 + 0x70], %f28
|
||||
ldd [%o0 + 0x78], %f30
|
||||
DES_IP(32, 32)
|
||||
DES_ROUND(0, 2, 32, 32)
|
||||
DES_ROUND(4, 6, 32, 32)
|
||||
DES_ROUND(8, 10, 32, 32)
|
||||
DES_ROUND(12, 14, 32, 32)
|
||||
DES_ROUND(16, 18, 32, 32)
|
||||
DES_ROUND(20, 22, 32, 32)
|
||||
DES_ROUND(24, 26, 32, 32)
|
||||
DES_ROUND(28, 30, 32, 32)
|
||||
DES_IIP(32, 32)
|
||||
std %f32, [%o2 + 0x00]
|
||||
retl
|
||||
VISExit
|
||||
ENDPROC(des_sparc64_crypt)
|
||||
|
||||
.align 32
|
||||
ENTRY(des_sparc64_load_keys)
|
||||
/* %o0=key */
|
||||
VISEntry
|
||||
ldd [%o0 + 0x00], %f0
|
||||
ldd [%o0 + 0x08], %f2
|
||||
ldd [%o0 + 0x10], %f4
|
||||
ldd [%o0 + 0x18], %f6
|
||||
ldd [%o0 + 0x20], %f8
|
||||
ldd [%o0 + 0x28], %f10
|
||||
ldd [%o0 + 0x30], %f12
|
||||
ldd [%o0 + 0x38], %f14
|
||||
ldd [%o0 + 0x40], %f16
|
||||
ldd [%o0 + 0x48], %f18
|
||||
ldd [%o0 + 0x50], %f20
|
||||
ldd [%o0 + 0x58], %f22
|
||||
ldd [%o0 + 0x60], %f24
|
||||
ldd [%o0 + 0x68], %f26
|
||||
ldd [%o0 + 0x70], %f28
|
||||
retl
|
||||
ldd [%o0 + 0x78], %f30
|
||||
ENDPROC(des_sparc64_load_keys)
|
||||
|
||||
.align 32
|
||||
ENTRY(des_sparc64_ecb_crypt)
|
||||
/* %o0=input, %o1=output, %o2=len */
|
||||
1: ldd [%o0 + 0x00], %f32
|
||||
add %o0, 0x08, %o0
|
||||
DES_IP(32, 32)
|
||||
DES_ROUND(0, 2, 32, 32)
|
||||
DES_ROUND(4, 6, 32, 32)
|
||||
DES_ROUND(8, 10, 32, 32)
|
||||
DES_ROUND(12, 14, 32, 32)
|
||||
DES_ROUND(16, 18, 32, 32)
|
||||
DES_ROUND(20, 22, 32, 32)
|
||||
DES_ROUND(24, 26, 32, 32)
|
||||
DES_ROUND(28, 30, 32, 32)
|
||||
DES_IIP(32, 32)
|
||||
std %f32, [%o1 + 0x00]
|
||||
subcc %o2, 0x08, %o2
|
||||
bne,pt %icc, 1b
|
||||
add %o1, 0x08, %o1
|
||||
retl
|
||||
nop
|
||||
ENDPROC(des_sparc64_ecb_crypt)
|
||||
|
||||
.align 32
|
||||
ENTRY(des_sparc64_cbc_encrypt)
|
||||
/* %o0=input, %o1=output, %o2=len, %o3=IV */
|
||||
ldd [%o3 + 0x00], %f32
|
||||
1: ldd [%o0 + 0x00], %f34
|
||||
fxor %f32, %f34, %f32
|
||||
DES_IP(32, 32)
|
||||
DES_ROUND(0, 2, 32, 32)
|
||||
DES_ROUND(4, 6, 32, 32)
|
||||
DES_ROUND(8, 10, 32, 32)
|
||||
DES_ROUND(12, 14, 32, 32)
|
||||
DES_ROUND(16, 18, 32, 32)
|
||||
DES_ROUND(20, 22, 32, 32)
|
||||
DES_ROUND(24, 26, 32, 32)
|
||||
DES_ROUND(28, 30, 32, 32)
|
||||
DES_IIP(32, 32)
|
||||
std %f32, [%o1 + 0x00]
|
||||
add %o0, 0x08, %o0
|
||||
subcc %o2, 0x08, %o2
|
||||
bne,pt %icc, 1b
|
||||
add %o1, 0x08, %o1
|
||||
retl
|
||||
std %f32, [%o3 + 0x00]
|
||||
ENDPROC(des_sparc64_cbc_encrypt)
|
||||
|
||||
.align 32
|
||||
ENTRY(des_sparc64_cbc_decrypt)
|
||||
/* %o0=input, %o1=output, %o2=len, %o3=IV */
|
||||
ldd [%o3 + 0x00], %f34
|
||||
1: ldd [%o0 + 0x00], %f36
|
||||
DES_IP(36, 32)
|
||||
DES_ROUND(0, 2, 32, 32)
|
||||
DES_ROUND(4, 6, 32, 32)
|
||||
DES_ROUND(8, 10, 32, 32)
|
||||
DES_ROUND(12, 14, 32, 32)
|
||||
DES_ROUND(16, 18, 32, 32)
|
||||
DES_ROUND(20, 22, 32, 32)
|
||||
DES_ROUND(24, 26, 32, 32)
|
||||
DES_ROUND(28, 30, 32, 32)
|
||||
DES_IIP(32, 32)
|
||||
fxor %f32, %f34, %f32
|
||||
fsrc2 %f36, %f34
|
||||
std %f32, [%o1 + 0x00]
|
||||
add %o0, 0x08, %o0
|
||||
subcc %o2, 0x08, %o2
|
||||
bne,pt %icc, 1b
|
||||
add %o1, 0x08, %o1
|
||||
retl
|
||||
std %f36, [%o3 + 0x00]
|
||||
ENDPROC(des_sparc64_cbc_decrypt)
|
||||
|
||||
.align 32
|
||||
ENTRY(des3_ede_sparc64_crypt)
|
||||
/* %o0=key, %o1=input, %o2=output */
|
||||
VISEntry
|
||||
ldd [%o1 + 0x00], %f32
|
||||
ldd [%o0 + 0x00], %f0
|
||||
ldd [%o0 + 0x08], %f2
|
||||
ldd [%o0 + 0x10], %f4
|
||||
ldd [%o0 + 0x18], %f6
|
||||
ldd [%o0 + 0x20], %f8
|
||||
ldd [%o0 + 0x28], %f10
|
||||
ldd [%o0 + 0x30], %f12
|
||||
ldd [%o0 + 0x38], %f14
|
||||
ldd [%o0 + 0x40], %f16
|
||||
ldd [%o0 + 0x48], %f18
|
||||
ldd [%o0 + 0x50], %f20
|
||||
ldd [%o0 + 0x58], %f22
|
||||
ldd [%o0 + 0x60], %f24
|
||||
ldd [%o0 + 0x68], %f26
|
||||
ldd [%o0 + 0x70], %f28
|
||||
ldd [%o0 + 0x78], %f30
|
||||
DES_IP(32, 32)
|
||||
DES_ROUND(0, 2, 32, 32)
|
||||
ldd [%o0 + 0x80], %f0
|
||||
ldd [%o0 + 0x88], %f2
|
||||
DES_ROUND(4, 6, 32, 32)
|
||||
ldd [%o0 + 0x90], %f4
|
||||
ldd [%o0 + 0x98], %f6
|
||||
DES_ROUND(8, 10, 32, 32)
|
||||
ldd [%o0 + 0xa0], %f8
|
||||
ldd [%o0 + 0xa8], %f10
|
||||
DES_ROUND(12, 14, 32, 32)
|
||||
ldd [%o0 + 0xb0], %f12
|
||||
ldd [%o0 + 0xb8], %f14
|
||||
DES_ROUND(16, 18, 32, 32)
|
||||
ldd [%o0 + 0xc0], %f16
|
||||
ldd [%o0 + 0xc8], %f18
|
||||
DES_ROUND(20, 22, 32, 32)
|
||||
ldd [%o0 + 0xd0], %f20
|
||||
ldd [%o0 + 0xd8], %f22
|
||||
DES_ROUND(24, 26, 32, 32)
|
||||
ldd [%o0 + 0xe0], %f24
|
||||
ldd [%o0 + 0xe8], %f26
|
||||
DES_ROUND(28, 30, 32, 32)
|
||||
ldd [%o0 + 0xf0], %f28
|
||||
ldd [%o0 + 0xf8], %f30
|
||||
DES_IIP(32, 32)
|
||||
DES_IP(32, 32)
|
||||
DES_ROUND(0, 2, 32, 32)
|
||||
ldd [%o0 + 0x100], %f0
|
||||
ldd [%o0 + 0x108], %f2
|
||||
DES_ROUND(4, 6, 32, 32)
|
||||
ldd [%o0 + 0x110], %f4
|
||||
ldd [%o0 + 0x118], %f6
|
||||
DES_ROUND(8, 10, 32, 32)
|
||||
ldd [%o0 + 0x120], %f8
|
||||
ldd [%o0 + 0x128], %f10
|
||||
DES_ROUND(12, 14, 32, 32)
|
||||
ldd [%o0 + 0x130], %f12
|
||||
ldd [%o0 + 0x138], %f14
|
||||
DES_ROUND(16, 18, 32, 32)
|
||||
ldd [%o0 + 0x140], %f16
|
||||
ldd [%o0 + 0x148], %f18
|
||||
DES_ROUND(20, 22, 32, 32)
|
||||
ldd [%o0 + 0x150], %f20
|
||||
ldd [%o0 + 0x158], %f22
|
||||
DES_ROUND(24, 26, 32, 32)
|
||||
ldd [%o0 + 0x160], %f24
|
||||
ldd [%o0 + 0x168], %f26
|
||||
DES_ROUND(28, 30, 32, 32)
|
||||
ldd [%o0 + 0x170], %f28
|
||||
ldd [%o0 + 0x178], %f30
|
||||
DES_IIP(32, 32)
|
||||
DES_IP(32, 32)
|
||||
DES_ROUND(0, 2, 32, 32)
|
||||
DES_ROUND(4, 6, 32, 32)
|
||||
DES_ROUND(8, 10, 32, 32)
|
||||
DES_ROUND(12, 14, 32, 32)
|
||||
DES_ROUND(16, 18, 32, 32)
|
||||
DES_ROUND(20, 22, 32, 32)
|
||||
DES_ROUND(24, 26, 32, 32)
|
||||
DES_ROUND(28, 30, 32, 32)
|
||||
DES_IIP(32, 32)
|
||||
|
||||
std %f32, [%o2 + 0x00]
|
||||
retl
|
||||
VISExit
|
||||
ENDPROC(des3_ede_sparc64_crypt)
|
||||
|
||||
.align 32
|
||||
ENTRY(des3_ede_sparc64_load_keys)
|
||||
/* %o0=key */
|
||||
VISEntry
|
||||
ldd [%o0 + 0x00], %f0
|
||||
ldd [%o0 + 0x08], %f2
|
||||
ldd [%o0 + 0x10], %f4
|
||||
ldd [%o0 + 0x18], %f6
|
||||
ldd [%o0 + 0x20], %f8
|
||||
ldd [%o0 + 0x28], %f10
|
||||
ldd [%o0 + 0x30], %f12
|
||||
ldd [%o0 + 0x38], %f14
|
||||
ldd [%o0 + 0x40], %f16
|
||||
ldd [%o0 + 0x48], %f18
|
||||
ldd [%o0 + 0x50], %f20
|
||||
ldd [%o0 + 0x58], %f22
|
||||
ldd [%o0 + 0x60], %f24
|
||||
ldd [%o0 + 0x68], %f26
|
||||
ldd [%o0 + 0x70], %f28
|
||||
ldd [%o0 + 0x78], %f30
|
||||
ldd [%o0 + 0x80], %f32
|
||||
ldd [%o0 + 0x88], %f34
|
||||
ldd [%o0 + 0x90], %f36
|
||||
ldd [%o0 + 0x98], %f38
|
||||
ldd [%o0 + 0xa0], %f40
|
||||
ldd [%o0 + 0xa8], %f42
|
||||
ldd [%o0 + 0xb0], %f44
|
||||
ldd [%o0 + 0xb8], %f46
|
||||
ldd [%o0 + 0xc0], %f48
|
||||
ldd [%o0 + 0xc8], %f50
|
||||
ldd [%o0 + 0xd0], %f52
|
||||
ldd [%o0 + 0xd8], %f54
|
||||
ldd [%o0 + 0xe0], %f56
|
||||
retl
|
||||
ldd [%o0 + 0xe8], %f58
|
||||
ENDPROC(des3_ede_sparc64_load_keys)
|
||||
|
||||
#define DES3_LOOP_BODY(X) \
|
||||
DES_IP(X, X) \
|
||||
DES_ROUND(0, 2, X, X) \
|
||||
DES_ROUND(4, 6, X, X) \
|
||||
DES_ROUND(8, 10, X, X) \
|
||||
DES_ROUND(12, 14, X, X) \
|
||||
DES_ROUND(16, 18, X, X) \
|
||||
ldd [%o0 + 0xf0], %f16; \
|
||||
ldd [%o0 + 0xf8], %f18; \
|
||||
DES_ROUND(20, 22, X, X) \
|
||||
ldd [%o0 + 0x100], %f20; \
|
||||
ldd [%o0 + 0x108], %f22; \
|
||||
DES_ROUND(24, 26, X, X) \
|
||||
ldd [%o0 + 0x110], %f24; \
|
||||
ldd [%o0 + 0x118], %f26; \
|
||||
DES_ROUND(28, 30, X, X) \
|
||||
ldd [%o0 + 0x120], %f28; \
|
||||
ldd [%o0 + 0x128], %f30; \
|
||||
DES_IIP(X, X) \
|
||||
DES_IP(X, X) \
|
||||
DES_ROUND(32, 34, X, X) \
|
||||
ldd [%o0 + 0x130], %f0; \
|
||||
ldd [%o0 + 0x138], %f2; \
|
||||
DES_ROUND(36, 38, X, X) \
|
||||
ldd [%o0 + 0x140], %f4; \
|
||||
ldd [%o0 + 0x148], %f6; \
|
||||
DES_ROUND(40, 42, X, X) \
|
||||
ldd [%o0 + 0x150], %f8; \
|
||||
ldd [%o0 + 0x158], %f10; \
|
||||
DES_ROUND(44, 46, X, X) \
|
||||
ldd [%o0 + 0x160], %f12; \
|
||||
ldd [%o0 + 0x168], %f14; \
|
||||
DES_ROUND(48, 50, X, X) \
|
||||
DES_ROUND(52, 54, X, X) \
|
||||
DES_ROUND(56, 58, X, X) \
|
||||
DES_ROUND(16, 18, X, X) \
|
||||
ldd [%o0 + 0x170], %f16; \
|
||||
ldd [%o0 + 0x178], %f18; \
|
||||
DES_IIP(X, X) \
|
||||
DES_IP(X, X) \
|
||||
DES_ROUND(20, 22, X, X) \
|
||||
ldd [%o0 + 0x50], %f20; \
|
||||
ldd [%o0 + 0x58], %f22; \
|
||||
DES_ROUND(24, 26, X, X) \
|
||||
ldd [%o0 + 0x60], %f24; \
|
||||
ldd [%o0 + 0x68], %f26; \
|
||||
DES_ROUND(28, 30, X, X) \
|
||||
ldd [%o0 + 0x70], %f28; \
|
||||
ldd [%o0 + 0x78], %f30; \
|
||||
DES_ROUND(0, 2, X, X) \
|
||||
ldd [%o0 + 0x00], %f0; \
|
||||
ldd [%o0 + 0x08], %f2; \
|
||||
DES_ROUND(4, 6, X, X) \
|
||||
ldd [%o0 + 0x10], %f4; \
|
||||
ldd [%o0 + 0x18], %f6; \
|
||||
DES_ROUND(8, 10, X, X) \
|
||||
ldd [%o0 + 0x20], %f8; \
|
||||
ldd [%o0 + 0x28], %f10; \
|
||||
DES_ROUND(12, 14, X, X) \
|
||||
ldd [%o0 + 0x30], %f12; \
|
||||
ldd [%o0 + 0x38], %f14; \
|
||||
DES_ROUND(16, 18, X, X) \
|
||||
ldd [%o0 + 0x40], %f16; \
|
||||
ldd [%o0 + 0x48], %f18; \
|
||||
DES_IIP(X, X)
|
||||
|
||||
.align 32
|
||||
ENTRY(des3_ede_sparc64_ecb_crypt)
|
||||
/* %o0=key, %o1=input, %o2=output, %o3=len */
|
||||
1: ldd [%o1 + 0x00], %f60
|
||||
DES3_LOOP_BODY(60)
|
||||
std %f60, [%o2 + 0x00]
|
||||
add %o1, 0x08, %o1
|
||||
subcc %o3, 0x08, %o3
|
||||
bne,pt %icc, 1b
|
||||
add %o2, 0x08, %o2
|
||||
retl
|
||||
nop
|
||||
ENDPROC(des3_ede_sparc64_ecb_crypt)
|
||||
|
||||
.align 32
|
||||
ENTRY(des3_ede_sparc64_cbc_encrypt)
|
||||
/* %o0=key, %o1=input, %o2=output, %o3=len, %o4=IV */
|
||||
ldd [%o4 + 0x00], %f60
|
||||
1: ldd [%o1 + 0x00], %f62
|
||||
fxor %f60, %f62, %f60
|
||||
DES3_LOOP_BODY(60)
|
||||
std %f60, [%o2 + 0x00]
|
||||
add %o1, 0x08, %o1
|
||||
subcc %o3, 0x08, %o3
|
||||
bne,pt %icc, 1b
|
||||
add %o2, 0x08, %o2
|
||||
retl
|
||||
std %f60, [%o4 + 0x00]
|
||||
ENDPROC(des3_ede_sparc64_cbc_encrypt)
|
||||
|
||||
.align 32
|
||||
ENTRY(des3_ede_sparc64_cbc_decrypt)
|
||||
/* %o0=key, %o1=input, %o2=output, %o3=len, %o4=IV */
|
||||
ldd [%o4 + 0x00], %f62
|
||||
1: ldx [%o1 + 0x00], %g1
|
||||
MOVXTOD_G1_F60
|
||||
DES3_LOOP_BODY(60)
|
||||
fxor %f62, %f60, %f60
|
||||
MOVXTOD_G1_F62
|
||||
std %f60, [%o2 + 0x00]
|
||||
add %o1, 0x08, %o1
|
||||
subcc %o3, 0x08, %o3
|
||||
bne,pt %icc, 1b
|
||||
add %o2, 0x08, %o2
|
||||
retl
|
||||
stx %g1, [%o4 + 0x00]
|
||||
ENDPROC(des3_ede_sparc64_cbc_decrypt)
|
537
arch/sparc/crypto/des_glue.c
Normal file
537
arch/sparc/crypto/des_glue.c
Normal file
|
@ -0,0 +1,537 @@
|
|||
/* Glue code for DES encryption optimized for sparc64 crypto opcodes.
|
||||
*
|
||||
* Copyright (C) 2012 David S. Miller <davem@davemloft.net>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/types.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/des.h>
|
||||
|
||||
#include <asm/fpumacro.h>
|
||||
#include <asm/pstate.h>
|
||||
#include <asm/elf.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
struct des_sparc64_ctx {
|
||||
u64 encrypt_expkey[DES_EXPKEY_WORDS / 2];
|
||||
u64 decrypt_expkey[DES_EXPKEY_WORDS / 2];
|
||||
};
|
||||
|
||||
struct des3_ede_sparc64_ctx {
|
||||
u64 encrypt_expkey[DES3_EDE_EXPKEY_WORDS / 2];
|
||||
u64 decrypt_expkey[DES3_EDE_EXPKEY_WORDS / 2];
|
||||
};
|
||||
|
||||
static void encrypt_to_decrypt(u64 *d, const u64 *e)
|
||||
{
|
||||
const u64 *s = e + (DES_EXPKEY_WORDS / 2) - 1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DES_EXPKEY_WORDS / 2; i++)
|
||||
*d++ = *s--;
|
||||
}
|
||||
|
||||
extern void des_sparc64_key_expand(const u32 *input_key, u64 *key);
|
||||
|
||||
static int des_set_key(struct crypto_tfm *tfm, const u8 *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
struct des_sparc64_ctx *dctx = crypto_tfm_ctx(tfm);
|
||||
u32 *flags = &tfm->crt_flags;
|
||||
u32 tmp[DES_EXPKEY_WORDS];
|
||||
int ret;
|
||||
|
||||
/* Even though we have special instructions for key expansion,
|
||||
* we call des_ekey() so that we don't have to write our own
|
||||
* weak key detection code.
|
||||
*/
|
||||
ret = des_ekey(tmp, key);
|
||||
if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
|
||||
*flags |= CRYPTO_TFM_RES_WEAK_KEY;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
des_sparc64_key_expand((const u32 *) key, &dctx->encrypt_expkey[0]);
|
||||
encrypt_to_decrypt(&dctx->decrypt_expkey[0], &dctx->encrypt_expkey[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void des_sparc64_crypt(const u64 *key, const u64 *input,
|
||||
u64 *output);
|
||||
|
||||
static void des_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||
{
|
||||
struct des_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
const u64 *K = ctx->encrypt_expkey;
|
||||
|
||||
des_sparc64_crypt(K, (const u64 *) src, (u64 *) dst);
|
||||
}
|
||||
|
||||
static void des_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||
{
|
||||
struct des_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
const u64 *K = ctx->decrypt_expkey;
|
||||
|
||||
des_sparc64_crypt(K, (const u64 *) src, (u64 *) dst);
|
||||
}
|
||||
|
||||
extern void des_sparc64_load_keys(const u64 *key);
|
||||
|
||||
extern void des_sparc64_ecb_crypt(const u64 *input, u64 *output,
|
||||
unsigned int len);
|
||||
|
||||
#define DES_BLOCK_MASK (~(DES_BLOCK_SIZE - 1))
|
||||
|
||||
static int __ecb_crypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes, bool encrypt)
|
||||
{
|
||||
struct des_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
if (encrypt)
|
||||
des_sparc64_load_keys(&ctx->encrypt_expkey[0]);
|
||||
else
|
||||
des_sparc64_load_keys(&ctx->decrypt_expkey[0]);
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
unsigned int block_len = nbytes & DES_BLOCK_MASK;
|
||||
|
||||
if (likely(block_len)) {
|
||||
des_sparc64_ecb_crypt((const u64 *)walk.src.virt.addr,
|
||||
(u64 *) walk.dst.virt.addr,
|
||||
block_len);
|
||||
}
|
||||
nbytes &= DES_BLOCK_SIZE - 1;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
fprs_write(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ecb_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
return __ecb_crypt(desc, dst, src, nbytes, true);
|
||||
}
|
||||
|
||||
static int ecb_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
return __ecb_crypt(desc, dst, src, nbytes, false);
|
||||
}
|
||||
|
||||
extern void des_sparc64_cbc_encrypt(const u64 *input, u64 *output,
|
||||
unsigned int len, u64 *iv);
|
||||
|
||||
static int cbc_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct des_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
des_sparc64_load_keys(&ctx->encrypt_expkey[0]);
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
unsigned int block_len = nbytes & DES_BLOCK_MASK;
|
||||
|
||||
if (likely(block_len)) {
|
||||
des_sparc64_cbc_encrypt((const u64 *)walk.src.virt.addr,
|
||||
(u64 *) walk.dst.virt.addr,
|
||||
block_len, (u64 *) walk.iv);
|
||||
}
|
||||
nbytes &= DES_BLOCK_SIZE - 1;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
fprs_write(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
extern void des_sparc64_cbc_decrypt(const u64 *input, u64 *output,
|
||||
unsigned int len, u64 *iv);
|
||||
|
||||
static int cbc_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct des_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
des_sparc64_load_keys(&ctx->decrypt_expkey[0]);
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
unsigned int block_len = nbytes & DES_BLOCK_MASK;
|
||||
|
||||
if (likely(block_len)) {
|
||||
des_sparc64_cbc_decrypt((const u64 *)walk.src.virt.addr,
|
||||
(u64 *) walk.dst.virt.addr,
|
||||
block_len, (u64 *) walk.iv);
|
||||
}
|
||||
nbytes &= DES_BLOCK_SIZE - 1;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
fprs_write(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int des3_ede_set_key(struct crypto_tfm *tfm, const u8 *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
struct des3_ede_sparc64_ctx *dctx = crypto_tfm_ctx(tfm);
|
||||
const u32 *K = (const u32 *)key;
|
||||
u32 *flags = &tfm->crt_flags;
|
||||
u64 k1[DES_EXPKEY_WORDS / 2];
|
||||
u64 k2[DES_EXPKEY_WORDS / 2];
|
||||
u64 k3[DES_EXPKEY_WORDS / 2];
|
||||
|
||||
if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
|
||||
!((K[2] ^ K[4]) | (K[3] ^ K[5]))) &&
|
||||
(*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
|
||||
*flags |= CRYPTO_TFM_RES_WEAK_KEY;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
des_sparc64_key_expand((const u32 *)key, k1);
|
||||
key += DES_KEY_SIZE;
|
||||
des_sparc64_key_expand((const u32 *)key, k2);
|
||||
key += DES_KEY_SIZE;
|
||||
des_sparc64_key_expand((const u32 *)key, k3);
|
||||
|
||||
memcpy(&dctx->encrypt_expkey[0], &k1[0], sizeof(k1));
|
||||
encrypt_to_decrypt(&dctx->encrypt_expkey[DES_EXPKEY_WORDS / 2], &k2[0]);
|
||||
memcpy(&dctx->encrypt_expkey[(DES_EXPKEY_WORDS / 2) * 2],
|
||||
&k3[0], sizeof(k3));
|
||||
|
||||
encrypt_to_decrypt(&dctx->decrypt_expkey[0], &k3[0]);
|
||||
memcpy(&dctx->decrypt_expkey[DES_EXPKEY_WORDS / 2],
|
||||
&k2[0], sizeof(k2));
|
||||
encrypt_to_decrypt(&dctx->decrypt_expkey[(DES_EXPKEY_WORDS / 2) * 2],
|
||||
&k1[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void des3_ede_sparc64_crypt(const u64 *key, const u64 *input,
|
||||
u64 *output);
|
||||
|
||||
static void des3_ede_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||
{
|
||||
struct des3_ede_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
const u64 *K = ctx->encrypt_expkey;
|
||||
|
||||
des3_ede_sparc64_crypt(K, (const u64 *) src, (u64 *) dst);
|
||||
}
|
||||
|
||||
static void des3_ede_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||
{
|
||||
struct des3_ede_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
const u64 *K = ctx->decrypt_expkey;
|
||||
|
||||
des3_ede_sparc64_crypt(K, (const u64 *) src, (u64 *) dst);
|
||||
}
|
||||
|
||||
extern void des3_ede_sparc64_load_keys(const u64 *key);
|
||||
|
||||
extern void des3_ede_sparc64_ecb_crypt(const u64 *expkey, const u64 *input,
|
||||
u64 *output, unsigned int len);
|
||||
|
||||
static int __ecb3_crypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes, bool encrypt)
|
||||
{
|
||||
struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
const u64 *K;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
if (encrypt)
|
||||
K = &ctx->encrypt_expkey[0];
|
||||
else
|
||||
K = &ctx->decrypt_expkey[0];
|
||||
des3_ede_sparc64_load_keys(K);
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
unsigned int block_len = nbytes & DES_BLOCK_MASK;
|
||||
|
||||
if (likely(block_len)) {
|
||||
const u64 *src64 = (const u64 *)walk.src.virt.addr;
|
||||
des3_ede_sparc64_ecb_crypt(K, src64,
|
||||
(u64 *) walk.dst.virt.addr,
|
||||
block_len);
|
||||
}
|
||||
nbytes &= DES_BLOCK_SIZE - 1;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
fprs_write(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ecb3_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
return __ecb3_crypt(desc, dst, src, nbytes, true);
|
||||
}
|
||||
|
||||
static int ecb3_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
return __ecb3_crypt(desc, dst, src, nbytes, false);
|
||||
}
|
||||
|
||||
extern void des3_ede_sparc64_cbc_encrypt(const u64 *expkey, const u64 *input,
|
||||
u64 *output, unsigned int len,
|
||||
u64 *iv);
|
||||
|
||||
static int cbc3_encrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
const u64 *K;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
K = &ctx->encrypt_expkey[0];
|
||||
des3_ede_sparc64_load_keys(K);
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
unsigned int block_len = nbytes & DES_BLOCK_MASK;
|
||||
|
||||
if (likely(block_len)) {
|
||||
const u64 *src64 = (const u64 *)walk.src.virt.addr;
|
||||
des3_ede_sparc64_cbc_encrypt(K, src64,
|
||||
(u64 *) walk.dst.virt.addr,
|
||||
block_len,
|
||||
(u64 *) walk.iv);
|
||||
}
|
||||
nbytes &= DES_BLOCK_SIZE - 1;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
fprs_write(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
extern void des3_ede_sparc64_cbc_decrypt(const u64 *expkey, const u64 *input,
|
||||
u64 *output, unsigned int len,
|
||||
u64 *iv);
|
||||
|
||||
static int cbc3_decrypt(struct blkcipher_desc *desc,
|
||||
struct scatterlist *dst, struct scatterlist *src,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
struct blkcipher_walk walk;
|
||||
const u64 *K;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
K = &ctx->decrypt_expkey[0];
|
||||
des3_ede_sparc64_load_keys(K);
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
unsigned int block_len = nbytes & DES_BLOCK_MASK;
|
||||
|
||||
if (likely(block_len)) {
|
||||
const u64 *src64 = (const u64 *)walk.src.virt.addr;
|
||||
des3_ede_sparc64_cbc_decrypt(K, src64,
|
||||
(u64 *) walk.dst.virt.addr,
|
||||
block_len,
|
||||
(u64 *) walk.iv);
|
||||
}
|
||||
nbytes &= DES_BLOCK_SIZE - 1;
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
fprs_write(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct crypto_alg algs[] = { {
|
||||
.cra_name = "des",
|
||||
.cra_driver_name = "des-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
|
||||
.cra_blocksize = DES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct des_sparc64_ctx),
|
||||
.cra_alignmask = 7,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.cipher = {
|
||||
.cia_min_keysize = DES_KEY_SIZE,
|
||||
.cia_max_keysize = DES_KEY_SIZE,
|
||||
.cia_setkey = des_set_key,
|
||||
.cia_encrypt = des_encrypt,
|
||||
.cia_decrypt = des_decrypt
|
||||
}
|
||||
}
|
||||
}, {
|
||||
.cra_name = "ecb(des)",
|
||||
.cra_driver_name = "ecb-des-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = DES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct des_sparc64_ctx),
|
||||
.cra_alignmask = 7,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = DES_KEY_SIZE,
|
||||
.max_keysize = DES_KEY_SIZE,
|
||||
.setkey = des_set_key,
|
||||
.encrypt = ecb_encrypt,
|
||||
.decrypt = ecb_decrypt,
|
||||
},
|
||||
},
|
||||
}, {
|
||||
.cra_name = "cbc(des)",
|
||||
.cra_driver_name = "cbc-des-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = DES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct des_sparc64_ctx),
|
||||
.cra_alignmask = 7,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = DES_KEY_SIZE,
|
||||
.max_keysize = DES_KEY_SIZE,
|
||||
.setkey = des_set_key,
|
||||
.encrypt = cbc_encrypt,
|
||||
.decrypt = cbc_decrypt,
|
||||
},
|
||||
},
|
||||
}, {
|
||||
.cra_name = "des3_ede",
|
||||
.cra_driver_name = "des3_ede-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
|
||||
.cra_blocksize = DES3_EDE_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx),
|
||||
.cra_alignmask = 7,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.cipher = {
|
||||
.cia_min_keysize = DES3_EDE_KEY_SIZE,
|
||||
.cia_max_keysize = DES3_EDE_KEY_SIZE,
|
||||
.cia_setkey = des3_ede_set_key,
|
||||
.cia_encrypt = des3_ede_encrypt,
|
||||
.cia_decrypt = des3_ede_decrypt
|
||||
}
|
||||
}
|
||||
}, {
|
||||
.cra_name = "ecb(des3_ede)",
|
||||
.cra_driver_name = "ecb-des3_ede-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = DES3_EDE_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx),
|
||||
.cra_alignmask = 7,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = DES3_EDE_KEY_SIZE,
|
||||
.max_keysize = DES3_EDE_KEY_SIZE,
|
||||
.setkey = des3_ede_set_key,
|
||||
.encrypt = ecb3_encrypt,
|
||||
.decrypt = ecb3_decrypt,
|
||||
},
|
||||
},
|
||||
}, {
|
||||
.cra_name = "cbc(des3_ede)",
|
||||
.cra_driver_name = "cbc-des3_ede-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = DES3_EDE_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx),
|
||||
.cra_alignmask = 7,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = DES3_EDE_KEY_SIZE,
|
||||
.max_keysize = DES3_EDE_KEY_SIZE,
|
||||
.setkey = des3_ede_set_key,
|
||||
.encrypt = cbc3_encrypt,
|
||||
.decrypt = cbc3_decrypt,
|
||||
},
|
||||
},
|
||||
} };
|
||||
|
||||
static bool __init sparc64_has_des_opcode(void)
|
||||
{
|
||||
unsigned long cfr;
|
||||
|
||||
if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
|
||||
return false;
|
||||
|
||||
__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
|
||||
if (!(cfr & CFR_DES))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __init des_sparc64_mod_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(algs); i++)
|
||||
INIT_LIST_HEAD(&algs[i].cra_list);
|
||||
|
||||
if (sparc64_has_des_opcode()) {
|
||||
pr_info("Using sparc64 des opcodes optimized DES implementation\n");
|
||||
return crypto_register_algs(algs, ARRAY_SIZE(algs));
|
||||
}
|
||||
pr_info("sparc64 des opcodes not available.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void __exit des_sparc64_mod_fini(void)
|
||||
{
|
||||
crypto_unregister_algs(algs, ARRAY_SIZE(algs));
|
||||
}
|
||||
|
||||
module_init(des_sparc64_mod_init);
|
||||
module_exit(des_sparc64_mod_fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated");
|
||||
|
||||
MODULE_ALIAS_CRYPTO("des");
|
||||
|
||||
#include "crop_devid.c"
|
70
arch/sparc/crypto/md5_asm.S
Normal file
70
arch/sparc/crypto/md5_asm.S
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include <linux/linkage.h>
|
||||
#include <asm/visasm.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
ENTRY(md5_sparc64_transform)
|
||||
/* %o0 = digest, %o1 = data, %o2 = rounds */
|
||||
VISEntryHalf
|
||||
ld [%o0 + 0x00], %f0
|
||||
ld [%o0 + 0x04], %f1
|
||||
andcc %o1, 0x7, %g0
|
||||
ld [%o0 + 0x08], %f2
|
||||
bne,pn %xcc, 10f
|
||||
ld [%o0 + 0x0c], %f3
|
||||
|
||||
1:
|
||||
ldd [%o1 + 0x00], %f8
|
||||
ldd [%o1 + 0x08], %f10
|
||||
ldd [%o1 + 0x10], %f12
|
||||
ldd [%o1 + 0x18], %f14
|
||||
ldd [%o1 + 0x20], %f16
|
||||
ldd [%o1 + 0x28], %f18
|
||||
ldd [%o1 + 0x30], %f20
|
||||
ldd [%o1 + 0x38], %f22
|
||||
|
||||
MD5
|
||||
|
||||
subcc %o2, 1, %o2
|
||||
bne,pt %xcc, 1b
|
||||
add %o1, 0x40, %o1
|
||||
|
||||
5:
|
||||
st %f0, [%o0 + 0x00]
|
||||
st %f1, [%o0 + 0x04]
|
||||
st %f2, [%o0 + 0x08]
|
||||
st %f3, [%o0 + 0x0c]
|
||||
retl
|
||||
VISExitHalf
|
||||
10:
|
||||
alignaddr %o1, %g0, %o1
|
||||
|
||||
ldd [%o1 + 0x00], %f10
|
||||
1:
|
||||
ldd [%o1 + 0x08], %f12
|
||||
ldd [%o1 + 0x10], %f14
|
||||
ldd [%o1 + 0x18], %f16
|
||||
ldd [%o1 + 0x20], %f18
|
||||
ldd [%o1 + 0x28], %f20
|
||||
ldd [%o1 + 0x30], %f22
|
||||
ldd [%o1 + 0x38], %f24
|
||||
ldd [%o1 + 0x40], %f26
|
||||
|
||||
faligndata %f10, %f12, %f8
|
||||
faligndata %f12, %f14, %f10
|
||||
faligndata %f14, %f16, %f12
|
||||
faligndata %f16, %f18, %f14
|
||||
faligndata %f18, %f20, %f16
|
||||
faligndata %f20, %f22, %f18
|
||||
faligndata %f22, %f24, %f20
|
||||
faligndata %f24, %f26, %f22
|
||||
|
||||
MD5
|
||||
|
||||
subcc %o2, 1, %o2
|
||||
fsrc2 %f26, %f10
|
||||
bne,pt %xcc, 1b
|
||||
add %o1, 0x40, %o1
|
||||
|
||||
ba,a,pt %xcc, 5b
|
||||
ENDPROC(md5_sparc64_transform)
|
190
arch/sparc/crypto/md5_glue.c
Normal file
190
arch/sparc/crypto/md5_glue.c
Normal file
|
@ -0,0 +1,190 @@
|
|||
/* Glue code for MD5 hashing optimized for sparc64 crypto opcodes.
|
||||
*
|
||||
* This is based largely upon arch/x86/crypto/sha1_ssse3_glue.c
|
||||
* and crypto/md5.c which are:
|
||||
*
|
||||
* Copyright (c) Alan Smithee.
|
||||
* Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
|
||||
* Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
|
||||
* Copyright (c) Mathias Krause <minipli@googlemail.com>
|
||||
* Copyright (c) Cryptoapi developers.
|
||||
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/cryptohash.h>
|
||||
#include <linux/types.h>
|
||||
#include <crypto/md5.h>
|
||||
|
||||
#include <asm/pstate.h>
|
||||
#include <asm/elf.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
asmlinkage void md5_sparc64_transform(u32 *digest, const char *data,
|
||||
unsigned int rounds);
|
||||
|
||||
static int md5_sparc64_init(struct shash_desc *desc)
|
||||
{
|
||||
struct md5_state *mctx = shash_desc_ctx(desc);
|
||||
|
||||
mctx->hash[0] = cpu_to_le32(0x67452301);
|
||||
mctx->hash[1] = cpu_to_le32(0xefcdab89);
|
||||
mctx->hash[2] = cpu_to_le32(0x98badcfe);
|
||||
mctx->hash[3] = cpu_to_le32(0x10325476);
|
||||
mctx->byte_count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __md5_sparc64_update(struct md5_state *sctx, const u8 *data,
|
||||
unsigned int len, unsigned int partial)
|
||||
{
|
||||
unsigned int done = 0;
|
||||
|
||||
sctx->byte_count += len;
|
||||
if (partial) {
|
||||
done = MD5_HMAC_BLOCK_SIZE - partial;
|
||||
memcpy((u8 *)sctx->block + partial, data, done);
|
||||
md5_sparc64_transform(sctx->hash, (u8 *)sctx->block, 1);
|
||||
}
|
||||
if (len - done >= MD5_HMAC_BLOCK_SIZE) {
|
||||
const unsigned int rounds = (len - done) / MD5_HMAC_BLOCK_SIZE;
|
||||
|
||||
md5_sparc64_transform(sctx->hash, data + done, rounds);
|
||||
done += rounds * MD5_HMAC_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
memcpy(sctx->block, data + done, len - done);
|
||||
}
|
||||
|
||||
static int md5_sparc64_update(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len)
|
||||
{
|
||||
struct md5_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int partial = sctx->byte_count % MD5_HMAC_BLOCK_SIZE;
|
||||
|
||||
/* Handle the fast case right here */
|
||||
if (partial + len < MD5_HMAC_BLOCK_SIZE) {
|
||||
sctx->byte_count += len;
|
||||
memcpy((u8 *)sctx->block + partial, data, len);
|
||||
} else
|
||||
__md5_sparc64_update(sctx, data, len, partial);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add padding and return the message digest. */
|
||||
static int md5_sparc64_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
struct md5_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int i, index, padlen;
|
||||
u32 *dst = (u32 *)out;
|
||||
__le64 bits;
|
||||
static const u8 padding[MD5_HMAC_BLOCK_SIZE] = { 0x80, };
|
||||
|
||||
bits = cpu_to_le64(sctx->byte_count << 3);
|
||||
|
||||
/* Pad out to 56 mod 64 and append length */
|
||||
index = sctx->byte_count % MD5_HMAC_BLOCK_SIZE;
|
||||
padlen = (index < 56) ? (56 - index) : ((MD5_HMAC_BLOCK_SIZE+56) - index);
|
||||
|
||||
/* We need to fill a whole block for __md5_sparc64_update() */
|
||||
if (padlen <= 56) {
|
||||
sctx->byte_count += padlen;
|
||||
memcpy((u8 *)sctx->block + index, padding, padlen);
|
||||
} else {
|
||||
__md5_sparc64_update(sctx, padding, padlen, index);
|
||||
}
|
||||
__md5_sparc64_update(sctx, (const u8 *)&bits, sizeof(bits), 56);
|
||||
|
||||
/* Store state in digest */
|
||||
for (i = 0; i < MD5_HASH_WORDS; i++)
|
||||
dst[i] = sctx->hash[i];
|
||||
|
||||
/* Wipe context */
|
||||
memset(sctx, 0, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int md5_sparc64_export(struct shash_desc *desc, void *out)
|
||||
{
|
||||
struct md5_state *sctx = shash_desc_ctx(desc);
|
||||
|
||||
memcpy(out, sctx, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int md5_sparc64_import(struct shash_desc *desc, const void *in)
|
||||
{
|
||||
struct md5_state *sctx = shash_desc_ctx(desc);
|
||||
|
||||
memcpy(sctx, in, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shash_alg alg = {
|
||||
.digestsize = MD5_DIGEST_SIZE,
|
||||
.init = md5_sparc64_init,
|
||||
.update = md5_sparc64_update,
|
||||
.final = md5_sparc64_final,
|
||||
.export = md5_sparc64_export,
|
||||
.import = md5_sparc64_import,
|
||||
.descsize = sizeof(struct md5_state),
|
||||
.statesize = sizeof(struct md5_state),
|
||||
.base = {
|
||||
.cra_name = "md5",
|
||||
.cra_driver_name= "md5-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = MD5_HMAC_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
static bool __init sparc64_has_md5_opcode(void)
|
||||
{
|
||||
unsigned long cfr;
|
||||
|
||||
if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
|
||||
return false;
|
||||
|
||||
__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
|
||||
if (!(cfr & CFR_MD5))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __init md5_sparc64_mod_init(void)
|
||||
{
|
||||
if (sparc64_has_md5_opcode()) {
|
||||
pr_info("Using sparc64 md5 opcode optimized MD5 implementation\n");
|
||||
return crypto_register_shash(&alg);
|
||||
}
|
||||
pr_info("sparc64 md5 opcode not available.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void __exit md5_sparc64_mod_fini(void)
|
||||
{
|
||||
crypto_unregister_shash(&alg);
|
||||
}
|
||||
|
||||
module_init(md5_sparc64_mod_init);
|
||||
module_exit(md5_sparc64_mod_fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated");
|
||||
|
||||
MODULE_ALIAS_CRYPTO("md5");
|
||||
|
||||
#include "crop_devid.c"
|
99
arch/sparc/crypto/opcodes.h
Normal file
99
arch/sparc/crypto/opcodes.h
Normal file
|
@ -0,0 +1,99 @@
|
|||
#ifndef _OPCODES_H
|
||||
#define _OPCODES_H
|
||||
|
||||
#define SPARC_CR_OPCODE_PRIORITY 300
|
||||
|
||||
#define F3F(x,y,z) (((x)<<30)|((y)<<19)|((z)<<5))
|
||||
|
||||
#define FPD_ENCODE(x) (((x) >> 5) | ((x) & ~(0x20)))
|
||||
|
||||
#define RS1(x) (FPD_ENCODE(x) << 14)
|
||||
#define RS2(x) (FPD_ENCODE(x) << 0)
|
||||
#define RS3(x) (FPD_ENCODE(x) << 9)
|
||||
#define RD(x) (FPD_ENCODE(x) << 25)
|
||||
#define IMM5_0(x) ((x) << 0)
|
||||
#define IMM5_9(x) ((x) << 9)
|
||||
|
||||
#define CRC32C(a,b,c) \
|
||||
.word (F3F(2,0x36,0x147)|RS1(a)|RS2(b)|RD(c));
|
||||
|
||||
#define MD5 \
|
||||
.word 0x81b02800;
|
||||
#define SHA1 \
|
||||
.word 0x81b02820;
|
||||
#define SHA256 \
|
||||
.word 0x81b02840;
|
||||
#define SHA512 \
|
||||
.word 0x81b02860;
|
||||
|
||||
#define AES_EROUND01(a,b,c,d) \
|
||||
.word (F3F(2, 0x19, 0)|RS1(a)|RS2(b)|RS3(c)|RD(d));
|
||||
#define AES_EROUND23(a,b,c,d) \
|
||||
.word (F3F(2, 0x19, 1)|RS1(a)|RS2(b)|RS3(c)|RD(d));
|
||||
#define AES_DROUND01(a,b,c,d) \
|
||||
.word (F3F(2, 0x19, 2)|RS1(a)|RS2(b)|RS3(c)|RD(d));
|
||||
#define AES_DROUND23(a,b,c,d) \
|
||||
.word (F3F(2, 0x19, 3)|RS1(a)|RS2(b)|RS3(c)|RD(d));
|
||||
#define AES_EROUND01_L(a,b,c,d) \
|
||||
.word (F3F(2, 0x19, 4)|RS1(a)|RS2(b)|RS3(c)|RD(d));
|
||||
#define AES_EROUND23_L(a,b,c,d) \
|
||||
.word (F3F(2, 0x19, 5)|RS1(a)|RS2(b)|RS3(c)|RD(d));
|
||||
#define AES_DROUND01_L(a,b,c,d) \
|
||||
.word (F3F(2, 0x19, 6)|RS1(a)|RS2(b)|RS3(c)|RD(d));
|
||||
#define AES_DROUND23_L(a,b,c,d) \
|
||||
.word (F3F(2, 0x19, 7)|RS1(a)|RS2(b)|RS3(c)|RD(d));
|
||||
#define AES_KEXPAND1(a,b,c,d) \
|
||||
.word (F3F(2, 0x19, 8)|RS1(a)|RS2(b)|IMM5_9(c)|RD(d));
|
||||
#define AES_KEXPAND0(a,b,c) \
|
||||
.word (F3F(2, 0x36, 0x130)|RS1(a)|RS2(b)|RD(c));
|
||||
#define AES_KEXPAND2(a,b,c) \
|
||||
.word (F3F(2, 0x36, 0x131)|RS1(a)|RS2(b)|RD(c));
|
||||
|
||||
#define DES_IP(a,b) \
|
||||
.word (F3F(2, 0x36, 0x134)|RS1(a)|RD(b));
|
||||
#define DES_IIP(a,b) \
|
||||
.word (F3F(2, 0x36, 0x135)|RS1(a)|RD(b));
|
||||
#define DES_KEXPAND(a,b,c) \
|
||||
.word (F3F(2, 0x36, 0x136)|RS1(a)|IMM5_0(b)|RD(c));
|
||||
#define DES_ROUND(a,b,c,d) \
|
||||
.word (F3F(2, 0x19, 0x009)|RS1(a)|RS2(b)|RS3(c)|RD(d));
|
||||
|
||||
#define CAMELLIA_F(a,b,c,d) \
|
||||
.word (F3F(2, 0x19, 0x00c)|RS1(a)|RS2(b)|RS3(c)|RD(d));
|
||||
#define CAMELLIA_FL(a,b,c) \
|
||||
.word (F3F(2, 0x36, 0x13c)|RS1(a)|RS2(b)|RD(c));
|
||||
#define CAMELLIA_FLI(a,b,c) \
|
||||
.word (F3F(2, 0x36, 0x13d)|RS1(a)|RS2(b)|RD(c));
|
||||
|
||||
#define MOVDTOX_F0_O4 \
|
||||
.word 0x99b02200
|
||||
#define MOVDTOX_F2_O5 \
|
||||
.word 0x9bb02202
|
||||
#define MOVXTOD_G1_F60 \
|
||||
.word 0xbbb02301
|
||||
#define MOVXTOD_G1_F62 \
|
||||
.word 0xbfb02301
|
||||
#define MOVXTOD_G3_F4 \
|
||||
.word 0x89b02303;
|
||||
#define MOVXTOD_G7_F6 \
|
||||
.word 0x8db02307;
|
||||
#define MOVXTOD_G3_F0 \
|
||||
.word 0x81b02303;
|
||||
#define MOVXTOD_G7_F2 \
|
||||
.word 0x85b02307;
|
||||
#define MOVXTOD_O0_F0 \
|
||||
.word 0x81b02308;
|
||||
#define MOVXTOD_O5_F0 \
|
||||
.word 0x81b0230d;
|
||||
#define MOVXTOD_O5_F2 \
|
||||
.word 0x85b0230d;
|
||||
#define MOVXTOD_O5_F4 \
|
||||
.word 0x89b0230d;
|
||||
#define MOVXTOD_O5_F6 \
|
||||
.word 0x8db0230d;
|
||||
#define MOVXTOD_G3_F60 \
|
||||
.word 0xbbb02303;
|
||||
#define MOVXTOD_G7_F62 \
|
||||
.word 0xbfb02307;
|
||||
|
||||
#endif /* _OPCODES_H */
|
72
arch/sparc/crypto/sha1_asm.S
Normal file
72
arch/sparc/crypto/sha1_asm.S
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include <linux/linkage.h>
|
||||
#include <asm/visasm.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
ENTRY(sha1_sparc64_transform)
|
||||
/* %o0 = digest, %o1 = data, %o2 = rounds */
|
||||
VISEntryHalf
|
||||
ld [%o0 + 0x00], %f0
|
||||
ld [%o0 + 0x04], %f1
|
||||
ld [%o0 + 0x08], %f2
|
||||
andcc %o1, 0x7, %g0
|
||||
ld [%o0 + 0x0c], %f3
|
||||
bne,pn %xcc, 10f
|
||||
ld [%o0 + 0x10], %f4
|
||||
|
||||
1:
|
||||
ldd [%o1 + 0x00], %f8
|
||||
ldd [%o1 + 0x08], %f10
|
||||
ldd [%o1 + 0x10], %f12
|
||||
ldd [%o1 + 0x18], %f14
|
||||
ldd [%o1 + 0x20], %f16
|
||||
ldd [%o1 + 0x28], %f18
|
||||
ldd [%o1 + 0x30], %f20
|
||||
ldd [%o1 + 0x38], %f22
|
||||
|
||||
SHA1
|
||||
|
||||
subcc %o2, 1, %o2
|
||||
bne,pt %xcc, 1b
|
||||
add %o1, 0x40, %o1
|
||||
|
||||
5:
|
||||
st %f0, [%o0 + 0x00]
|
||||
st %f1, [%o0 + 0x04]
|
||||
st %f2, [%o0 + 0x08]
|
||||
st %f3, [%o0 + 0x0c]
|
||||
st %f4, [%o0 + 0x10]
|
||||
retl
|
||||
VISExitHalf
|
||||
10:
|
||||
alignaddr %o1, %g0, %o1
|
||||
|
||||
ldd [%o1 + 0x00], %f10
|
||||
1:
|
||||
ldd [%o1 + 0x08], %f12
|
||||
ldd [%o1 + 0x10], %f14
|
||||
ldd [%o1 + 0x18], %f16
|
||||
ldd [%o1 + 0x20], %f18
|
||||
ldd [%o1 + 0x28], %f20
|
||||
ldd [%o1 + 0x30], %f22
|
||||
ldd [%o1 + 0x38], %f24
|
||||
ldd [%o1 + 0x40], %f26
|
||||
|
||||
faligndata %f10, %f12, %f8
|
||||
faligndata %f12, %f14, %f10
|
||||
faligndata %f14, %f16, %f12
|
||||
faligndata %f16, %f18, %f14
|
||||
faligndata %f18, %f20, %f16
|
||||
faligndata %f20, %f22, %f18
|
||||
faligndata %f22, %f24, %f20
|
||||
faligndata %f24, %f26, %f22
|
||||
|
||||
SHA1
|
||||
|
||||
subcc %o2, 1, %o2
|
||||
fsrc2 %f26, %f10
|
||||
bne,pt %xcc, 1b
|
||||
add %o1, 0x40, %o1
|
||||
|
||||
ba,a,pt %xcc, 5b
|
||||
ENDPROC(sha1_sparc64_transform)
|
185
arch/sparc/crypto/sha1_glue.c
Normal file
185
arch/sparc/crypto/sha1_glue.c
Normal file
|
@ -0,0 +1,185 @@
|
|||
/* Glue code for SHA1 hashing optimized for sparc64 crypto opcodes.
|
||||
*
|
||||
* This is based largely upon arch/x86/crypto/sha1_ssse3_glue.c
|
||||
*
|
||||
* Copyright (c) Alan Smithee.
|
||||
* Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
|
||||
* Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
|
||||
* Copyright (c) Mathias Krause <minipli@googlemail.com>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/cryptohash.h>
|
||||
#include <linux/types.h>
|
||||
#include <crypto/sha.h>
|
||||
|
||||
#include <asm/pstate.h>
|
||||
#include <asm/elf.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
asmlinkage void sha1_sparc64_transform(u32 *digest, const char *data,
|
||||
unsigned int rounds);
|
||||
|
||||
static int sha1_sparc64_init(struct shash_desc *desc)
|
||||
{
|
||||
struct sha1_state *sctx = shash_desc_ctx(desc);
|
||||
|
||||
*sctx = (struct sha1_state){
|
||||
.state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __sha1_sparc64_update(struct sha1_state *sctx, const u8 *data,
|
||||
unsigned int len, unsigned int partial)
|
||||
{
|
||||
unsigned int done = 0;
|
||||
|
||||
sctx->count += len;
|
||||
if (partial) {
|
||||
done = SHA1_BLOCK_SIZE - partial;
|
||||
memcpy(sctx->buffer + partial, data, done);
|
||||
sha1_sparc64_transform(sctx->state, sctx->buffer, 1);
|
||||
}
|
||||
if (len - done >= SHA1_BLOCK_SIZE) {
|
||||
const unsigned int rounds = (len - done) / SHA1_BLOCK_SIZE;
|
||||
|
||||
sha1_sparc64_transform(sctx->state, data + done, rounds);
|
||||
done += rounds * SHA1_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
memcpy(sctx->buffer, data + done, len - done);
|
||||
}
|
||||
|
||||
static int sha1_sparc64_update(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len)
|
||||
{
|
||||
struct sha1_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int partial = sctx->count % SHA1_BLOCK_SIZE;
|
||||
|
||||
/* Handle the fast case right here */
|
||||
if (partial + len < SHA1_BLOCK_SIZE) {
|
||||
sctx->count += len;
|
||||
memcpy(sctx->buffer + partial, data, len);
|
||||
} else
|
||||
__sha1_sparc64_update(sctx, data, len, partial);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add padding and return the message digest. */
|
||||
static int sha1_sparc64_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
struct sha1_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int i, index, padlen;
|
||||
__be32 *dst = (__be32 *)out;
|
||||
__be64 bits;
|
||||
static const u8 padding[SHA1_BLOCK_SIZE] = { 0x80, };
|
||||
|
||||
bits = cpu_to_be64(sctx->count << 3);
|
||||
|
||||
/* Pad out to 56 mod 64 and append length */
|
||||
index = sctx->count % SHA1_BLOCK_SIZE;
|
||||
padlen = (index < 56) ? (56 - index) : ((SHA1_BLOCK_SIZE+56) - index);
|
||||
|
||||
/* We need to fill a whole block for __sha1_sparc64_update() */
|
||||
if (padlen <= 56) {
|
||||
sctx->count += padlen;
|
||||
memcpy(sctx->buffer + index, padding, padlen);
|
||||
} else {
|
||||
__sha1_sparc64_update(sctx, padding, padlen, index);
|
||||
}
|
||||
__sha1_sparc64_update(sctx, (const u8 *)&bits, sizeof(bits), 56);
|
||||
|
||||
/* Store state in digest */
|
||||
for (i = 0; i < 5; i++)
|
||||
dst[i] = cpu_to_be32(sctx->state[i]);
|
||||
|
||||
/* Wipe context */
|
||||
memset(sctx, 0, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha1_sparc64_export(struct shash_desc *desc, void *out)
|
||||
{
|
||||
struct sha1_state *sctx = shash_desc_ctx(desc);
|
||||
|
||||
memcpy(out, sctx, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha1_sparc64_import(struct shash_desc *desc, const void *in)
|
||||
{
|
||||
struct sha1_state *sctx = shash_desc_ctx(desc);
|
||||
|
||||
memcpy(sctx, in, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shash_alg alg = {
|
||||
.digestsize = SHA1_DIGEST_SIZE,
|
||||
.init = sha1_sparc64_init,
|
||||
.update = sha1_sparc64_update,
|
||||
.final = sha1_sparc64_final,
|
||||
.export = sha1_sparc64_export,
|
||||
.import = sha1_sparc64_import,
|
||||
.descsize = sizeof(struct sha1_state),
|
||||
.statesize = sizeof(struct sha1_state),
|
||||
.base = {
|
||||
.cra_name = "sha1",
|
||||
.cra_driver_name= "sha1-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA1_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
static bool __init sparc64_has_sha1_opcode(void)
|
||||
{
|
||||
unsigned long cfr;
|
||||
|
||||
if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
|
||||
return false;
|
||||
|
||||
__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
|
||||
if (!(cfr & CFR_SHA1))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __init sha1_sparc64_mod_init(void)
|
||||
{
|
||||
if (sparc64_has_sha1_opcode()) {
|
||||
pr_info("Using sparc64 sha1 opcode optimized SHA-1 implementation\n");
|
||||
return crypto_register_shash(&alg);
|
||||
}
|
||||
pr_info("sparc64 sha1 opcode not available.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void __exit sha1_sparc64_mod_fini(void)
|
||||
{
|
||||
crypto_unregister_shash(&alg);
|
||||
}
|
||||
|
||||
module_init(sha1_sparc64_mod_init);
|
||||
module_exit(sha1_sparc64_mod_fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated");
|
||||
|
||||
MODULE_ALIAS_CRYPTO("sha1");
|
||||
|
||||
#include "crop_devid.c"
|
78
arch/sparc/crypto/sha256_asm.S
Normal file
78
arch/sparc/crypto/sha256_asm.S
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include <linux/linkage.h>
|
||||
#include <asm/visasm.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
ENTRY(sha256_sparc64_transform)
|
||||
/* %o0 = digest, %o1 = data, %o2 = rounds */
|
||||
VISEntryHalf
|
||||
ld [%o0 + 0x00], %f0
|
||||
ld [%o0 + 0x04], %f1
|
||||
ld [%o0 + 0x08], %f2
|
||||
ld [%o0 + 0x0c], %f3
|
||||
ld [%o0 + 0x10], %f4
|
||||
ld [%o0 + 0x14], %f5
|
||||
andcc %o1, 0x7, %g0
|
||||
ld [%o0 + 0x18], %f6
|
||||
bne,pn %xcc, 10f
|
||||
ld [%o0 + 0x1c], %f7
|
||||
|
||||
1:
|
||||
ldd [%o1 + 0x00], %f8
|
||||
ldd [%o1 + 0x08], %f10
|
||||
ldd [%o1 + 0x10], %f12
|
||||
ldd [%o1 + 0x18], %f14
|
||||
ldd [%o1 + 0x20], %f16
|
||||
ldd [%o1 + 0x28], %f18
|
||||
ldd [%o1 + 0x30], %f20
|
||||
ldd [%o1 + 0x38], %f22
|
||||
|
||||
SHA256
|
||||
|
||||
subcc %o2, 1, %o2
|
||||
bne,pt %xcc, 1b
|
||||
add %o1, 0x40, %o1
|
||||
|
||||
5:
|
||||
st %f0, [%o0 + 0x00]
|
||||
st %f1, [%o0 + 0x04]
|
||||
st %f2, [%o0 + 0x08]
|
||||
st %f3, [%o0 + 0x0c]
|
||||
st %f4, [%o0 + 0x10]
|
||||
st %f5, [%o0 + 0x14]
|
||||
st %f6, [%o0 + 0x18]
|
||||
st %f7, [%o0 + 0x1c]
|
||||
retl
|
||||
VISExitHalf
|
||||
10:
|
||||
alignaddr %o1, %g0, %o1
|
||||
|
||||
ldd [%o1 + 0x00], %f10
|
||||
1:
|
||||
ldd [%o1 + 0x08], %f12
|
||||
ldd [%o1 + 0x10], %f14
|
||||
ldd [%o1 + 0x18], %f16
|
||||
ldd [%o1 + 0x20], %f18
|
||||
ldd [%o1 + 0x28], %f20
|
||||
ldd [%o1 + 0x30], %f22
|
||||
ldd [%o1 + 0x38], %f24
|
||||
ldd [%o1 + 0x40], %f26
|
||||
|
||||
faligndata %f10, %f12, %f8
|
||||
faligndata %f12, %f14, %f10
|
||||
faligndata %f14, %f16, %f12
|
||||
faligndata %f16, %f18, %f14
|
||||
faligndata %f18, %f20, %f16
|
||||
faligndata %f20, %f22, %f18
|
||||
faligndata %f22, %f24, %f20
|
||||
faligndata %f24, %f26, %f22
|
||||
|
||||
SHA256
|
||||
|
||||
subcc %o2, 1, %o2
|
||||
fsrc2 %f26, %f10
|
||||
bne,pt %xcc, 1b
|
||||
add %o1, 0x40, %o1
|
||||
|
||||
ba,a,pt %xcc, 5b
|
||||
ENDPROC(sha256_sparc64_transform)
|
243
arch/sparc/crypto/sha256_glue.c
Normal file
243
arch/sparc/crypto/sha256_glue.c
Normal file
|
@ -0,0 +1,243 @@
|
|||
/* Glue code for SHA256 hashing optimized for sparc64 crypto opcodes.
|
||||
*
|
||||
* This is based largely upon crypto/sha256_generic.c
|
||||
*
|
||||
* Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
|
||||
* Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
|
||||
* Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
|
||||
* SHA224 Support Copyright 2007 Intel Corporation <jonathan.lynch@intel.com>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/cryptohash.h>
|
||||
#include <linux/types.h>
|
||||
#include <crypto/sha.h>
|
||||
|
||||
#include <asm/pstate.h>
|
||||
#include <asm/elf.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
asmlinkage void sha256_sparc64_transform(u32 *digest, const char *data,
|
||||
unsigned int rounds);
|
||||
|
||||
static int sha224_sparc64_init(struct shash_desc *desc)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
sctx->state[0] = SHA224_H0;
|
||||
sctx->state[1] = SHA224_H1;
|
||||
sctx->state[2] = SHA224_H2;
|
||||
sctx->state[3] = SHA224_H3;
|
||||
sctx->state[4] = SHA224_H4;
|
||||
sctx->state[5] = SHA224_H5;
|
||||
sctx->state[6] = SHA224_H6;
|
||||
sctx->state[7] = SHA224_H7;
|
||||
sctx->count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha256_sparc64_init(struct shash_desc *desc)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
sctx->state[0] = SHA256_H0;
|
||||
sctx->state[1] = SHA256_H1;
|
||||
sctx->state[2] = SHA256_H2;
|
||||
sctx->state[3] = SHA256_H3;
|
||||
sctx->state[4] = SHA256_H4;
|
||||
sctx->state[5] = SHA256_H5;
|
||||
sctx->state[6] = SHA256_H6;
|
||||
sctx->state[7] = SHA256_H7;
|
||||
sctx->count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __sha256_sparc64_update(struct sha256_state *sctx, const u8 *data,
|
||||
unsigned int len, unsigned int partial)
|
||||
{
|
||||
unsigned int done = 0;
|
||||
|
||||
sctx->count += len;
|
||||
if (partial) {
|
||||
done = SHA256_BLOCK_SIZE - partial;
|
||||
memcpy(sctx->buf + partial, data, done);
|
||||
sha256_sparc64_transform(sctx->state, sctx->buf, 1);
|
||||
}
|
||||
if (len - done >= SHA256_BLOCK_SIZE) {
|
||||
const unsigned int rounds = (len - done) / SHA256_BLOCK_SIZE;
|
||||
|
||||
sha256_sparc64_transform(sctx->state, data + done, rounds);
|
||||
done += rounds * SHA256_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
memcpy(sctx->buf, data + done, len - done);
|
||||
}
|
||||
|
||||
static int sha256_sparc64_update(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int partial = sctx->count % SHA256_BLOCK_SIZE;
|
||||
|
||||
/* Handle the fast case right here */
|
||||
if (partial + len < SHA256_BLOCK_SIZE) {
|
||||
sctx->count += len;
|
||||
memcpy(sctx->buf + partial, data, len);
|
||||
} else
|
||||
__sha256_sparc64_update(sctx, data, len, partial);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha256_sparc64_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int i, index, padlen;
|
||||
__be32 *dst = (__be32 *)out;
|
||||
__be64 bits;
|
||||
static const u8 padding[SHA256_BLOCK_SIZE] = { 0x80, };
|
||||
|
||||
bits = cpu_to_be64(sctx->count << 3);
|
||||
|
||||
/* Pad out to 56 mod 64 and append length */
|
||||
index = sctx->count % SHA256_BLOCK_SIZE;
|
||||
padlen = (index < 56) ? (56 - index) : ((SHA256_BLOCK_SIZE+56) - index);
|
||||
|
||||
/* We need to fill a whole block for __sha256_sparc64_update() */
|
||||
if (padlen <= 56) {
|
||||
sctx->count += padlen;
|
||||
memcpy(sctx->buf + index, padding, padlen);
|
||||
} else {
|
||||
__sha256_sparc64_update(sctx, padding, padlen, index);
|
||||
}
|
||||
__sha256_sparc64_update(sctx, (const u8 *)&bits, sizeof(bits), 56);
|
||||
|
||||
/* Store state in digest */
|
||||
for (i = 0; i < 8; i++)
|
||||
dst[i] = cpu_to_be32(sctx->state[i]);
|
||||
|
||||
/* Wipe context */
|
||||
memset(sctx, 0, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha224_sparc64_final(struct shash_desc *desc, u8 *hash)
|
||||
{
|
||||
u8 D[SHA256_DIGEST_SIZE];
|
||||
|
||||
sha256_sparc64_final(desc, D);
|
||||
|
||||
memcpy(hash, D, SHA224_DIGEST_SIZE);
|
||||
memset(D, 0, SHA256_DIGEST_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha256_sparc64_export(struct shash_desc *desc, void *out)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
|
||||
memcpy(out, sctx, sizeof(*sctx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha256_sparc64_import(struct shash_desc *desc, const void *in)
|
||||
{
|
||||
struct sha256_state *sctx = shash_desc_ctx(desc);
|
||||
|
||||
memcpy(sctx, in, sizeof(*sctx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shash_alg sha256 = {
|
||||
.digestsize = SHA256_DIGEST_SIZE,
|
||||
.init = sha256_sparc64_init,
|
||||
.update = sha256_sparc64_update,
|
||||
.final = sha256_sparc64_final,
|
||||
.export = sha256_sparc64_export,
|
||||
.import = sha256_sparc64_import,
|
||||
.descsize = sizeof(struct sha256_state),
|
||||
.statesize = sizeof(struct sha256_state),
|
||||
.base = {
|
||||
.cra_name = "sha256",
|
||||
.cra_driver_name= "sha256-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA256_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
static struct shash_alg sha224 = {
|
||||
.digestsize = SHA224_DIGEST_SIZE,
|
||||
.init = sha224_sparc64_init,
|
||||
.update = sha256_sparc64_update,
|
||||
.final = sha224_sparc64_final,
|
||||
.descsize = sizeof(struct sha256_state),
|
||||
.base = {
|
||||
.cra_name = "sha224",
|
||||
.cra_driver_name= "sha224-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA224_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
static bool __init sparc64_has_sha256_opcode(void)
|
||||
{
|
||||
unsigned long cfr;
|
||||
|
||||
if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
|
||||
return false;
|
||||
|
||||
__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
|
||||
if (!(cfr & CFR_SHA256))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __init sha256_sparc64_mod_init(void)
|
||||
{
|
||||
if (sparc64_has_sha256_opcode()) {
|
||||
int ret = crypto_register_shash(&sha224);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = crypto_register_shash(&sha256);
|
||||
if (ret < 0) {
|
||||
crypto_unregister_shash(&sha224);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pr_info("Using sparc64 sha256 opcode optimized SHA-256/SHA-224 implementation\n");
|
||||
return 0;
|
||||
}
|
||||
pr_info("sparc64 sha256 opcode not available.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void __exit sha256_sparc64_mod_fini(void)
|
||||
{
|
||||
crypto_unregister_shash(&sha224);
|
||||
crypto_unregister_shash(&sha256);
|
||||
}
|
||||
|
||||
module_init(sha256_sparc64_mod_init);
|
||||
module_exit(sha256_sparc64_mod_fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 opcode accelerated");
|
||||
|
||||
MODULE_ALIAS_CRYPTO("sha224");
|
||||
MODULE_ALIAS_CRYPTO("sha256");
|
||||
|
||||
#include "crop_devid.c"
|
102
arch/sparc/crypto/sha512_asm.S
Normal file
102
arch/sparc/crypto/sha512_asm.S
Normal file
|
@ -0,0 +1,102 @@
|
|||
#include <linux/linkage.h>
|
||||
#include <asm/visasm.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
ENTRY(sha512_sparc64_transform)
|
||||
/* %o0 = digest, %o1 = data, %o2 = rounds */
|
||||
VISEntry
|
||||
ldd [%o0 + 0x00], %f0
|
||||
ldd [%o0 + 0x08], %f2
|
||||
ldd [%o0 + 0x10], %f4
|
||||
ldd [%o0 + 0x18], %f6
|
||||
ldd [%o0 + 0x20], %f8
|
||||
ldd [%o0 + 0x28], %f10
|
||||
andcc %o1, 0x7, %g0
|
||||
ldd [%o0 + 0x30], %f12
|
||||
bne,pn %xcc, 10f
|
||||
ldd [%o0 + 0x38], %f14
|
||||
|
||||
1:
|
||||
ldd [%o1 + 0x00], %f16
|
||||
ldd [%o1 + 0x08], %f18
|
||||
ldd [%o1 + 0x10], %f20
|
||||
ldd [%o1 + 0x18], %f22
|
||||
ldd [%o1 + 0x20], %f24
|
||||
ldd [%o1 + 0x28], %f26
|
||||
ldd [%o1 + 0x30], %f28
|
||||
ldd [%o1 + 0x38], %f30
|
||||
ldd [%o1 + 0x40], %f32
|
||||
ldd [%o1 + 0x48], %f34
|
||||
ldd [%o1 + 0x50], %f36
|
||||
ldd [%o1 + 0x58], %f38
|
||||
ldd [%o1 + 0x60], %f40
|
||||
ldd [%o1 + 0x68], %f42
|
||||
ldd [%o1 + 0x70], %f44
|
||||
ldd [%o1 + 0x78], %f46
|
||||
|
||||
SHA512
|
||||
|
||||
subcc %o2, 1, %o2
|
||||
bne,pt %xcc, 1b
|
||||
add %o1, 0x80, %o1
|
||||
|
||||
5:
|
||||
std %f0, [%o0 + 0x00]
|
||||
std %f2, [%o0 + 0x08]
|
||||
std %f4, [%o0 + 0x10]
|
||||
std %f6, [%o0 + 0x18]
|
||||
std %f8, [%o0 + 0x20]
|
||||
std %f10, [%o0 + 0x28]
|
||||
std %f12, [%o0 + 0x30]
|
||||
std %f14, [%o0 + 0x38]
|
||||
retl
|
||||
VISExit
|
||||
10:
|
||||
alignaddr %o1, %g0, %o1
|
||||
|
||||
ldd [%o1 + 0x00], %f18
|
||||
1:
|
||||
ldd [%o1 + 0x08], %f20
|
||||
ldd [%o1 + 0x10], %f22
|
||||
ldd [%o1 + 0x18], %f24
|
||||
ldd [%o1 + 0x20], %f26
|
||||
ldd [%o1 + 0x28], %f28
|
||||
ldd [%o1 + 0x30], %f30
|
||||
ldd [%o1 + 0x38], %f32
|
||||
ldd [%o1 + 0x40], %f34
|
||||
ldd [%o1 + 0x48], %f36
|
||||
ldd [%o1 + 0x50], %f38
|
||||
ldd [%o1 + 0x58], %f40
|
||||
ldd [%o1 + 0x60], %f42
|
||||
ldd [%o1 + 0x68], %f44
|
||||
ldd [%o1 + 0x70], %f46
|
||||
ldd [%o1 + 0x78], %f48
|
||||
ldd [%o1 + 0x80], %f50
|
||||
|
||||
faligndata %f18, %f20, %f16
|
||||
faligndata %f20, %f22, %f18
|
||||
faligndata %f22, %f24, %f20
|
||||
faligndata %f24, %f26, %f22
|
||||
faligndata %f26, %f28, %f24
|
||||
faligndata %f28, %f30, %f26
|
||||
faligndata %f30, %f32, %f28
|
||||
faligndata %f32, %f34, %f30
|
||||
faligndata %f34, %f36, %f32
|
||||
faligndata %f36, %f38, %f34
|
||||
faligndata %f38, %f40, %f36
|
||||
faligndata %f40, %f42, %f38
|
||||
faligndata %f42, %f44, %f40
|
||||
faligndata %f44, %f46, %f42
|
||||
faligndata %f46, %f48, %f44
|
||||
faligndata %f48, %f50, %f46
|
||||
|
||||
SHA512
|
||||
|
||||
subcc %o2, 1, %o2
|
||||
fsrc2 %f50, %f18
|
||||
bne,pt %xcc, 1b
|
||||
add %o1, 0x80, %o1
|
||||
|
||||
ba,a,pt %xcc, 5b
|
||||
ENDPROC(sha512_sparc64_transform)
|
228
arch/sparc/crypto/sha512_glue.c
Normal file
228
arch/sparc/crypto/sha512_glue.c
Normal file
|
@ -0,0 +1,228 @@
|
|||
/* Glue code for SHA512 hashing optimized for sparc64 crypto opcodes.
|
||||
*
|
||||
* This is based largely upon crypto/sha512_generic.c
|
||||
*
|
||||
* Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
|
||||
* Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
|
||||
* Copyright (c) 2003 Kyle McMartin <kyle@debian.org>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/cryptohash.h>
|
||||
#include <linux/types.h>
|
||||
#include <crypto/sha.h>
|
||||
|
||||
#include <asm/pstate.h>
|
||||
#include <asm/elf.h>
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
asmlinkage void sha512_sparc64_transform(u64 *digest, const char *data,
|
||||
unsigned int rounds);
|
||||
|
||||
static int sha512_sparc64_init(struct shash_desc *desc)
|
||||
{
|
||||
struct sha512_state *sctx = shash_desc_ctx(desc);
|
||||
sctx->state[0] = SHA512_H0;
|
||||
sctx->state[1] = SHA512_H1;
|
||||
sctx->state[2] = SHA512_H2;
|
||||
sctx->state[3] = SHA512_H3;
|
||||
sctx->state[4] = SHA512_H4;
|
||||
sctx->state[5] = SHA512_H5;
|
||||
sctx->state[6] = SHA512_H6;
|
||||
sctx->state[7] = SHA512_H7;
|
||||
sctx->count[0] = sctx->count[1] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha384_sparc64_init(struct shash_desc *desc)
|
||||
{
|
||||
struct sha512_state *sctx = shash_desc_ctx(desc);
|
||||
sctx->state[0] = SHA384_H0;
|
||||
sctx->state[1] = SHA384_H1;
|
||||
sctx->state[2] = SHA384_H2;
|
||||
sctx->state[3] = SHA384_H3;
|
||||
sctx->state[4] = SHA384_H4;
|
||||
sctx->state[5] = SHA384_H5;
|
||||
sctx->state[6] = SHA384_H6;
|
||||
sctx->state[7] = SHA384_H7;
|
||||
sctx->count[0] = sctx->count[1] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __sha512_sparc64_update(struct sha512_state *sctx, const u8 *data,
|
||||
unsigned int len, unsigned int partial)
|
||||
{
|
||||
unsigned int done = 0;
|
||||
|
||||
if ((sctx->count[0] += len) < len)
|
||||
sctx->count[1]++;
|
||||
if (partial) {
|
||||
done = SHA512_BLOCK_SIZE - partial;
|
||||
memcpy(sctx->buf + partial, data, done);
|
||||
sha512_sparc64_transform(sctx->state, sctx->buf, 1);
|
||||
}
|
||||
if (len - done >= SHA512_BLOCK_SIZE) {
|
||||
const unsigned int rounds = (len - done) / SHA512_BLOCK_SIZE;
|
||||
|
||||
sha512_sparc64_transform(sctx->state, data + done, rounds);
|
||||
done += rounds * SHA512_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
memcpy(sctx->buf, data + done, len - done);
|
||||
}
|
||||
|
||||
static int sha512_sparc64_update(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len)
|
||||
{
|
||||
struct sha512_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int partial = sctx->count[0] % SHA512_BLOCK_SIZE;
|
||||
|
||||
/* Handle the fast case right here */
|
||||
if (partial + len < SHA512_BLOCK_SIZE) {
|
||||
if ((sctx->count[0] += len) < len)
|
||||
sctx->count[1]++;
|
||||
memcpy(sctx->buf + partial, data, len);
|
||||
} else
|
||||
__sha512_sparc64_update(sctx, data, len, partial);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha512_sparc64_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
struct sha512_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int i, index, padlen;
|
||||
__be64 *dst = (__be64 *)out;
|
||||
__be64 bits[2];
|
||||
static const u8 padding[SHA512_BLOCK_SIZE] = { 0x80, };
|
||||
|
||||
/* Save number of bits */
|
||||
bits[1] = cpu_to_be64(sctx->count[0] << 3);
|
||||
bits[0] = cpu_to_be64(sctx->count[1] << 3 | sctx->count[0] >> 61);
|
||||
|
||||
/* Pad out to 112 mod 128 and append length */
|
||||
index = sctx->count[0] % SHA512_BLOCK_SIZE;
|
||||
padlen = (index < 112) ? (112 - index) : ((SHA512_BLOCK_SIZE+112) - index);
|
||||
|
||||
/* We need to fill a whole block for __sha512_sparc64_update() */
|
||||
if (padlen <= 112) {
|
||||
if ((sctx->count[0] += padlen) < padlen)
|
||||
sctx->count[1]++;
|
||||
memcpy(sctx->buf + index, padding, padlen);
|
||||
} else {
|
||||
__sha512_sparc64_update(sctx, padding, padlen, index);
|
||||
}
|
||||
__sha512_sparc64_update(sctx, (const u8 *)&bits, sizeof(bits), 112);
|
||||
|
||||
/* Store state in digest */
|
||||
for (i = 0; i < 8; i++)
|
||||
dst[i] = cpu_to_be64(sctx->state[i]);
|
||||
|
||||
/* Wipe context */
|
||||
memset(sctx, 0, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha384_sparc64_final(struct shash_desc *desc, u8 *hash)
|
||||
{
|
||||
u8 D[64];
|
||||
|
||||
sha512_sparc64_final(desc, D);
|
||||
|
||||
memcpy(hash, D, 48);
|
||||
memset(D, 0, 64);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shash_alg sha512 = {
|
||||
.digestsize = SHA512_DIGEST_SIZE,
|
||||
.init = sha512_sparc64_init,
|
||||
.update = sha512_sparc64_update,
|
||||
.final = sha512_sparc64_final,
|
||||
.descsize = sizeof(struct sha512_state),
|
||||
.base = {
|
||||
.cra_name = "sha512",
|
||||
.cra_driver_name= "sha512-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA512_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
static struct shash_alg sha384 = {
|
||||
.digestsize = SHA384_DIGEST_SIZE,
|
||||
.init = sha384_sparc64_init,
|
||||
.update = sha512_sparc64_update,
|
||||
.final = sha384_sparc64_final,
|
||||
.descsize = sizeof(struct sha512_state),
|
||||
.base = {
|
||||
.cra_name = "sha384",
|
||||
.cra_driver_name= "sha384-sparc64",
|
||||
.cra_priority = SPARC_CR_OPCODE_PRIORITY,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA384_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
static bool __init sparc64_has_sha512_opcode(void)
|
||||
{
|
||||
unsigned long cfr;
|
||||
|
||||
if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
|
||||
return false;
|
||||
|
||||
__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
|
||||
if (!(cfr & CFR_SHA512))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __init sha512_sparc64_mod_init(void)
|
||||
{
|
||||
if (sparc64_has_sha512_opcode()) {
|
||||
int ret = crypto_register_shash(&sha384);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = crypto_register_shash(&sha512);
|
||||
if (ret < 0) {
|
||||
crypto_unregister_shash(&sha384);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pr_info("Using sparc64 sha512 opcode optimized SHA-512/SHA-384 implementation\n");
|
||||
return 0;
|
||||
}
|
||||
pr_info("sparc64 sha512 opcode not available.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void __exit sha512_sparc64_mod_fini(void)
|
||||
{
|
||||
crypto_unregister_shash(&sha384);
|
||||
crypto_unregister_shash(&sha512);
|
||||
}
|
||||
|
||||
module_init(sha512_sparc64_mod_init);
|
||||
module_exit(sha512_sparc64_mod_fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("SHA-384 and SHA-512 Secure Hash Algorithm, sparc64 sha512 opcode accelerated");
|
||||
|
||||
MODULE_ALIAS_CRYPTO("sha384");
|
||||
MODULE_ALIAS_CRYPTO("sha512");
|
||||
|
||||
#include "crop_devid.c"
|
23
arch/sparc/include/asm/Kbuild
Normal file
23
arch/sparc/include/asm/Kbuild
Normal file
|
@ -0,0 +1,23 @@
|
|||
# User exported sparc header files
|
||||
|
||||
|
||||
generic-y += clkdev.h
|
||||
generic-y += cputime.h
|
||||
generic-y += div64.h
|
||||
generic-y += emergency-restart.h
|
||||
generic-y += exec.h
|
||||
generic-y += hash.h
|
||||
generic-y += irq_regs.h
|
||||
generic-y += irq_work.h
|
||||
generic-y += linkage.h
|
||||
generic-y += local.h
|
||||
generic-y += local64.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += module.h
|
||||
generic-y += mutex.h
|
||||
generic-y += preempt.h
|
||||
generic-y += scatterlist.h
|
||||
generic-y += serial.h
|
||||
generic-y += trace_clock.h
|
||||
generic-y += types.h
|
||||
generic-y += word-at-a-time.h
|
16
arch/sparc/include/asm/agp.h
Normal file
16
arch/sparc/include/asm/agp.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef AGP_H
|
||||
#define AGP_H 1
|
||||
|
||||
/* dummy for now */
|
||||
|
||||
#define map_page_into_agp(page)
|
||||
#define unmap_page_from_agp(page)
|
||||
#define flush_agp_cache() mb()
|
||||
|
||||
/* GATT allocation. Returns/accepts GATT kernel virtual address. */
|
||||
#define alloc_gatt_pages(order) \
|
||||
((char *)__get_free_pages(GFP_KERNEL, (order)))
|
||||
#define free_gatt_pages(table, order) \
|
||||
free_pages((unsigned long)(table), (order))
|
||||
|
||||
#endif
|
36
arch/sparc/include/asm/apb.h
Normal file
36
arch/sparc/include/asm/apb.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* apb.h: Advanced PCI Bridge Configuration Registers and Bits
|
||||
*
|
||||
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC64_APB_H
|
||||
#define _SPARC64_APB_H
|
||||
|
||||
#define APB_TICK_REGISTER 0xb0
|
||||
#define APB_INT_ACK 0xb8
|
||||
#define APB_PRIMARY_MASTER_RETRY_LIMIT 0xc0
|
||||
#define APB_DMA_ASFR 0xc8
|
||||
#define APB_DMA_AFAR 0xd0
|
||||
#define APB_PIO_TARGET_RETRY_LIMIT 0xd8
|
||||
#define APB_PIO_TARGET_LATENCY_TIMER 0xd9
|
||||
#define APB_DMA_TARGET_RETRY_LIMIT 0xda
|
||||
#define APB_DMA_TARGET_LATENCY_TIMER 0xdb
|
||||
#define APB_SECONDARY_MASTER_RETRY_LIMIT 0xdc
|
||||
#define APB_SECONDARY_CONTROL 0xdd
|
||||
#define APB_IO_ADDRESS_MAP 0xde
|
||||
#define APB_MEM_ADDRESS_MAP 0xdf
|
||||
|
||||
#define APB_PCI_CONTROL_LOW 0xe0
|
||||
# define APB_PCI_CTL_LOW_ARB_PARK (1 << 21)
|
||||
# define APB_PCI_CTL_LOW_ERRINT_EN (1 << 8)
|
||||
|
||||
#define APB_PCI_CONTROL_HIGH 0xe4
|
||||
# define APB_PCI_CTL_HIGH_SERR (1 << 2)
|
||||
# define APB_PCI_CTL_HIGH_ARBITER_EN (1 << 0)
|
||||
|
||||
#define APB_PIO_ASFR 0xe8
|
||||
#define APB_PIO_AFAR 0xf0
|
||||
#define APB_DIAG_REGISTER 0xf8
|
||||
|
||||
#endif /* !(_SPARC64_APB_H) */
|
1
arch/sparc/include/asm/asm-offsets.h
Normal file
1
arch/sparc/include/asm/asm-offsets.h
Normal file
|
@ -0,0 +1 @@
|
|||
#include <generated/asm-offsets.h>
|
40
arch/sparc/include/asm/asm.h
Normal file
40
arch/sparc/include/asm/asm.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#ifndef _SPARC_ASM_H
|
||||
#define _SPARC_ASM_H
|
||||
|
||||
/* Macros to assist the sharing of assembler code between 32-bit and
|
||||
* 64-bit sparc.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SPARC64
|
||||
#define BRANCH32(TYPE, PREDICT, DEST) \
|
||||
TYPE,PREDICT %icc, DEST
|
||||
#define BRANCH32_ANNUL(TYPE, PREDICT, DEST) \
|
||||
TYPE,a,PREDICT %icc, DEST
|
||||
#define BRANCH_REG_ZERO(PREDICT, REG, DEST) \
|
||||
brz,PREDICT REG, DEST
|
||||
#define BRANCH_REG_ZERO_ANNUL(PREDICT, REG, DEST) \
|
||||
brz,a,PREDICT REG, DEST
|
||||
#define BRANCH_REG_NOT_ZERO(PREDICT, REG, DEST) \
|
||||
brnz,PREDICT REG, DEST
|
||||
#define BRANCH_REG_NOT_ZERO_ANNUL(PREDICT, REG, DEST) \
|
||||
brnz,a,PREDICT REG, DEST
|
||||
#else
|
||||
#define BRANCH32(TYPE, PREDICT, DEST) \
|
||||
TYPE DEST
|
||||
#define BRANCH32_ANNUL(TYPE, PREDICT, DEST) \
|
||||
TYPE,a DEST
|
||||
#define BRANCH_REG_ZERO(PREDICT, REG, DEST) \
|
||||
cmp REG, 0; \
|
||||
be DEST
|
||||
#define BRANCH_REG_ZERO_ANNUL(PREDICT, REG, DEST) \
|
||||
cmp REG, 0; \
|
||||
be,a DEST
|
||||
#define BRANCH_REG_NOT_ZERO(PREDICT, REG, DEST) \
|
||||
cmp REG, 0; \
|
||||
bne DEST
|
||||
#define BRANCH_REG_NOT_ZERO_ANNUL(PREDICT, REG, DEST) \
|
||||
cmp REG, 0; \
|
||||
bne,a DEST
|
||||
#endif
|
||||
|
||||
#endif /* _SPARC_ASM_H */
|
45
arch/sparc/include/asm/asmmacro.h
Normal file
45
arch/sparc/include/asm/asmmacro.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/* asmmacro.h: Assembler macros.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_ASMMACRO_H
|
||||
#define _SPARC_ASMMACRO_H
|
||||
|
||||
/* All trap entry points _must_ begin with this macro or else you
|
||||
* lose. It makes sure the kernel has a proper window so that
|
||||
* c-code can be called.
|
||||
*/
|
||||
#define SAVE_ALL_HEAD \
|
||||
sethi %hi(trap_setup), %l4; \
|
||||
jmpl %l4 + %lo(trap_setup), %l6;
|
||||
#define SAVE_ALL \
|
||||
SAVE_ALL_HEAD \
|
||||
nop;
|
||||
|
||||
/* All traps low-level code here must end with this macro. */
|
||||
#define RESTORE_ALL b ret_trap_entry; clr %l6;
|
||||
|
||||
/* Support for run-time patching of single instructions.
|
||||
* This is used to handle the differences in the ASI for
|
||||
* MMUREGS for LEON and SUN.
|
||||
*
|
||||
* Sample:
|
||||
* LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %o0
|
||||
* SUN_PI_(lda [%g0] ASI_M_MMUREGS, %o0
|
||||
* PI == Patch Instruction
|
||||
*
|
||||
* For LEON we will use the first variant,
|
||||
* and for all other we will use the SUN variant.
|
||||
* The order is important.
|
||||
*/
|
||||
#define LEON_PI(...) \
|
||||
662: __VA_ARGS__
|
||||
|
||||
#define SUN_PI_(...) \
|
||||
.section .leon_1insn_patch, "ax"; \
|
||||
.word 662b; \
|
||||
__VA_ARGS__; \
|
||||
.previous
|
||||
|
||||
#endif /* !(_SPARC_ASMMACRO_H) */
|
8
arch/sparc/include/asm/atomic.h
Normal file
8
arch/sparc/include/asm/atomic.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ___ASM_SPARC_ATOMIC_H
|
||||
#define ___ASM_SPARC_ATOMIC_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm/atomic_64.h>
|
||||
#else
|
||||
#include <asm/atomic_32.h>
|
||||
#endif
|
||||
#endif
|
55
arch/sparc/include/asm/atomic_32.h
Normal file
55
arch/sparc/include/asm/atomic_32.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* atomic.h: These still suck, but the I-cache hit rate is higher.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au)
|
||||
* Copyright (C) 2007 Kyle McMartin (kyle@parisc-linux.org)
|
||||
*
|
||||
* Additions by Keith M Wesolowski (wesolows@foobazco.org) based
|
||||
* on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_SPARC_ATOMIC__
|
||||
#define __ARCH_SPARC_ATOMIC__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/cmpxchg.h>
|
||||
#include <asm/barrier.h>
|
||||
#include <asm-generic/atomic64.h>
|
||||
|
||||
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
|
||||
int atomic_add_return(int, atomic_t *);
|
||||
int atomic_cmpxchg(atomic_t *, int, int);
|
||||
int atomic_xchg(atomic_t *, int);
|
||||
int __atomic_add_unless(atomic_t *, int, int);
|
||||
void atomic_set(atomic_t *, int);
|
||||
|
||||
#define atomic_read(v) ACCESS_ONCE((v)->counter)
|
||||
|
||||
#define atomic_add(i, v) ((void)atomic_add_return( (int)(i), (v)))
|
||||
#define atomic_sub(i, v) ((void)atomic_add_return(-(int)(i), (v)))
|
||||
#define atomic_inc(v) ((void)atomic_add_return( 1, (v)))
|
||||
#define atomic_dec(v) ((void)atomic_add_return( -1, (v)))
|
||||
|
||||
#define atomic_sub_return(i, v) (atomic_add_return(-(int)(i), (v)))
|
||||
#define atomic_inc_return(v) (atomic_add_return( 1, (v)))
|
||||
#define atomic_dec_return(v) (atomic_add_return( -1, (v)))
|
||||
|
||||
#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
|
||||
|
||||
/*
|
||||
* atomic_inc_and_test - increment and test
|
||||
* @v: pointer of type atomic_t
|
||||
*
|
||||
* Atomically increments @v by 1
|
||||
* and returns true if the result is zero, or false for all
|
||||
* other cases.
|
||||
*/
|
||||
#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
|
||||
|
||||
#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
|
||||
#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
|
||||
|
||||
#endif /* !(__ARCH_SPARC_ATOMIC__) */
|
113
arch/sparc/include/asm/atomic_64.h
Normal file
113
arch/sparc/include/asm/atomic_64.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
/* atomic.h: Thankfully the V9 is at least reasonable for this
|
||||
* stuff.
|
||||
*
|
||||
* Copyright (C) 1996, 1997, 2000, 2012 David S. Miller (davem@redhat.com)
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_SPARC64_ATOMIC__
|
||||
#define __ARCH_SPARC64_ATOMIC__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/cmpxchg.h>
|
||||
#include <asm/barrier.h>
|
||||
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
#define ATOMIC64_INIT(i) { (i) }
|
||||
|
||||
#define atomic_read(v) ACCESS_ONCE((v)->counter)
|
||||
#define atomic64_read(v) ACCESS_ONCE((v)->counter)
|
||||
|
||||
#define atomic_set(v, i) (((v)->counter) = i)
|
||||
#define atomic64_set(v, i) (((v)->counter) = i)
|
||||
|
||||
#define ATOMIC_OP(op) \
|
||||
void atomic_##op(int, atomic_t *); \
|
||||
void atomic64_##op(long, atomic64_t *);
|
||||
|
||||
#define ATOMIC_OP_RETURN(op) \
|
||||
int atomic_##op##_return(int, atomic_t *); \
|
||||
long atomic64_##op##_return(long, atomic64_t *);
|
||||
|
||||
#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op)
|
||||
|
||||
ATOMIC_OPS(add)
|
||||
ATOMIC_OPS(sub)
|
||||
|
||||
#undef ATOMIC_OPS
|
||||
#undef ATOMIC_OP_RETURN
|
||||
#undef ATOMIC_OP
|
||||
|
||||
#define atomic_dec_return(v) atomic_sub_return(1, v)
|
||||
#define atomic64_dec_return(v) atomic64_sub_return(1, v)
|
||||
|
||||
#define atomic_inc_return(v) atomic_add_return(1, v)
|
||||
#define atomic64_inc_return(v) atomic64_add_return(1, v)
|
||||
|
||||
/*
|
||||
* atomic_inc_and_test - increment and test
|
||||
* @v: pointer of type atomic_t
|
||||
*
|
||||
* Atomically increments @v by 1
|
||||
* and returns true if the result is zero, or false for all
|
||||
* other cases.
|
||||
*/
|
||||
#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
|
||||
#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
|
||||
|
||||
#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
|
||||
#define atomic64_sub_and_test(i, v) (atomic64_sub_return(i, v) == 0)
|
||||
|
||||
#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
|
||||
#define atomic64_dec_and_test(v) (atomic64_sub_return(1, v) == 0)
|
||||
|
||||
#define atomic_inc(v) atomic_add(1, v)
|
||||
#define atomic64_inc(v) atomic64_add(1, v)
|
||||
|
||||
#define atomic_dec(v) atomic_sub(1, v)
|
||||
#define atomic64_dec(v) atomic64_sub(1, v)
|
||||
|
||||
#define atomic_add_negative(i, v) (atomic_add_return(i, v) < 0)
|
||||
#define atomic64_add_negative(i, v) (atomic64_add_return(i, v) < 0)
|
||||
|
||||
#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
|
||||
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
|
||||
|
||||
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
|
||||
{
|
||||
int c, old;
|
||||
c = atomic_read(v);
|
||||
for (;;) {
|
||||
if (unlikely(c == (u)))
|
||||
break;
|
||||
old = atomic_cmpxchg((v), c, c + (a));
|
||||
if (likely(old == c))
|
||||
break;
|
||||
c = old;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
#define atomic64_cmpxchg(v, o, n) \
|
||||
((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
|
||||
#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
|
||||
|
||||
static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
|
||||
{
|
||||
long c, old;
|
||||
c = atomic64_read(v);
|
||||
for (;;) {
|
||||
if (unlikely(c == (u)))
|
||||
break;
|
||||
old = atomic64_cmpxchg((v), c, c + (a));
|
||||
if (likely(old == c))
|
||||
break;
|
||||
c = old;
|
||||
}
|
||||
return c != (u);
|
||||
}
|
||||
|
||||
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
|
||||
|
||||
long atomic64_dec_if_positive(atomic64_t *v);
|
||||
|
||||
#endif /* !(__ARCH_SPARC64_ATOMIC__) */
|
15
arch/sparc/include/asm/auxio.h
Normal file
15
arch/sparc/include/asm/auxio.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef ___ASM_SPARC_AUXIO_H
|
||||
#define ___ASM_SPARC_AUXIO_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern void __iomem *auxio_register;
|
||||
|
||||
#endif /* ifndef __ASSEMBLY__ */
|
||||
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm/auxio_64.h>
|
||||
#else
|
||||
#include <asm/auxio_32.h>
|
||||
#endif
|
||||
#endif
|
88
arch/sparc/include/asm/auxio_32.h
Normal file
88
arch/sparc/include/asm/auxio_32.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* auxio.h: Definitions and code for the Auxiliary I/O register.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
#ifndef _SPARC_AUXIO_H
|
||||
#define _SPARC_AUXIO_H
|
||||
|
||||
#include <asm/vaddrs.h>
|
||||
|
||||
/* This register is an unsigned char in IO space. It does two things.
|
||||
* First, it is used to control the front panel LED light on machines
|
||||
* that have it (good for testing entry points to trap handlers and irq's)
|
||||
* Secondly, it controls various floppy drive parameters.
|
||||
*/
|
||||
#define AUXIO_ORMEIN 0xf0 /* All writes must set these bits. */
|
||||
#define AUXIO_ORMEIN4M 0xc0 /* sun4m - All writes must set these bits. */
|
||||
#define AUXIO_FLPY_DENS 0x20 /* Floppy density, high if set. Read only. */
|
||||
#define AUXIO_FLPY_DCHG 0x10 /* A disk change occurred. Read only. */
|
||||
#define AUXIO_EDGE_ON 0x10 /* sun4m - On means Jumper block is in. */
|
||||
#define AUXIO_FLPY_DSEL 0x08 /* Drive select/start-motor. Write only. */
|
||||
#define AUXIO_LINK_TEST 0x08 /* sun4m - On means TPE Carrier detect. */
|
||||
|
||||
/* Set the following to one, then zero, after doing a pseudo DMA transfer. */
|
||||
#define AUXIO_FLPY_TCNT 0x04 /* Floppy terminal count. Write only. */
|
||||
|
||||
/* Set the following to zero to eject the floppy. */
|
||||
#define AUXIO_FLPY_EJCT 0x02 /* Eject floppy disk. Write only. */
|
||||
#define AUXIO_LED 0x01 /* On if set, off if unset. Read/Write */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* NOTE: these routines are implementation dependent--
|
||||
* understand the hardware you are querying!
|
||||
*/
|
||||
void set_auxio(unsigned char bits_on, unsigned char bits_off);
|
||||
unsigned char get_auxio(void); /* .../asm/floppy.h */
|
||||
|
||||
/*
|
||||
* The following routines are provided for driver-compatibility
|
||||
* with sparc64 (primarily sunlance.c)
|
||||
*/
|
||||
|
||||
#define AUXIO_LTE_ON 1
|
||||
#define AUXIO_LTE_OFF 0
|
||||
|
||||
/* auxio_set_lte - Set Link Test Enable (TPE Link Detect)
|
||||
*
|
||||
* on - AUXIO_LTE_ON or AUXIO_LTE_OFF
|
||||
*/
|
||||
#define auxio_set_lte(on) \
|
||||
do { \
|
||||
if(on) { \
|
||||
set_auxio(AUXIO_LINK_TEST, 0); \
|
||||
} else { \
|
||||
set_auxio(0, AUXIO_LINK_TEST); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define AUXIO_LED_ON 1
|
||||
#define AUXIO_LED_OFF 0
|
||||
|
||||
/* auxio_set_led - Set system front panel LED
|
||||
*
|
||||
* on - AUXIO_LED_ON or AUXIO_LED_OFF
|
||||
*/
|
||||
#define auxio_set_led(on) \
|
||||
do { \
|
||||
if(on) { \
|
||||
set_auxio(AUXIO_LED, 0); \
|
||||
} else { \
|
||||
set_auxio(0, AUXIO_LED); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
|
||||
/* AUXIO2 (Power Off Control) */
|
||||
extern volatile u8 __iomem *auxio_power_register;
|
||||
|
||||
#define AUXIO_POWER_DETECT_FAILURE 32
|
||||
#define AUXIO_POWER_CLEAR_FAILURE 2
|
||||
#define AUXIO_POWER_OFF 1
|
||||
|
||||
|
||||
#endif /* !(_SPARC_AUXIO_H) */
|
98
arch/sparc/include/asm/auxio_64.h
Normal file
98
arch/sparc/include/asm/auxio_64.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* auxio.h: Definitions and code for the Auxiliary I/O registers.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*
|
||||
* Refactoring for unified NCR/PCIO support 2002 Eric Brower (ebrower@usa.net)
|
||||
*/
|
||||
#ifndef _SPARC64_AUXIO_H
|
||||
#define _SPARC64_AUXIO_H
|
||||
|
||||
/* AUXIO implementations:
|
||||
* sbus-based NCR89C105 "Slavio"
|
||||
* LED/Floppy (AUX1) register
|
||||
* Power (AUX2) register
|
||||
*
|
||||
* ebus-based auxio on PCIO
|
||||
* LED Auxio Register
|
||||
* Power Auxio Register
|
||||
*
|
||||
* Register definitions from NCR _NCR89C105 Chip Specification_
|
||||
*
|
||||
* SLAVIO AUX1 @ 0x1900000
|
||||
* -------------------------------------------------
|
||||
* | (R) | (R) | D | (R) | E | M | T | L |
|
||||
* -------------------------------------------------
|
||||
* (R) - bit 7:6,4 are reserved and should be masked in s/w
|
||||
* D - Floppy Density Sense (1=high density) R/O
|
||||
* E - Link Test Enable, directly reflected on AT&T 7213 LTE pin
|
||||
* M - Monitor/Mouse Mux, directly reflected on MON_MSE_MUX pin
|
||||
* T - Terminal Count: sends TC pulse to 82077 floppy controller
|
||||
* L - System LED on front panel (0=off, 1=on)
|
||||
*/
|
||||
#define AUXIO_AUX1_MASK 0xc0 /* Mask bits */
|
||||
#define AUXIO_AUX1_FDENS 0x20 /* Floppy Density Sense */
|
||||
#define AUXIO_AUX1_LTE 0x08 /* Link Test Enable */
|
||||
#define AUXIO_AUX1_MMUX 0x04 /* Monitor/Mouse Mux */
|
||||
#define AUXIO_AUX1_FTCNT 0x02 /* Terminal Count, */
|
||||
#define AUXIO_AUX1_LED 0x01 /* System LED */
|
||||
|
||||
/* SLAVIO AUX2 @ 0x1910000
|
||||
* -------------------------------------------------
|
||||
* | (R) | (R) | D | (R) | (R) | (R) | C | F |
|
||||
* -------------------------------------------------
|
||||
* (R) - bits 7:6,4:2 are reserved and should be masked in s/w
|
||||
* D - Power Failure Detect (1=power fail)
|
||||
* C - Clear Power Failure Detect Int (1=clear)
|
||||
* F - Power Off (1=power off)
|
||||
*/
|
||||
#define AUXIO_AUX2_MASK 0xdc /* Mask Bits */
|
||||
#define AUXIO_AUX2_PFAILDET 0x20 /* Power Fail Detect */
|
||||
#define AUXIO_AUX2_PFAILCLR 0x02 /* Clear Pwr Fail Det Intr */
|
||||
#define AUXIO_AUX2_PWR_OFF 0x01 /* Power Off */
|
||||
|
||||
/* Register definitions from Sun Microsystems _PCIO_ p/n 802-7837
|
||||
*
|
||||
* PCIO LED Auxio @ 0x726000
|
||||
* -------------------------------------------------
|
||||
* | 31:1 Unused | LED |
|
||||
* -------------------------------------------------
|
||||
* Bits 31:1 unused
|
||||
* LED - System LED on front panel (0=off, 1=on)
|
||||
*/
|
||||
#define AUXIO_PCIO_LED 0x01 /* System LED */
|
||||
|
||||
/* PCIO Power Auxio @ 0x724000
|
||||
* -------------------------------------------------
|
||||
* | 31:2 Unused | CPO | SPO |
|
||||
* -------------------------------------------------
|
||||
* Bits 31:2 unused
|
||||
* CPO - Courtesy Power Off (1=off)
|
||||
* SPO - System Power Off (1=off)
|
||||
*/
|
||||
#define AUXIO_PCIO_CPWR_OFF 0x02 /* Courtesy Power Off */
|
||||
#define AUXIO_PCIO_SPWR_OFF 0x01 /* System Power Off */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define AUXIO_LTE_ON 1
|
||||
#define AUXIO_LTE_OFF 0
|
||||
|
||||
/* auxio_set_lte - Set Link Test Enable (TPE Link Detect)
|
||||
*
|
||||
* on - AUXIO_LTE_ON or AUXIO_LTE_OFF
|
||||
*/
|
||||
void auxio_set_lte(int on);
|
||||
|
||||
#define AUXIO_LED_ON 1
|
||||
#define AUXIO_LED_OFF 0
|
||||
|
||||
/* auxio_set_led - Set system front panel LED
|
||||
*
|
||||
* on - AUXIO_LED_ON or AUXIO_LED_OFF
|
||||
*/
|
||||
void auxio_set_led(int on);
|
||||
|
||||
#endif /* ifndef __ASSEMBLY__ */
|
||||
|
||||
#endif /* !(_SPARC64_AUXIO_H) */
|
85
arch/sparc/include/asm/backoff.h
Normal file
85
arch/sparc/include/asm/backoff.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
#ifndef _SPARC64_BACKOFF_H
|
||||
#define _SPARC64_BACKOFF_H
|
||||
|
||||
/* The macros in this file implement an exponential backoff facility
|
||||
* for atomic operations.
|
||||
*
|
||||
* When multiple threads compete on an atomic operation, it is
|
||||
* possible for one thread to be continually denied a successful
|
||||
* completion of the compare-and-swap instruction. Heavily
|
||||
* threaded cpu implementations like Niagara can compound this
|
||||
* problem even further.
|
||||
*
|
||||
* When an atomic operation fails and needs to be retried, we spin a
|
||||
* certain number of times. At each subsequent failure of the same
|
||||
* operation we double the spin count, realizing an exponential
|
||||
* backoff.
|
||||
*
|
||||
* When we spin, we try to use an operation that will cause the
|
||||
* current cpu strand to block, and therefore make the core fully
|
||||
* available to any other other runnable strands. There are two
|
||||
* options, based upon cpu capabilities.
|
||||
*
|
||||
* On all cpus prior to SPARC-T4 we do three dummy reads of the
|
||||
* condition code register. Each read blocks the strand for something
|
||||
* between 40 and 50 cpu cycles.
|
||||
*
|
||||
* For SPARC-T4 and later we have a special "pause" instruction
|
||||
* available. This is implemented using writes to register %asr27.
|
||||
* The cpu will block the number of cycles written into the register,
|
||||
* unless a disrupting trap happens first. SPARC-T4 specifically
|
||||
* implements pause with a granularity of 8 cycles. Each strand has
|
||||
* an internal pause counter which decrements every 8 cycles. So the
|
||||
* chip shifts the %asr27 value down by 3 bits, and writes the result
|
||||
* into the pause counter. If a value smaller than 8 is written, the
|
||||
* chip blocks for 1 cycle.
|
||||
*
|
||||
* To achieve the same amount of backoff as the three %ccr reads give
|
||||
* on earlier chips, we shift the backoff value up by 7 bits. (Three
|
||||
* %ccr reads block for about 128 cycles, 1 << 7 == 128) We write the
|
||||
* whole amount we want to block into the pause register, rather than
|
||||
* loop writing 128 each time.
|
||||
*/
|
||||
|
||||
#define BACKOFF_LIMIT (4 * 1024)
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
#define BACKOFF_SETUP(reg) \
|
||||
mov 1, reg
|
||||
|
||||
#define BACKOFF_LABEL(spin_label, continue_label) \
|
||||
spin_label
|
||||
|
||||
#define BACKOFF_SPIN(reg, tmp, label) \
|
||||
mov reg, tmp; \
|
||||
88: rd %ccr, %g0; \
|
||||
rd %ccr, %g0; \
|
||||
rd %ccr, %g0; \
|
||||
.section .pause_3insn_patch,"ax";\
|
||||
.word 88b; \
|
||||
sllx tmp, 7, tmp; \
|
||||
wr tmp, 0, %asr27; \
|
||||
clr tmp; \
|
||||
.previous; \
|
||||
brnz,pt tmp, 88b; \
|
||||
sub tmp, 1, tmp; \
|
||||
set BACKOFF_LIMIT, tmp; \
|
||||
cmp reg, tmp; \
|
||||
bg,pn %xcc, label; \
|
||||
nop; \
|
||||
ba,pt %xcc, label; \
|
||||
sllx reg, 1, reg;
|
||||
|
||||
#else
|
||||
|
||||
#define BACKOFF_SETUP(reg)
|
||||
|
||||
#define BACKOFF_LABEL(spin_label, continue_label) \
|
||||
continue_label
|
||||
|
||||
#define BACKOFF_SPIN(reg, tmp, label)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _SPARC64_BACKOFF_H */
|
8
arch/sparc/include/asm/barrier.h
Normal file
8
arch/sparc/include/asm/barrier.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ___ASM_SPARC_BARRIER_H
|
||||
#define ___ASM_SPARC_BARRIER_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm/barrier_64.h>
|
||||
#else
|
||||
#include <asm/barrier_32.h>
|
||||
#endif
|
||||
#endif
|
7
arch/sparc/include/asm/barrier_32.h
Normal file
7
arch/sparc/include/asm/barrier_32.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef __SPARC_BARRIER_H
|
||||
#define __SPARC_BARRIER_H
|
||||
|
||||
#include <asm/processor.h> /* for nop() */
|
||||
#include <asm-generic/barrier.h>
|
||||
|
||||
#endif /* !(__SPARC_BARRIER_H) */
|
74
arch/sparc/include/asm/barrier_64.h
Normal file
74
arch/sparc/include/asm/barrier_64.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
#ifndef __SPARC64_BARRIER_H
|
||||
#define __SPARC64_BARRIER_H
|
||||
|
||||
/* These are here in an effort to more fully work around Spitfire Errata
|
||||
* #51. Essentially, if a memory barrier occurs soon after a mispredicted
|
||||
* branch, the chip can stop executing instructions until a trap occurs.
|
||||
* Therefore, if interrupts are disabled, the chip can hang forever.
|
||||
*
|
||||
* It used to be believed that the memory barrier had to be right in the
|
||||
* delay slot, but a case has been traced recently wherein the memory barrier
|
||||
* was one instruction after the branch delay slot and the chip still hung.
|
||||
* The offending sequence was the following in sym_wakeup_done() of the
|
||||
* sym53c8xx_2 driver:
|
||||
*
|
||||
* call sym_ccb_from_dsa, 0
|
||||
* movge %icc, 0, %l0
|
||||
* brz,pn %o0, .LL1303
|
||||
* mov %o0, %l2
|
||||
* membar #LoadLoad
|
||||
*
|
||||
* The branch has to be mispredicted for the bug to occur. Therefore, we put
|
||||
* the memory barrier explicitly into a "branch always, predicted taken"
|
||||
* delay slot to avoid the problem case.
|
||||
*/
|
||||
#define membar_safe(type) \
|
||||
do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
|
||||
" membar " type "\n" \
|
||||
"1:\n" \
|
||||
: : : "memory"); \
|
||||
} while (0)
|
||||
|
||||
/* The kernel always executes in TSO memory model these days,
|
||||
* and furthermore most sparc64 chips implement more stringent
|
||||
* memory ordering than required by the specifications.
|
||||
*/
|
||||
#define mb() membar_safe("#StoreLoad")
|
||||
#define rmb() __asm__ __volatile__("":::"memory")
|
||||
#define wmb() __asm__ __volatile__("":::"memory")
|
||||
|
||||
#define read_barrier_depends() do { } while(0)
|
||||
#define set_mb(__var, __value) \
|
||||
do { __var = __value; membar_safe("#StoreLoad"); } while(0)
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define smp_mb() mb()
|
||||
#define smp_rmb() rmb()
|
||||
#define smp_wmb() wmb()
|
||||
#else
|
||||
#define smp_mb() __asm__ __volatile__("":::"memory")
|
||||
#define smp_rmb() __asm__ __volatile__("":::"memory")
|
||||
#define smp_wmb() __asm__ __volatile__("":::"memory")
|
||||
#endif
|
||||
|
||||
#define smp_read_barrier_depends() do { } while(0)
|
||||
|
||||
#define smp_store_release(p, v) \
|
||||
do { \
|
||||
compiletime_assert_atomic_type(*p); \
|
||||
barrier(); \
|
||||
ACCESS_ONCE(*p) = (v); \
|
||||
} while (0)
|
||||
|
||||
#define smp_load_acquire(p) \
|
||||
({ \
|
||||
typeof(*p) ___p1 = ACCESS_ONCE(*p); \
|
||||
compiletime_assert_atomic_type(*p); \
|
||||
barrier(); \
|
||||
___p1; \
|
||||
})
|
||||
|
||||
#define smp_mb__before_atomic() barrier()
|
||||
#define smp_mb__after_atomic() barrier()
|
||||
|
||||
#endif /* !(__SPARC64_BARRIER_H) */
|
225
arch/sparc/include/asm/bbc.h
Normal file
225
arch/sparc/include/asm/bbc.h
Normal file
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* bbc.h: Defines for BootBus Controller found on UltraSPARC-III
|
||||
* systems.
|
||||
*
|
||||
* Copyright (C) 2000 David S. Miller (davem@redhat.com)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC64_BBC_H
|
||||
#define _SPARC64_BBC_H
|
||||
|
||||
/* Register sizes are indicated by "B" (Byte, 1-byte),
|
||||
* "H" (Half-word, 2 bytes), "W" (Word, 4 bytes) or
|
||||
* "Q" (Quad, 8 bytes) inside brackets.
|
||||
*/
|
||||
|
||||
#define BBC_AID 0x00 /* [B] Agent ID */
|
||||
#define BBC_DEVP 0x01 /* [B] Device Present */
|
||||
#define BBC_ARB 0x02 /* [B] Arbitration */
|
||||
#define BBC_QUIESCE 0x03 /* [B] Quiesce */
|
||||
#define BBC_WDACTION 0x04 /* [B] Watchdog Action */
|
||||
#define BBC_SPG 0x06 /* [B] Soft POR Gen */
|
||||
#define BBC_SXG 0x07 /* [B] Soft XIR Gen */
|
||||
#define BBC_PSRC 0x08 /* [W] POR Source */
|
||||
#define BBC_XSRC 0x0c /* [B] XIR Source */
|
||||
#define BBC_CSC 0x0d /* [B] Clock Synthesizers Control*/
|
||||
#define BBC_ES_CTRL 0x0e /* [H] Energy Star Control */
|
||||
#define BBC_ES_ACT 0x10 /* [W] E* Assert Change Time */
|
||||
#define BBC_ES_DACT 0x14 /* [B] E* De-Assert Change Time */
|
||||
#define BBC_ES_DABT 0x15 /* [B] E* De-Assert Bypass Time */
|
||||
#define BBC_ES_ABT 0x16 /* [H] E* Assert Bypass Time */
|
||||
#define BBC_ES_PST 0x18 /* [W] E* PLL Settle Time */
|
||||
#define BBC_ES_FSL 0x1c /* [W] E* Frequency Switch Latency*/
|
||||
#define BBC_EBUST 0x20 /* [Q] EBUS Timing */
|
||||
#define BBC_JTAG_CMD 0x28 /* [W] JTAG+ Command */
|
||||
#define BBC_JTAG_CTRL 0x2c /* [B] JTAG+ Control */
|
||||
#define BBC_I2C_SEL 0x2d /* [B] I2C Selection */
|
||||
#define BBC_I2C_0_S1 0x2e /* [B] I2C ctrlr-0 reg S1 */
|
||||
#define BBC_I2C_0_S0 0x2f /* [B] I2C ctrlr-0 regs S0,S0',S2,S3*/
|
||||
#define BBC_I2C_1_S1 0x30 /* [B] I2C ctrlr-1 reg S1 */
|
||||
#define BBC_I2C_1_S0 0x31 /* [B] I2C ctrlr-1 regs S0,S0',S2,S3*/
|
||||
#define BBC_KBD_BEEP 0x32 /* [B] Keyboard Beep */
|
||||
#define BBC_KBD_BCNT 0x34 /* [W] Keyboard Beep Counter */
|
||||
|
||||
#define BBC_REGS_SIZE 0x40
|
||||
|
||||
/* There is a 2K scratch ram area at offset 0x80000 but I doubt
|
||||
* we will use it for anything.
|
||||
*/
|
||||
|
||||
/* Agent ID register. This register shows the Safari Agent ID
|
||||
* for the processors. The value returned depends upon which
|
||||
* cpu is reading the register.
|
||||
*/
|
||||
#define BBC_AID_ID 0x07 /* Safari ID */
|
||||
#define BBC_AID_RESV 0xf8 /* Reserved */
|
||||
|
||||
/* Device Present register. One can determine which cpus are actually
|
||||
* present in the machine by interrogating this register.
|
||||
*/
|
||||
#define BBC_DEVP_CPU0 0x01 /* Processor 0 present */
|
||||
#define BBC_DEVP_CPU1 0x02 /* Processor 1 present */
|
||||
#define BBC_DEVP_CPU2 0x04 /* Processor 2 present */
|
||||
#define BBC_DEVP_CPU3 0x08 /* Processor 3 present */
|
||||
#define BBC_DEVP_RESV 0xf0 /* Reserved */
|
||||
|
||||
/* Arbitration register. This register is used to block access to
|
||||
* the BBC from a particular cpu.
|
||||
*/
|
||||
#define BBC_ARB_CPU0 0x01 /* Enable cpu 0 BBC arbitratrion */
|
||||
#define BBC_ARB_CPU1 0x02 /* Enable cpu 1 BBC arbitratrion */
|
||||
#define BBC_ARB_CPU2 0x04 /* Enable cpu 2 BBC arbitratrion */
|
||||
#define BBC_ARB_CPU3 0x08 /* Enable cpu 3 BBC arbitratrion */
|
||||
#define BBC_ARB_RESV 0xf0 /* Reserved */
|
||||
|
||||
/* Quiesce register. Bus and BBC segments for cpus can be disabled
|
||||
* with this register, ie. for hot plugging.
|
||||
*/
|
||||
#define BBC_QUIESCE_S02 0x01 /* Quiesce Safari segment for cpu 0 and 2 */
|
||||
#define BBC_QUIESCE_S13 0x02 /* Quiesce Safari segment for cpu 1 and 3 */
|
||||
#define BBC_QUIESCE_B02 0x04 /* Quiesce BBC segment for cpu 0 and 2 */
|
||||
#define BBC_QUIESCE_B13 0x08 /* Quiesce BBC segment for cpu 1 and 3 */
|
||||
#define BBC_QUIESCE_FD0 0x10 /* Disable Fatal_Error[0] reporting */
|
||||
#define BBC_QUIESCE_FD1 0x20 /* Disable Fatal_Error[1] reporting */
|
||||
#define BBC_QUIESCE_FD2 0x40 /* Disable Fatal_Error[2] reporting */
|
||||
#define BBC_QUIESCE_FD3 0x80 /* Disable Fatal_Error[3] reporting */
|
||||
|
||||
/* Watchdog Action register. When the watchdog device timer expires
|
||||
* a line is enabled to the BBC. The action BBC takes when this line
|
||||
* is asserted can be controlled by this regiser.
|
||||
*/
|
||||
#define BBC_WDACTION_RST 0x01 /* When set, watchdog causes system reset.
|
||||
* When clear, BBC ignores watchdog signal.
|
||||
*/
|
||||
#define BBC_WDACTION_RESV 0xfe /* Reserved */
|
||||
|
||||
/* Soft_POR_GEN register. The POR (Power On Reset) signal may be asserted
|
||||
* for specific processors or all processors via this register.
|
||||
*/
|
||||
#define BBC_SPG_CPU0 0x01 /* Assert POR for processor 0 */
|
||||
#define BBC_SPG_CPU1 0x02 /* Assert POR for processor 1 */
|
||||
#define BBC_SPG_CPU2 0x04 /* Assert POR for processor 2 */
|
||||
#define BBC_SPG_CPU3 0x08 /* Assert POR for processor 3 */
|
||||
#define BBC_SPG_CPUALL 0x10 /* Reset all processors and reset
|
||||
* the entire system.
|
||||
*/
|
||||
#define BBC_SPG_RESV 0xe0 /* Reserved */
|
||||
|
||||
/* Soft_XIR_GEN register. The XIR (eXternally Initiated Reset) signal
|
||||
* may be asserted to specific processors via this register.
|
||||
*/
|
||||
#define BBC_SXG_CPU0 0x01 /* Assert XIR for processor 0 */
|
||||
#define BBC_SXG_CPU1 0x02 /* Assert XIR for processor 1 */
|
||||
#define BBC_SXG_CPU2 0x04 /* Assert XIR for processor 2 */
|
||||
#define BBC_SXG_CPU3 0x08 /* Assert XIR for processor 3 */
|
||||
#define BBC_SXG_RESV 0xf0 /* Reserved */
|
||||
|
||||
/* POR Source register. One may identify the cause of the most recent
|
||||
* reset by reading this register.
|
||||
*/
|
||||
#define BBC_PSRC_SPG0 0x0001 /* CPU 0 reset via BBC_SPG register */
|
||||
#define BBC_PSRC_SPG1 0x0002 /* CPU 1 reset via BBC_SPG register */
|
||||
#define BBC_PSRC_SPG2 0x0004 /* CPU 2 reset via BBC_SPG register */
|
||||
#define BBC_PSRC_SPG3 0x0008 /* CPU 3 reset via BBC_SPG register */
|
||||
#define BBC_PSRC_SPGSYS 0x0010 /* System reset via BBC_SPG register */
|
||||
#define BBC_PSRC_JTAG 0x0020 /* System reset via JTAG+ */
|
||||
#define BBC_PSRC_BUTTON 0x0040 /* System reset via push-button dongle */
|
||||
#define BBC_PSRC_PWRUP 0x0080 /* System reset via power-up */
|
||||
#define BBC_PSRC_FE0 0x0100 /* CPU 0 reported Fatal_Error */
|
||||
#define BBC_PSRC_FE1 0x0200 /* CPU 1 reported Fatal_Error */
|
||||
#define BBC_PSRC_FE2 0x0400 /* CPU 2 reported Fatal_Error */
|
||||
#define BBC_PSRC_FE3 0x0800 /* CPU 3 reported Fatal_Error */
|
||||
#define BBC_PSRC_FE4 0x1000 /* Schizo reported Fatal_Error */
|
||||
#define BBC_PSRC_FE5 0x2000 /* Safari device 5 reported Fatal_Error */
|
||||
#define BBC_PSRC_FE6 0x4000 /* CPMS reported Fatal_Error */
|
||||
#define BBC_PSRC_SYNTH 0x8000 /* System reset when on-board clock synthesizers
|
||||
* were updated.
|
||||
*/
|
||||
#define BBC_PSRC_WDT 0x10000 /* System reset via Super I/O watchdog */
|
||||
#define BBC_PSRC_RSC 0x20000 /* System reset via RSC remote monitoring
|
||||
* device
|
||||
*/
|
||||
|
||||
/* XIR Source register. The source of an XIR event sent to a processor may
|
||||
* be determined via this register.
|
||||
*/
|
||||
#define BBC_XSRC_SXG0 0x01 /* CPU 0 received XIR via Soft_XIR_GEN reg */
|
||||
#define BBC_XSRC_SXG1 0x02 /* CPU 1 received XIR via Soft_XIR_GEN reg */
|
||||
#define BBC_XSRC_SXG2 0x04 /* CPU 2 received XIR via Soft_XIR_GEN reg */
|
||||
#define BBC_XSRC_SXG3 0x08 /* CPU 3 received XIR via Soft_XIR_GEN reg */
|
||||
#define BBC_XSRC_JTAG 0x10 /* All CPUs received XIR via JTAG+ */
|
||||
#define BBC_XSRC_W_OR_B 0x20 /* All CPUs received XIR either because:
|
||||
* a) Super I/O watchdog fired, or
|
||||
* b) XIR push button was activated
|
||||
*/
|
||||
#define BBC_XSRC_RESV 0xc0 /* Reserved */
|
||||
|
||||
/* Clock Synthesizers Control register. This register provides the big-bang
|
||||
* programming interface to the two clock synthesizers of the machine.
|
||||
*/
|
||||
#define BBC_CSC_SLOAD 0x01 /* Directly connected to S_LOAD pins */
|
||||
#define BBC_CSC_SDATA 0x02 /* Directly connected to S_DATA pins */
|
||||
#define BBC_CSC_SCLOCK 0x04 /* Directly connected to S_CLOCK pins */
|
||||
#define BBC_CSC_RESV 0x78 /* Reserved */
|
||||
#define BBC_CSC_RST 0x80 /* Generate system reset when S_LOAD==1 */
|
||||
|
||||
/* Energy Star Control register. This register is used to generate the
|
||||
* clock frequency change trigger to the main system devices (Schizo and
|
||||
* the processors). The transition occurs when bits in this register
|
||||
* go from 0 to 1, only one bit must be set at once else no action
|
||||
* occurs. Basically the sequence of events is:
|
||||
* a) Choose new frequency: full, 1/2 or 1/32
|
||||
* b) Program this desired frequency into the cpus and Schizo.
|
||||
* c) Set the same value in this register.
|
||||
* d) 16 system clocks later, clear this register.
|
||||
*/
|
||||
#define BBC_ES_CTRL_1_1 0x01 /* Full frequency */
|
||||
#define BBC_ES_CTRL_1_2 0x02 /* 1/2 frequency */
|
||||
#define BBC_ES_CTRL_1_32 0x20 /* 1/32 frequency */
|
||||
#define BBC_ES_RESV 0xdc /* Reserved */
|
||||
|
||||
/* Energy Star Assert Change Time register. This determines the number
|
||||
* of BBC clock cycles (which is half the system frequency) between
|
||||
* the detection of FREEZE_ACK being asserted and the assertion of
|
||||
* the CLK_CHANGE_L[2:0] signals.
|
||||
*/
|
||||
#define BBC_ES_ACT_VAL 0xff
|
||||
|
||||
/* Energy Star Assert Bypass Time register. This determines the number
|
||||
* of BBC clock cycles (which is half the system frequency) between
|
||||
* the assertion of the CLK_CHANGE_L[2:0] signals and the assertion of
|
||||
* the ESTAR_PLL_BYPASS signal.
|
||||
*/
|
||||
#define BBC_ES_ABT_VAL 0xffff
|
||||
|
||||
/* Energy Star PLL Settle Time register. This determines the number of
|
||||
* BBC clock cycles (which is half the system frequency) between the
|
||||
* de-assertion of CLK_CHANGE_L[2:0] and the de-assertion of the FREEZE_L
|
||||
* signal.
|
||||
*/
|
||||
#define BBC_ES_PST_VAL 0xffffffff
|
||||
|
||||
/* Energy Star Frequency Switch Latency register. This is the number of
|
||||
* BBC clocks between the de-assertion of CLK_CHANGE_L[2:0] and the first
|
||||
* edge of the Safari clock at the new frequency.
|
||||
*/
|
||||
#define BBC_ES_FSL_VAL 0xffffffff
|
||||
|
||||
/* Keyboard Beep control register. This is a simple enabler for the audio
|
||||
* beep sound.
|
||||
*/
|
||||
#define BBC_KBD_BEEP_ENABLE 0x01 /* Enable beep */
|
||||
#define BBC_KBD_BEEP_RESV 0xfe /* Reserved */
|
||||
|
||||
/* Keyboard Beep Counter register. There is a free-running counter inside
|
||||
* the BBC which runs at half the system clock. The bit set in this register
|
||||
* determines when the audio sound is generated. So for example if bit
|
||||
* 10 is set, the audio beep will oscillate at 1/(2**12). The keyboard beep
|
||||
* generator automatically selects a different bit to use if the system clock
|
||||
* is changed via Energy Star.
|
||||
*/
|
||||
#define BBC_KBD_BCNT_BITS 0x0007fc00
|
||||
#define BBC_KBC_BCNT_RESV 0xfff803ff
|
||||
|
||||
#endif /* _SPARC64_BBC_H */
|
||||
|
27
arch/sparc/include/asm/bitext.h
Normal file
27
arch/sparc/include/asm/bitext.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* bitext.h: Bit string operations on the sparc, specific to architecture.
|
||||
*
|
||||
* Copyright 2002 Pete Zaitcev <zaitcev@yahoo.com>
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_BITEXT_H
|
||||
#define _SPARC_BITEXT_H
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
struct bit_map {
|
||||
spinlock_t lock;
|
||||
unsigned long *map;
|
||||
int size;
|
||||
int used;
|
||||
int last_off;
|
||||
int last_size;
|
||||
int first_free;
|
||||
int num_colors;
|
||||
};
|
||||
|
||||
int bit_map_string_get(struct bit_map *t, int len, int align);
|
||||
void bit_map_clear(struct bit_map *t, int offset, int len);
|
||||
void bit_map_init(struct bit_map *t, unsigned long *map, int size);
|
||||
|
||||
#endif /* defined(_SPARC_BITEXT_H) */
|
8
arch/sparc/include/asm/bitops.h
Normal file
8
arch/sparc/include/asm/bitops.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ___ASM_SPARC_BITOPS_H
|
||||
#define ___ASM_SPARC_BITOPS_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm/bitops_64.h>
|
||||
#else
|
||||
#include <asm/bitops_32.h>
|
||||
#endif
|
||||
#endif
|
108
arch/sparc/include/asm/bitops_32.h
Normal file
108
arch/sparc/include/asm/bitops_32.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* bitops.h: Bit string operations on the Sparc.
|
||||
*
|
||||
* Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
* Copyright 1996 Eddie C. Dost (ecd@skynet.be)
|
||||
* Copyright 2001 Anton Blanchard (anton@samba.org)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_BITOPS_H
|
||||
#define _SPARC_BITOPS_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef _LINUX_BITOPS_H
|
||||
#error only <linux/bitops.h> can be included directly
|
||||
#endif
|
||||
|
||||
unsigned long ___set_bit(unsigned long *addr, unsigned long mask);
|
||||
unsigned long ___clear_bit(unsigned long *addr, unsigned long mask);
|
||||
unsigned long ___change_bit(unsigned long *addr, unsigned long mask);
|
||||
|
||||
/*
|
||||
* Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0'
|
||||
* is in the highest of the four bytes and bit '31' is the high bit
|
||||
* within the first byte. Sparc is BIG-Endian. Unless noted otherwise
|
||||
* all bit-ops return 0 if bit was previously clear and != 0 otherwise.
|
||||
*/
|
||||
static inline int test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
return ___set_bit(ADDR, mask) != 0;
|
||||
}
|
||||
|
||||
static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
(void) ___set_bit(ADDR, mask);
|
||||
}
|
||||
|
||||
static inline int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
return ___clear_bit(ADDR, mask) != 0;
|
||||
}
|
||||
|
||||
static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
(void) ___clear_bit(ADDR, mask);
|
||||
}
|
||||
|
||||
static inline int test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
return ___change_bit(ADDR, mask) != 0;
|
||||
}
|
||||
|
||||
static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long *ADDR, mask;
|
||||
|
||||
ADDR = ((unsigned long *) addr) + (nr >> 5);
|
||||
mask = 1 << (nr & 31);
|
||||
|
||||
(void) ___change_bit(ADDR, mask);
|
||||
}
|
||||
|
||||
#include <asm-generic/bitops/non-atomic.h>
|
||||
|
||||
#include <asm-generic/bitops/ffz.h>
|
||||
#include <asm-generic/bitops/__ffs.h>
|
||||
#include <asm-generic/bitops/sched.h>
|
||||
#include <asm-generic/bitops/ffs.h>
|
||||
#include <asm-generic/bitops/fls.h>
|
||||
#include <asm-generic/bitops/__fls.h>
|
||||
#include <asm-generic/bitops/fls64.h>
|
||||
#include <asm-generic/bitops/hweight.h>
|
||||
#include <asm-generic/bitops/lock.h>
|
||||
#include <asm-generic/bitops/find.h>
|
||||
#include <asm-generic/bitops/le.h>
|
||||
#include <asm-generic/bitops/ext2-atomic.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* defined(_SPARC_BITOPS_H) */
|
63
arch/sparc/include/asm/bitops_64.h
Normal file
63
arch/sparc/include/asm/bitops_64.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* bitops.h: Bit string operations on the V9.
|
||||
*
|
||||
* Copyright 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC64_BITOPS_H
|
||||
#define _SPARC64_BITOPS_H
|
||||
|
||||
#ifndef _LINUX_BITOPS_H
|
||||
#error only <linux/bitops.h> can be included directly
|
||||
#endif
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/barrier.h>
|
||||
|
||||
int test_and_set_bit(unsigned long nr, volatile unsigned long *addr);
|
||||
int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr);
|
||||
int test_and_change_bit(unsigned long nr, volatile unsigned long *addr);
|
||||
void set_bit(unsigned long nr, volatile unsigned long *addr);
|
||||
void clear_bit(unsigned long nr, volatile unsigned long *addr);
|
||||
void change_bit(unsigned long nr, volatile unsigned long *addr);
|
||||
|
||||
#include <asm-generic/bitops/non-atomic.h>
|
||||
|
||||
#include <asm-generic/bitops/fls.h>
|
||||
#include <asm-generic/bitops/__fls.h>
|
||||
#include <asm-generic/bitops/fls64.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
int ffs(int x);
|
||||
unsigned long __ffs(unsigned long);
|
||||
|
||||
#include <asm-generic/bitops/ffz.h>
|
||||
#include <asm-generic/bitops/sched.h>
|
||||
|
||||
/*
|
||||
* hweightN: returns the hamming weight (i.e. the number
|
||||
* of bits set) of a N-bit word
|
||||
*/
|
||||
|
||||
unsigned long __arch_hweight64(__u64 w);
|
||||
unsigned int __arch_hweight32(unsigned int w);
|
||||
unsigned int __arch_hweight16(unsigned int w);
|
||||
unsigned int __arch_hweight8(unsigned int w);
|
||||
|
||||
#include <asm-generic/bitops/const_hweight.h>
|
||||
#include <asm-generic/bitops/lock.h>
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#include <asm-generic/bitops/find.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <asm-generic/bitops/le.h>
|
||||
|
||||
#include <asm-generic/bitops/ext2-atomic-setbit.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* defined(_SPARC64_BITOPS_H) */
|
6
arch/sparc/include/asm/btext.h
Normal file
6
arch/sparc/include/asm/btext.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef _SPARC_BTEXT_H
|
||||
#define _SPARC_BTEXT_H
|
||||
|
||||
int btext_find_display(void);
|
||||
|
||||
#endif /* _SPARC_BTEXT_H */
|
25
arch/sparc/include/asm/bug.h
Normal file
25
arch/sparc/include/asm/bug.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef _SPARC_BUG_H
|
||||
#define _SPARC_BUG_H
|
||||
|
||||
#ifdef CONFIG_BUG
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
||||
void do_BUG(const char *file, int line);
|
||||
#define BUG() do { \
|
||||
do_BUG(__FILE__, __LINE__); \
|
||||
__builtin_trap(); \
|
||||
} while (0)
|
||||
#else
|
||||
#define BUG() __builtin_trap()
|
||||
#endif
|
||||
|
||||
#define HAVE_ARCH_BUG
|
||||
#endif
|
||||
|
||||
#include <asm-generic/bug.h>
|
||||
|
||||
struct pt_regs;
|
||||
void __noreturn die_if_kernel(char *str, struct pt_regs *regs);
|
||||
|
||||
#endif
|
17
arch/sparc/include/asm/bugs.h
Normal file
17
arch/sparc/include/asm/bugs.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* include/asm/bugs.h: Sparc probes for various bugs.
|
||||
*
|
||||
* Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SPARC32
|
||||
#include <asm/cpudata.h>
|
||||
#endif
|
||||
|
||||
extern unsigned long loops_per_jiffy;
|
||||
|
||||
static void __init check_bugs(void)
|
||||
{
|
||||
#if defined(CONFIG_SPARC32) && !defined(CONFIG_SMP)
|
||||
cpu_data(0).udelay_val = loops_per_jiffy;
|
||||
#endif
|
||||
}
|
25
arch/sparc/include/asm/cache.h
Normal file
25
arch/sparc/include/asm/cache.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* cache.h: Cache specific code for the Sparc. These include flushing
|
||||
* and direct tag/data line access.
|
||||
*
|
||||
* Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_CACHE_H
|
||||
#define _SPARC_CACHE_H
|
||||
|
||||
#define ARCH_SLAB_MINALIGN __alignof__(unsigned long long)
|
||||
|
||||
#define L1_CACHE_SHIFT 5
|
||||
#define L1_CACHE_BYTES 32
|
||||
|
||||
#ifdef CONFIG_SPARC32
|
||||
#define SMP_CACHE_BYTES_SHIFT 5
|
||||
#else
|
||||
#define SMP_CACHE_BYTES_SHIFT 6
|
||||
#endif
|
||||
|
||||
#define SMP_CACHE_BYTES (1 << SMP_CACHE_BYTES_SHIFT)
|
||||
|
||||
#define __read_mostly __attribute__((__section__(".data..read_mostly")))
|
||||
|
||||
#endif /* !(_SPARC_CACHE_H) */
|
12
arch/sparc/include/asm/cacheflush.h
Normal file
12
arch/sparc/include/asm/cacheflush.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef ___ASM_SPARC_CACHEFLUSH_H
|
||||
#define ___ASM_SPARC_CACHEFLUSH_H
|
||||
|
||||
/* flush addr - to allow use of self-modifying code */
|
||||
#define flushi(addr) __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory")
|
||||
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm/cacheflush_64.h>
|
||||
#else
|
||||
#include <asm/cacheflush_32.h>
|
||||
#endif
|
||||
#endif
|
58
arch/sparc/include/asm/cacheflush_32.h
Normal file
58
arch/sparc/include/asm/cacheflush_32.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
#ifndef _SPARC_CACHEFLUSH_H
|
||||
#define _SPARC_CACHEFLUSH_H
|
||||
|
||||
#include <asm/cachetlb_32.h>
|
||||
|
||||
#define flush_cache_all() \
|
||||
sparc32_cachetlb_ops->cache_all()
|
||||
#define flush_cache_mm(mm) \
|
||||
sparc32_cachetlb_ops->cache_mm(mm)
|
||||
#define flush_cache_dup_mm(mm) \
|
||||
sparc32_cachetlb_ops->cache_mm(mm)
|
||||
#define flush_cache_range(vma,start,end) \
|
||||
sparc32_cachetlb_ops->cache_range(vma, start, end)
|
||||
#define flush_cache_page(vma,addr,pfn) \
|
||||
sparc32_cachetlb_ops->cache_page(vma, addr)
|
||||
#define flush_icache_range(start, end) do { } while (0)
|
||||
#define flush_icache_page(vma, pg) do { } while (0)
|
||||
|
||||
#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
|
||||
|
||||
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
|
||||
do { \
|
||||
flush_cache_page(vma, vaddr, page_to_pfn(page));\
|
||||
memcpy(dst, src, len); \
|
||||
} while (0)
|
||||
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
|
||||
do { \
|
||||
flush_cache_page(vma, vaddr, page_to_pfn(page));\
|
||||
memcpy(dst, src, len); \
|
||||
} while (0)
|
||||
|
||||
#define __flush_page_to_ram(addr) \
|
||||
sparc32_cachetlb_ops->page_to_ram(addr)
|
||||
#define flush_sig_insns(mm,insn_addr) \
|
||||
sparc32_cachetlb_ops->sig_insns(mm, insn_addr)
|
||||
#define flush_page_for_dma(addr) \
|
||||
sparc32_cachetlb_ops->page_for_dma(addr)
|
||||
|
||||
void sparc_flush_page_to_ram(struct page *page);
|
||||
|
||||
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
|
||||
#define flush_dcache_page(page) sparc_flush_page_to_ram(page)
|
||||
#define flush_dcache_mmap_lock(mapping) do { } while (0)
|
||||
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
|
||||
|
||||
#define flush_cache_vmap(start, end) flush_cache_all()
|
||||
#define flush_cache_vunmap(start, end) flush_cache_all()
|
||||
|
||||
/* When a context switch happens we must flush all user windows so that
|
||||
* the windows of the current process are flushed onto its stack. This
|
||||
* way the windows are all clean for the next process and the stack
|
||||
* frames are up to date.
|
||||
*/
|
||||
void flush_user_windows(void);
|
||||
void kill_user_windows(void);
|
||||
void flushw_all(void);
|
||||
|
||||
#endif /* _SPARC_CACHEFLUSH_H */
|
84
arch/sparc/include/asm/cacheflush_64.h
Normal file
84
arch/sparc/include/asm/cacheflush_64.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
#ifndef _SPARC64_CACHEFLUSH_H
|
||||
#define _SPARC64_CACHEFLUSH_H
|
||||
|
||||
#include <asm/page.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/mm.h>
|
||||
|
||||
/* Cache flush operations. */
|
||||
#define flushw_all() __asm__ __volatile__("flushw")
|
||||
|
||||
void __flushw_user(void);
|
||||
#define flushw_user() __flushw_user()
|
||||
|
||||
#define flush_user_windows flushw_user
|
||||
#define flush_register_windows flushw_all
|
||||
|
||||
/* These are the same regardless of whether this is an SMP kernel or not. */
|
||||
#define flush_cache_mm(__mm) \
|
||||
do { if ((__mm) == current->mm) flushw_user(); } while(0)
|
||||
#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
|
||||
#define flush_cache_range(vma, start, end) \
|
||||
flush_cache_mm((vma)->vm_mm)
|
||||
#define flush_cache_page(vma, page, pfn) \
|
||||
flush_cache_mm((vma)->vm_mm)
|
||||
|
||||
/*
|
||||
* On spitfire, the icache doesn't snoop local stores and we don't
|
||||
* use block commit stores (which invalidate icache lines) during
|
||||
* module load, so we need this.
|
||||
*/
|
||||
void flush_icache_range(unsigned long start, unsigned long end);
|
||||
void __flush_icache_page(unsigned long);
|
||||
|
||||
void __flush_dcache_page(void *addr, int flush_icache);
|
||||
void flush_dcache_page_impl(struct page *page);
|
||||
#ifdef CONFIG_SMP
|
||||
void smp_flush_dcache_page_impl(struct page *page, int cpu);
|
||||
void flush_dcache_page_all(struct mm_struct *mm, struct page *page);
|
||||
#else
|
||||
#define smp_flush_dcache_page_impl(page,cpu) flush_dcache_page_impl(page)
|
||||
#define flush_dcache_page_all(mm,page) flush_dcache_page_impl(page)
|
||||
#endif
|
||||
|
||||
void __flush_dcache_range(unsigned long start, unsigned long end);
|
||||
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
|
||||
void flush_dcache_page(struct page *page);
|
||||
|
||||
#define flush_icache_page(vma, pg) do { } while(0)
|
||||
#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
|
||||
|
||||
void flush_ptrace_access(struct vm_area_struct *, struct page *,
|
||||
unsigned long uaddr, void *kaddr,
|
||||
unsigned long len, int write);
|
||||
|
||||
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
|
||||
do { \
|
||||
flush_cache_page(vma, vaddr, page_to_pfn(page)); \
|
||||
memcpy(dst, src, len); \
|
||||
flush_ptrace_access(vma, page, vaddr, src, len, 0); \
|
||||
} while (0)
|
||||
|
||||
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
|
||||
do { \
|
||||
flush_cache_page(vma, vaddr, page_to_pfn(page)); \
|
||||
memcpy(dst, src, len); \
|
||||
flush_ptrace_access(vma, page, vaddr, dst, len, 1); \
|
||||
} while (0)
|
||||
|
||||
#define flush_dcache_mmap_lock(mapping) do { } while (0)
|
||||
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
|
||||
|
||||
#define flush_cache_vmap(start, end) do { } while (0)
|
||||
#define flush_cache_vunmap(start, end) do { } while (0)
|
||||
|
||||
#ifdef CONFIG_DEBUG_PAGEALLOC
|
||||
/* internal debugging function */
|
||||
void kernel_map_pages(struct page *page, int numpages, int enable);
|
||||
#endif
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _SPARC64_CACHEFLUSH_H */
|
29
arch/sparc/include/asm/cachetlb_32.h
Normal file
29
arch/sparc/include/asm/cachetlb_32.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef _SPARC_CACHETLB_H
|
||||
#define _SPARC_CACHETLB_H
|
||||
|
||||
struct mm_struct;
|
||||
struct vm_area_struct;
|
||||
|
||||
struct sparc32_cachetlb_ops {
|
||||
void (*cache_all)(void);
|
||||
void (*cache_mm)(struct mm_struct *);
|
||||
void (*cache_range)(struct vm_area_struct *, unsigned long,
|
||||
unsigned long);
|
||||
void (*cache_page)(struct vm_area_struct *, unsigned long);
|
||||
|
||||
void (*tlb_all)(void);
|
||||
void (*tlb_mm)(struct mm_struct *);
|
||||
void (*tlb_range)(struct vm_area_struct *, unsigned long,
|
||||
unsigned long);
|
||||
void (*tlb_page)(struct vm_area_struct *, unsigned long);
|
||||
|
||||
void (*page_to_ram)(unsigned long);
|
||||
void (*sig_insns)(struct mm_struct *, unsigned long);
|
||||
void (*page_for_dma)(unsigned long);
|
||||
};
|
||||
extern const struct sparc32_cachetlb_ops *sparc32_cachetlb_ops;
|
||||
#ifdef CONFIG_SMP
|
||||
extern const struct sparc32_cachetlb_ops *local_ops;
|
||||
#endif
|
||||
|
||||
#endif /* SPARC_CACHETLB_H */
|
241
arch/sparc/include/asm/chafsr.h
Normal file
241
arch/sparc/include/asm/chafsr.h
Normal file
|
@ -0,0 +1,241 @@
|
|||
#ifndef _SPARC64_CHAFSR_H
|
||||
#define _SPARC64_CHAFSR_H
|
||||
|
||||
/* Cheetah Asynchronous Fault Status register, ASI=0x4C VA<63:0>=0x0 */
|
||||
|
||||
/* Comments indicate which processor variants on which the bit definition
|
||||
* is valid. Codes are:
|
||||
* ch --> cheetah
|
||||
* ch+ --> cheetah plus
|
||||
* jp --> jalapeno
|
||||
*/
|
||||
|
||||
/* All bits of this register except M_SYNDROME and E_SYNDROME are
|
||||
* read, write 1 to clear. M_SYNDROME and E_SYNDROME are read-only.
|
||||
*/
|
||||
|
||||
/* Software bit set by linux trap handlers to indicate that the trap was
|
||||
* signalled at %tl >= 1.
|
||||
*/
|
||||
#define CHAFSR_TL1 (1UL << 63UL) /* n/a */
|
||||
|
||||
/* Unmapped error from system bus for prefetch queue or
|
||||
* store queue read operation
|
||||
*/
|
||||
#define CHPAFSR_DTO (1UL << 59UL) /* ch+ */
|
||||
|
||||
/* Bus error from system bus for prefetch queue or store queue
|
||||
* read operation
|
||||
*/
|
||||
#define CHPAFSR_DBERR (1UL << 58UL) /* ch+ */
|
||||
|
||||
/* Hardware corrected E-cache Tag ECC error */
|
||||
#define CHPAFSR_THCE (1UL << 57UL) /* ch+ */
|
||||
/* System interface protocol error, hw timeout caused */
|
||||
#define JPAFSR_JETO (1UL << 57UL) /* jp */
|
||||
|
||||
/* SW handled correctable E-cache Tag ECC error */
|
||||
#define CHPAFSR_TSCE (1UL << 56UL) /* ch+ */
|
||||
/* Parity error on system snoop results */
|
||||
#define JPAFSR_SCE (1UL << 56UL) /* jp */
|
||||
|
||||
/* Uncorrectable E-cache Tag ECC error */
|
||||
#define CHPAFSR_TUE (1UL << 55UL) /* ch+ */
|
||||
/* System interface protocol error, illegal command detected */
|
||||
#define JPAFSR_JEIC (1UL << 55UL) /* jp */
|
||||
|
||||
/* Uncorrectable system bus data ECC error due to prefetch
|
||||
* or store fill request
|
||||
*/
|
||||
#define CHPAFSR_DUE (1UL << 54UL) /* ch+ */
|
||||
/* System interface protocol error, illegal ADTYPE detected */
|
||||
#define JPAFSR_JEIT (1UL << 54UL) /* jp */
|
||||
|
||||
/* Multiple errors of the same type have occurred. This bit is set when
|
||||
* an uncorrectable error or a SW correctable error occurs and the status
|
||||
* bit to report that error is already set. When multiple errors of
|
||||
* different types are indicated by setting multiple status bits.
|
||||
*
|
||||
* This bit is not set if multiple HW corrected errors with the same
|
||||
* status bit occur, only uncorrectable and SW correctable ones have
|
||||
* this behavior.
|
||||
*
|
||||
* This bit is not set when multiple ECC errors happen within a single
|
||||
* 64-byte system bus transaction. Only the first ECC error in a 16-byte
|
||||
* subunit will be logged. All errors in subsequent 16-byte subunits
|
||||
* from the same 64-byte transaction are ignored.
|
||||
*/
|
||||
#define CHAFSR_ME (1UL << 53UL) /* ch,ch+,jp */
|
||||
|
||||
/* Privileged state error has occurred. This is a capture of PSTATE.PRIV
|
||||
* at the time the error is detected.
|
||||
*/
|
||||
#define CHAFSR_PRIV (1UL << 52UL) /* ch,ch+,jp */
|
||||
|
||||
/* The following bits 51 (CHAFSR_PERR) to 33 (CHAFSR_CE) are sticky error
|
||||
* bits and record the most recently detected errors. Bits accumulate
|
||||
* errors that have been detected since the last write to clear the bit.
|
||||
*/
|
||||
|
||||
/* System interface protocol error. The processor asserts its' ERROR
|
||||
* pin when this event occurs and it also logs a specific cause code
|
||||
* into a JTAG scannable flop.
|
||||
*/
|
||||
#define CHAFSR_PERR (1UL << 51UL) /* ch,ch+,jp */
|
||||
|
||||
/* Internal processor error. The processor asserts its' ERROR
|
||||
* pin when this event occurs and it also logs a specific cause code
|
||||
* into a JTAG scannable flop.
|
||||
*/
|
||||
#define CHAFSR_IERR (1UL << 50UL) /* ch,ch+,jp */
|
||||
|
||||
/* System request parity error on incoming address */
|
||||
#define CHAFSR_ISAP (1UL << 49UL) /* ch,ch+,jp */
|
||||
|
||||
/* HW Corrected system bus MTAG ECC error */
|
||||
#define CHAFSR_EMC (1UL << 48UL) /* ch,ch+ */
|
||||
/* Parity error on L2 cache tag SRAM */
|
||||
#define JPAFSR_ETP (1UL << 48UL) /* jp */
|
||||
|
||||
/* Uncorrectable system bus MTAG ECC error */
|
||||
#define CHAFSR_EMU (1UL << 47UL) /* ch,ch+ */
|
||||
/* Out of range memory error has occurred */
|
||||
#define JPAFSR_OM (1UL << 47UL) /* jp */
|
||||
|
||||
/* HW Corrected system bus data ECC error for read of interrupt vector */
|
||||
#define CHAFSR_IVC (1UL << 46UL) /* ch,ch+ */
|
||||
/* Error due to unsupported store */
|
||||
#define JPAFSR_UMS (1UL << 46UL) /* jp */
|
||||
|
||||
/* Uncorrectable system bus data ECC error for read of interrupt vector */
|
||||
#define CHAFSR_IVU (1UL << 45UL) /* ch,ch+,jp */
|
||||
|
||||
/* Unmapped error from system bus */
|
||||
#define CHAFSR_TO (1UL << 44UL) /* ch,ch+,jp */
|
||||
|
||||
/* Bus error response from system bus */
|
||||
#define CHAFSR_BERR (1UL << 43UL) /* ch,ch+,jp */
|
||||
|
||||
/* SW Correctable E-cache ECC error for instruction fetch or data access
|
||||
* other than block load.
|
||||
*/
|
||||
#define CHAFSR_UCC (1UL << 42UL) /* ch,ch+,jp */
|
||||
|
||||
/* Uncorrectable E-cache ECC error for instruction fetch or data access
|
||||
* other than block load.
|
||||
*/
|
||||
#define CHAFSR_UCU (1UL << 41UL) /* ch,ch+,jp */
|
||||
|
||||
/* Copyout HW Corrected ECC error */
|
||||
#define CHAFSR_CPC (1UL << 40UL) /* ch,ch+,jp */
|
||||
|
||||
/* Copyout Uncorrectable ECC error */
|
||||
#define CHAFSR_CPU (1UL << 39UL) /* ch,ch+,jp */
|
||||
|
||||
/* HW Corrected ECC error from E-cache for writeback */
|
||||
#define CHAFSR_WDC (1UL << 38UL) /* ch,ch+,jp */
|
||||
|
||||
/* Uncorrectable ECC error from E-cache for writeback */
|
||||
#define CHAFSR_WDU (1UL << 37UL) /* ch,ch+,jp */
|
||||
|
||||
/* HW Corrected ECC error from E-cache for store merge or block load */
|
||||
#define CHAFSR_EDC (1UL << 36UL) /* ch,ch+,jp */
|
||||
|
||||
/* Uncorrectable ECC error from E-cache for store merge or block load */
|
||||
#define CHAFSR_EDU (1UL << 35UL) /* ch,ch+,jp */
|
||||
|
||||
/* Uncorrectable system bus data ECC error for read of memory or I/O */
|
||||
#define CHAFSR_UE (1UL << 34UL) /* ch,ch+,jp */
|
||||
|
||||
/* HW Corrected system bus data ECC error for read of memory or I/O */
|
||||
#define CHAFSR_CE (1UL << 33UL) /* ch,ch+,jp */
|
||||
|
||||
/* Uncorrectable ECC error from remote cache/memory */
|
||||
#define JPAFSR_RUE (1UL << 32UL) /* jp */
|
||||
|
||||
/* Correctable ECC error from remote cache/memory */
|
||||
#define JPAFSR_RCE (1UL << 31UL) /* jp */
|
||||
|
||||
/* JBUS parity error on returned read data */
|
||||
#define JPAFSR_BP (1UL << 30UL) /* jp */
|
||||
|
||||
/* JBUS parity error on data for writeback or block store */
|
||||
#define JPAFSR_WBP (1UL << 29UL) /* jp */
|
||||
|
||||
/* Foreign read to DRAM incurring correctable ECC error */
|
||||
#define JPAFSR_FRC (1UL << 28UL) /* jp */
|
||||
|
||||
/* Foreign read to DRAM incurring uncorrectable ECC error */
|
||||
#define JPAFSR_FRU (1UL << 27UL) /* jp */
|
||||
|
||||
#define CHAFSR_ERRORS (CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP | CHAFSR_EMC | \
|
||||
CHAFSR_EMU | CHAFSR_IVC | CHAFSR_IVU | CHAFSR_TO | \
|
||||
CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | CHAFSR_CPC | \
|
||||
CHAFSR_CPU | CHAFSR_WDC | CHAFSR_WDU | CHAFSR_EDC | \
|
||||
CHAFSR_EDU | CHAFSR_UE | CHAFSR_CE)
|
||||
#define CHPAFSR_ERRORS (CHPAFSR_DTO | CHPAFSR_DBERR | CHPAFSR_THCE | \
|
||||
CHPAFSR_TSCE | CHPAFSR_TUE | CHPAFSR_DUE | \
|
||||
CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP | CHAFSR_EMC | \
|
||||
CHAFSR_EMU | CHAFSR_IVC | CHAFSR_IVU | CHAFSR_TO | \
|
||||
CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | CHAFSR_CPC | \
|
||||
CHAFSR_CPU | CHAFSR_WDC | CHAFSR_WDU | CHAFSR_EDC | \
|
||||
CHAFSR_EDU | CHAFSR_UE | CHAFSR_CE)
|
||||
#define JPAFSR_ERRORS (JPAFSR_JETO | JPAFSR_SCE | JPAFSR_JEIC | \
|
||||
JPAFSR_JEIT | CHAFSR_PERR | CHAFSR_IERR | \
|
||||
CHAFSR_ISAP | JPAFSR_ETP | JPAFSR_OM | \
|
||||
JPAFSR_UMS | CHAFSR_IVU | CHAFSR_TO | \
|
||||
CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | \
|
||||
CHAFSR_CPC | CHAFSR_CPU | CHAFSR_WDC | \
|
||||
CHAFSR_WDU | CHAFSR_EDC | CHAFSR_EDU | \
|
||||
CHAFSR_UE | CHAFSR_CE | JPAFSR_RUE | \
|
||||
JPAFSR_RCE | JPAFSR_BP | JPAFSR_WBP | \
|
||||
JPAFSR_FRC | JPAFSR_FRU)
|
||||
|
||||
/* Active JBUS request signal when error occurred */
|
||||
#define JPAFSR_JBREQ (0x7UL << 24UL) /* jp */
|
||||
#define JPAFSR_JBREQ_SHIFT 24UL
|
||||
|
||||
/* L2 cache way information */
|
||||
#define JPAFSR_ETW (0x3UL << 22UL) /* jp */
|
||||
#define JPAFSR_ETW_SHIFT 22UL
|
||||
|
||||
/* System bus MTAG ECC syndrome. This field captures the status of the
|
||||
* first occurrence of the highest-priority error according to the M_SYND
|
||||
* overwrite policy. After the AFSR sticky bit, corresponding to the error
|
||||
* for which the M_SYND is reported, is cleared, the contents of the M_SYND
|
||||
* field will be unchanged by will be unfrozen for further error capture.
|
||||
*/
|
||||
#define CHAFSR_M_SYNDROME (0xfUL << 16UL) /* ch,ch+,jp */
|
||||
#define CHAFSR_M_SYNDROME_SHIFT 16UL
|
||||
|
||||
/* Agenid Id of the foreign device causing the UE/CE errors */
|
||||
#define JPAFSR_AID (0x1fUL << 9UL) /* jp */
|
||||
#define JPAFSR_AID_SHIFT 9UL
|
||||
|
||||
/* System bus or E-cache data ECC syndrome. This field captures the status
|
||||
* of the first occurrence of the highest-priority error according to the
|
||||
* E_SYND overwrite policy. After the AFSR sticky bit, corresponding to the
|
||||
* error for which the E_SYND is reported, is cleare, the contents of the E_SYND
|
||||
* field will be unchanged but will be unfrozen for further error capture.
|
||||
*/
|
||||
#define CHAFSR_E_SYNDROME (0x1ffUL << 0UL) /* ch,ch+,jp */
|
||||
#define CHAFSR_E_SYNDROME_SHIFT 0UL
|
||||
|
||||
/* The AFSR must be explicitly cleared by software, it is not cleared automatically
|
||||
* by a read. Writes to bits <51:33> with bits set will clear the corresponding
|
||||
* bits in the AFSR. Bits associated with disrupting traps must be cleared before
|
||||
* interrupts are re-enabled to prevent multiple traps for the same error. I.e.
|
||||
* PSTATE.IE and AFSR bits control delivery of disrupting traps.
|
||||
*
|
||||
* Since there is only one AFAR, when multiple events have been logged by the
|
||||
* bits in the AFSR, at most one of these events will have its status captured
|
||||
* in the AFAR. The highest priority of those event bits will get AFAR logging.
|
||||
* The AFAR will be unlocked and available to capture the address of another event
|
||||
* as soon as the one bit in AFSR that corresponds to the event logged in AFAR is
|
||||
* cleared. For example, if AFSR.CE is detected, then AFSR.UE (which overwrites
|
||||
* the AFAR), and AFSR.UE is cleared by not AFSR.CE, then the AFAR will be unlocked
|
||||
* and ready for another event, even though AFSR.CE is still set. The same rules
|
||||
* also apply to the M_SYNDROME and E_SYNDROME fields of the AFSR.
|
||||
*/
|
||||
|
||||
#endif /* _SPARC64_CHAFSR_H */
|
8
arch/sparc/include/asm/checksum.h
Normal file
8
arch/sparc/include/asm/checksum.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ___ASM_SPARC_CHECKSUM_H
|
||||
#define ___ASM_SPARC_CHECKSUM_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm/checksum_64.h>
|
||||
#else
|
||||
#include <asm/checksum_32.h>
|
||||
#endif
|
||||
#endif
|
253
arch/sparc/include/asm/checksum_32.h
Normal file
253
arch/sparc/include/asm/checksum_32.h
Normal file
|
@ -0,0 +1,253 @@
|
|||
#ifndef __SPARC_CHECKSUM_H
|
||||
#define __SPARC_CHECKSUM_H
|
||||
|
||||
/* checksum.h: IP/UDP/TCP checksum routines on the Sparc.
|
||||
*
|
||||
* Copyright(C) 1995 Linus Torvalds
|
||||
* Copyright(C) 1995 Miguel de Icaza
|
||||
* Copyright(C) 1996 David S. Miller
|
||||
* Copyright(C) 1996 Eddie C. Dost
|
||||
* Copyright(C) 1997 Jakub Jelinek
|
||||
*
|
||||
* derived from:
|
||||
* Alpha checksum c-code
|
||||
* ix86 inline assembly
|
||||
* RFC1071 Computing the Internet Checksum
|
||||
*/
|
||||
|
||||
#include <linux/in6.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
/* computes the checksum of a memory block at buff, length len,
|
||||
* and adds in "sum" (32-bit)
|
||||
*
|
||||
* returns a 32-bit number suitable for feeding into itself
|
||||
* or csum_tcpudp_magic
|
||||
*
|
||||
* this function must be called with even lengths, except
|
||||
* for the last fragment, which may be odd
|
||||
*
|
||||
* it's best to have buff aligned on a 32-bit boundary
|
||||
*/
|
||||
__wsum csum_partial(const void *buff, int len, __wsum sum);
|
||||
|
||||
/* the same as csum_partial, but copies from fs: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_sparc_generic (const unsigned char *, unsigned char *);
|
||||
|
||||
static inline __wsum
|
||||
csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
|
||||
{
|
||||
register unsigned int ret asm("o0") = (unsigned int)src;
|
||||
register char *d asm("o1") = dst;
|
||||
register int l asm("g1") = len;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"call __csum_partial_copy_sparc_generic\n\t"
|
||||
" mov %6, %%g7\n"
|
||||
: "=&r" (ret), "=&r" (d), "=&r" (l)
|
||||
: "0" (ret), "1" (d), "2" (l), "r" (sum)
|
||||
: "o2", "o3", "o4", "o5", "o7",
|
||||
"g2", "g3", "g4", "g5", "g7",
|
||||
"memory", "cc");
|
||||
return (__force __wsum)ret;
|
||||
}
|
||||
|
||||
static inline __wsum
|
||||
csum_partial_copy_from_user(const void __user *src, void *dst, int len,
|
||||
__wsum sum, int *err)
|
||||
{
|
||||
register unsigned long ret asm("o0") = (unsigned long)src;
|
||||
register char *d asm("o1") = dst;
|
||||
register int l asm("g1") = len;
|
||||
register __wsum s asm("g7") = sum;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
".section __ex_table,#alloc\n\t"
|
||||
".align 4\n\t"
|
||||
".word 1f,2\n\t"
|
||||
".previous\n"
|
||||
"1:\n\t"
|
||||
"call __csum_partial_copy_sparc_generic\n\t"
|
||||
" st %8, [%%sp + 64]\n"
|
||||
: "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s)
|
||||
: "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err)
|
||||
: "o2", "o3", "o4", "o5", "o7", "g2", "g3", "g4", "g5",
|
||||
"cc", "memory");
|
||||
return (__force __wsum)ret;
|
||||
}
|
||||
|
||||
static inline __wsum
|
||||
csum_partial_copy_to_user(const void *src, void __user *dst, int len,
|
||||
__wsum sum, int *err)
|
||||
{
|
||||
if (!access_ok (VERIFY_WRITE, dst, len)) {
|
||||
*err = -EFAULT;
|
||||
return sum;
|
||||
} else {
|
||||
register unsigned long ret asm("o0") = (unsigned long)src;
|
||||
register char __user *d asm("o1") = dst;
|
||||
register int l asm("g1") = len;
|
||||
register __wsum s asm("g7") = sum;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
".section __ex_table,#alloc\n\t"
|
||||
".align 4\n\t"
|
||||
".word 1f,1\n\t"
|
||||
".previous\n"
|
||||
"1:\n\t"
|
||||
"call __csum_partial_copy_sparc_generic\n\t"
|
||||
" st %8, [%%sp + 64]\n"
|
||||
: "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s)
|
||||
: "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err)
|
||||
: "o2", "o3", "o4", "o5", "o7",
|
||||
"g2", "g3", "g4", "g5",
|
||||
"cc", "memory");
|
||||
return (__force __wsum)ret;
|
||||
}
|
||||
}
|
||||
|
||||
#define HAVE_CSUM_COPY_USER
|
||||
#define csum_and_copy_to_user csum_partial_copy_to_user
|
||||
|
||||
/* ihl is always 5 or greater, almost always is 5, and iph is word aligned
|
||||
* the majority of the time.
|
||||
*/
|
||||
static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
|
||||
{
|
||||
__sum16 sum;
|
||||
|
||||
/* Note: We must read %2 before we touch %0 for the first time,
|
||||
* because GCC can legitimately use the same register for
|
||||
* both operands.
|
||||
*/
|
||||
__asm__ __volatile__("sub\t%2, 4, %%g4\n\t"
|
||||
"ld\t[%1 + 0x00], %0\n\t"
|
||||
"ld\t[%1 + 0x04], %%g2\n\t"
|
||||
"ld\t[%1 + 0x08], %%g3\n\t"
|
||||
"addcc\t%%g2, %0, %0\n\t"
|
||||
"addxcc\t%%g3, %0, %0\n\t"
|
||||
"ld\t[%1 + 0x0c], %%g2\n\t"
|
||||
"ld\t[%1 + 0x10], %%g3\n\t"
|
||||
"addxcc\t%%g2, %0, %0\n\t"
|
||||
"addx\t%0, %%g0, %0\n"
|
||||
"1:\taddcc\t%%g3, %0, %0\n\t"
|
||||
"add\t%1, 4, %1\n\t"
|
||||
"addxcc\t%0, %%g0, %0\n\t"
|
||||
"subcc\t%%g4, 1, %%g4\n\t"
|
||||
"be,a\t2f\n\t"
|
||||
"sll\t%0, 16, %%g2\n\t"
|
||||
"b\t1b\n\t"
|
||||
"ld\t[%1 + 0x10], %%g3\n"
|
||||
"2:\taddcc\t%0, %%g2, %%g2\n\t"
|
||||
"srl\t%%g2, 16, %0\n\t"
|
||||
"addx\t%0, %%g0, %0\n\t"
|
||||
"xnor\t%%g0, %0, %0"
|
||||
: "=r" (sum), "=&r" (iph)
|
||||
: "r" (ihl), "1" (iph)
|
||||
: "g2", "g3", "g4", "cc", "memory");
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* Fold a partial checksum without adding pseudo headers. */
|
||||
static inline __sum16 csum_fold(__wsum sum)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
__asm__ __volatile__("addcc\t%0, %1, %1\n\t"
|
||||
"srl\t%1, 16, %1\n\t"
|
||||
"addx\t%1, %%g0, %1\n\t"
|
||||
"xnor\t%%g0, %1, %0"
|
||||
: "=&r" (sum), "=r" (tmp)
|
||||
: "0" (sum), "1" ((__force u32)sum<<16)
|
||||
: "cc");
|
||||
return (__force __sum16)sum;
|
||||
}
|
||||
|
||||
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
|
||||
unsigned short len,
|
||||
unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
__asm__ __volatile__("addcc\t%1, %0, %0\n\t"
|
||||
"addxcc\t%2, %0, %0\n\t"
|
||||
"addxcc\t%3, %0, %0\n\t"
|
||||
"addx\t%0, %%g0, %0\n\t"
|
||||
: "=r" (sum), "=r" (saddr)
|
||||
: "r" (daddr), "r" (proto + len), "0" (sum),
|
||||
"1" (saddr)
|
||||
: "cc");
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*
|
||||
* computes the checksum of the TCP/UDP pseudo-header
|
||||
* returns a 16-bit checksum, already complemented
|
||||
*/
|
||||
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
|
||||
unsigned short len,
|
||||
unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
|
||||
}
|
||||
|
||||
#define _HAVE_ARCH_IPV6_CSUM
|
||||
|
||||
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
|
||||
const struct in6_addr *daddr,
|
||||
__u32 len, unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"addcc %3, %4, %%g4\n\t"
|
||||
"addxcc %5, %%g4, %%g4\n\t"
|
||||
"ld [%2 + 0x0c], %%g2\n\t"
|
||||
"ld [%2 + 0x08], %%g3\n\t"
|
||||
"addxcc %%g2, %%g4, %%g4\n\t"
|
||||
"ld [%2 + 0x04], %%g2\n\t"
|
||||
"addxcc %%g3, %%g4, %%g4\n\t"
|
||||
"ld [%2 + 0x00], %%g3\n\t"
|
||||
"addxcc %%g2, %%g4, %%g4\n\t"
|
||||
"ld [%1 + 0x0c], %%g2\n\t"
|
||||
"addxcc %%g3, %%g4, %%g4\n\t"
|
||||
"ld [%1 + 0x08], %%g3\n\t"
|
||||
"addxcc %%g2, %%g4, %%g4\n\t"
|
||||
"ld [%1 + 0x04], %%g2\n\t"
|
||||
"addxcc %%g3, %%g4, %%g4\n\t"
|
||||
"ld [%1 + 0x00], %%g3\n\t"
|
||||
"addxcc %%g2, %%g4, %%g4\n\t"
|
||||
"addxcc %%g3, %%g4, %0\n\t"
|
||||
"addx 0, %0, %0\n"
|
||||
: "=&r" (sum)
|
||||
: "r" (saddr), "r" (daddr),
|
||||
"r"(htonl(len)), "r"(htonl(proto)), "r"(sum)
|
||||
: "g2", "g3", "g4", "cc");
|
||||
|
||||
return csum_fold(sum);
|
||||
}
|
||||
|
||||
/* this routine is used for miscellaneous IP-like checksums, mainly in icmp.c */
|
||||
static inline __sum16 ip_compute_csum(const void *buff, int len)
|
||||
{
|
||||
return csum_fold(csum_partial(buff, len, 0));
|
||||
}
|
||||
|
||||
#define HAVE_ARCH_CSUM_ADD
|
||||
static inline __wsum csum_add(__wsum csum, __wsum addend)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"addcc %0, %1, %0\n"
|
||||
"addx %0, %%g0, %0"
|
||||
: "=r" (csum)
|
||||
: "r" (addend), "0" (csum));
|
||||
|
||||
return csum;
|
||||
}
|
||||
|
||||
#endif /* !(__SPARC_CHECKSUM_H) */
|
179
arch/sparc/include/asm/checksum_64.h
Normal file
179
arch/sparc/include/asm/checksum_64.h
Normal file
|
@ -0,0 +1,179 @@
|
|||
#ifndef __SPARC64_CHECKSUM_H
|
||||
#define __SPARC64_CHECKSUM_H
|
||||
|
||||
/* checksum.h: IP/UDP/TCP checksum routines on the V9.
|
||||
*
|
||||
* Copyright(C) 1995 Linus Torvalds
|
||||
* Copyright(C) 1995 Miguel de Icaza
|
||||
* Copyright(C) 1996 David S. Miller
|
||||
* Copyright(C) 1996 Eddie C. Dost
|
||||
* Copyright(C) 1997 Jakub Jelinek
|
||||
*
|
||||
* derived from:
|
||||
* Alpha checksum c-code
|
||||
* ix86 inline assembly
|
||||
* RFC1071 Computing the Internet Checksum
|
||||
*/
|
||||
|
||||
#include <linux/in6.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
/* computes the checksum of a memory block at buff, length len,
|
||||
* and adds in "sum" (32-bit)
|
||||
*
|
||||
* returns a 32-bit number suitable for feeding into itself
|
||||
* or csum_tcpudp_magic
|
||||
*
|
||||
* this function must be called with even lengths, except
|
||||
* for the last fragment, which may be odd
|
||||
*
|
||||
* it's best to have buff aligned on a 32-bit boundary
|
||||
*/
|
||||
__wsum csum_partial(const void * buff, int len, __wsum sum);
|
||||
|
||||
/* the same as csum_partial, but copies from user space while it
|
||||
* checksums
|
||||
*
|
||||
* here even more important to align src and dst on a 32-bit (or even
|
||||
* better 64-bit) boundary
|
||||
*/
|
||||
__wsum csum_partial_copy_nocheck(const void *src, void *dst,
|
||||
int len, __wsum sum);
|
||||
|
||||
long __csum_partial_copy_from_user(const void __user *src,
|
||||
void *dst, int len,
|
||||
__wsum sum);
|
||||
|
||||
static inline __wsum
|
||||
csum_partial_copy_from_user(const void __user *src,
|
||||
void *dst, int len,
|
||||
__wsum sum, int *err)
|
||||
{
|
||||
long ret = __csum_partial_copy_from_user(src, dst, len, sum);
|
||||
if (ret < 0)
|
||||
*err = -EFAULT;
|
||||
return (__force __wsum) ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy and checksum to user
|
||||
*/
|
||||
#define HAVE_CSUM_COPY_USER
|
||||
long __csum_partial_copy_to_user(const void *src,
|
||||
void __user *dst, int len,
|
||||
__wsum sum);
|
||||
|
||||
static inline __wsum
|
||||
csum_and_copy_to_user(const void *src,
|
||||
void __user *dst, int len,
|
||||
__wsum sum, int *err)
|
||||
{
|
||||
long ret = __csum_partial_copy_to_user(src, dst, len, sum);
|
||||
if (ret < 0)
|
||||
*err = -EFAULT;
|
||||
return (__force __wsum) ret;
|
||||
}
|
||||
|
||||
/* ihl is always 5 or greater, almost always is 5, and iph is word aligned
|
||||
* the majority of the time.
|
||||
*/
|
||||
__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
|
||||
|
||||
/* Fold a partial checksum without adding pseudo headers. */
|
||||
static inline __sum16 csum_fold(__wsum sum)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
__asm__ __volatile__(
|
||||
" addcc %0, %1, %1\n"
|
||||
" srl %1, 16, %1\n"
|
||||
" addc %1, %%g0, %1\n"
|
||||
" xnor %%g0, %1, %0\n"
|
||||
: "=&r" (sum), "=r" (tmp)
|
||||
: "0" (sum), "1" ((__force u32)sum<<16)
|
||||
: "cc");
|
||||
return (__force __sum16)sum;
|
||||
}
|
||||
|
||||
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
|
||||
unsigned int len,
|
||||
unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
" addcc %1, %0, %0\n"
|
||||
" addccc %2, %0, %0\n"
|
||||
" addccc %3, %0, %0\n"
|
||||
" addc %0, %%g0, %0\n"
|
||||
: "=r" (sum), "=r" (saddr)
|
||||
: "r" (daddr), "r" (proto + len), "0" (sum), "1" (saddr)
|
||||
: "cc");
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*
|
||||
* computes the checksum of the TCP/UDP pseudo-header
|
||||
* returns a 16-bit checksum, already complemented
|
||||
*/
|
||||
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
|
||||
unsigned short len,
|
||||
unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
|
||||
}
|
||||
|
||||
#define _HAVE_ARCH_IPV6_CSUM
|
||||
|
||||
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
|
||||
const struct in6_addr *daddr,
|
||||
__u32 len, unsigned short proto,
|
||||
__wsum sum)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
" addcc %3, %4, %%g7\n"
|
||||
" addccc %5, %%g7, %%g7\n"
|
||||
" lduw [%2 + 0x0c], %%g2\n"
|
||||
" lduw [%2 + 0x08], %%g3\n"
|
||||
" addccc %%g2, %%g7, %%g7\n"
|
||||
" lduw [%2 + 0x04], %%g2\n"
|
||||
" addccc %%g3, %%g7, %%g7\n"
|
||||
" lduw [%2 + 0x00], %%g3\n"
|
||||
" addccc %%g2, %%g7, %%g7\n"
|
||||
" lduw [%1 + 0x0c], %%g2\n"
|
||||
" addccc %%g3, %%g7, %%g7\n"
|
||||
" lduw [%1 + 0x08], %%g3\n"
|
||||
" addccc %%g2, %%g7, %%g7\n"
|
||||
" lduw [%1 + 0x04], %%g2\n"
|
||||
" addccc %%g3, %%g7, %%g7\n"
|
||||
" lduw [%1 + 0x00], %%g3\n"
|
||||
" addccc %%g2, %%g7, %%g7\n"
|
||||
" addccc %%g3, %%g7, %0\n"
|
||||
" addc 0, %0, %0\n"
|
||||
: "=&r" (sum)
|
||||
: "r" (saddr), "r" (daddr), "r"(htonl(len)),
|
||||
"r"(htonl(proto)), "r"(sum)
|
||||
: "g2", "g3", "g7", "cc");
|
||||
|
||||
return csum_fold(sum);
|
||||
}
|
||||
|
||||
/* this routine is used for miscellaneous IP-like checksums, mainly in icmp.c */
|
||||
static inline __sum16 ip_compute_csum(const void *buff, int len)
|
||||
{
|
||||
return csum_fold(csum_partial(buff, len, 0));
|
||||
}
|
||||
|
||||
#define HAVE_ARCH_CSUM_ADD
|
||||
static inline __wsum csum_add(__wsum csum, __wsum addend)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"addcc %0, %1, %0\n"
|
||||
"addx %0, %%g0, %0"
|
||||
: "=r" (csum)
|
||||
: "r" (addend), "0" (csum));
|
||||
|
||||
return csum;
|
||||
}
|
||||
|
||||
#endif /* !(__SPARC64_CHECKSUM_H) */
|
183
arch/sparc/include/asm/chmctrl.h
Normal file
183
arch/sparc/include/asm/chmctrl.h
Normal file
|
@ -0,0 +1,183 @@
|
|||
#ifndef _SPARC64_CHMCTRL_H
|
||||
#define _SPARC64_CHMCTRL_H
|
||||
|
||||
/* Cheetah memory controller programmable registers. */
|
||||
#define CHMCTRL_TCTRL1 0x00 /* Memory Timing Control I */
|
||||
#define CHMCTRL_TCTRL2 0x08 /* Memory Timing Control II */
|
||||
#define CHMCTRL_TCTRL3 0x38 /* Memory Timing Control III */
|
||||
#define CHMCTRL_TCTRL4 0x40 /* Memory Timing Control IV */
|
||||
#define CHMCTRL_DECODE1 0x10 /* Memory Address Decode I */
|
||||
#define CHMCTRL_DECODE2 0x18 /* Memory Address Decode II */
|
||||
#define CHMCTRL_DECODE3 0x20 /* Memory Address Decode III */
|
||||
#define CHMCTRL_DECODE4 0x28 /* Memory Address Decode IV */
|
||||
#define CHMCTRL_MACTRL 0x30 /* Memory Address Control */
|
||||
|
||||
/* Memory Timing Control I */
|
||||
#define TCTRL1_SDRAMCTL_DLY 0xf000000000000000UL
|
||||
#define TCTRL1_SDRAMCTL_DLY_SHIFT 60
|
||||
#define TCTRL1_SDRAMCLK_DLY 0x0e00000000000000UL
|
||||
#define TCTRL1_SDRAMCLK_DLY_SHIFT 57
|
||||
#define TCTRL1_R 0x0100000000000000UL
|
||||
#define TCTRL1_R_SHIFT 56
|
||||
#define TCTRL1_AUTORFR_CYCLE 0x00fe000000000000UL
|
||||
#define TCTRL1_AUTORFR_CYCLE_SHIFT 49
|
||||
#define TCTRL1_RD_WAIT 0x0001f00000000000UL
|
||||
#define TCTRL1_RD_WAIT_SHIFT 44
|
||||
#define TCTRL1_PC_CYCLE 0x00000fc000000000UL
|
||||
#define TCTRL1_PC_CYCLE_SHIFT 38
|
||||
#define TCTRL1_WR_MORE_RAS_PW 0x0000003f00000000UL
|
||||
#define TCTRL1_WR_MORE_RAS_PW_SHIFT 32
|
||||
#define TCTRL1_RD_MORE_RAW_PW 0x00000000fc000000UL
|
||||
#define TCTRL1_RD_MORE_RAS_PW_SHIFT 26
|
||||
#define TCTRL1_ACT_WR_DLY 0x0000000003f00000UL
|
||||
#define TCTRL1_ACT_WR_DLY_SHIFT 20
|
||||
#define TCTRL1_ACT_RD_DLY 0x00000000000fc000UL
|
||||
#define TCTRL1_ACT_RD_DLY_SHIFT 14
|
||||
#define TCTRL1_BANK_PRESENT 0x0000000000003000UL
|
||||
#define TCTRL1_BANK_PRESENT_SHIFT 12
|
||||
#define TCTRL1_RFR_INT 0x0000000000000ff8UL
|
||||
#define TCTRL1_RFR_INT_SHIFT 3
|
||||
#define TCTRL1_SET_MODE_REG 0x0000000000000004UL
|
||||
#define TCTRL1_SET_MODE_REG_SHIFT 2
|
||||
#define TCTRL1_RFR_ENABLE 0x0000000000000002UL
|
||||
#define TCTRL1_RFR_ENABLE_SHIFT 1
|
||||
#define TCTRL1_PRECHG_ALL 0x0000000000000001UL
|
||||
#define TCTRL1_PRECHG_ALL_SHIFT 0
|
||||
|
||||
/* Memory Timing Control II */
|
||||
#define TCTRL2_WR_MSEL_DLY 0xfc00000000000000UL
|
||||
#define TCTRL2_WR_MSEL_DLY_SHIFT 58
|
||||
#define TCTRL2_RD_MSEL_DLY 0x03f0000000000000UL
|
||||
#define TCTRL2_RD_MSEL_DLY_SHIFT 52
|
||||
#define TCTRL2_WRDATA_THLD 0x000c000000000000UL
|
||||
#define TCTRL2_WRDATA_THLD_SHIFT 50
|
||||
#define TCTRL2_RDWR_RD_TI_DLY 0x0003f00000000000UL
|
||||
#define TCTRL2_RDWR_RD_TI_DLY_SHIFT 44
|
||||
#define TCTRL2_AUTOPRECHG_ENBL 0x0000080000000000UL
|
||||
#define TCTRL2_AUTOPRECHG_ENBL_SHIFT 43
|
||||
#define TCTRL2_RDWR_PI_MORE_DLY 0x000007c000000000UL
|
||||
#define TCTRL2_RDWR_PI_MORE_DLY_SHIFT 38
|
||||
#define TCTRL2_RDWR_1_DLY 0x0000003f00000000UL
|
||||
#define TCTRL2_RDWR_1_DLY_SHIFT 32
|
||||
#define TCTRL2_WRWR_PI_MORE_DLY 0x00000000f8000000UL
|
||||
#define TCTRL2_WRWR_PI_MORE_DLY_SHIFT 27
|
||||
#define TCTRL2_WRWR_1_DLY 0x0000000007e00000UL
|
||||
#define TCTRL2_WRWR_1_DLY_SHIFT 21
|
||||
#define TCTRL2_RDWR_RD_PI_MORE_DLY 0x00000000001f0000UL
|
||||
#define TCTRL2_RDWR_RD_PI_MORE_DLY_SHIFT 16
|
||||
#define TCTRL2_R 0x0000000000008000UL
|
||||
#define TCTRL2_R_SHIFT 15
|
||||
#define TCTRL2_SDRAM_MODE_REG_DATA 0x0000000000007fffUL
|
||||
#define TCTRL2_SDRAM_MODE_REG_DATA_SHIFT 0
|
||||
|
||||
/* Memory Timing Control III */
|
||||
#define TCTRL3_SDRAM_CTL_DLY 0xf000000000000000UL
|
||||
#define TCTRL3_SDRAM_CTL_DLY_SHIFT 60
|
||||
#define TCTRL3_SDRAM_CLK_DLY 0x0e00000000000000UL
|
||||
#define TCTRL3_SDRAM_CLK_DLY_SHIFT 57
|
||||
#define TCTRL3_R 0x0100000000000000UL
|
||||
#define TCTRL3_R_SHIFT 56
|
||||
#define TCTRL3_AUTO_RFR_CYCLE 0x00fe000000000000UL
|
||||
#define TCTRL3_AUTO_RFR_CYCLE_SHIFT 49
|
||||
#define TCTRL3_RD_WAIT 0x0001f00000000000UL
|
||||
#define TCTRL3_RD_WAIT_SHIFT 44
|
||||
#define TCTRL3_PC_CYCLE 0x00000fc000000000UL
|
||||
#define TCTRL3_PC_CYCLE_SHIFT 38
|
||||
#define TCTRL3_WR_MORE_RAW_PW 0x0000003f00000000UL
|
||||
#define TCTRL3_WR_MORE_RAW_PW_SHIFT 32
|
||||
#define TCTRL3_RD_MORE_RAW_PW 0x00000000fc000000UL
|
||||
#define TCTRL3_RD_MORE_RAW_PW_SHIFT 26
|
||||
#define TCTRL3_ACT_WR_DLY 0x0000000003f00000UL
|
||||
#define TCTRL3_ACT_WR_DLY_SHIFT 20
|
||||
#define TCTRL3_ACT_RD_DLY 0x00000000000fc000UL
|
||||
#define TCTRL3_ACT_RD_DLY_SHIFT 14
|
||||
#define TCTRL3_BANK_PRESENT 0x0000000000003000UL
|
||||
#define TCTRL3_BANK_PRESENT_SHIFT 12
|
||||
#define TCTRL3_RFR_INT 0x0000000000000ff8UL
|
||||
#define TCTRL3_RFR_INT_SHIFT 3
|
||||
#define TCTRL3_SET_MODE_REG 0x0000000000000004UL
|
||||
#define TCTRL3_SET_MODE_REG_SHIFT 2
|
||||
#define TCTRL3_RFR_ENABLE 0x0000000000000002UL
|
||||
#define TCTRL3_RFR_ENABLE_SHIFT 1
|
||||
#define TCTRL3_PRECHG_ALL 0x0000000000000001UL
|
||||
#define TCTRL3_PRECHG_ALL_SHIFT 0
|
||||
|
||||
/* Memory Timing Control IV */
|
||||
#define TCTRL4_WR_MSEL_DLY 0xfc00000000000000UL
|
||||
#define TCTRL4_WR_MSEL_DLY_SHIFT 58
|
||||
#define TCTRL4_RD_MSEL_DLY 0x03f0000000000000UL
|
||||
#define TCTRL4_RD_MSEL_DLY_SHIFT 52
|
||||
#define TCTRL4_WRDATA_THLD 0x000c000000000000UL
|
||||
#define TCTRL4_WRDATA_THLD_SHIFT 50
|
||||
#define TCTRL4_RDWR_RD_RI_DLY 0x0003f00000000000UL
|
||||
#define TCTRL4_RDWR_RD_RI_DLY_SHIFT 44
|
||||
#define TCTRL4_AUTO_PRECHG_ENBL 0x0000080000000000UL
|
||||
#define TCTRL4_AUTO_PRECHG_ENBL_SHIFT 43
|
||||
#define TCTRL4_RD_WR_PI_MORE_DLY 0x000007c000000000UL
|
||||
#define TCTRL4_RD_WR_PI_MORE_DLY_SHIFT 38
|
||||
#define TCTRL4_RD_WR_TI_DLY 0x0000003f00000000UL
|
||||
#define TCTRL4_RD_WR_TI_DLY_SHIFT 32
|
||||
#define TCTRL4_WR_WR_PI_MORE_DLY 0x00000000f8000000UL
|
||||
#define TCTRL4_WR_WR_PI_MORE_DLY_SHIFT 27
|
||||
#define TCTRL4_WR_WR_TI_DLY 0x0000000007e00000UL
|
||||
#define TCTRL4_WR_WR_TI_DLY_SHIFT 21
|
||||
#define TCTRL4_RDWR_RD_PI_MORE_DLY 0x00000000001f000UL0
|
||||
#define TCTRL4_RDWR_RD_PI_MORE_DLY_SHIFT 16
|
||||
#define TCTRL4_R 0x0000000000008000UL
|
||||
#define TCTRL4_R_SHIFT 15
|
||||
#define TCTRL4_SDRAM_MODE_REG_DATA 0x0000000000007fffUL
|
||||
#define TCTRL4_SDRAM_MODE_REG_DATA_SHIFT 0
|
||||
|
||||
/* All 4 memory address decoding registers have the
|
||||
* same layout.
|
||||
*/
|
||||
#define MEM_DECODE_VALID 0x8000000000000000UL /* Valid */
|
||||
#define MEM_DECODE_VALID_SHIFT 63
|
||||
#define MEM_DECODE_UK 0x001ffe0000000000UL /* Upper mask */
|
||||
#define MEM_DECODE_UK_SHIFT 41
|
||||
#define MEM_DECODE_UM 0x0000001ffff00000UL /* Upper match */
|
||||
#define MEM_DECODE_UM_SHIFT 20
|
||||
#define MEM_DECODE_LK 0x000000000003c000UL /* Lower mask */
|
||||
#define MEM_DECODE_LK_SHIFT 14
|
||||
#define MEM_DECODE_LM 0x0000000000000f00UL /* Lower match */
|
||||
#define MEM_DECODE_LM_SHIFT 8
|
||||
|
||||
#define PA_UPPER_BITS 0x000007fffc000000UL
|
||||
#define PA_UPPER_BITS_SHIFT 26
|
||||
#define PA_LOWER_BITS 0x00000000000003c0UL
|
||||
#define PA_LOWER_BITS_SHIFT 6
|
||||
|
||||
#define MACTRL_R0 0x8000000000000000UL
|
||||
#define MACTRL_R0_SHIFT 63
|
||||
#define MACTRL_ADDR_LE_PW 0x7000000000000000UL
|
||||
#define MACTRL_ADDR_LE_PW_SHIFT 60
|
||||
#define MACTRL_CMD_PW 0x0f00000000000000UL
|
||||
#define MACTRL_CMD_PW_SHIFT 56
|
||||
#define MACTRL_HALF_MODE_WR_MSEL_DLY 0x00fc000000000000UL
|
||||
#define MACTRL_HALF_MODE_WR_MSEL_DLY_SHIFT 50
|
||||
#define MACTRL_HALF_MODE_RD_MSEL_DLY 0x0003f00000000000UL
|
||||
#define MACTRL_HALF_MODE_RD_MSEL_DLY_SHIFT 44
|
||||
#define MACTRL_HALF_MODE_SDRAM_CTL_DLY 0x00000f0000000000UL
|
||||
#define MACTRL_HALF_MODE_SDRAM_CTL_DLY_SHIFT 40
|
||||
#define MACTRL_HALF_MODE_SDRAM_CLK_DLY 0x000000e000000000UL
|
||||
#define MACTRL_HALF_MODE_SDRAM_CLK_DLY_SHIFT 37
|
||||
#define MACTRL_R1 0x0000001000000000UL
|
||||
#define MACTRL_R1_SHIFT 36
|
||||
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B3 0x0000000f00000000UL
|
||||
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B3_SHIFT 32
|
||||
#define MACTRL_ENC_INTLV_B3 0x00000000f8000000UL
|
||||
#define MACTRL_ENC_INTLV_B3_SHIFT 27
|
||||
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B2 0x0000000007800000UL
|
||||
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B2_SHIFT 23
|
||||
#define MACTRL_ENC_INTLV_B2 0x00000000007c0000UL
|
||||
#define MACTRL_ENC_INTLV_B2_SHIFT 18
|
||||
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B1 0x000000000003c000UL
|
||||
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B1_SHIFT 14
|
||||
#define MACTRL_ENC_INTLV_B1 0x0000000000003e00UL
|
||||
#define MACTRL_ENC_INTLV_B1_SHIFT 9
|
||||
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B0 0x00000000000001e0UL
|
||||
#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B0_SHIFT 5
|
||||
#define MACTRL_ENC_INTLV_B0 0x000000000000001fUL
|
||||
#define MACTRL_ENC_INTLV_B0_SHIFT 0
|
||||
|
||||
#endif /* _SPARC64_CHMCTRL_H */
|
11
arch/sparc/include/asm/clock.h
Normal file
11
arch/sparc/include/asm/clock.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* clock.h: Definitions for clock operations on the Sparc.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
#ifndef _SPARC_CLOCK_H
|
||||
#define _SPARC_CLOCK_H
|
||||
|
||||
/* Foo for now. */
|
||||
|
||||
#endif /* !(_SPARC_CLOCK_H) */
|
8
arch/sparc/include/asm/cmpxchg.h
Normal file
8
arch/sparc/include/asm/cmpxchg.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ___ASM_SPARC_CMPXCHG_H
|
||||
#define ___ASM_SPARC_CMPXCHG_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm/cmpxchg_64.h>
|
||||
#else
|
||||
#include <asm/cmpxchg_32.h>
|
||||
#endif
|
||||
#endif
|
77
arch/sparc/include/asm/cmpxchg_32.h
Normal file
77
arch/sparc/include/asm/cmpxchg_32.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* 32-bit atomic xchg() and cmpxchg() definitions.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au)
|
||||
* Copyright (C) 2007 Kyle McMartin (kyle@parisc-linux.org)
|
||||
*
|
||||
* Additions by Keith M Wesolowski (wesolows@foobazco.org) based
|
||||
* on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_SPARC_CMPXCHG__
|
||||
#define __ARCH_SPARC_CMPXCHG__
|
||||
|
||||
unsigned long __xchg_u32(volatile u32 *m, u32 new);
|
||||
void __xchg_called_with_bad_pointer(void);
|
||||
|
||||
static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 4:
|
||||
return __xchg_u32(ptr, x);
|
||||
}
|
||||
__xchg_called_with_bad_pointer();
|
||||
return x;
|
||||
}
|
||||
|
||||
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
|
||||
|
||||
/* Emulate cmpxchg() the same way we emulate atomics,
|
||||
* by hashing the object address and indexing into an array
|
||||
* of spinlocks to get a bit of performance...
|
||||
*
|
||||
* See arch/sparc/lib/atomic32.c for implementation.
|
||||
*
|
||||
* Cribbed from <asm-parisc/atomic.h>
|
||||
*/
|
||||
#define __HAVE_ARCH_CMPXCHG 1
|
||||
|
||||
/* bug catcher for when unsupported size is used - won't link */
|
||||
void __cmpxchg_called_with_bad_pointer(void);
|
||||
/* we only need to support cmpxchg of a u32 on sparc */
|
||||
unsigned long __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
|
||||
|
||||
/* don't worry...optimizer will get rid of most of this */
|
||||
static inline unsigned long
|
||||
__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 4:
|
||||
return __cmpxchg_u32((u32 *)ptr, (u32)old, (u32)new_);
|
||||
default:
|
||||
__cmpxchg_called_with_bad_pointer();
|
||||
break;
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
#define cmpxchg(ptr, o, n) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) _o_ = (o); \
|
||||
__typeof__(*(ptr)) _n_ = (n); \
|
||||
(__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
|
||||
(unsigned long)_n_, sizeof(*(ptr))); \
|
||||
})
|
||||
|
||||
#include <asm-generic/cmpxchg-local.h>
|
||||
|
||||
/*
|
||||
* cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
|
||||
* them available.
|
||||
*/
|
||||
#define cmpxchg_local(ptr, o, n) \
|
||||
((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
|
||||
(unsigned long)(n), sizeof(*(ptr))))
|
||||
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
|
||||
|
||||
#endif /* __ARCH_SPARC_CMPXCHG__ */
|
146
arch/sparc/include/asm/cmpxchg_64.h
Normal file
146
arch/sparc/include/asm/cmpxchg_64.h
Normal file
|
@ -0,0 +1,146 @@
|
|||
/* 64-bit atomic xchg() and cmpxchg() definitions.
|
||||
*
|
||||
* Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com)
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_SPARC64_CMPXCHG__
|
||||
#define __ARCH_SPARC64_CMPXCHG__
|
||||
|
||||
static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val)
|
||||
{
|
||||
unsigned long tmp1, tmp2;
|
||||
|
||||
__asm__ __volatile__(
|
||||
" mov %0, %1\n"
|
||||
"1: lduw [%4], %2\n"
|
||||
" cas [%4], %2, %0\n"
|
||||
" cmp %2, %0\n"
|
||||
" bne,a,pn %%icc, 1b\n"
|
||||
" mov %1, %0\n"
|
||||
: "=&r" (val), "=&r" (tmp1), "=&r" (tmp2)
|
||||
: "0" (val), "r" (m)
|
||||
: "cc", "memory");
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long val)
|
||||
{
|
||||
unsigned long tmp1, tmp2;
|
||||
|
||||
__asm__ __volatile__(
|
||||
" mov %0, %1\n"
|
||||
"1: ldx [%4], %2\n"
|
||||
" casx [%4], %2, %0\n"
|
||||
" cmp %2, %0\n"
|
||||
" bne,a,pn %%xcc, 1b\n"
|
||||
" mov %1, %0\n"
|
||||
: "=&r" (val), "=&r" (tmp1), "=&r" (tmp2)
|
||||
: "0" (val), "r" (m)
|
||||
: "cc", "memory");
|
||||
return val;
|
||||
}
|
||||
|
||||
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
|
||||
|
||||
void __xchg_called_with_bad_pointer(void);
|
||||
|
||||
static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
|
||||
int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 4:
|
||||
return xchg32(ptr, x);
|
||||
case 8:
|
||||
return xchg64(ptr, x);
|
||||
}
|
||||
__xchg_called_with_bad_pointer();
|
||||
return x;
|
||||
}
|
||||
|
||||
/*
|
||||
* Atomic compare and exchange. Compare OLD with MEM, if identical,
|
||||
* store NEW in MEM. Return the initial value in MEM. Success is
|
||||
* indicated by comparing RETURN with OLD.
|
||||
*/
|
||||
|
||||
#include <asm-generic/cmpxchg-local.h>
|
||||
|
||||
#define __HAVE_ARCH_CMPXCHG 1
|
||||
|
||||
static inline unsigned long
|
||||
__cmpxchg_u32(volatile int *m, int old, int new)
|
||||
{
|
||||
__asm__ __volatile__("cas [%2], %3, %0"
|
||||
: "=&r" (new)
|
||||
: "0" (new), "r" (m), "r" (old)
|
||||
: "memory");
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
|
||||
{
|
||||
__asm__ __volatile__("casx [%2], %3, %0"
|
||||
: "=&r" (new)
|
||||
: "0" (new), "r" (m), "r" (old)
|
||||
: "memory");
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/* This function doesn't exist, so you'll get a linker error
|
||||
if something tries to do an invalid cmpxchg(). */
|
||||
void __cmpxchg_called_with_bad_pointer(void);
|
||||
|
||||
static inline unsigned long
|
||||
__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 4:
|
||||
return __cmpxchg_u32(ptr, old, new);
|
||||
case 8:
|
||||
return __cmpxchg_u64(ptr, old, new);
|
||||
}
|
||||
__cmpxchg_called_with_bad_pointer();
|
||||
return old;
|
||||
}
|
||||
|
||||
#define cmpxchg(ptr,o,n) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) _o_ = (o); \
|
||||
__typeof__(*(ptr)) _n_ = (n); \
|
||||
(__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
|
||||
(unsigned long)_n_, sizeof(*(ptr))); \
|
||||
})
|
||||
|
||||
/*
|
||||
* cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
|
||||
* them available.
|
||||
*/
|
||||
|
||||
static inline unsigned long __cmpxchg_local(volatile void *ptr,
|
||||
unsigned long old,
|
||||
unsigned long new, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 4:
|
||||
case 8: return __cmpxchg(ptr, old, new, size);
|
||||
default:
|
||||
return __cmpxchg_local_generic(ptr, old, new, size);
|
||||
}
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
#define cmpxchg_local(ptr, o, n) \
|
||||
((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
|
||||
(unsigned long)(n), sizeof(*(ptr))))
|
||||
#define cmpxchg64_local(ptr, o, n) \
|
||||
({ \
|
||||
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
|
||||
cmpxchg_local((ptr), (o), (n)); \
|
||||
})
|
||||
#define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n))
|
||||
|
||||
#endif /* __ARCH_SPARC64_CMPXCHG__ */
|
310
arch/sparc/include/asm/compat.h
Normal file
310
arch/sparc/include/asm/compat.h
Normal file
|
@ -0,0 +1,310 @@
|
|||
#ifndef _ASM_SPARC64_COMPAT_H
|
||||
#define _ASM_SPARC64_COMPAT_H
|
||||
/*
|
||||
* Architecture specific compatibility types
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
|
||||
#define COMPAT_USER_HZ 100
|
||||
#define COMPAT_UTS_MACHINE "sparc\0\0"
|
||||
|
||||
typedef u32 compat_size_t;
|
||||
typedef s32 compat_ssize_t;
|
||||
typedef s32 compat_time_t;
|
||||
typedef s32 compat_clock_t;
|
||||
typedef s32 compat_pid_t;
|
||||
typedef u16 __compat_uid_t;
|
||||
typedef u16 __compat_gid_t;
|
||||
typedef u32 __compat_uid32_t;
|
||||
typedef u32 __compat_gid32_t;
|
||||
typedef u16 compat_mode_t;
|
||||
typedef u32 compat_ino_t;
|
||||
typedef u16 compat_dev_t;
|
||||
typedef s32 compat_off_t;
|
||||
typedef s64 compat_loff_t;
|
||||
typedef s16 compat_nlink_t;
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
typedef s32 compat_daddr_t;
|
||||
typedef u32 compat_caddr_t;
|
||||
typedef __kernel_fsid_t compat_fsid_t;
|
||||
typedef s32 compat_key_t;
|
||||
typedef s32 compat_timer_t;
|
||||
|
||||
typedef s32 compat_int_t;
|
||||
typedef s32 compat_long_t;
|
||||
typedef s64 compat_s64;
|
||||
typedef u32 compat_uint_t;
|
||||
typedef u32 compat_ulong_t;
|
||||
typedef u64 compat_u64;
|
||||
typedef u32 compat_uptr_t;
|
||||
|
||||
struct compat_timespec {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_nsec;
|
||||
};
|
||||
|
||||
struct compat_timeval {
|
||||
compat_time_t tv_sec;
|
||||
s32 tv_usec;
|
||||
};
|
||||
|
||||
struct compat_stat {
|
||||
compat_dev_t st_dev;
|
||||
compat_ino_t st_ino;
|
||||
compat_mode_t st_mode;
|
||||
compat_nlink_t st_nlink;
|
||||
__compat_uid_t st_uid;
|
||||
__compat_gid_t st_gid;
|
||||
compat_dev_t st_rdev;
|
||||
compat_off_t st_size;
|
||||
compat_time_t st_atime;
|
||||
compat_ulong_t st_atime_nsec;
|
||||
compat_time_t st_mtime;
|
||||
compat_ulong_t st_mtime_nsec;
|
||||
compat_time_t st_ctime;
|
||||
compat_ulong_t st_ctime_nsec;
|
||||
compat_off_t st_blksize;
|
||||
compat_off_t st_blocks;
|
||||
u32 __unused4[2];
|
||||
};
|
||||
|
||||
struct compat_stat64 {
|
||||
unsigned long long st_dev;
|
||||
|
||||
unsigned long long st_ino;
|
||||
|
||||
unsigned int st_mode;
|
||||
unsigned int st_nlink;
|
||||
|
||||
unsigned int st_uid;
|
||||
unsigned int st_gid;
|
||||
|
||||
unsigned long long st_rdev;
|
||||
|
||||
unsigned char __pad3[8];
|
||||
|
||||
long long st_size;
|
||||
unsigned int st_blksize;
|
||||
|
||||
unsigned char __pad4[8];
|
||||
unsigned int st_blocks;
|
||||
|
||||
unsigned int st_atime;
|
||||
unsigned int st_atime_nsec;
|
||||
|
||||
unsigned int st_mtime;
|
||||
unsigned int st_mtime_nsec;
|
||||
|
||||
unsigned int st_ctime;
|
||||
unsigned int st_ctime_nsec;
|
||||
|
||||
unsigned int __unused4;
|
||||
unsigned int __unused5;
|
||||
};
|
||||
|
||||
struct compat_flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_off_t l_start;
|
||||
compat_off_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
short __unused;
|
||||
};
|
||||
|
||||
#define F_GETLK64 12
|
||||
#define F_SETLK64 13
|
||||
#define F_SETLKW64 14
|
||||
|
||||
struct compat_flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_loff_t l_start;
|
||||
compat_loff_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
short __unused;
|
||||
};
|
||||
|
||||
struct compat_statfs {
|
||||
int f_type;
|
||||
int f_bsize;
|
||||
int f_blocks;
|
||||
int f_bfree;
|
||||
int f_bavail;
|
||||
int f_files;
|
||||
int f_ffree;
|
||||
compat_fsid_t f_fsid;
|
||||
int f_namelen; /* SunOS ignores this field. */
|
||||
int f_frsize;
|
||||
int f_flags;
|
||||
int f_spare[4];
|
||||
};
|
||||
|
||||
#define COMPAT_RLIM_INFINITY 0x7fffffff
|
||||
|
||||
typedef u32 compat_old_sigset_t;
|
||||
|
||||
#define _COMPAT_NSIG 64
|
||||
#define _COMPAT_NSIG_BPW 32
|
||||
|
||||
typedef u32 compat_sigset_word;
|
||||
|
||||
typedef union compat_sigval {
|
||||
compat_int_t sival_int;
|
||||
compat_uptr_t sival_ptr;
|
||||
} compat_sigval_t;
|
||||
|
||||
#define SI_PAD_SIZE32 (128/sizeof(int) - 3)
|
||||
|
||||
typedef struct compat_siginfo {
|
||||
int si_signo;
|
||||
int si_errno;
|
||||
int si_code;
|
||||
|
||||
union {
|
||||
int _pad[SI_PAD_SIZE32];
|
||||
|
||||
/* kill() */
|
||||
struct {
|
||||
compat_pid_t _pid; /* sender's pid */
|
||||
unsigned int _uid; /* sender's uid */
|
||||
} _kill;
|
||||
|
||||
/* POSIX.1b timers */
|
||||
struct {
|
||||
compat_timer_t _tid; /* timer id */
|
||||
int _overrun; /* overrun count */
|
||||
compat_sigval_t _sigval; /* same as below */
|
||||
int _sys_private; /* not to be passed to user */
|
||||
} _timer;
|
||||
|
||||
/* POSIX.1b signals */
|
||||
struct {
|
||||
compat_pid_t _pid; /* sender's pid */
|
||||
unsigned int _uid; /* sender's uid */
|
||||
compat_sigval_t _sigval;
|
||||
} _rt;
|
||||
|
||||
/* SIGCHLD */
|
||||
struct {
|
||||
compat_pid_t _pid; /* which child */
|
||||
unsigned int _uid; /* sender's uid */
|
||||
int _status; /* exit code */
|
||||
compat_clock_t _utime;
|
||||
compat_clock_t _stime;
|
||||
} _sigchld;
|
||||
|
||||
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
|
||||
struct {
|
||||
u32 _addr; /* faulting insn/memory ref. */
|
||||
int _trapno;
|
||||
} _sigfault;
|
||||
|
||||
/* SIGPOLL */
|
||||
struct {
|
||||
int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
|
||||
int _fd;
|
||||
} _sigpoll;
|
||||
} _sifields;
|
||||
} compat_siginfo_t;
|
||||
|
||||
#define COMPAT_OFF_T_MAX 0x7fffffff
|
||||
#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
|
||||
|
||||
/*
|
||||
* A pointer passed in from user mode. This should not
|
||||
* be used for syscall parameters, just declare them
|
||||
* as pointers because the syscall entry code will have
|
||||
* appropriately converted them already.
|
||||
*/
|
||||
|
||||
static inline void __user *compat_ptr(compat_uptr_t uptr)
|
||||
{
|
||||
return (void __user *)(unsigned long)uptr;
|
||||
}
|
||||
|
||||
static inline compat_uptr_t ptr_to_compat(void __user *uptr)
|
||||
{
|
||||
return (u32)(unsigned long)uptr;
|
||||
}
|
||||
|
||||
static inline void __user *arch_compat_alloc_user_space(long len)
|
||||
{
|
||||
struct pt_regs *regs = current_thread_info()->kregs;
|
||||
unsigned long usp = regs->u_regs[UREG_I6];
|
||||
|
||||
if (test_thread_64bit_stack(usp))
|
||||
usp += STACK_BIAS;
|
||||
|
||||
if (test_thread_flag(TIF_32BIT))
|
||||
usp &= 0xffffffffUL;
|
||||
|
||||
usp -= len;
|
||||
usp &= ~0x7UL;
|
||||
|
||||
return (void __user *) usp;
|
||||
}
|
||||
|
||||
struct compat_ipc64_perm {
|
||||
compat_key_t key;
|
||||
__compat_uid32_t uid;
|
||||
__compat_gid32_t gid;
|
||||
__compat_uid32_t cuid;
|
||||
__compat_gid32_t cgid;
|
||||
unsigned short __pad1;
|
||||
compat_mode_t mode;
|
||||
unsigned short __pad2;
|
||||
unsigned short seq;
|
||||
unsigned long __unused1; /* yes they really are 64bit pads */
|
||||
unsigned long __unused2;
|
||||
};
|
||||
|
||||
struct compat_semid64_ds {
|
||||
struct compat_ipc64_perm sem_perm;
|
||||
unsigned int __pad1;
|
||||
compat_time_t sem_otime;
|
||||
unsigned int __pad2;
|
||||
compat_time_t sem_ctime;
|
||||
u32 sem_nsems;
|
||||
u32 __unused1;
|
||||
u32 __unused2;
|
||||
};
|
||||
|
||||
struct compat_msqid64_ds {
|
||||
struct compat_ipc64_perm msg_perm;
|
||||
unsigned int __pad1;
|
||||
compat_time_t msg_stime;
|
||||
unsigned int __pad2;
|
||||
compat_time_t msg_rtime;
|
||||
unsigned int __pad3;
|
||||
compat_time_t msg_ctime;
|
||||
unsigned int msg_cbytes;
|
||||
unsigned int msg_qnum;
|
||||
unsigned int msg_qbytes;
|
||||
compat_pid_t msg_lspid;
|
||||
compat_pid_t msg_lrpid;
|
||||
unsigned int __unused1;
|
||||
unsigned int __unused2;
|
||||
};
|
||||
|
||||
struct compat_shmid64_ds {
|
||||
struct compat_ipc64_perm shm_perm;
|
||||
unsigned int __pad1;
|
||||
compat_time_t shm_atime;
|
||||
unsigned int __pad2;
|
||||
compat_time_t shm_dtime;
|
||||
unsigned int __pad3;
|
||||
compat_time_t shm_ctime;
|
||||
compat_size_t shm_segsz;
|
||||
compat_pid_t shm_cpid;
|
||||
compat_pid_t shm_lpid;
|
||||
unsigned int shm_nattch;
|
||||
unsigned int __unused1;
|
||||
unsigned int __unused2;
|
||||
};
|
||||
|
||||
static inline int is_compat_task(void)
|
||||
{
|
||||
return test_thread_flag(TIF_32BIT);
|
||||
}
|
||||
|
||||
#endif /* _ASM_SPARC64_COMPAT_H */
|
23
arch/sparc/include/asm/compat_signal.h
Normal file
23
arch/sparc/include/asm/compat_signal.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef _COMPAT_SIGNAL_H
|
||||
#define _COMPAT_SIGNAL_H
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <asm/signal.h>
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
struct __new_sigaction32 {
|
||||
unsigned sa_handler;
|
||||
unsigned int sa_flags;
|
||||
unsigned sa_restorer; /* not used by Linux/SPARC yet */
|
||||
compat_sigset_t sa_mask;
|
||||
};
|
||||
|
||||
struct __old_sigaction32 {
|
||||
unsigned sa_handler;
|
||||
compat_old_sigset_t sa_mask;
|
||||
unsigned int sa_flags;
|
||||
unsigned sa_restorer; /* not used by Linux/SPARC yet */
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* !(_COMPAT_SIGNAL_H) */
|
31
arch/sparc/include/asm/contregs.h
Normal file
31
arch/sparc/include/asm/contregs.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef _SPARC_CONTREGS_H
|
||||
#define _SPARC_CONTREGS_H
|
||||
|
||||
/* contregs.h: Addresses of registers in the ASI_CONTROL alternate address
|
||||
* space. These are for the mmu's context register, etc.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
|
||||
/* s=Swift, h=Ross_HyperSPARC, v=TI_Viking, t=Tsunami, r=Ross_Cypress */
|
||||
#define AC_M_PCR 0x0000 /* shv Processor Control Reg */
|
||||
#define AC_M_CTPR 0x0100 /* shv Context Table Pointer Reg */
|
||||
#define AC_M_CXR 0x0200 /* shv Context Register */
|
||||
#define AC_M_SFSR 0x0300 /* shv Synchronous Fault Status Reg */
|
||||
#define AC_M_SFAR 0x0400 /* shv Synchronous Fault Address Reg */
|
||||
#define AC_M_AFSR 0x0500 /* hv Asynchronous Fault Status Reg */
|
||||
#define AC_M_AFAR 0x0600 /* hv Asynchronous Fault Address Reg */
|
||||
#define AC_M_RESET 0x0700 /* hv Reset Reg */
|
||||
#define AC_M_RPR 0x1000 /* hv Root Pointer Reg */
|
||||
#define AC_M_TSUTRCR 0x1000 /* s TLB Replacement Ctrl Reg */
|
||||
#define AC_M_IAPTP 0x1100 /* hv Instruction Access PTP */
|
||||
#define AC_M_DAPTP 0x1200 /* hv Data Access PTP */
|
||||
#define AC_M_ITR 0x1300 /* hv Index Tag Register */
|
||||
#define AC_M_TRCR 0x1400 /* hv TLB Replacement Control Reg */
|
||||
#define AC_M_SFSRX 0x1300 /* s Synch Fault Status Reg prim */
|
||||
#define AC_M_SFARX 0x1400 /* s Synch Fault Address Reg prim */
|
||||
#define AC_M_RPR1 0x1500 /* h Root Pointer Reg (entry 2) */
|
||||
#define AC_M_IAPTP1 0x1600 /* h Instruction Access PTP (entry 2) */
|
||||
#define AC_M_DAPTP1 0x1700 /* h Data Access PTP (entry 2) */
|
||||
|
||||
#endif /* _SPARC_CONTREGS_H */
|
28
arch/sparc/include/asm/cpu_type.h
Normal file
28
arch/sparc/include/asm/cpu_type.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef __ASM_CPU_TYPE_H
|
||||
#define __ASM_CPU_TYPE_H
|
||||
|
||||
/*
|
||||
* Sparc (general) CPU types
|
||||
*/
|
||||
enum sparc_cpu {
|
||||
sun4m = 0x00,
|
||||
sun4d = 0x01,
|
||||
sun4e = 0x02,
|
||||
sun4u = 0x03, /* V8 ploos ploos */
|
||||
sun_unknown = 0x04,
|
||||
ap1000 = 0x05, /* almost a sun4m */
|
||||
sparc_leon = 0x06, /* Leon SoC */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SPARC32
|
||||
extern enum sparc_cpu sparc_cpu_model;
|
||||
|
||||
#define SUN4M_NCPUS 4 /* Architectural limit of sun4m. */
|
||||
|
||||
#else
|
||||
|
||||
#define sparc_cpu_model sun4u
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_CPU_TYPE_H */
|
18
arch/sparc/include/asm/cpudata.h
Normal file
18
arch/sparc/include/asm/cpudata.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef ___ASM_SPARC_CPUDATA_H
|
||||
#define ___ASM_SPARC_CPUDATA_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/threads.h>
|
||||
#include <linux/percpu.h>
|
||||
|
||||
extern const struct seq_operations cpuinfo_op;
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm/cpudata_64.h>
|
||||
#else
|
||||
#include <asm/cpudata_32.h>
|
||||
#endif
|
||||
#endif
|
31
arch/sparc/include/asm/cpudata_32.h
Normal file
31
arch/sparc/include/asm/cpudata_32.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* cpudata.h: Per-cpu parameters.
|
||||
*
|
||||
* Copyright (C) 2004 Keith M Wesolowski (wesolows@foobazco.org)
|
||||
*
|
||||
* Based on include/asm/cpudata.h and Linux 2.4 smp.h
|
||||
* both (C) David S. Miller.
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_CPUDATA_H
|
||||
#define _SPARC_CPUDATA_H
|
||||
|
||||
#include <linux/percpu.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned long udelay_val;
|
||||
unsigned long clock_tick;
|
||||
unsigned int counter;
|
||||
#ifdef CONFIG_SMP
|
||||
unsigned int irq_resched_count;
|
||||
unsigned int irq_call_count;
|
||||
#endif
|
||||
int prom_node;
|
||||
int mid;
|
||||
int next;
|
||||
} cpuinfo_sparc;
|
||||
|
||||
DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
|
||||
#define cpu_data(__cpu) per_cpu(__cpu_data, (__cpu))
|
||||
#define local_cpu_data() (*this_cpu_ptr(&__cpu_data))
|
||||
|
||||
#endif /* _SPARC_CPUDATA_H */
|
39
arch/sparc/include/asm/cpudata_64.h
Normal file
39
arch/sparc/include/asm/cpudata_64.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/* cpudata.h: Per-cpu parameters.
|
||||
*
|
||||
* Copyright (C) 2003, 2005, 2006 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC64_CPUDATA_H
|
||||
#define _SPARC64_CPUDATA_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
typedef struct {
|
||||
/* Dcache line 1 */
|
||||
unsigned int __softirq_pending; /* must be 1st, see rtrap.S */
|
||||
unsigned int __nmi_count;
|
||||
unsigned long clock_tick; /* %tick's per second */
|
||||
unsigned long __pad;
|
||||
unsigned int irq0_irqs;
|
||||
unsigned int __pad2;
|
||||
|
||||
/* Dcache line 2, rarely used */
|
||||
unsigned int dcache_size;
|
||||
unsigned int dcache_line_size;
|
||||
unsigned int icache_size;
|
||||
unsigned int icache_line_size;
|
||||
unsigned int ecache_size;
|
||||
unsigned int ecache_line_size;
|
||||
int core_id;
|
||||
int proc_id;
|
||||
} cpuinfo_sparc;
|
||||
|
||||
DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
|
||||
#define cpu_data(__cpu) per_cpu(__cpu_data, (__cpu))
|
||||
#define local_cpu_data() (*this_cpu_ptr(&__cpu_data))
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
||||
#include <asm/trap_block.h>
|
||||
|
||||
#endif /* _SPARC64_CPUDATA_H */
|
34
arch/sparc/include/asm/current.h
Normal file
34
arch/sparc/include/asm/current.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* include/asm/current.h
|
||||
*
|
||||
* Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
|
||||
* Copyright (C) 2002 Pete Zaitcev (zaitcev@yahoo.com)
|
||||
* Copyright (C) 2007 David S. Miller (davem@davemloft.net)
|
||||
*
|
||||
* Derived from "include/asm-s390/current.h" by
|
||||
* Martin Schwidefsky (schwidefsky@de.ibm.com)
|
||||
* Derived from "include/asm-i386/current.h"
|
||||
*/
|
||||
#ifndef _SPARC_CURRENT_H
|
||||
#define _SPARC_CURRENT_H
|
||||
|
||||
#include <linux/thread_info.h>
|
||||
|
||||
#ifdef CONFIG_SPARC64
|
||||
register struct task_struct *current asm("g4");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPARC32
|
||||
/* We might want to consider using %g4 like sparc64 to shave a few cycles.
|
||||
*
|
||||
* Two stage process (inline + #define) for type-checking.
|
||||
* We also obfuscate get_current() to check if anyone used that by mistake.
|
||||
*/
|
||||
struct task_struct;
|
||||
static inline struct task_struct *__get_current(void)
|
||||
{
|
||||
return current_thread_info()->task;
|
||||
}
|
||||
#define current __get_current()
|
||||
#endif
|
||||
|
||||
#endif /* !(_SPARC_CURRENT_H) */
|
14
arch/sparc/include/asm/dcr.h
Normal file
14
arch/sparc/include/asm/dcr.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef _SPARC64_DCR_H
|
||||
#define _SPARC64_DCR_H
|
||||
|
||||
/* UltraSparc-III/III+ Dispatch Control Register, ASR 0x12 */
|
||||
#define DCR_DPE 0x0000000000001000 /* III+: D$ Parity Error Enable */
|
||||
#define DCR_OBS 0x0000000000000fc0 /* Observability Bus Controls */
|
||||
#define DCR_BPE 0x0000000000000020 /* Branch Predict Enable */
|
||||
#define DCR_RPE 0x0000000000000010 /* Return Address Prediction Enable */
|
||||
#define DCR_SI 0x0000000000000008 /* Single Instruction Disable */
|
||||
#define DCR_IPE 0x0000000000000004 /* III+: I$ Parity Error Enable */
|
||||
#define DCR_IFPOE 0x0000000000000002 /* IRQ FP Operation Enable */
|
||||
#define DCR_MS 0x0000000000000001 /* Multi-Scalar dispatch */
|
||||
|
||||
#endif /* _SPARC64_DCR_H */
|
27
arch/sparc/include/asm/dcu.h
Normal file
27
arch/sparc/include/asm/dcu.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef _SPARC64_DCU_H
|
||||
#define _SPARC64_DCU_H
|
||||
|
||||
#include <linux/const.h>
|
||||
|
||||
/* UltraSparc-III Data Cache Unit Control Register */
|
||||
#define DCU_CP _AC(0x0002000000000000,UL) /* Phys Cache Enable w/o mmu */
|
||||
#define DCU_CV _AC(0x0001000000000000,UL) /* Virt Cache Enable w/o mmu */
|
||||
#define DCU_ME _AC(0x0000800000000000,UL) /* NC-store Merging Enable */
|
||||
#define DCU_RE _AC(0x0000400000000000,UL) /* RAW bypass Enable */
|
||||
#define DCU_PE _AC(0x0000200000000000,UL) /* PCache Enable */
|
||||
#define DCU_HPE _AC(0x0000100000000000,UL) /* HW prefetch Enable */
|
||||
#define DCU_SPE _AC(0x0000080000000000,UL) /* SW prefetch Enable */
|
||||
#define DCU_SL _AC(0x0000040000000000,UL) /* Secondary ld-steering Enab*/
|
||||
#define DCU_WE _AC(0x0000020000000000,UL) /* WCache enable */
|
||||
#define DCU_PM _AC(0x000001fe00000000,UL) /* PA Watchpoint Byte Mask */
|
||||
#define DCU_VM _AC(0x00000001fe000000,UL) /* VA Watchpoint Byte Mask */
|
||||
#define DCU_PR _AC(0x0000000001000000,UL) /* PA Watchpoint Read Enable */
|
||||
#define DCU_PW _AC(0x0000000000800000,UL) /* PA Watchpoint Write Enable*/
|
||||
#define DCU_VR _AC(0x0000000000400000,UL) /* VA Watchpoint Read Enable */
|
||||
#define DCU_VW _AC(0x0000000000200000,UL) /* VA Watchpoint Write Enable*/
|
||||
#define DCU_DM _AC(0x0000000000000008,UL) /* DMMU Enable */
|
||||
#define DCU_IM _AC(0x0000000000000004,UL) /* IMMU Enable */
|
||||
#define DCU_DC _AC(0x0000000000000002,UL) /* Data Cache Enable */
|
||||
#define DCU_IC _AC(0x0000000000000001,UL) /* Instruction Cache Enable */
|
||||
|
||||
#endif /* _SPARC64_DCU_H */
|
8
arch/sparc/include/asm/delay.h
Normal file
8
arch/sparc/include/asm/delay.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ___ASM_SPARC_DELAY_H
|
||||
#define ___ASM_SPARC_DELAY_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm/delay_64.h>
|
||||
#else
|
||||
#include <asm/delay_32.h>
|
||||
#endif
|
||||
#endif
|
34
arch/sparc/include/asm/delay_32.h
Normal file
34
arch/sparc/include/asm/delay_32.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* delay.h: Linux delay routines on the Sparc.
|
||||
*
|
||||
* Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu).
|
||||
*/
|
||||
|
||||
#ifndef __SPARC_DELAY_H
|
||||
#define __SPARC_DELAY_H
|
||||
|
||||
#include <asm/cpudata.h>
|
||||
|
||||
static inline void __delay(unsigned long loops)
|
||||
{
|
||||
__asm__ __volatile__("cmp %0, 0\n\t"
|
||||
"1: bne 1b\n\t"
|
||||
"subcc %0, 1, %0\n" :
|
||||
"=&r" (loops) :
|
||||
"0" (loops) :
|
||||
"cc");
|
||||
}
|
||||
|
||||
/* This is too messy with inline asm on the Sparc. */
|
||||
void __udelay(unsigned long usecs, unsigned long lpj);
|
||||
void __ndelay(unsigned long nsecs, unsigned long lpj);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define __udelay_val cpu_data(smp_processor_id()).udelay_val
|
||||
#else /* SMP */
|
||||
#define __udelay_val loops_per_jiffy
|
||||
#endif /* SMP */
|
||||
#define udelay(__usecs) __udelay(__usecs, __udelay_val)
|
||||
#define ndelay(__nsecs) __ndelay(__nsecs, __udelay_val)
|
||||
|
||||
#endif /* defined(__SPARC_DELAY_H) */
|
17
arch/sparc/include/asm/delay_64.h
Normal file
17
arch/sparc/include/asm/delay_64.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* delay.h: Linux delay routines on sparc64.
|
||||
*
|
||||
* Copyright (C) 1996, 2004, 2007 David S. Miller (davem@davemloft.net).
|
||||
*/
|
||||
|
||||
#ifndef _SPARC64_DELAY_H
|
||||
#define _SPARC64_DELAY_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
void __delay(unsigned long loops);
|
||||
void udelay(unsigned long usecs);
|
||||
#define mdelay(n) udelay((n) * 1000)
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _SPARC64_DELAY_H */
|
30
arch/sparc/include/asm/device.h
Normal file
30
arch/sparc/include/asm/device.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Arch specific extensions to struct device
|
||||
*
|
||||
* This file is released under the GPLv2
|
||||
*/
|
||||
#ifndef _ASM_SPARC_DEVICE_H
|
||||
#define _ASM_SPARC_DEVICE_H
|
||||
|
||||
#include <asm/openprom.h>
|
||||
|
||||
struct device_node;
|
||||
struct platform_device;
|
||||
|
||||
struct dev_archdata {
|
||||
void *iommu;
|
||||
void *stc;
|
||||
void *host_controller;
|
||||
struct platform_device *op;
|
||||
int numa_node;
|
||||
};
|
||||
|
||||
void of_propagate_archdata(struct platform_device *bus);
|
||||
|
||||
struct pdev_archdata {
|
||||
struct resource resource[PROMREG_MAX];
|
||||
unsigned int irqs[PROMINTR_MAX];
|
||||
int num_irqs;
|
||||
};
|
||||
|
||||
#endif /* _ASM_SPARC_DEVICE_H */
|
89
arch/sparc/include/asm/dma-mapping.h
Normal file
89
arch/sparc/include/asm/dma-mapping.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
#ifndef ___ASM_SPARC_DMA_MAPPING_H
|
||||
#define ___ASM_SPARC_DMA_MAPPING_H
|
||||
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/dma-debug.h>
|
||||
|
||||
#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
|
||||
|
||||
int dma_supported(struct device *dev, u64 mask);
|
||||
|
||||
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
|
||||
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
|
||||
|
||||
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||
enum dma_data_direction dir)
|
||||
{
|
||||
/* Since dma_{alloc,free}_noncoherent() allocated coherent memory, this
|
||||
* routine can be a nop.
|
||||
*/
|
||||
}
|
||||
|
||||
extern struct dma_map_ops *dma_ops;
|
||||
extern struct dma_map_ops *leon_dma_ops;
|
||||
extern struct dma_map_ops pci32_dma_ops;
|
||||
|
||||
extern struct bus_type pci_bus_type;
|
||||
|
||||
static inline struct dma_map_ops *get_dma_ops(struct device *dev)
|
||||
{
|
||||
#ifdef CONFIG_SPARC_LEON
|
||||
if (sparc_cpu_model == sparc_leon)
|
||||
return leon_dma_ops;
|
||||
#endif
|
||||
#if defined(CONFIG_SPARC32) && defined(CONFIG_PCI)
|
||||
if (dev->bus == &pci_bus_type)
|
||||
return &pci32_dma_ops;
|
||||
#endif
|
||||
return dma_ops;
|
||||
}
|
||||
|
||||
#include <asm-generic/dma-mapping-common.h>
|
||||
|
||||
#define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL)
|
||||
|
||||
static inline void *dma_alloc_attrs(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
struct dma_map_ops *ops = get_dma_ops(dev);
|
||||
void *cpu_addr;
|
||||
|
||||
cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs);
|
||||
debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
|
||||
return cpu_addr;
|
||||
}
|
||||
|
||||
#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
|
||||
|
||||
static inline void dma_free_attrs(struct device *dev, size_t size,
|
||||
void *cpu_addr, dma_addr_t dma_handle,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
struct dma_map_ops *ops = get_dma_ops(dev);
|
||||
|
||||
debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
|
||||
ops->free(dev, size, cpu_addr, dma_handle, attrs);
|
||||
}
|
||||
|
||||
static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
|
||||
{
|
||||
debug_dma_mapping_error(dev, dma_addr);
|
||||
return (dma_addr == DMA_ERROR_CODE);
|
||||
}
|
||||
|
||||
static inline int dma_set_mask(struct device *dev, u64 mask)
|
||||
{
|
||||
#ifdef CONFIG_PCI
|
||||
if (dev->bus == &pci_bus_type) {
|
||||
if (!dev->dma_mask || !dma_supported(dev, mask))
|
||||
return -EINVAL;
|
||||
*dev->dma_mask = mask;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#endif
|
143
arch/sparc/include/asm/dma.h
Normal file
143
arch/sparc/include/asm/dma.h
Normal file
|
@ -0,0 +1,143 @@
|
|||
#ifndef _ASM_SPARC_DMA_H
|
||||
#define _ASM_SPARC_DMA_H
|
||||
|
||||
/* These are irrelevant for Sparc DMA, but we leave it in so that
|
||||
* things can compile.
|
||||
*/
|
||||
#define MAX_DMA_CHANNELS 8
|
||||
#define DMA_MODE_READ 1
|
||||
#define DMA_MODE_WRITE 2
|
||||
#define MAX_DMA_ADDRESS (~0UL)
|
||||
|
||||
/* Useful constants */
|
||||
#define SIZE_16MB (16*1024*1024)
|
||||
#define SIZE_64K (64*1024)
|
||||
|
||||
/* SBUS DMA controller reg offsets */
|
||||
#define DMA_CSR 0x00UL /* rw DMA control/status register 0x00 */
|
||||
#define DMA_ADDR 0x04UL /* rw DMA transfer address register 0x04 */
|
||||
#define DMA_COUNT 0x08UL /* rw DMA transfer count register 0x08 */
|
||||
#define DMA_TEST 0x0cUL /* rw DMA test/debug register 0x0c */
|
||||
|
||||
/* Fields in the cond_reg register */
|
||||
/* First, the version identification bits */
|
||||
#define DMA_DEVICE_ID 0xf0000000 /* Device identification bits */
|
||||
#define DMA_VERS0 0x00000000 /* Sunray DMA version */
|
||||
#define DMA_ESCV1 0x40000000 /* DMA ESC Version 1 */
|
||||
#define DMA_VERS1 0x80000000 /* DMA rev 1 */
|
||||
#define DMA_VERS2 0xa0000000 /* DMA rev 2 */
|
||||
#define DMA_VERHME 0xb0000000 /* DMA hme gate array */
|
||||
#define DMA_VERSPLUS 0x90000000 /* DMA rev 1 PLUS */
|
||||
|
||||
#define DMA_HNDL_INTR 0x00000001 /* An IRQ needs to be handled */
|
||||
#define DMA_HNDL_ERROR 0x00000002 /* We need to take an error */
|
||||
#define DMA_FIFO_ISDRAIN 0x0000000c /* The DMA FIFO is draining */
|
||||
#define DMA_INT_ENAB 0x00000010 /* Turn on interrupts */
|
||||
#define DMA_FIFO_INV 0x00000020 /* Invalidate the FIFO */
|
||||
#define DMA_ACC_SZ_ERR 0x00000040 /* The access size was bad */
|
||||
#define DMA_FIFO_STDRAIN 0x00000040 /* DMA_VERS1 Drain the FIFO */
|
||||
#define DMA_RST_SCSI 0x00000080 /* Reset the SCSI controller */
|
||||
#define DMA_RST_ENET DMA_RST_SCSI /* Reset the ENET controller */
|
||||
#define DMA_ST_WRITE 0x00000100 /* write from device to memory */
|
||||
#define DMA_ENABLE 0x00000200 /* Fire up DMA, handle requests */
|
||||
#define DMA_PEND_READ 0x00000400 /* DMA_VERS1/0/PLUS Pending Read */
|
||||
#define DMA_ESC_BURST 0x00000800 /* 1=16byte 0=32byte */
|
||||
#define DMA_READ_AHEAD 0x00001800 /* DMA read ahead partial longword */
|
||||
#define DMA_DSBL_RD_DRN 0x00001000 /* No EC drain on slave reads */
|
||||
#define DMA_BCNT_ENAB 0x00002000 /* If on, use the byte counter */
|
||||
#define DMA_TERM_CNTR 0x00004000 /* Terminal counter */
|
||||
#define DMA_SCSI_SBUS64 0x00008000 /* HME: Enable 64-bit SBUS mode. */
|
||||
#define DMA_CSR_DISAB 0x00010000 /* No FIFO drains during csr */
|
||||
#define DMA_SCSI_DISAB 0x00020000 /* No FIFO drains during reg */
|
||||
#define DMA_DSBL_WR_INV 0x00020000 /* No EC inval. on slave writes */
|
||||
#define DMA_ADD_ENABLE 0x00040000 /* Special ESC DVMA optimization */
|
||||
#define DMA_E_BURSTS 0x000c0000 /* ENET: SBUS r/w burst mask */
|
||||
#define DMA_E_BURST32 0x00040000 /* ENET: SBUS 32 byte r/w burst */
|
||||
#define DMA_E_BURST16 0x00000000 /* ENET: SBUS 16 byte r/w burst */
|
||||
#define DMA_BRST_SZ 0x000c0000 /* SCSI: SBUS r/w burst size */
|
||||
#define DMA_BRST64 0x000c0000 /* SCSI: 64byte bursts (HME on UltraSparc only) */
|
||||
#define DMA_BRST32 0x00040000 /* SCSI: 32byte bursts */
|
||||
#define DMA_BRST16 0x00000000 /* SCSI: 16byte bursts */
|
||||
#define DMA_BRST0 0x00080000 /* SCSI: no bursts (non-HME gate arrays) */
|
||||
#define DMA_ADDR_DISAB 0x00100000 /* No FIFO drains during addr */
|
||||
#define DMA_2CLKS 0x00200000 /* Each transfer = 2 clock ticks */
|
||||
#define DMA_3CLKS 0x00400000 /* Each transfer = 3 clock ticks */
|
||||
#define DMA_EN_ENETAUI DMA_3CLKS /* Put lance into AUI-cable mode */
|
||||
#define DMA_CNTR_DISAB 0x00800000 /* No IRQ when DMA_TERM_CNTR set */
|
||||
#define DMA_AUTO_NADDR 0x01000000 /* Use "auto nxt addr" feature */
|
||||
#define DMA_SCSI_ON 0x02000000 /* Enable SCSI dma */
|
||||
#define DMA_PARITY_OFF 0x02000000 /* HME: disable parity checking */
|
||||
#define DMA_LOADED_ADDR 0x04000000 /* Address has been loaded */
|
||||
#define DMA_LOADED_NADDR 0x08000000 /* Next address has been loaded */
|
||||
#define DMA_RESET_FAS366 0x08000000 /* HME: Assert RESET to FAS366 */
|
||||
|
||||
/* Values describing the burst-size property from the PROM */
|
||||
#define DMA_BURST1 0x01
|
||||
#define DMA_BURST2 0x02
|
||||
#define DMA_BURST4 0x04
|
||||
#define DMA_BURST8 0x08
|
||||
#define DMA_BURST16 0x10
|
||||
#define DMA_BURST32 0x20
|
||||
#define DMA_BURST64 0x40
|
||||
#define DMA_BURSTBITS 0x7f
|
||||
|
||||
/* From PCI */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
extern int isa_dma_bridge_buggy;
|
||||
#else
|
||||
#define isa_dma_bridge_buggy (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPARC32
|
||||
|
||||
/* Routines for data transfer buffers. */
|
||||
struct device;
|
||||
struct scatterlist;
|
||||
|
||||
struct sparc32_dma_ops {
|
||||
__u32 (*get_scsi_one)(struct device *, char *, unsigned long);
|
||||
void (*get_scsi_sgl)(struct device *, struct scatterlist *, int);
|
||||
void (*release_scsi_one)(struct device *, __u32, unsigned long);
|
||||
void (*release_scsi_sgl)(struct device *, struct scatterlist *,int);
|
||||
#ifdef CONFIG_SBUS
|
||||
int (*map_dma_area)(struct device *, dma_addr_t *, unsigned long, unsigned long, int);
|
||||
void (*unmap_dma_area)(struct device *, unsigned long, int);
|
||||
#endif
|
||||
};
|
||||
extern const struct sparc32_dma_ops *sparc32_dma_ops;
|
||||
|
||||
#define mmu_get_scsi_one(dev,vaddr,len) \
|
||||
sparc32_dma_ops->get_scsi_one(dev, vaddr, len)
|
||||
#define mmu_get_scsi_sgl(dev,sg,sz) \
|
||||
sparc32_dma_ops->get_scsi_sgl(dev, sg, sz)
|
||||
#define mmu_release_scsi_one(dev,vaddr,len) \
|
||||
sparc32_dma_ops->release_scsi_one(dev, vaddr,len)
|
||||
#define mmu_release_scsi_sgl(dev,sg,sz) \
|
||||
sparc32_dma_ops->release_scsi_sgl(dev, sg, sz)
|
||||
|
||||
#ifdef CONFIG_SBUS
|
||||
/*
|
||||
* mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep.
|
||||
*
|
||||
* The mmu_map_dma_area establishes two mappings in one go.
|
||||
* These mappings point to pages normally mapped at 'va' (linear address).
|
||||
* First mapping is for CPU visible address at 'a', uncached.
|
||||
* This is an alias, but it works because it is an uncached mapping.
|
||||
* Second mapping is for device visible address, or "bus" address.
|
||||
* The bus address is returned at '*pba'.
|
||||
*
|
||||
* These functions seem distinct, but are hard to split.
|
||||
* On sun4m, page attributes depend on the CPU type, so we have to
|
||||
* know if we are mapping RAM or I/O, so it has to be an additional argument
|
||||
* to a separate mapping function for CPU visible mappings.
|
||||
*/
|
||||
#define sbus_map_dma_area(dev,pba,va,a,len) \
|
||||
sparc32_dma_ops->map_dma_area(dev, pba, va, a, len)
|
||||
#define sbus_unmap_dma_area(dev,ba,len) \
|
||||
sparc32_dma_ops->unmap_dma_area(dev, ba, len)
|
||||
#endif /* CONFIG_SBUS */
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* !(_ASM_SPARC_DMA_H) */
|
35
arch/sparc/include/asm/ebus_dma.h
Normal file
35
arch/sparc/include/asm/ebus_dma.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef __ASM_SPARC_EBUS_DMA_H
|
||||
#define __ASM_SPARC_EBUS_DMA_H
|
||||
|
||||
struct ebus_dma_info {
|
||||
spinlock_t lock;
|
||||
void __iomem *regs;
|
||||
|
||||
unsigned int flags;
|
||||
#define EBUS_DMA_FLAG_USE_EBDMA_HANDLER 0x00000001
|
||||
#define EBUS_DMA_FLAG_TCI_DISABLE 0x00000002
|
||||
|
||||
/* These are only valid is EBUS_DMA_FLAG_USE_EBDMA_HANDLER is
|
||||
* set.
|
||||
*/
|
||||
void (*callback)(struct ebus_dma_info *p, int event, void *cookie);
|
||||
void *client_cookie;
|
||||
unsigned int irq;
|
||||
#define EBUS_DMA_EVENT_ERROR 1
|
||||
#define EBUS_DMA_EVENT_DMA 2
|
||||
#define EBUS_DMA_EVENT_DEVICE 4
|
||||
|
||||
unsigned char name[64];
|
||||
};
|
||||
|
||||
int ebus_dma_register(struct ebus_dma_info *p);
|
||||
int ebus_dma_irq_enable(struct ebus_dma_info *p, int on);
|
||||
void ebus_dma_unregister(struct ebus_dma_info *p);
|
||||
int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr,
|
||||
size_t len);
|
||||
void ebus_dma_prepare(struct ebus_dma_info *p, int write);
|
||||
unsigned int ebus_dma_residue(struct ebus_dma_info *p);
|
||||
unsigned int ebus_dma_addr(struct ebus_dma_info *p);
|
||||
void ebus_dma_enable(struct ebus_dma_info *p, int on);
|
||||
|
||||
#endif /* __ASM_SPARC_EBUS_DMA_H */
|
122
arch/sparc/include/asm/ecc.h
Normal file
122
arch/sparc/include/asm/ecc.h
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* ecc.h: Definitions and defines for the external cache/memory
|
||||
* controller on the sun4m.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC_ECC_H
|
||||
#define _SPARC_ECC_H
|
||||
|
||||
/* These registers are accessed through the SRMMU passthrough ASI 0x20 */
|
||||
#define ECC_ENABLE 0x00000000 /* ECC enable register */
|
||||
#define ECC_FSTATUS 0x00000008 /* ECC fault status register */
|
||||
#define ECC_FADDR 0x00000010 /* ECC fault address register */
|
||||
#define ECC_DIGNOSTIC 0x00000018 /* ECC diagnostics register */
|
||||
#define ECC_MBAENAB 0x00000020 /* MBus arbiter enable register */
|
||||
#define ECC_DMESG 0x00001000 /* Diagnostic message passing area */
|
||||
|
||||
/* ECC MBus Arbiter Enable register:
|
||||
*
|
||||
* ----------------------------------------
|
||||
* | |SBUS|MOD3|MOD2|MOD1|RSV|
|
||||
* ----------------------------------------
|
||||
* 31 5 4 3 2 1 0
|
||||
*
|
||||
* SBUS: Enable MBus Arbiter on the SBus 0=off 1=on
|
||||
* MOD3: Enable MBus Arbiter on MBus module 3 0=off 1=on
|
||||
* MOD2: Enable MBus Arbiter on MBus module 2 0=off 1=on
|
||||
* MOD1: Enable MBus Arbiter on MBus module 1 0=off 1=on
|
||||
*/
|
||||
|
||||
#define ECC_MBAE_SBUS 0x00000010
|
||||
#define ECC_MBAE_MOD3 0x00000008
|
||||
#define ECC_MBAE_MOD2 0x00000004
|
||||
#define ECC_MBAE_MOD1 0x00000002
|
||||
|
||||
/* ECC Fault Control Register layout:
|
||||
*
|
||||
* -----------------------------
|
||||
* | RESV | ECHECK | EINT |
|
||||
* -----------------------------
|
||||
* 31 2 1 0
|
||||
*
|
||||
* ECHECK: Enable ECC checking. 0=off 1=on
|
||||
* EINT: Enable Interrupts for correctable errors. 0=off 1=on
|
||||
*/
|
||||
#define ECC_FCR_CHECK 0x00000002
|
||||
#define ECC_FCR_INTENAB 0x00000001
|
||||
|
||||
/* ECC Fault Address Register Zero layout:
|
||||
*
|
||||
* -----------------------------------------------------
|
||||
* | MID | S | RSV | VA | BM |AT| C| SZ |TYP| PADDR |
|
||||
* -----------------------------------------------------
|
||||
* 31-28 27 26-22 21-14 13 12 11 10-8 7-4 3-0
|
||||
*
|
||||
* MID: ModuleID of the faulting processor. ie. who did it?
|
||||
* S: Supervisor/Privileged access? 0=no 1=yes
|
||||
* VA: Bits 19-12 of the virtual faulting address, these are the
|
||||
* superset bits in the virtual cache and can be used for
|
||||
* a flush operation if necessary.
|
||||
* BM: Boot mode? 0=no 1=yes This is just like the SRMMU boot
|
||||
* mode bit.
|
||||
* AT: Did this fault happen during an atomic instruction? 0=no
|
||||
* 1=yes. This means either an 'ldstub' or 'swap' instruction
|
||||
* was in progress (but not finished) when this fault happened.
|
||||
* This indicated whether the bus was locked when the fault
|
||||
* occurred.
|
||||
* C: Did the pte for this access indicate that it was cacheable?
|
||||
* 0=no 1=yes
|
||||
* SZ: The size of the transaction.
|
||||
* TYP: The transaction type.
|
||||
* PADDR: Bits 35-32 of the physical address for the fault.
|
||||
*/
|
||||
#define ECC_FADDR0_MIDMASK 0xf0000000
|
||||
#define ECC_FADDR0_S 0x08000000
|
||||
#define ECC_FADDR0_VADDR 0x003fc000
|
||||
#define ECC_FADDR0_BMODE 0x00002000
|
||||
#define ECC_FADDR0_ATOMIC 0x00001000
|
||||
#define ECC_FADDR0_CACHE 0x00000800
|
||||
#define ECC_FADDR0_SIZE 0x00000700
|
||||
#define ECC_FADDR0_TYPE 0x000000f0
|
||||
#define ECC_FADDR0_PADDR 0x0000000f
|
||||
|
||||
/* ECC Fault Address Register One layout:
|
||||
*
|
||||
* -------------------------------------
|
||||
* | Physical Address 31-0 |
|
||||
* -------------------------------------
|
||||
* 31 0
|
||||
*
|
||||
* You get the upper 4 bits of the physical address from the
|
||||
* PADDR field in ECC Fault Address Zero register.
|
||||
*/
|
||||
|
||||
/* ECC Fault Status Register layout:
|
||||
*
|
||||
* ----------------------------------------------
|
||||
* | RESV|C2E|MULT|SYNDROME|DWORD|UNC|TIMEO|BS|C|
|
||||
* ----------------------------------------------
|
||||
* 31-18 17 16 15-8 7-4 3 2 1 0
|
||||
*
|
||||
* C2E: A C2 graphics error occurred. 0=no 1=yes (SS10 only)
|
||||
* MULT: Multiple errors occurred ;-O 0=no 1=prom_panic(yes)
|
||||
* SYNDROME: Controller is mentally unstable.
|
||||
* DWORD:
|
||||
* UNC: Uncorrectable error. 0=no 1=yes
|
||||
* TIMEO: Timeout occurred. 0=no 1=yes
|
||||
* BS: C2 graphics bad slot access. 0=no 1=yes (SS10 only)
|
||||
* C: Correctable error? 0=no 1=yes
|
||||
*/
|
||||
|
||||
#define ECC_FSR_C2ERR 0x00020000
|
||||
#define ECC_FSR_MULT 0x00010000
|
||||
#define ECC_FSR_SYND 0x0000ff00
|
||||
#define ECC_FSR_DWORD 0x000000f0
|
||||
#define ECC_FSR_UNC 0x00000008
|
||||
#define ECC_FSR_TIMEO 0x00000004
|
||||
#define ECC_FSR_BADSLOT 0x00000002
|
||||
#define ECC_FSR_C 0x00000001
|
||||
|
||||
#endif /* !(_SPARC_ECC_H) */
|
9
arch/sparc/include/asm/eeprom.h
Normal file
9
arch/sparc/include/asm/eeprom.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* eeprom.h: Definitions for the Sun eeprom.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
|
||||
/* The EEPROM and the Mostek Mk48t02 use the same IO address space
|
||||
* for their registers/data areas. The IDPROM lives here too.
|
||||
*/
|
8
arch/sparc/include/asm/elf.h
Normal file
8
arch/sparc/include/asm/elf.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ___ASM_SPARC_ELF_H
|
||||
#define ___ASM_SPARC_ELF_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm/elf_64.h>
|
||||
#else
|
||||
#include <asm/elf_32.h>
|
||||
#endif
|
||||
#endif
|
131
arch/sparc/include/asm/elf_32.h
Normal file
131
arch/sparc/include/asm/elf_32.h
Normal file
|
@ -0,0 +1,131 @@
|
|||
#ifndef __ASMSPARC_ELF_H
|
||||
#define __ASMSPARC_ELF_H
|
||||
|
||||
/*
|
||||
* ELF register definitions..
|
||||
*/
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
/*
|
||||
* Sparc section types
|
||||
*/
|
||||
#define STT_REGISTER 13
|
||||
|
||||
/*
|
||||
* Sparc ELF relocation types
|
||||
*/
|
||||
#define R_SPARC_NONE 0
|
||||
#define R_SPARC_8 1
|
||||
#define R_SPARC_16 2
|
||||
#define R_SPARC_32 3
|
||||
#define R_SPARC_DISP8 4
|
||||
#define R_SPARC_DISP16 5
|
||||
#define R_SPARC_DISP32 6
|
||||
#define R_SPARC_WDISP30 7
|
||||
#define R_SPARC_WDISP22 8
|
||||
#define R_SPARC_HI22 9
|
||||
#define R_SPARC_22 10
|
||||
#define R_SPARC_13 11
|
||||
#define R_SPARC_LO10 12
|
||||
#define R_SPARC_GOT10 13
|
||||
#define R_SPARC_GOT13 14
|
||||
#define R_SPARC_GOT22 15
|
||||
#define R_SPARC_PC10 16
|
||||
#define R_SPARC_PC22 17
|
||||
#define R_SPARC_WPLT30 18
|
||||
#define R_SPARC_COPY 19
|
||||
#define R_SPARC_GLOB_DAT 20
|
||||
#define R_SPARC_JMP_SLOT 21
|
||||
#define R_SPARC_RELATIVE 22
|
||||
#define R_SPARC_UA32 23
|
||||
#define R_SPARC_PLT32 24
|
||||
#define R_SPARC_HIPLT22 25
|
||||
#define R_SPARC_LOPLT10 26
|
||||
#define R_SPARC_PCPLT32 27
|
||||
#define R_SPARC_PCPLT22 28
|
||||
#define R_SPARC_PCPLT10 29
|
||||
#define R_SPARC_10 30
|
||||
#define R_SPARC_11 31
|
||||
#define R_SPARC_64 32
|
||||
#define R_SPARC_OLO10 33
|
||||
#define R_SPARC_WDISP16 40
|
||||
#define R_SPARC_WDISP19 41
|
||||
#define R_SPARC_7 43
|
||||
#define R_SPARC_5 44
|
||||
#define R_SPARC_6 45
|
||||
|
||||
/* Bits present in AT_HWCAP, primarily for Sparc32. */
|
||||
|
||||
#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */
|
||||
#define HWCAP_SPARC_STBAR 2
|
||||
#define HWCAP_SPARC_SWAP 4
|
||||
#define HWCAP_SPARC_MULDIV 8
|
||||
#define HWCAP_SPARC_V9 16
|
||||
#define HWCAP_SPARC_ULTRA3 32
|
||||
|
||||
#define CORE_DUMP_USE_REGSET
|
||||
|
||||
/* Format is:
|
||||
* G0 --> G7
|
||||
* O0 --> O7
|
||||
* L0 --> L7
|
||||
* I0 --> I7
|
||||
* PSR, PC, nPC, Y, WIM, TBR
|
||||
*/
|
||||
typedef unsigned long elf_greg_t;
|
||||
#define ELF_NGREG 38
|
||||
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
unsigned long pr_regs[32];
|
||||
double pr_dregs[16];
|
||||
} pr_fr;
|
||||
unsigned long __unused;
|
||||
unsigned long pr_fsr;
|
||||
unsigned char pr_qcnt;
|
||||
unsigned char pr_q_entrysize;
|
||||
unsigned char pr_en;
|
||||
unsigned int pr_q[64];
|
||||
} elf_fpregset_t;
|
||||
|
||||
#include <asm/mbus.h>
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch(x) ((x)->e_machine == EM_SPARC)
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
*/
|
||||
#define ELF_ARCH EM_SPARC
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_DATA ELFDATA2MSB
|
||||
|
||||
#define ELF_EXEC_PAGESIZE 4096
|
||||
|
||||
|
||||
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
|
||||
use of this is to invoke "./ld.so someprog" to test out a new version of
|
||||
the loader. We need to make sure that it is out of the way of the program
|
||||
that it will "exec", and that there is sufficient room for the brk. */
|
||||
|
||||
#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
|
||||
|
||||
/* This yields a mask that user programs can use to figure out what
|
||||
instruction set this cpu supports. This can NOT be done in userspace
|
||||
on Sparc. */
|
||||
|
||||
/* Most sun4m's have them all. */
|
||||
#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \
|
||||
HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV)
|
||||
|
||||
/* 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)
|
||||
|
||||
#endif /* !(__ASMSPARC_ELF_H) */
|
212
arch/sparc/include/asm/elf_64.h
Normal file
212
arch/sparc/include/asm/elf_64.h
Normal file
|
@ -0,0 +1,212 @@
|
|||
#ifndef __ASM_SPARC64_ELF_H
|
||||
#define __ASM_SPARC64_ELF_H
|
||||
|
||||
/*
|
||||
* ELF register definitions..
|
||||
*/
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/spitfire.h>
|
||||
|
||||
/*
|
||||
* Sparc section types
|
||||
*/
|
||||
#define STT_REGISTER 13
|
||||
|
||||
/*
|
||||
* Sparc ELF relocation types
|
||||
*/
|
||||
#define R_SPARC_NONE 0
|
||||
#define R_SPARC_8 1
|
||||
#define R_SPARC_16 2
|
||||
#define R_SPARC_32 3
|
||||
#define R_SPARC_DISP8 4
|
||||
#define R_SPARC_DISP16 5
|
||||
#define R_SPARC_DISP32 6
|
||||
#define R_SPARC_WDISP30 7
|
||||
#define R_SPARC_WDISP22 8
|
||||
#define R_SPARC_HI22 9
|
||||
#define R_SPARC_22 10
|
||||
#define R_SPARC_13 11
|
||||
#define R_SPARC_LO10 12
|
||||
#define R_SPARC_GOT10 13
|
||||
#define R_SPARC_GOT13 14
|
||||
#define R_SPARC_GOT22 15
|
||||
#define R_SPARC_PC10 16
|
||||
#define R_SPARC_PC22 17
|
||||
#define R_SPARC_WPLT30 18
|
||||
#define R_SPARC_COPY 19
|
||||
#define R_SPARC_GLOB_DAT 20
|
||||
#define R_SPARC_JMP_SLOT 21
|
||||
#define R_SPARC_RELATIVE 22
|
||||
#define R_SPARC_UA32 23
|
||||
#define R_SPARC_PLT32 24
|
||||
#define R_SPARC_HIPLT22 25
|
||||
#define R_SPARC_LOPLT10 26
|
||||
#define R_SPARC_PCPLT32 27
|
||||
#define R_SPARC_PCPLT22 28
|
||||
#define R_SPARC_PCPLT10 29
|
||||
#define R_SPARC_10 30
|
||||
#define R_SPARC_11 31
|
||||
#define R_SPARC_64 32
|
||||
#define R_SPARC_OLO10 33
|
||||
#define R_SPARC_WDISP16 40
|
||||
#define R_SPARC_WDISP19 41
|
||||
#define R_SPARC_7 43
|
||||
#define R_SPARC_5 44
|
||||
#define R_SPARC_6 45
|
||||
|
||||
/* Bits present in AT_HWCAP, primarily for Sparc32. */
|
||||
#define HWCAP_SPARC_FLUSH 0x00000001
|
||||
#define HWCAP_SPARC_STBAR 0x00000002
|
||||
#define HWCAP_SPARC_SWAP 0x00000004
|
||||
#define HWCAP_SPARC_MULDIV 0x00000008
|
||||
#define HWCAP_SPARC_V9 0x00000010
|
||||
#define HWCAP_SPARC_ULTRA3 0x00000020
|
||||
#define HWCAP_SPARC_BLKINIT 0x00000040
|
||||
#define HWCAP_SPARC_N2 0x00000080
|
||||
|
||||
/* Solaris compatible AT_HWCAP bits. */
|
||||
#define AV_SPARC_MUL32 0x00000100 /* 32x32 multiply is efficient */
|
||||
#define AV_SPARC_DIV32 0x00000200 /* 32x32 divide is efficient */
|
||||
#define AV_SPARC_FSMULD 0x00000400 /* 'fsmuld' is efficient */
|
||||
#define AV_SPARC_V8PLUS 0x00000800 /* v9 insn available to 32bit */
|
||||
#define AV_SPARC_POPC 0x00001000 /* 'popc' is efficient */
|
||||
#define AV_SPARC_VIS 0x00002000 /* VIS insns available */
|
||||
#define AV_SPARC_VIS2 0x00004000 /* VIS2 insns available */
|
||||
#define AV_SPARC_ASI_BLK_INIT 0x00008000 /* block init ASIs available */
|
||||
#define AV_SPARC_FMAF 0x00010000 /* fused multiply-add */
|
||||
#define AV_SPARC_VIS3 0x00020000 /* VIS3 insns available */
|
||||
#define AV_SPARC_HPC 0x00040000 /* HPC insns available */
|
||||
#define AV_SPARC_RANDOM 0x00080000 /* 'random' insn available */
|
||||
#define AV_SPARC_TRANS 0x00100000 /* transaction insns available */
|
||||
#define AV_SPARC_FJFMAU 0x00200000 /* unfused multiply-add */
|
||||
#define AV_SPARC_IMA 0x00400000 /* integer multiply-add */
|
||||
#define AV_SPARC_ASI_CACHE_SPARING \
|
||||
0x00800000 /* cache sparing ASIs available */
|
||||
#define AV_SPARC_PAUSE 0x01000000 /* PAUSE available */
|
||||
#define AV_SPARC_CBCOND 0x02000000 /* CBCOND insns available */
|
||||
|
||||
/* Solaris decided to enumerate every single crypto instruction type
|
||||
* in the AT_HWCAP bits. This is wasteful, since if crypto is present,
|
||||
* you still need to look in the CFR register to see if the opcode is
|
||||
* really available. So we simply advertise only "crypto" support.
|
||||
*/
|
||||
#define HWCAP_SPARC_CRYPTO 0x04000000 /* CRYPTO insns available */
|
||||
|
||||
#define CORE_DUMP_USE_REGSET
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
*/
|
||||
#define ELF_ARCH EM_SPARCV9
|
||||
#define ELF_CLASS ELFCLASS64
|
||||
#define ELF_DATA ELFDATA2MSB
|
||||
|
||||
/* Format of 64-bit elf_gregset_t is:
|
||||
* G0 --> G7
|
||||
* O0 --> O7
|
||||
* L0 --> L7
|
||||
* I0 --> I7
|
||||
* TSTATE
|
||||
* TPC
|
||||
* TNPC
|
||||
* Y
|
||||
*/
|
||||
typedef unsigned long elf_greg_t;
|
||||
#define ELF_NGREG 36
|
||||
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||
|
||||
typedef struct {
|
||||
unsigned long pr_regs[32];
|
||||
unsigned long pr_fsr;
|
||||
unsigned long pr_gsr;
|
||||
unsigned long pr_fprs;
|
||||
} elf_fpregset_t;
|
||||
|
||||
/* Format of 32-bit elf_gregset_t is:
|
||||
* G0 --> G7
|
||||
* O0 --> O7
|
||||
* L0 --> L7
|
||||
* I0 --> I7
|
||||
* PSR, PC, nPC, Y, WIM, TBR
|
||||
*/
|
||||
typedef unsigned int compat_elf_greg_t;
|
||||
#define COMPAT_ELF_NGREG 38
|
||||
typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
unsigned int pr_regs[32];
|
||||
unsigned long pr_dregs[16];
|
||||
} pr_fr;
|
||||
unsigned int __unused;
|
||||
unsigned int pr_fsr;
|
||||
unsigned char pr_qcnt;
|
||||
unsigned char pr_q_entrysize;
|
||||
unsigned char pr_en;
|
||||
unsigned int pr_q[64];
|
||||
} compat_elf_fpregset_t;
|
||||
|
||||
/* UltraSparc extensions. Still unused, but will be eventually. */
|
||||
typedef struct {
|
||||
unsigned int pr_type;
|
||||
unsigned int pr_align;
|
||||
union {
|
||||
struct {
|
||||
union {
|
||||
unsigned int pr_regs[32];
|
||||
unsigned long pr_dregs[16];
|
||||
long double pr_qregs[8];
|
||||
} pr_xfr;
|
||||
} pr_v8p;
|
||||
unsigned int pr_xfsr;
|
||||
unsigned int pr_fprs;
|
||||
unsigned int pr_xg[8];
|
||||
unsigned int pr_xo[8];
|
||||
unsigned long pr_tstate;
|
||||
unsigned int pr_filler[8];
|
||||
} pr_un;
|
||||
} elf_xregset_t;
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
|
||||
#define compat_elf_check_arch(x) ((x)->e_machine == EM_SPARC || \
|
||||
(x)->e_machine == EM_SPARC32PLUS)
|
||||
#define compat_start_thread start_thread32
|
||||
|
||||
#define ELF_EXEC_PAGESIZE PAGE_SIZE
|
||||
|
||||
/* 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 0x0000010000000000UL
|
||||
#define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
|
||||
|
||||
extern unsigned long sparc64_elf_hwcap;
|
||||
#define ELF_HWCAP sparc64_elf_hwcap
|
||||
|
||||
/* This yields a string that ld.so will use to load implementation
|
||||
specific libraries for optimization. This is more specific in
|
||||
intent than poking at uname or /proc/cpuinfo. */
|
||||
|
||||
#define ELF_PLATFORM (NULL)
|
||||
|
||||
#define SET_PERSONALITY(ex) \
|
||||
do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
|
||||
set_thread_flag(TIF_32BIT); \
|
||||
else \
|
||||
clear_thread_flag(TIF_32BIT); \
|
||||
/* flush_thread will update pgd cache */ \
|
||||
if (personality(current->personality) != PER_LINUX32) \
|
||||
set_personality(PER_LINUX | \
|
||||
(current->personality & (~PER_MASK))); \
|
||||
} while (0)
|
||||
|
||||
#endif /* !(__ASM_SPARC64_ELF_H) */
|
49
arch/sparc/include/asm/estate.h
Normal file
49
arch/sparc/include/asm/estate.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
#ifndef _SPARC64_ESTATE_H
|
||||
#define _SPARC64_ESTATE_H
|
||||
|
||||
/* UltraSPARC-III E-cache Error Enable */
|
||||
#define ESTATE_ERROR_FMT 0x0000000000040000 /* Force MTAG ECC */
|
||||
#define ESTATE_ERROR_FMESS 0x000000000003c000 /* Forced MTAG ECC val */
|
||||
#define ESTATE_ERROR_FMD 0x0000000000002000 /* Force DATA ECC */
|
||||
#define ESTATE_ERROR_FDECC 0x0000000000001ff0 /* Forced DATA ECC val */
|
||||
#define ESTATE_ERROR_UCEEN 0x0000000000000008 /* See below */
|
||||
#define ESTATE_ERROR_NCEEN 0x0000000000000002 /* See below */
|
||||
#define ESTATE_ERROR_CEEN 0x0000000000000001 /* See below */
|
||||
|
||||
/* UCEEN enables the fast_ECC_error trap for: 1) software correctable E-cache
|
||||
* errors 2) uncorrectable E-cache errors. Such events only occur on reads
|
||||
* of the E-cache by the local processor for: 1) data loads 2) instruction
|
||||
* fetches 3) atomic operations. Such events _cannot_ occur for: 1) merge
|
||||
* 2) writeback 2) copyout. The AFSR bits associated with these traps are
|
||||
* UCC and UCU.
|
||||
*/
|
||||
|
||||
/* NCEEN enables instruction_access_error, data_access_error, and ECC_error traps
|
||||
* for uncorrectable ECC errors and system errors.
|
||||
*
|
||||
* Uncorrectable system bus data error or MTAG ECC error, system bus TimeOUT,
|
||||
* or system bus BusERR:
|
||||
* 1) As the result of an instruction fetch, will generate instruction_access_error
|
||||
* 2) As the result of a load etc. will generate data_access_error.
|
||||
* 3) As the result of store merge completion, writeback, or copyout will
|
||||
* generate a disrupting ECC_error trap.
|
||||
* 4) As the result of such errors on instruction vector fetch can generate any
|
||||
* of the 3 trap types.
|
||||
*
|
||||
* The AFSR bits associated with these traps are EMU, EDU, WDU, CPU, IVU, UE,
|
||||
* BERR, and TO.
|
||||
*/
|
||||
|
||||
/* CEEN enables the ECC_error trap for hardware corrected ECC errors. System bus
|
||||
* reads resulting in a hardware corrected data or MTAG ECC error will generate an
|
||||
* ECC_error disrupting trap with this bit enabled.
|
||||
*
|
||||
* This same trap will also be generated when a hardware corrected ECC error results
|
||||
* during store merge, writeback, and copyout operations.
|
||||
*/
|
||||
|
||||
/* In general, if the trap enable bits above are disabled the AFSR bits will still
|
||||
* log the events even though the trap will not be generated by the processor.
|
||||
*/
|
||||
|
||||
#endif /* _SPARC64_ESTATE_H */
|
33
arch/sparc/include/asm/fb.h
Normal file
33
arch/sparc/include/asm/fb.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef _SPARC_FB_H_
|
||||
#define _SPARC_FB_H_
|
||||
#include <linux/console.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
#ifdef CONFIG_SPARC64
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
struct device *dev = info->device;
|
||||
struct device_node *node;
|
||||
|
||||
if (console_set_on_cmdline)
|
||||
return 0;
|
||||
|
||||
node = dev->of_node;
|
||||
if (node &&
|
||||
node == of_console_device)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _SPARC_FB_H_ */
|
72
arch/sparc/include/asm/fbio.h
Normal file
72
arch/sparc/include/asm/fbio.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
#ifndef __LINUX_FBIO_H
|
||||
#define __LINUX_FBIO_H
|
||||
|
||||
#include <uapi/asm/fbio.h>
|
||||
|
||||
#define FBIOPUTCMAP_SPARC _IOW('F', 3, struct fbcmap)
|
||||
#define FBIOGETCMAP_SPARC _IOW('F', 4, struct fbcmap)
|
||||
/* Addresses on the fd of a cgsix that are mappable */
|
||||
#define CG6_FBC 0x70000000
|
||||
#define CG6_TEC 0x70001000
|
||||
#define CG6_BTREGS 0x70002000
|
||||
#define CG6_FHC 0x70004000
|
||||
#define CG6_THC 0x70005000
|
||||
#define CG6_ROM 0x70006000
|
||||
#define CG6_RAM 0x70016000
|
||||
#define CG6_DHC 0x80000000
|
||||
|
||||
#define CG3_MMAP_OFFSET 0x4000000
|
||||
|
||||
/* Addresses on the fd of a tcx that are mappable */
|
||||
#define TCX_RAM8BIT 0x00000000
|
||||
#define TCX_RAM24BIT 0x01000000
|
||||
#define TCX_UNK3 0x10000000
|
||||
#define TCX_UNK4 0x20000000
|
||||
#define TCX_CONTROLPLANE 0x28000000
|
||||
#define TCX_UNK6 0x30000000
|
||||
#define TCX_UNK7 0x38000000
|
||||
#define TCX_TEC 0x70000000
|
||||
#define TCX_BTREGS 0x70002000
|
||||
#define TCX_THC 0x70004000
|
||||
#define TCX_DHC 0x70008000
|
||||
#define TCX_ALT 0x7000a000
|
||||
#define TCX_SYNC 0x7000e000
|
||||
#define TCX_UNK2 0x70010000
|
||||
|
||||
/* CG14 definitions */
|
||||
|
||||
/* Offsets into the OBIO space: */
|
||||
#define CG14_REGS 0 /* registers */
|
||||
#define CG14_CURSORREGS 0x1000 /* cursor registers */
|
||||
#define CG14_DACREGS 0x2000 /* DAC registers */
|
||||
#define CG14_XLUT 0x3000 /* X Look Up Table -- ??? */
|
||||
#define CG14_CLUT1 0x4000 /* Color Look Up Table */
|
||||
#define CG14_CLUT2 0x5000 /* Color Look Up Table */
|
||||
#define CG14_CLUT3 0x6000 /* Color Look Up Table */
|
||||
#define CG14_AUTO 0xf000
|
||||
|
||||
struct fbcmap32 {
|
||||
int index; /* first element (0 origin) */
|
||||
int count;
|
||||
u32 red;
|
||||
u32 green;
|
||||
u32 blue;
|
||||
};
|
||||
|
||||
#define FBIOPUTCMAP32 _IOW('F', 3, struct fbcmap32)
|
||||
#define FBIOGETCMAP32 _IOW('F', 4, struct fbcmap32)
|
||||
|
||||
struct fbcursor32 {
|
||||
short set; /* what to set, choose from the list above */
|
||||
short enable; /* cursor on/off */
|
||||
struct fbcurpos pos; /* cursor position */
|
||||
struct fbcurpos hot; /* cursor hot spot */
|
||||
struct fbcmap32 cmap; /* color map info */
|
||||
struct fbcurpos size; /* cursor bit map size */
|
||||
u32 image; /* cursor image bits */
|
||||
u32 mask; /* cursor mask bits */
|
||||
};
|
||||
|
||||
#define FBIOSCURSOR32 _IOW('F', 24, struct fbcursor32)
|
||||
#define FBIOGCURSOR32 _IOW('F', 25, struct fbcursor32)
|
||||
#endif /* __LINUX_FBIO_H */
|
80
arch/sparc/include/asm/fhc.h
Normal file
80
arch/sparc/include/asm/fhc.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/* fhc.h: FHC and Clock board register definitions.
|
||||
*
|
||||
* Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC64_FHC_H
|
||||
#define _SPARC64_FHC_H
|
||||
|
||||
/* Clock board register offsets. */
|
||||
#define CLOCK_CTRL 0x00UL /* Main control */
|
||||
#define CLOCK_STAT1 0x10UL /* Status one */
|
||||
#define CLOCK_STAT2 0x20UL /* Status two */
|
||||
#define CLOCK_PWRSTAT 0x30UL /* Power status */
|
||||
#define CLOCK_PWRPRES 0x40UL /* Power presence */
|
||||
#define CLOCK_TEMP 0x50UL /* Temperature */
|
||||
#define CLOCK_IRQDIAG 0x60UL /* IRQ diagnostics */
|
||||
#define CLOCK_PWRSTAT2 0x70UL /* Power status two */
|
||||
|
||||
#define CLOCK_CTRL_LLED 0x04 /* Left LED, 0 == on */
|
||||
#define CLOCK_CTRL_MLED 0x02 /* Mid LED, 1 == on */
|
||||
#define CLOCK_CTRL_RLED 0x01 /* RIght LED, 1 == on */
|
||||
|
||||
/* Firehose controller register offsets */
|
||||
#define FHC_PREGS_ID 0x00UL /* FHC ID */
|
||||
#define FHC_ID_VERS 0xf0000000 /* Version of this FHC */
|
||||
#define FHC_ID_PARTID 0x0ffff000 /* Part ID code (0x0f9f == FHC) */
|
||||
#define FHC_ID_MANUF 0x0000007e /* Manufacturer (0x3e == SUN's JEDEC)*/
|
||||
#define FHC_ID_RESV 0x00000001 /* Read as one */
|
||||
#define FHC_PREGS_RCS 0x10UL /* FHC Reset Control/Status Register */
|
||||
#define FHC_RCS_POR 0x80000000 /* Last reset was a power cycle */
|
||||
#define FHC_RCS_SPOR 0x40000000 /* Last reset was sw power on reset */
|
||||
#define FHC_RCS_SXIR 0x20000000 /* Last reset was sw XIR reset */
|
||||
#define FHC_RCS_BPOR 0x10000000 /* Last reset was due to POR button */
|
||||
#define FHC_RCS_BXIR 0x08000000 /* Last reset was due to XIR button */
|
||||
#define FHC_RCS_WEVENT 0x04000000 /* CPU reset was due to wakeup event */
|
||||
#define FHC_RCS_CFATAL 0x02000000 /* Centerplane Fatal Error signalled */
|
||||
#define FHC_RCS_FENAB 0x01000000 /* Fatal errors elicit system reset */
|
||||
#define FHC_PREGS_CTRL 0x20UL /* FHC Control Register */
|
||||
#define FHC_CONTROL_ICS 0x00100000 /* Ignore Centerplane Signals */
|
||||
#define FHC_CONTROL_FRST 0x00080000 /* Fatal Error Reset Enable */
|
||||
#define FHC_CONTROL_LFAT 0x00040000 /* AC/DC signalled a local error */
|
||||
#define FHC_CONTROL_SLINE 0x00010000 /* Firmware Synchronization Line */
|
||||
#define FHC_CONTROL_DCD 0x00008000 /* DC-->DC Converter Disable */
|
||||
#define FHC_CONTROL_POFF 0x00004000 /* AC/DC Controller PLL Disable */
|
||||
#define FHC_CONTROL_FOFF 0x00002000 /* FHC Controller PLL Disable */
|
||||
#define FHC_CONTROL_AOFF 0x00001000 /* CPU A SRAM/SBD Low Power Mode */
|
||||
#define FHC_CONTROL_BOFF 0x00000800 /* CPU B SRAM/SBD Low Power Mode */
|
||||
#define FHC_CONTROL_PSOFF 0x00000400 /* Turns off this FHC's power supply */
|
||||
#define FHC_CONTROL_IXIST 0x00000200 /* 0=FHC tells clock board it exists */
|
||||
#define FHC_CONTROL_XMSTR 0x00000100 /* 1=Causes this FHC to be XIR master*/
|
||||
#define FHC_CONTROL_LLED 0x00000040 /* 0=Left LED ON */
|
||||
#define FHC_CONTROL_MLED 0x00000020 /* 1=Middle LED ON */
|
||||
#define FHC_CONTROL_RLED 0x00000010 /* 1=Right LED */
|
||||
#define FHC_CONTROL_BPINS 0x00000003 /* Spare Bidirectional Pins */
|
||||
#define FHC_PREGS_BSR 0x30UL /* FHC Board Status Register */
|
||||
#define FHC_BSR_DA64 0x00040000 /* Port A: 0=128bit 1=64bit data path */
|
||||
#define FHC_BSR_DB64 0x00020000 /* Port B: 0=128bit 1=64bit data path */
|
||||
#define FHC_BSR_BID 0x0001e000 /* Board ID */
|
||||
#define FHC_BSR_SA 0x00001c00 /* Port A UPA Speed (from the pins) */
|
||||
#define FHC_BSR_SB 0x00000380 /* Port B UPA Speed (from the pins) */
|
||||
#define FHC_BSR_NDIAG 0x00000040 /* Not in Diag Mode */
|
||||
#define FHC_BSR_NTBED 0x00000020 /* Not in TestBED Mode */
|
||||
#define FHC_BSR_NIA 0x0000001c /* Jumper, bit 18 in PROM space */
|
||||
#define FHC_BSR_SI 0x00000001 /* Spare input pin value */
|
||||
#define FHC_PREGS_ECC 0x40UL /* FHC ECC Control Register (16 bits) */
|
||||
#define FHC_PREGS_JCTRL 0xf0UL /* FHC JTAG Control Register */
|
||||
#define FHC_JTAG_CTRL_MENAB 0x80000000 /* Indicates this is JTAG Master */
|
||||
#define FHC_JTAG_CTRL_MNONE 0x40000000 /* Indicates no JTAG Master present */
|
||||
#define FHC_PREGS_JCMD 0x100UL /* FHC JTAG Command Register */
|
||||
#define FHC_IREG_IGN 0x00UL /* This FHC's IGN */
|
||||
#define FHC_FFREGS_IMAP 0x00UL /* FHC Fanfail IMAP */
|
||||
#define FHC_FFREGS_ICLR 0x10UL /* FHC Fanfail ICLR */
|
||||
#define FHC_SREGS_IMAP 0x00UL /* FHC System IMAP */
|
||||
#define FHC_SREGS_ICLR 0x10UL /* FHC System ICLR */
|
||||
#define FHC_UREGS_IMAP 0x00UL /* FHC Uart IMAP */
|
||||
#define FHC_UREGS_ICLR 0x10UL /* FHC Uart ICLR */
|
||||
#define FHC_TREGS_IMAP 0x00UL /* FHC TOD IMAP */
|
||||
#define FHC_TREGS_ICLR 0x10UL /* FHC TOD ICLR */
|
||||
|
||||
#endif /* !(_SPARC64_FHC_H) */
|
8
arch/sparc/include/asm/floppy.h
Normal file
8
arch/sparc/include/asm/floppy.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ___ASM_SPARC_FLOPPY_H
|
||||
#define ___ASM_SPARC_FLOPPY_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm/floppy_64.h>
|
||||
#else
|
||||
#include <asm/floppy_32.h>
|
||||
#endif
|
||||
#endif
|
393
arch/sparc/include/asm/floppy_32.h
Normal file
393
arch/sparc/include/asm/floppy_32.h
Normal file
|
@ -0,0 +1,393 @@
|
|||
/* asm/floppy.h: Sparc specific parts of the Floppy driver.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#ifndef __ASM_SPARC_FLOPPY_H
|
||||
#define __ASM_SPARC_FLOPPY_H
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/idprom.h>
|
||||
#include <asm/oplib.h>
|
||||
#include <asm/auxio.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
/* We don't need no stinkin' I/O port allocation crap. */
|
||||
#undef release_region
|
||||
#undef request_region
|
||||
#define release_region(X, Y) do { } while(0)
|
||||
#define request_region(X, Y, Z) (1)
|
||||
|
||||
/* References:
|
||||
* 1) Netbsd Sun floppy driver.
|
||||
* 2) NCR 82077 controller manual
|
||||
* 3) Intel 82077 controller manual
|
||||
*/
|
||||
struct sun_flpy_controller {
|
||||
volatile unsigned char status_82072; /* Main Status reg. */
|
||||
#define dcr_82072 status_82072 /* Digital Control reg. */
|
||||
#define status1_82077 status_82072 /* Auxiliary Status reg. 1 */
|
||||
|
||||
volatile unsigned char data_82072; /* Data fifo. */
|
||||
#define status2_82077 data_82072 /* Auxiliary Status reg. 2 */
|
||||
|
||||
volatile unsigned char dor_82077; /* Digital Output reg. */
|
||||
volatile unsigned char tapectl_82077; /* What the? Tape control reg? */
|
||||
|
||||
volatile unsigned char status_82077; /* Main Status Register. */
|
||||
#define drs_82077 status_82077 /* Digital Rate Select reg. */
|
||||
|
||||
volatile unsigned char data_82077; /* Data fifo. */
|
||||
volatile unsigned char ___unused;
|
||||
volatile unsigned char dir_82077; /* Digital Input reg. */
|
||||
#define dcr_82077 dir_82077 /* Config Control reg. */
|
||||
};
|
||||
|
||||
/* You'll only ever find one controller on a SparcStation anyways. */
|
||||
static struct sun_flpy_controller *sun_fdc = NULL;
|
||||
|
||||
struct sun_floppy_ops {
|
||||
unsigned char (*fd_inb)(int port);
|
||||
void (*fd_outb)(unsigned char value, int port);
|
||||
};
|
||||
|
||||
static struct sun_floppy_ops sun_fdops;
|
||||
|
||||
#define fd_inb(port) sun_fdops.fd_inb(port)
|
||||
#define fd_outb(value,port) sun_fdops.fd_outb(value,port)
|
||||
#define fd_enable_dma() sun_fd_enable_dma()
|
||||
#define fd_disable_dma() sun_fd_disable_dma()
|
||||
#define fd_request_dma() (0) /* nothing... */
|
||||
#define fd_free_dma() /* nothing... */
|
||||
#define fd_clear_dma_ff() /* nothing... */
|
||||
#define fd_set_dma_mode(mode) sun_fd_set_dma_mode(mode)
|
||||
#define fd_set_dma_addr(addr) sun_fd_set_dma_addr(addr)
|
||||
#define fd_set_dma_count(count) sun_fd_set_dma_count(count)
|
||||
#define fd_enable_irq() /* nothing... */
|
||||
#define fd_disable_irq() /* nothing... */
|
||||
#define fd_cacheflush(addr, size) /* nothing... */
|
||||
#define fd_request_irq() sun_fd_request_irq()
|
||||
#define fd_free_irq() /* nothing... */
|
||||
#if 0 /* P3: added by Alain, these cause a MMU corruption. 19960524 XXX */
|
||||
#define fd_dma_mem_alloc(size) ((unsigned long) vmalloc(size))
|
||||
#define fd_dma_mem_free(addr,size) (vfree((void *)(addr)))
|
||||
#endif
|
||||
|
||||
/* XXX This isn't really correct. XXX */
|
||||
#define get_dma_residue(x) (0)
|
||||
|
||||
#define FLOPPY0_TYPE 4
|
||||
#define FLOPPY1_TYPE 0
|
||||
|
||||
/* Super paranoid... */
|
||||
#undef HAVE_DISABLE_HLT
|
||||
|
||||
/* Here is where we catch the floppy driver trying to initialize,
|
||||
* therefore this is where we call the PROM device tree probing
|
||||
* routine etc. on the Sparc.
|
||||
*/
|
||||
#define FDC1 sun_floppy_init()
|
||||
|
||||
#define N_FDC 1
|
||||
#define N_DRIVE 8
|
||||
|
||||
/* No 64k boundary crossing problems on the Sparc. */
|
||||
#define CROSS_64KB(a,s) (0)
|
||||
|
||||
/* Routines unique to each controller type on a Sun. */
|
||||
static void sun_set_dor(unsigned char value, int fdc_82077)
|
||||
{
|
||||
if (fdc_82077)
|
||||
sun_fdc->dor_82077 = value;
|
||||
}
|
||||
|
||||
static unsigned char sun_read_dir(void)
|
||||
{
|
||||
return sun_fdc->dir_82077;
|
||||
}
|
||||
|
||||
static unsigned char sun_82072_fd_inb(int port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to read unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 4: /* FD_STATUS */
|
||||
return sun_fdc->status_82072 & ~STATUS_DMA;
|
||||
case 5: /* FD_DATA */
|
||||
return sun_fdc->data_82072;
|
||||
case 7: /* FD_DIR */
|
||||
return sun_read_dir();
|
||||
}
|
||||
panic("sun_82072_fd_inb: How did I get here?");
|
||||
}
|
||||
|
||||
static void sun_82072_fd_outb(unsigned char value, int port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to write to unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 2: /* FD_DOR */
|
||||
sun_set_dor(value, 0);
|
||||
break;
|
||||
case 5: /* FD_DATA */
|
||||
sun_fdc->data_82072 = value;
|
||||
break;
|
||||
case 7: /* FD_DCR */
|
||||
sun_fdc->dcr_82072 = value;
|
||||
break;
|
||||
case 4: /* FD_STATUS */
|
||||
sun_fdc->status_82072 = value;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static unsigned char sun_82077_fd_inb(int port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to read unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 0: /* FD_STATUS_0 */
|
||||
return sun_fdc->status1_82077;
|
||||
case 1: /* FD_STATUS_1 */
|
||||
return sun_fdc->status2_82077;
|
||||
case 2: /* FD_DOR */
|
||||
return sun_fdc->dor_82077;
|
||||
case 3: /* FD_TDR */
|
||||
return sun_fdc->tapectl_82077;
|
||||
case 4: /* FD_STATUS */
|
||||
return sun_fdc->status_82077 & ~STATUS_DMA;
|
||||
case 5: /* FD_DATA */
|
||||
return sun_fdc->data_82077;
|
||||
case 7: /* FD_DIR */
|
||||
return sun_read_dir();
|
||||
}
|
||||
panic("sun_82077_fd_inb: How did I get here?");
|
||||
}
|
||||
|
||||
static void sun_82077_fd_outb(unsigned char value, int port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to write to unknown port %d\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 2: /* FD_DOR */
|
||||
sun_set_dor(value, 1);
|
||||
break;
|
||||
case 5: /* FD_DATA */
|
||||
sun_fdc->data_82077 = value;
|
||||
break;
|
||||
case 7: /* FD_DCR */
|
||||
sun_fdc->dcr_82077 = value;
|
||||
break;
|
||||
case 4: /* FD_STATUS */
|
||||
sun_fdc->status_82077 = value;
|
||||
break;
|
||||
case 3: /* FD_TDR */
|
||||
sun_fdc->tapectl_82077 = value;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* For pseudo-dma (Sun floppy drives have no real DMA available to
|
||||
* them so we must eat the data fifo bytes directly ourselves) we have
|
||||
* three state variables. doing_pdma tells our inline low-level
|
||||
* assembly floppy interrupt entry point whether it should sit and eat
|
||||
* bytes from the fifo or just transfer control up to the higher level
|
||||
* floppy interrupt c-code. I tried very hard but I could not get the
|
||||
* pseudo-dma to work in c-code without getting many overruns and
|
||||
* underruns. If non-zero, doing_pdma encodes the direction of
|
||||
* the transfer for debugging. 1=read 2=write
|
||||
*/
|
||||
|
||||
/* Common routines to all controller types on the Sparc. */
|
||||
static inline void virtual_dma_init(void)
|
||||
{
|
||||
/* nothing... */
|
||||
}
|
||||
|
||||
static inline void sun_fd_disable_dma(void)
|
||||
{
|
||||
doing_pdma = 0;
|
||||
pdma_base = NULL;
|
||||
}
|
||||
|
||||
static inline void sun_fd_set_dma_mode(int mode)
|
||||
{
|
||||
switch(mode) {
|
||||
case DMA_MODE_READ:
|
||||
doing_pdma = 1;
|
||||
break;
|
||||
case DMA_MODE_WRITE:
|
||||
doing_pdma = 2;
|
||||
break;
|
||||
default:
|
||||
printk("Unknown dma mode %d\n", mode);
|
||||
panic("floppy: Giving up...");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void sun_fd_set_dma_addr(char *buffer)
|
||||
{
|
||||
pdma_vaddr = buffer;
|
||||
}
|
||||
|
||||
static inline void sun_fd_set_dma_count(int length)
|
||||
{
|
||||
pdma_size = length;
|
||||
}
|
||||
|
||||
static inline void sun_fd_enable_dma(void)
|
||||
{
|
||||
pdma_base = pdma_vaddr;
|
||||
pdma_areasize = pdma_size;
|
||||
}
|
||||
|
||||
int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler);
|
||||
|
||||
static int sun_fd_request_irq(void)
|
||||
{
|
||||
static int once = 0;
|
||||
|
||||
if (!once) {
|
||||
once = 1;
|
||||
return sparc_floppy_request_irq(FLOPPY_IRQ, floppy_interrupt);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static struct linux_prom_registers fd_regs[2];
|
||||
|
||||
static int sun_floppy_init(void)
|
||||
{
|
||||
struct platform_device *op;
|
||||
struct device_node *dp;
|
||||
struct resource r;
|
||||
char state[128];
|
||||
phandle fd_node;
|
||||
phandle tnode;
|
||||
int num_regs;
|
||||
|
||||
use_virtual_dma = 1;
|
||||
|
||||
/* Forget it if we aren't on a machine that could possibly
|
||||
* ever have a floppy drive.
|
||||
*/
|
||||
if (sparc_cpu_model != sun4m) {
|
||||
/* We certainly don't have a floppy controller. */
|
||||
goto no_sun_fdc;
|
||||
}
|
||||
/* Well, try to find one. */
|
||||
tnode = prom_getchild(prom_root_node);
|
||||
fd_node = prom_searchsiblings(tnode, "obio");
|
||||
if (fd_node != 0) {
|
||||
tnode = prom_getchild(fd_node);
|
||||
fd_node = prom_searchsiblings(tnode, "SUNW,fdtwo");
|
||||
} else {
|
||||
fd_node = prom_searchsiblings(tnode, "fd");
|
||||
}
|
||||
if (fd_node == 0) {
|
||||
goto no_sun_fdc;
|
||||
}
|
||||
|
||||
/* The sun4m lets us know if the controller is actually usable. */
|
||||
if (prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) {
|
||||
if(!strcmp(state, "disabled")) {
|
||||
goto no_sun_fdc;
|
||||
}
|
||||
}
|
||||
num_regs = prom_getproperty(fd_node, "reg", (char *) fd_regs, sizeof(fd_regs));
|
||||
num_regs = (num_regs / sizeof(fd_regs[0]));
|
||||
prom_apply_obio_ranges(fd_regs, num_regs);
|
||||
memset(&r, 0, sizeof(r));
|
||||
r.flags = fd_regs[0].which_io;
|
||||
r.start = fd_regs[0].phys_addr;
|
||||
sun_fdc = of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");
|
||||
|
||||
/* Look up irq in platform_device.
|
||||
* We try "SUNW,fdtwo" and "fd"
|
||||
*/
|
||||
op = NULL;
|
||||
for_each_node_by_name(dp, "SUNW,fdtwo") {
|
||||
op = of_find_device_by_node(dp);
|
||||
if (op)
|
||||
break;
|
||||
}
|
||||
if (!op) {
|
||||
for_each_node_by_name(dp, "fd") {
|
||||
op = of_find_device_by_node(dp);
|
||||
if (op)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!op)
|
||||
goto no_sun_fdc;
|
||||
|
||||
FLOPPY_IRQ = op->archdata.irqs[0];
|
||||
|
||||
/* Last minute sanity check... */
|
||||
if (sun_fdc->status_82072 == 0xff) {
|
||||
sun_fdc = NULL;
|
||||
goto no_sun_fdc;
|
||||
}
|
||||
|
||||
sun_fdops.fd_inb = sun_82077_fd_inb;
|
||||
sun_fdops.fd_outb = sun_82077_fd_outb;
|
||||
fdc_status = &sun_fdc->status_82077;
|
||||
|
||||
if (sun_fdc->dor_82077 == 0x80) {
|
||||
sun_fdc->dor_82077 = 0x02;
|
||||
if (sun_fdc->dor_82077 == 0x80) {
|
||||
sun_fdops.fd_inb = sun_82072_fd_inb;
|
||||
sun_fdops.fd_outb = sun_82072_fd_outb;
|
||||
fdc_status = &sun_fdc->status_82072;
|
||||
}
|
||||
}
|
||||
|
||||
/* Success... */
|
||||
allowed_drive_mask = 0x01;
|
||||
return (int) sun_fdc;
|
||||
|
||||
no_sun_fdc:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int sparc_eject(void)
|
||||
{
|
||||
set_dor(0x00, 0xff, 0x90);
|
||||
udelay(500);
|
||||
set_dor(0x00, 0x6f, 0x00);
|
||||
udelay(500);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define fd_eject(drive) sparc_eject()
|
||||
|
||||
#define EXTRA_FLOPPY_PARAMS
|
||||
|
||||
static DEFINE_SPINLOCK(dma_spin_lock);
|
||||
|
||||
#define claim_dma_lock() \
|
||||
({ unsigned long flags; \
|
||||
spin_lock_irqsave(&dma_spin_lock, flags); \
|
||||
flags; \
|
||||
})
|
||||
|
||||
#define release_dma_lock(__flags) \
|
||||
spin_unlock_irqrestore(&dma_spin_lock, __flags);
|
||||
|
||||
#endif /* !(__ASM_SPARC_FLOPPY_H) */
|
774
arch/sparc/include/asm/floppy_64.h
Normal file
774
arch/sparc/include/asm/floppy_64.h
Normal file
|
@ -0,0 +1,774 @@
|
|||
/* floppy.h: Sparc specific parts of the Floppy driver.
|
||||
*
|
||||
* Copyright (C) 1996, 2007, 2008 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
|
||||
*
|
||||
* Ultra/PCI support added: Sep 1997 Eddie C. Dost (ecd@skynet.be)
|
||||
*/
|
||||
|
||||
#ifndef __ASM_SPARC64_FLOPPY_H
|
||||
#define __ASM_SPARC64_FLOPPY_H
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <asm/auxio.h>
|
||||
|
||||
/*
|
||||
* Define this to enable exchanging drive 0 and 1 if only drive 1 is
|
||||
* probed on PCI machines.
|
||||
*/
|
||||
#undef PCI_FDC_SWAP_DRIVES
|
||||
|
||||
|
||||
/* References:
|
||||
* 1) Netbsd Sun floppy driver.
|
||||
* 2) NCR 82077 controller manual
|
||||
* 3) Intel 82077 controller manual
|
||||
*/
|
||||
struct sun_flpy_controller {
|
||||
volatile unsigned char status1_82077; /* Auxiliary Status reg. 1 */
|
||||
volatile unsigned char status2_82077; /* Auxiliary Status reg. 2 */
|
||||
volatile unsigned char dor_82077; /* Digital Output reg. */
|
||||
volatile unsigned char tapectl_82077; /* Tape Control reg */
|
||||
volatile unsigned char status_82077; /* Main Status Register. */
|
||||
#define drs_82077 status_82077 /* Digital Rate Select reg. */
|
||||
volatile unsigned char data_82077; /* Data fifo. */
|
||||
volatile unsigned char ___unused;
|
||||
volatile unsigned char dir_82077; /* Digital Input reg. */
|
||||
#define dcr_82077 dir_82077 /* Config Control reg. */
|
||||
};
|
||||
|
||||
/* You'll only ever find one controller on an Ultra anyways. */
|
||||
static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1;
|
||||
unsigned long fdc_status;
|
||||
static struct platform_device *floppy_op = NULL;
|
||||
|
||||
struct sun_floppy_ops {
|
||||
unsigned char (*fd_inb) (unsigned long port);
|
||||
void (*fd_outb) (unsigned char value, unsigned long port);
|
||||
void (*fd_enable_dma) (void);
|
||||
void (*fd_disable_dma) (void);
|
||||
void (*fd_set_dma_mode) (int);
|
||||
void (*fd_set_dma_addr) (char *);
|
||||
void (*fd_set_dma_count) (int);
|
||||
unsigned int (*get_dma_residue) (void);
|
||||
int (*fd_request_irq) (void);
|
||||
void (*fd_free_irq) (void);
|
||||
int (*fd_eject) (int);
|
||||
};
|
||||
|
||||
static struct sun_floppy_ops sun_fdops;
|
||||
|
||||
#define fd_inb(port) sun_fdops.fd_inb(port)
|
||||
#define fd_outb(value,port) sun_fdops.fd_outb(value,port)
|
||||
#define fd_enable_dma() sun_fdops.fd_enable_dma()
|
||||
#define fd_disable_dma() sun_fdops.fd_disable_dma()
|
||||
#define fd_request_dma() (0) /* nothing... */
|
||||
#define fd_free_dma() /* nothing... */
|
||||
#define fd_clear_dma_ff() /* nothing... */
|
||||
#define fd_set_dma_mode(mode) sun_fdops.fd_set_dma_mode(mode)
|
||||
#define fd_set_dma_addr(addr) sun_fdops.fd_set_dma_addr(addr)
|
||||
#define fd_set_dma_count(count) sun_fdops.fd_set_dma_count(count)
|
||||
#define get_dma_residue(x) sun_fdops.get_dma_residue()
|
||||
#define fd_cacheflush(addr, size) /* nothing... */
|
||||
#define fd_request_irq() sun_fdops.fd_request_irq()
|
||||
#define fd_free_irq() sun_fdops.fd_free_irq()
|
||||
#define fd_eject(drive) sun_fdops.fd_eject(drive)
|
||||
|
||||
/* Super paranoid... */
|
||||
#undef HAVE_DISABLE_HLT
|
||||
|
||||
static int sun_floppy_types[2] = { 0, 0 };
|
||||
|
||||
/* Here is where we catch the floppy driver trying to initialize,
|
||||
* therefore this is where we call the PROM device tree probing
|
||||
* routine etc. on the Sparc.
|
||||
*/
|
||||
#define FLOPPY0_TYPE sun_floppy_init()
|
||||
#define FLOPPY1_TYPE sun_floppy_types[1]
|
||||
|
||||
#define FDC1 ((unsigned long)sun_fdc)
|
||||
|
||||
#define N_FDC 1
|
||||
#define N_DRIVE 8
|
||||
|
||||
/* No 64k boundary crossing problems on the Sparc. */
|
||||
#define CROSS_64KB(a,s) (0)
|
||||
|
||||
static unsigned char sun_82077_fd_inb(unsigned long port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to read unknown port %lx\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 4: /* FD_STATUS */
|
||||
return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA;
|
||||
case 5: /* FD_DATA */
|
||||
return sbus_readb(&sun_fdc->data_82077);
|
||||
case 7: /* FD_DIR */
|
||||
/* XXX: Is DCL on 0x80 in sun4m? */
|
||||
return sbus_readb(&sun_fdc->dir_82077);
|
||||
}
|
||||
panic("sun_82072_fd_inb: How did I get here?");
|
||||
}
|
||||
|
||||
static void sun_82077_fd_outb(unsigned char value, unsigned long port)
|
||||
{
|
||||
udelay(5);
|
||||
switch(port & 7) {
|
||||
default:
|
||||
printk("floppy: Asked to write to unknown port %lx\n", port);
|
||||
panic("floppy: Port bolixed.");
|
||||
case 2: /* FD_DOR */
|
||||
/* Happily, the 82077 has a real DOR register. */
|
||||
sbus_writeb(value, &sun_fdc->dor_82077);
|
||||
break;
|
||||
case 5: /* FD_DATA */
|
||||
sbus_writeb(value, &sun_fdc->data_82077);
|
||||
break;
|
||||
case 7: /* FD_DCR */
|
||||
sbus_writeb(value, &sun_fdc->dcr_82077);
|
||||
break;
|
||||
case 4: /* FD_STATUS */
|
||||
sbus_writeb(value, &sun_fdc->status_82077);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* For pseudo-dma (Sun floppy drives have no real DMA available to
|
||||
* them so we must eat the data fifo bytes directly ourselves) we have
|
||||
* three state variables. doing_pdma tells our inline low-level
|
||||
* assembly floppy interrupt entry point whether it should sit and eat
|
||||
* bytes from the fifo or just transfer control up to the higher level
|
||||
* floppy interrupt c-code. I tried very hard but I could not get the
|
||||
* pseudo-dma to work in c-code without getting many overruns and
|
||||
* underruns. If non-zero, doing_pdma encodes the direction of
|
||||
* the transfer for debugging. 1=read 2=write
|
||||
*/
|
||||
unsigned char *pdma_vaddr;
|
||||
unsigned long pdma_size;
|
||||
volatile int doing_pdma = 0;
|
||||
|
||||
/* This is software state */
|
||||
char *pdma_base = NULL;
|
||||
unsigned long pdma_areasize;
|
||||
|
||||
/* Common routines to all controller types on the Sparc. */
|
||||
static void sun_fd_disable_dma(void)
|
||||
{
|
||||
doing_pdma = 0;
|
||||
pdma_base = NULL;
|
||||
}
|
||||
|
||||
static void sun_fd_set_dma_mode(int mode)
|
||||
{
|
||||
switch(mode) {
|
||||
case DMA_MODE_READ:
|
||||
doing_pdma = 1;
|
||||
break;
|
||||
case DMA_MODE_WRITE:
|
||||
doing_pdma = 2;
|
||||
break;
|
||||
default:
|
||||
printk("Unknown dma mode %d\n", mode);
|
||||
panic("floppy: Giving up...");
|
||||
}
|
||||
}
|
||||
|
||||
static void sun_fd_set_dma_addr(char *buffer)
|
||||
{
|
||||
pdma_vaddr = buffer;
|
||||
}
|
||||
|
||||
static void sun_fd_set_dma_count(int length)
|
||||
{
|
||||
pdma_size = length;
|
||||
}
|
||||
|
||||
static void sun_fd_enable_dma(void)
|
||||
{
|
||||
pdma_base = pdma_vaddr;
|
||||
pdma_areasize = pdma_size;
|
||||
}
|
||||
|
||||
irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie)
|
||||
{
|
||||
if (likely(doing_pdma)) {
|
||||
void __iomem *stat = (void __iomem *) fdc_status;
|
||||
unsigned char *vaddr = pdma_vaddr;
|
||||
unsigned long size = pdma_size;
|
||||
u8 val;
|
||||
|
||||
while (size) {
|
||||
val = readb(stat);
|
||||
if (unlikely(!(val & 0x80))) {
|
||||
pdma_vaddr = vaddr;
|
||||
pdma_size = size;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
if (unlikely(!(val & 0x20))) {
|
||||
pdma_vaddr = vaddr;
|
||||
pdma_size = size;
|
||||
doing_pdma = 0;
|
||||
goto main_interrupt;
|
||||
}
|
||||
if (val & 0x40) {
|
||||
/* read */
|
||||
*vaddr++ = readb(stat + 1);
|
||||
} else {
|
||||
unsigned char data = *vaddr++;
|
||||
|
||||
/* write */
|
||||
writeb(data, stat + 1);
|
||||
}
|
||||
size--;
|
||||
}
|
||||
|
||||
pdma_vaddr = vaddr;
|
||||
pdma_size = size;
|
||||
|
||||
/* Send Terminal Count pulse to floppy controller. */
|
||||
val = readb(auxio_register);
|
||||
val |= AUXIO_AUX1_FTCNT;
|
||||
writeb(val, auxio_register);
|
||||
val &= ~AUXIO_AUX1_FTCNT;
|
||||
writeb(val, auxio_register);
|
||||
|
||||
doing_pdma = 0;
|
||||
}
|
||||
|
||||
main_interrupt:
|
||||
return floppy_interrupt(irq, dev_cookie);
|
||||
}
|
||||
|
||||
static int sun_fd_request_irq(void)
|
||||
{
|
||||
static int once = 0;
|
||||
int error;
|
||||
|
||||
if(!once) {
|
||||
once = 1;
|
||||
|
||||
error = request_irq(FLOPPY_IRQ, sparc_floppy_irq,
|
||||
0, "floppy", NULL);
|
||||
|
||||
return ((error == 0) ? 0 : -1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sun_fd_free_irq(void)
|
||||
{
|
||||
}
|
||||
|
||||
static unsigned int sun_get_dma_residue(void)
|
||||
{
|
||||
/* XXX This isn't really correct. XXX */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sun_fd_eject(int drive)
|
||||
{
|
||||
set_dor(0x00, 0xff, 0x90);
|
||||
udelay(500);
|
||||
set_dor(0x00, 0x6f, 0x00);
|
||||
udelay(500);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <asm/ebus_dma.h>
|
||||
#include <asm/ns87303.h>
|
||||
|
||||
static struct ebus_dma_info sun_pci_fd_ebus_dma;
|
||||
static struct device *sun_floppy_dev;
|
||||
static int sun_pci_broken_drive = -1;
|
||||
|
||||
struct sun_pci_dma_op {
|
||||
unsigned int addr;
|
||||
int len;
|
||||
int direction;
|
||||
char *buf;
|
||||
};
|
||||
static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL};
|
||||
static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
|
||||
|
||||
irqreturn_t floppy_interrupt(int irq, void *dev_id);
|
||||
|
||||
static unsigned char sun_pci_fd_inb(unsigned long port)
|
||||
{
|
||||
udelay(5);
|
||||
return inb(port);
|
||||
}
|
||||
|
||||
static void sun_pci_fd_outb(unsigned char val, unsigned long port)
|
||||
{
|
||||
udelay(5);
|
||||
outb(val, port);
|
||||
}
|
||||
|
||||
static void sun_pci_fd_broken_outb(unsigned char val, unsigned long port)
|
||||
{
|
||||
udelay(5);
|
||||
/*
|
||||
* XXX: Due to SUN's broken floppy connector on AX and AXi
|
||||
* we need to turn on MOTOR_0 also, if the floppy is
|
||||
* jumpered to DS1 (like most PC floppies are). I hope
|
||||
* this does not hurt correct hardware like the AXmp.
|
||||
* (Eddie, Sep 12 1998).
|
||||
*/
|
||||
if (port == ((unsigned long)sun_fdc) + 2) {
|
||||
if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) {
|
||||
val |= 0x10;
|
||||
}
|
||||
}
|
||||
outb(val, port);
|
||||
}
|
||||
|
||||
#ifdef PCI_FDC_SWAP_DRIVES
|
||||
static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long port)
|
||||
{
|
||||
udelay(5);
|
||||
/*
|
||||
* XXX: Due to SUN's broken floppy connector on AX and AXi
|
||||
* we need to turn on MOTOR_0 also, if the floppy is
|
||||
* jumpered to DS1 (like most PC floppies are). I hope
|
||||
* this does not hurt correct hardware like the AXmp.
|
||||
* (Eddie, Sep 12 1998).
|
||||
*/
|
||||
if (port == ((unsigned long)sun_fdc) + 2) {
|
||||
if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) {
|
||||
val &= ~(0x03);
|
||||
val |= 0x21;
|
||||
}
|
||||
}
|
||||
outb(val, port);
|
||||
}
|
||||
#endif /* PCI_FDC_SWAP_DRIVES */
|
||||
|
||||
static void sun_pci_fd_enable_dma(void)
|
||||
{
|
||||
BUG_ON((NULL == sun_pci_dma_pending.buf) ||
|
||||
(0 == sun_pci_dma_pending.len) ||
|
||||
(0 == sun_pci_dma_pending.direction));
|
||||
|
||||
sun_pci_dma_current.buf = sun_pci_dma_pending.buf;
|
||||
sun_pci_dma_current.len = sun_pci_dma_pending.len;
|
||||
sun_pci_dma_current.direction = sun_pci_dma_pending.direction;
|
||||
|
||||
sun_pci_dma_pending.buf = NULL;
|
||||
sun_pci_dma_pending.len = 0;
|
||||
sun_pci_dma_pending.direction = 0;
|
||||
sun_pci_dma_pending.addr = -1U;
|
||||
|
||||
sun_pci_dma_current.addr =
|
||||
dma_map_single(sun_floppy_dev,
|
||||
sun_pci_dma_current.buf,
|
||||
sun_pci_dma_current.len,
|
||||
sun_pci_dma_current.direction);
|
||||
|
||||
ebus_dma_enable(&sun_pci_fd_ebus_dma, 1);
|
||||
|
||||
if (ebus_dma_request(&sun_pci_fd_ebus_dma,
|
||||
sun_pci_dma_current.addr,
|
||||
sun_pci_dma_current.len))
|
||||
BUG();
|
||||
}
|
||||
|
||||
static void sun_pci_fd_disable_dma(void)
|
||||
{
|
||||
ebus_dma_enable(&sun_pci_fd_ebus_dma, 0);
|
||||
if (sun_pci_dma_current.addr != -1U)
|
||||
dma_unmap_single(sun_floppy_dev,
|
||||
sun_pci_dma_current.addr,
|
||||
sun_pci_dma_current.len,
|
||||
sun_pci_dma_current.direction);
|
||||
sun_pci_dma_current.addr = -1U;
|
||||
}
|
||||
|
||||
static void sun_pci_fd_set_dma_mode(int mode)
|
||||
{
|
||||
if (mode == DMA_MODE_WRITE)
|
||||
sun_pci_dma_pending.direction = DMA_TO_DEVICE;
|
||||
else
|
||||
sun_pci_dma_pending.direction = DMA_FROM_DEVICE;
|
||||
|
||||
ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE);
|
||||
}
|
||||
|
||||
static void sun_pci_fd_set_dma_count(int length)
|
||||
{
|
||||
sun_pci_dma_pending.len = length;
|
||||
}
|
||||
|
||||
static void sun_pci_fd_set_dma_addr(char *buffer)
|
||||
{
|
||||
sun_pci_dma_pending.buf = buffer;
|
||||
}
|
||||
|
||||
static unsigned int sun_pci_get_dma_residue(void)
|
||||
{
|
||||
return ebus_dma_residue(&sun_pci_fd_ebus_dma);
|
||||
}
|
||||
|
||||
static int sun_pci_fd_request_irq(void)
|
||||
{
|
||||
return ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1);
|
||||
}
|
||||
|
||||
static void sun_pci_fd_free_irq(void)
|
||||
{
|
||||
ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0);
|
||||
}
|
||||
|
||||
static int sun_pci_fd_eject(int drive)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie)
|
||||
{
|
||||
floppy_interrupt(0, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI,
|
||||
* even if this is configured using DS1, thus looks like /dev/fd1 with
|
||||
* the cabling used in Ultras.
|
||||
*/
|
||||
#define DOR (port + 2)
|
||||
#define MSR (port + 4)
|
||||
#define FIFO (port + 5)
|
||||
|
||||
static void sun_pci_fd_out_byte(unsigned long port, unsigned char val,
|
||||
unsigned long reg)
|
||||
{
|
||||
unsigned char status;
|
||||
int timeout = 1000;
|
||||
|
||||
while (!((status = inb(MSR)) & 0x80) && --timeout)
|
||||
udelay(100);
|
||||
outb(val, reg);
|
||||
}
|
||||
|
||||
static unsigned char sun_pci_fd_sensei(unsigned long port)
|
||||
{
|
||||
unsigned char result[2] = { 0x70, 0x00 };
|
||||
unsigned char status;
|
||||
int i = 0;
|
||||
|
||||
sun_pci_fd_out_byte(port, 0x08, FIFO);
|
||||
do {
|
||||
int timeout = 1000;
|
||||
|
||||
while (!((status = inb(MSR)) & 0x80) && --timeout)
|
||||
udelay(100);
|
||||
|
||||
if (!timeout)
|
||||
break;
|
||||
|
||||
if ((status & 0xf0) == 0xd0)
|
||||
result[i++] = inb(FIFO);
|
||||
else
|
||||
break;
|
||||
} while (i < 2);
|
||||
|
||||
return result[0];
|
||||
}
|
||||
|
||||
static void sun_pci_fd_reset(unsigned long port)
|
||||
{
|
||||
unsigned char mask = 0x00;
|
||||
unsigned char status;
|
||||
int timeout = 10000;
|
||||
|
||||
outb(0x80, MSR);
|
||||
do {
|
||||
status = sun_pci_fd_sensei(port);
|
||||
if ((status & 0xc0) == 0xc0)
|
||||
mask |= 1 << (status & 0x03);
|
||||
else
|
||||
udelay(100);
|
||||
} while ((mask != 0x0f) && --timeout);
|
||||
}
|
||||
|
||||
static int sun_pci_fd_test_drive(unsigned long port, int drive)
|
||||
{
|
||||
unsigned char status, data;
|
||||
int timeout = 1000;
|
||||
int ready;
|
||||
|
||||
sun_pci_fd_reset(port);
|
||||
|
||||
data = (0x10 << drive) | 0x0c | drive;
|
||||
sun_pci_fd_out_byte(port, data, DOR);
|
||||
|
||||
sun_pci_fd_out_byte(port, 0x07, FIFO);
|
||||
sun_pci_fd_out_byte(port, drive & 0x03, FIFO);
|
||||
|
||||
do {
|
||||
udelay(100);
|
||||
status = sun_pci_fd_sensei(port);
|
||||
} while (((status & 0xc0) == 0x80) && --timeout);
|
||||
|
||||
if (!timeout)
|
||||
ready = 0;
|
||||
else
|
||||
ready = (status & 0x10) ? 0 : 1;
|
||||
|
||||
sun_pci_fd_reset(port);
|
||||
return ready;
|
||||
}
|
||||
#undef FIFO
|
||||
#undef MSR
|
||||
#undef DOR
|
||||
|
||||
static int __init ebus_fdthree_p(struct device_node *dp)
|
||||
{
|
||||
if (!strcmp(dp->name, "fdthree"))
|
||||
return 1;
|
||||
if (!strcmp(dp->name, "floppy")) {
|
||||
const char *compat;
|
||||
|
||||
compat = of_get_property(dp, "compatible", NULL);
|
||||
if (compat && !strcmp(compat, "fdthree"))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long __init sun_floppy_init(void)
|
||||
{
|
||||
static int initialized = 0;
|
||||
struct device_node *dp;
|
||||
struct platform_device *op;
|
||||
const char *prop;
|
||||
char state[128];
|
||||
|
||||
if (initialized)
|
||||
return sun_floppy_types[0];
|
||||
initialized = 1;
|
||||
|
||||
op = NULL;
|
||||
|
||||
for_each_node_by_name(dp, "SUNW,fdtwo") {
|
||||
if (strcmp(dp->parent->name, "sbus"))
|
||||
continue;
|
||||
op = of_find_device_by_node(dp);
|
||||
if (op)
|
||||
break;
|
||||
}
|
||||
if (op) {
|
||||
floppy_op = op;
|
||||
FLOPPY_IRQ = op->archdata.irqs[0];
|
||||
} else {
|
||||
struct device_node *ebus_dp;
|
||||
void __iomem *auxio_reg;
|
||||
const char *state_prop;
|
||||
unsigned long config;
|
||||
|
||||
dp = NULL;
|
||||
for_each_node_by_name(ebus_dp, "ebus") {
|
||||
for (dp = ebus_dp->child; dp; dp = dp->sibling) {
|
||||
if (ebus_fdthree_p(dp))
|
||||
goto found_fdthree;
|
||||
}
|
||||
}
|
||||
found_fdthree:
|
||||
if (!dp)
|
||||
return 0;
|
||||
|
||||
op = of_find_device_by_node(dp);
|
||||
if (!op)
|
||||
return 0;
|
||||
|
||||
state_prop = of_get_property(op->dev.of_node, "status", NULL);
|
||||
if (state_prop && !strncmp(state_prop, "disabled", 8))
|
||||
return 0;
|
||||
|
||||
FLOPPY_IRQ = op->archdata.irqs[0];
|
||||
|
||||
/* Make sure the high density bit is set, some systems
|
||||
* (most notably Ultra5/Ultra10) come up with it clear.
|
||||
*/
|
||||
auxio_reg = (void __iomem *) op->resource[2].start;
|
||||
writel(readl(auxio_reg)|0x2, auxio_reg);
|
||||
|
||||
sun_floppy_dev = &op->dev;
|
||||
|
||||
spin_lock_init(&sun_pci_fd_ebus_dma.lock);
|
||||
|
||||
/* XXX ioremap */
|
||||
sun_pci_fd_ebus_dma.regs = (void __iomem *)
|
||||
op->resource[1].start;
|
||||
if (!sun_pci_fd_ebus_dma.regs)
|
||||
return 0;
|
||||
|
||||
sun_pci_fd_ebus_dma.flags = (EBUS_DMA_FLAG_USE_EBDMA_HANDLER |
|
||||
EBUS_DMA_FLAG_TCI_DISABLE);
|
||||
sun_pci_fd_ebus_dma.callback = sun_pci_fd_dma_callback;
|
||||
sun_pci_fd_ebus_dma.client_cookie = NULL;
|
||||
sun_pci_fd_ebus_dma.irq = FLOPPY_IRQ;
|
||||
strcpy(sun_pci_fd_ebus_dma.name, "floppy");
|
||||
if (ebus_dma_register(&sun_pci_fd_ebus_dma))
|
||||
return 0;
|
||||
|
||||
/* XXX ioremap */
|
||||
sun_fdc = (struct sun_flpy_controller *) op->resource[0].start;
|
||||
|
||||
sun_fdops.fd_inb = sun_pci_fd_inb;
|
||||
sun_fdops.fd_outb = sun_pci_fd_outb;
|
||||
|
||||
can_use_virtual_dma = use_virtual_dma = 0;
|
||||
sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma;
|
||||
sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma;
|
||||
sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode;
|
||||
sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr;
|
||||
sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count;
|
||||
sun_fdops.get_dma_residue = sun_pci_get_dma_residue;
|
||||
|
||||
sun_fdops.fd_request_irq = sun_pci_fd_request_irq;
|
||||
sun_fdops.fd_free_irq = sun_pci_fd_free_irq;
|
||||
|
||||
sun_fdops.fd_eject = sun_pci_fd_eject;
|
||||
|
||||
fdc_status = (unsigned long) &sun_fdc->status_82077;
|
||||
|
||||
/*
|
||||
* XXX: Find out on which machines this is really needed.
|
||||
*/
|
||||
if (1) {
|
||||
sun_pci_broken_drive = 1;
|
||||
sun_fdops.fd_outb = sun_pci_fd_broken_outb;
|
||||
}
|
||||
|
||||
allowed_drive_mask = 0;
|
||||
if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0))
|
||||
sun_floppy_types[0] = 4;
|
||||
if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1))
|
||||
sun_floppy_types[1] = 4;
|
||||
|
||||
/*
|
||||
* Find NS87303 SuperIO config registers (through ecpp).
|
||||
*/
|
||||
config = 0;
|
||||
for (dp = ebus_dp->child; dp; dp = dp->sibling) {
|
||||
if (!strcmp(dp->name, "ecpp")) {
|
||||
struct platform_device *ecpp_op;
|
||||
|
||||
ecpp_op = of_find_device_by_node(dp);
|
||||
if (ecpp_op)
|
||||
config = ecpp_op->resource[1].start;
|
||||
goto config_done;
|
||||
}
|
||||
}
|
||||
config_done:
|
||||
|
||||
/*
|
||||
* Sanity check, is this really the NS87303?
|
||||
*/
|
||||
switch (config & 0x3ff) {
|
||||
case 0x02e:
|
||||
case 0x15c:
|
||||
case 0x26e:
|
||||
case 0x398:
|
||||
break;
|
||||
default:
|
||||
config = 0;
|
||||
}
|
||||
|
||||
if (!config)
|
||||
return sun_floppy_types[0];
|
||||
|
||||
/* Enable PC-AT mode. */
|
||||
ns87303_modify(config, ASC, 0, 0xc0);
|
||||
|
||||
#ifdef PCI_FDC_SWAP_DRIVES
|
||||
/*
|
||||
* If only Floppy 1 is present, swap drives.
|
||||
*/
|
||||
if (!sun_floppy_types[0] && sun_floppy_types[1]) {
|
||||
/*
|
||||
* Set the drive exchange bit in FCR on NS87303,
|
||||
* make sure other bits are sane before doing so.
|
||||
*/
|
||||
ns87303_modify(config, FER, FER_EDM, 0);
|
||||
ns87303_modify(config, ASC, ASC_DRV2_SEL, 0);
|
||||
ns87303_modify(config, FCR, 0, FCR_LDE);
|
||||
|
||||
config = sun_floppy_types[0];
|
||||
sun_floppy_types[0] = sun_floppy_types[1];
|
||||
sun_floppy_types[1] = config;
|
||||
|
||||
if (sun_pci_broken_drive != -1) {
|
||||
sun_pci_broken_drive = 1 - sun_pci_broken_drive;
|
||||
sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb;
|
||||
}
|
||||
}
|
||||
#endif /* PCI_FDC_SWAP_DRIVES */
|
||||
|
||||
return sun_floppy_types[0];
|
||||
}
|
||||
prop = of_get_property(op->dev.of_node, "status", NULL);
|
||||
if (prop && !strncmp(state, "disabled", 8))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We cannot do of_ioremap here: it does request_region,
|
||||
* which the generic floppy driver tries to do once again.
|
||||
* But we must use the sdev resource values as they have
|
||||
* had parent ranges applied.
|
||||
*/
|
||||
sun_fdc = (struct sun_flpy_controller *)
|
||||
(op->resource[0].start +
|
||||
((op->resource[0].flags & 0x1ffUL) << 32UL));
|
||||
|
||||
/* Last minute sanity check... */
|
||||
if (sbus_readb(&sun_fdc->status1_82077) == 0xff) {
|
||||
sun_fdc = (struct sun_flpy_controller *)-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sun_fdops.fd_inb = sun_82077_fd_inb;
|
||||
sun_fdops.fd_outb = sun_82077_fd_outb;
|
||||
|
||||
can_use_virtual_dma = use_virtual_dma = 1;
|
||||
sun_fdops.fd_enable_dma = sun_fd_enable_dma;
|
||||
sun_fdops.fd_disable_dma = sun_fd_disable_dma;
|
||||
sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
|
||||
sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
|
||||
sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
|
||||
sun_fdops.get_dma_residue = sun_get_dma_residue;
|
||||
|
||||
sun_fdops.fd_request_irq = sun_fd_request_irq;
|
||||
sun_fdops.fd_free_irq = sun_fd_free_irq;
|
||||
|
||||
sun_fdops.fd_eject = sun_fd_eject;
|
||||
|
||||
fdc_status = (unsigned long) &sun_fdc->status_82077;
|
||||
|
||||
/* Success... */
|
||||
allowed_drive_mask = 0x01;
|
||||
sun_floppy_types[0] = 4;
|
||||
sun_floppy_types[1] = 0;
|
||||
|
||||
return sun_floppy_types[0];
|
||||
}
|
||||
|
||||
#define EXTRA_FLOPPY_PARAMS
|
||||
|
||||
static DEFINE_SPINLOCK(dma_spin_lock);
|
||||
|
||||
#define claim_dma_lock() \
|
||||
({ unsigned long flags; \
|
||||
spin_lock_irqsave(&dma_spin_lock, flags); \
|
||||
flags; \
|
||||
})
|
||||
|
||||
#define release_dma_lock(__flags) \
|
||||
spin_unlock_irqrestore(&dma_spin_lock, __flags);
|
||||
|
||||
#endif /* !(__ASM_SPARC64_FLOPPY_H) */
|
33
arch/sparc/include/asm/fpumacro.h
Normal file
33
arch/sparc/include/asm/fpumacro.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* fpumacro.h: FPU related macros.
|
||||
*
|
||||
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
|
||||
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
|
||||
*/
|
||||
|
||||
#ifndef _SPARC64_FPUMACRO_H
|
||||
#define _SPARC64_FPUMACRO_H
|
||||
|
||||
#include <asm/asi.h>
|
||||
#include <asm/visasm.h>
|
||||
|
||||
struct fpustate {
|
||||
u32 regs[64];
|
||||
};
|
||||
|
||||
#define FPUSTATE (struct fpustate *)(current_thread_info()->fpregs)
|
||||
|
||||
static inline unsigned long fprs_read(void)
|
||||
{
|
||||
unsigned long retval;
|
||||
|
||||
__asm__ __volatile__("rd %%fprs, %0" : "=r" (retval));
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline void fprs_write(unsigned long val)
|
||||
{
|
||||
__asm__ __volatile__("wr %0, 0x0, %%fprs" : : "r" (val));
|
||||
}
|
||||
|
||||
#endif /* !(_SPARC64_FPUMACRO_H) */
|
29
arch/sparc/include/asm/ftrace.h
Normal file
29
arch/sparc/include/asm/ftrace.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef _ASM_SPARC64_FTRACE
|
||||
#define _ASM_SPARC64_FTRACE
|
||||
|
||||
#ifdef CONFIG_MCOUNT
|
||||
#define MCOUNT_ADDR ((long)(_mcount))
|
||||
#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
void _mcount(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
/* reloction of mcount call site is the same as the address */
|
||||
static inline unsigned long ftrace_call_adjust(unsigned long addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
struct dyn_arch_ftrace {
|
||||
};
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE */
|
||||
|
||||
unsigned long prepare_ftrace_return(unsigned long parent,
|
||||
unsigned long self_addr,
|
||||
unsigned long frame_pointer);
|
||||
|
||||
#endif /* _ASM_SPARC64_FTRACE */
|
8
arch/sparc/include/asm/futex.h
Normal file
8
arch/sparc/include/asm/futex.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ___ASM_SPARC_FUTEX_H
|
||||
#define ___ASM_SPARC_FUTEX_H
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm/futex_64.h>
|
||||
#else
|
||||
#include <asm/futex_32.h>
|
||||
#endif
|
||||
#endif
|
6
arch/sparc/include/asm/futex_32.h
Normal file
6
arch/sparc/include/asm/futex_32.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef _ASM_FUTEX_H
|
||||
#define _ASM_FUTEX_H
|
||||
|
||||
#include <asm-generic/futex.h>
|
||||
|
||||
#endif
|
113
arch/sparc/include/asm/futex_64.h
Normal file
113
arch/sparc/include/asm/futex_64.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
#ifndef _SPARC64_FUTEX_H
|
||||
#define _SPARC64_FUTEX_H
|
||||
|
||||
#include <linux/futex.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/errno.h>
|
||||
|
||||
#define __futex_cas_op(insn, ret, oldval, uaddr, oparg) \
|
||||
__asm__ __volatile__( \
|
||||
"\n1: lduwa [%3] %%asi, %2\n" \
|
||||
" " insn "\n" \
|
||||
"2: casa [%3] %%asi, %2, %1\n" \
|
||||
" cmp %2, %1\n" \
|
||||
" bne,pn %%icc, 1b\n" \
|
||||
" mov 0, %0\n" \
|
||||
"3:\n" \
|
||||
" .section .fixup,#alloc,#execinstr\n" \
|
||||
" .align 4\n" \
|
||||
"4: sethi %%hi(3b), %0\n" \
|
||||
" jmpl %0 + %%lo(3b), %%g0\n" \
|
||||
" mov %5, %0\n" \
|
||||
" .previous\n" \
|
||||
" .section __ex_table,\"a\"\n" \
|
||||
" .align 4\n" \
|
||||
" .word 1b, 4b\n" \
|
||||
" .word 2b, 4b\n" \
|
||||
" .previous\n" \
|
||||
: "=&r" (ret), "=&r" (oldval), "=&r" (tem) \
|
||||
: "r" (uaddr), "r" (oparg), "i" (-EFAULT) \
|
||||
: "memory")
|
||||
|
||||
static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret, tem;
|
||||
|
||||
if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))))
|
||||
return -EFAULT;
|
||||
if (unlikely((((unsigned long) uaddr) & 0x3UL)))
|
||||
return -EINVAL;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
switch (op) {
|
||||
case FUTEX_OP_SET:
|
||||
__futex_cas_op("mov\t%4, %1", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ADD:
|
||||
__futex_cas_op("add\t%2, %4, %1", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_OR:
|
||||
__futex_cas_op("or\t%2, %4, %1", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ANDN:
|
||||
__futex_cas_op("andn\t%2, %4, %1", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_XOR:
|
||||
__futex_cas_op("xor\t%2, %4, %1", ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int
|
||||
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
||||
u32 oldval, u32 newval)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"\n1: casa [%4] %%asi, %3, %1\n"
|
||||
"2:\n"
|
||||
" .section .fixup,#alloc,#execinstr\n"
|
||||
" .align 4\n"
|
||||
"3: sethi %%hi(2b), %0\n"
|
||||
" jmpl %0 + %%lo(2b), %%g0\n"
|
||||
" mov %5, %0\n"
|
||||
" .previous\n"
|
||||
" .section __ex_table,\"a\"\n"
|
||||
" .align 4\n"
|
||||
" .word 1b, 3b\n"
|
||||
" .previous\n"
|
||||
: "+r" (ret), "=r" (newval)
|
||||
: "1" (newval), "r" (oldval), "r" (uaddr), "i" (-EFAULT)
|
||||
: "memory");
|
||||
|
||||
*uval = newval;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* !(_SPARC64_FUTEX_H) */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue