forked from Minki/linux
metag: Remove arch/metag/
The earliest Meta architecture port of Linux I have a record of was an import of a Meta port of Linux v2.4.1 in February 2004, which was worked on significantly over the next few years by Graham Whaley, Will Newton, Matt Fleming, myself and others. Eventually the port was merged into mainline in v3.9 in March 2013, not long after Imagination Technologies bought MIPS Technologies and shifted its CPU focus over to the MIPS architecture. As a result, though the port was maintained for a while, kept on life support for a while longer, and useful for testing a few specific drivers for which I don't have ready access to the equivalent MIPS hardware, it is now essentially dead with no users. It is also stuck using an out-of-tree toolchain based on GCC 4.2.4 which is no longer maintained, now struggles to build modern kernels due to toolchain bugs, and doesn't itself build with a modern GCC. The latest buildroot port is still using an old uClibc snapshot which is no longer served, and the latest uClibc doesn't build with GCC 4.2.4. So lets call it a day and drop the Meta architecture port from the kernel. RIP Meta. Signed-off-by: James Hogan <jhogan@kernel.org> Link: https://lkml.kernel.org/r/95906b76-6ce1-3f84-eaba-c29b4ae952eb@roeck-us.net Reviewed-by: Guenter Roeck <linux@roeck-us.net> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Graham Whaley <graham.whaley@gmail.com> Cc: linux-metag@vger.kernel.org
This commit is contained in:
parent
91ab883eb2
commit
bb6fb6dfcc
@ -1,287 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
config METAG
|
||||
def_bool y
|
||||
select EMBEDDED
|
||||
select GENERIC_ATOMIC64
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_IRQ_SHOW
|
||||
select GENERIC_SMP_IDLE_THREAD
|
||||
select HAVE_64BIT_ALIGNED_ACCESS
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_C_RECORDMCOUNT
|
||||
select HAVE_DEBUG_KMEMLEAK
|
||||
select HAVE_DEBUG_STACKOVERFLOW
|
||||
select HAVE_DYNAMIC_FTRACE
|
||||
select HAVE_EXIT_THREAD
|
||||
select HAVE_FTRACE_MCOUNT_RECORD
|
||||
select HAVE_FUNCTION_TRACER
|
||||
select HAVE_KERNEL_BZIP2
|
||||
select HAVE_KERNEL_GZIP
|
||||
select HAVE_KERNEL_LZO
|
||||
select HAVE_KERNEL_XZ
|
||||
select HAVE_MEMBLOCK
|
||||
select HAVE_MEMBLOCK_NODE_MAP
|
||||
select HAVE_MOD_ARCH_SPECIFIC
|
||||
select HAVE_OPROFILE
|
||||
select HAVE_PERF_EVENTS
|
||||
select HAVE_SYSCALL_TRACEPOINTS
|
||||
select HAVE_UNDERSCORE_SYMBOL_PREFIX
|
||||
select IRQ_DOMAIN
|
||||
select GENERIC_IRQ_EFFECTIVE_AFF_MASK
|
||||
select MODULES_USE_ELF_RELA
|
||||
select OF
|
||||
select OF_EARLY_FLATTREE
|
||||
select SPARSE_IRQ
|
||||
select CPU_NO_EFFICIENT_FFS
|
||||
|
||||
config STACKTRACE_SUPPORT
|
||||
def_bool y
|
||||
|
||||
config LOCKDEP_SUPPORT
|
||||
def_bool y
|
||||
|
||||
config RWSEM_GENERIC_SPINLOCK
|
||||
def_bool y
|
||||
|
||||
config RWSEM_XCHGADD_ALGORITHM
|
||||
bool
|
||||
|
||||
config GENERIC_HWEIGHT
|
||||
def_bool y
|
||||
|
||||
config GENERIC_CALIBRATE_DELAY
|
||||
def_bool y
|
||||
|
||||
config NO_IOPORT_MAP
|
||||
def_bool y
|
||||
|
||||
source "init/Kconfig"
|
||||
|
||||
source "kernel/Kconfig.freezer"
|
||||
|
||||
menu "Processor type and features"
|
||||
|
||||
config MMU
|
||||
def_bool y
|
||||
|
||||
config STACK_GROWSUP
|
||||
def_bool y
|
||||
|
||||
config HOTPLUG_CPU
|
||||
bool "Enable CPU hotplug support"
|
||||
depends on SMP
|
||||
help
|
||||
Say Y here to allow turning CPUs off and on. CPUs can be
|
||||
controlled through /sys/devices/system/cpu.
|
||||
|
||||
Say N if you want to disable CPU hotplug.
|
||||
|
||||
config HIGHMEM
|
||||
bool "High Memory Support"
|
||||
help
|
||||
The address space of Meta processors is only 4 Gigabytes large
|
||||
and it has to accommodate user address space, kernel address
|
||||
space as well as some memory mapped IO. That means that, if you
|
||||
have a large amount of physical memory and/or IO, not all of the
|
||||
memory can be "permanently mapped" by the kernel. The physical
|
||||
memory that is not permanently mapped is called "high memory".
|
||||
|
||||
Depending on the selected kernel/user memory split, minimum
|
||||
vmalloc space and actual amount of RAM, you may not need this
|
||||
option which should result in a slightly faster kernel.
|
||||
|
||||
If unsure, say n.
|
||||
|
||||
source "arch/metag/mm/Kconfig"
|
||||
|
||||
source "arch/metag/Kconfig.soc"
|
||||
|
||||
config METAG_META12
|
||||
bool
|
||||
help
|
||||
Select this from the SoC config symbol to indicate that it contains a
|
||||
Meta 1.2 core.
|
||||
|
||||
config METAG_META21
|
||||
bool
|
||||
help
|
||||
Select this from the SoC config symbol to indicate that it contains a
|
||||
Meta 2.1 core.
|
||||
|
||||
config SMP
|
||||
bool "Symmetric multi-processing support"
|
||||
depends on METAG_META21 && METAG_META21_MMU
|
||||
help
|
||||
This enables support for systems with more than one thread running
|
||||
Linux. If you have a system with only one thread running Linux,
|
||||
say N. Otherwise, say Y.
|
||||
|
||||
config NR_CPUS
|
||||
int "Maximum number of CPUs (2-4)" if SMP
|
||||
range 2 4 if SMP
|
||||
default "1" if !SMP
|
||||
default "4" if SMP
|
||||
|
||||
config METAG_SMP_WRITE_REORDERING
|
||||
bool
|
||||
help
|
||||
This attempts to prevent cache-memory incoherence due to external
|
||||
reordering of writes from different hardware threads when SMP is
|
||||
enabled. It adds fences (system event 0) to smp_mb and smp_rmb in an
|
||||
attempt to catch some of the cases, and also before writes to shared
|
||||
memory in LOCK1 protected atomics and spinlocks.
|
||||
This will not completely prevent cache incoherency on affected cores.
|
||||
|
||||
config METAG_LNKGET_AROUND_CACHE
|
||||
bool
|
||||
depends on METAG_META21
|
||||
help
|
||||
This indicates that the LNKGET/LNKSET instructions go around the
|
||||
cache, which requires some extra cache flushes when the memory needs
|
||||
to be accessed by normal GET/SET instructions too.
|
||||
|
||||
choice
|
||||
prompt "Atomicity primitive"
|
||||
default METAG_ATOMICITY_LNKGET
|
||||
help
|
||||
This option selects the mechanism for performing atomic operations.
|
||||
|
||||
config METAG_ATOMICITY_IRQSOFF
|
||||
depends on !SMP
|
||||
bool "irqsoff"
|
||||
help
|
||||
This option disables interrupts to achieve atomicity. This mechanism
|
||||
is not SMP-safe.
|
||||
|
||||
config METAG_ATOMICITY_LNKGET
|
||||
depends on METAG_META21
|
||||
bool "lnkget/lnkset"
|
||||
help
|
||||
This option uses the LNKGET and LNKSET instructions to achieve
|
||||
atomicity. LNKGET/LNKSET are load-link/store-conditional instructions.
|
||||
Choose this option if your system requires low latency.
|
||||
|
||||
config METAG_ATOMICITY_LOCK1
|
||||
depends on SMP
|
||||
bool "lock1"
|
||||
help
|
||||
This option uses the LOCK1 instruction for atomicity. This is mainly
|
||||
provided as a debugging aid if the lnkget/lnkset atomicity primitive
|
||||
isn't working properly.
|
||||
|
||||
endchoice
|
||||
|
||||
config METAG_FPU
|
||||
bool "FPU Support"
|
||||
depends on METAG_META21
|
||||
default y
|
||||
help
|
||||
This option allows processes to use FPU hardware available with this
|
||||
CPU. If this option is not enabled FPU registers will not be saved
|
||||
and restored on context-switch.
|
||||
|
||||
If you plan on running programs which are compiled to use hard floats
|
||||
say Y here.
|
||||
|
||||
config METAG_DSP
|
||||
bool "DSP Support"
|
||||
help
|
||||
This option allows processes to use DSP hardware available
|
||||
with this CPU. If this option is not enabled DSP registers
|
||||
will not be saved and restored on context-switch.
|
||||
|
||||
If you plan on running DSP programs say Y here.
|
||||
|
||||
config METAG_PERFCOUNTER_IRQS
|
||||
bool "PerfCounters interrupt support"
|
||||
depends on METAG_META21
|
||||
help
|
||||
This option enables using interrupts to collect information from
|
||||
Performance Counters. This option is supported in new META21
|
||||
(starting from HTP265).
|
||||
|
||||
When disabled, Performance Counters information will be collected
|
||||
based on Timer Interrupt.
|
||||
|
||||
config HW_PERF_EVENTS
|
||||
def_bool METAG_PERFCOUNTER_IRQS && PERF_EVENTS
|
||||
|
||||
config METAG_DA
|
||||
bool "DA support"
|
||||
help
|
||||
Say Y if you plan to use a DA debug adapter with Linux. The presence
|
||||
of the DA will be detected automatically at boot, so it is safe to say
|
||||
Y to this option even when booting without a DA.
|
||||
|
||||
This enables support for services provided by DA JTAG debug adapters,
|
||||
such as:
|
||||
- communication over DA channels (such as the console driver).
|
||||
- use of the DA filesystem.
|
||||
|
||||
menu "Boot options"
|
||||
|
||||
config METAG_BUILTIN_DTB
|
||||
bool "Embed DTB in kernel image"
|
||||
default y
|
||||
help
|
||||
Embeds a device tree binary in the kernel image.
|
||||
|
||||
config METAG_BUILTIN_DTB_NAME
|
||||
string "Built in DTB"
|
||||
depends on METAG_BUILTIN_DTB
|
||||
help
|
||||
Set the name of the DTB to embed (leave blank to pick one
|
||||
automatically based on kernel configuration).
|
||||
|
||||
config CMDLINE_BOOL
|
||||
bool "Default bootloader kernel arguments"
|
||||
|
||||
config CMDLINE
|
||||
string "Kernel command line"
|
||||
depends on CMDLINE_BOOL
|
||||
help
|
||||
On some architectures there is currently no way for the boot loader
|
||||
to pass arguments to the kernel. For these architectures, you should
|
||||
supply some command-line options at build time by entering them
|
||||
here.
|
||||
|
||||
config CMDLINE_FORCE
|
||||
bool "Force default kernel command string"
|
||||
depends on CMDLINE_BOOL
|
||||
help
|
||||
Set this to have arguments from the default kernel command string
|
||||
override those passed by the boot loader.
|
||||
|
||||
endmenu
|
||||
|
||||
source "kernel/Kconfig.preempt"
|
||||
|
||||
source kernel/Kconfig.hz
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Power management options"
|
||||
|
||||
source kernel/power/Kconfig
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Executable file formats"
|
||||
|
||||
source "fs/Kconfig.binfmt"
|
||||
|
||||
endmenu
|
||||
|
||||
source "net/Kconfig"
|
||||
|
||||
source "drivers/Kconfig"
|
||||
|
||||
source "fs/Kconfig"
|
||||
|
||||
source "arch/metag/Kconfig.debug"
|
||||
|
||||
source "security/Kconfig"
|
||||
|
||||
source "crypto/Kconfig"
|
||||
|
||||
source "lib/Kconfig"
|
@ -1,34 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
menu "Kernel hacking"
|
||||
|
||||
config TRACE_IRQFLAGS_SUPPORT
|
||||
bool
|
||||
default y
|
||||
|
||||
source "lib/Kconfig.debug"
|
||||
|
||||
config 4KSTACKS
|
||||
bool "Use 4Kb for kernel stacks instead of 8Kb"
|
||||
depends on DEBUG_KERNEL
|
||||
help
|
||||
If you say Y here the kernel will use a 4Kb stacksize for the
|
||||
kernel stack attached to each process/thread. This facilitates
|
||||
running more threads on a system and also reduces the pressure
|
||||
on the VM subsystem for higher order allocations. This option
|
||||
will also use IRQ stacks to compensate for the reduced stackspace.
|
||||
|
||||
config METAG_FUNCTION_TRACE
|
||||
bool "Output Meta real-time trace data for function entry/exit"
|
||||
help
|
||||
If you say Y here the kernel will use the Meta hardware trace
|
||||
unit to output information about function entry and exit that
|
||||
can be used by a debugger for profiling and call-graphs.
|
||||
|
||||
config METAG_POISON_CATCH_BUFFERS
|
||||
bool "Poison catch buffer contents on kernel entry"
|
||||
help
|
||||
If you say Y here the kernel will write poison data to the
|
||||
catch buffer registers on kernel entry. This will make any
|
||||
problem with catch buffer handling much more apparent.
|
||||
|
||||
endmenu
|
@ -1,69 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
choice
|
||||
prompt "SoC Type"
|
||||
default META21_FPGA
|
||||
|
||||
config META12_FPGA
|
||||
bool "Meta 1.2 FPGA"
|
||||
select METAG_META12
|
||||
help
|
||||
This is a Meta 1.2 FPGA bitstream, just a bare CPU.
|
||||
|
||||
config META21_FPGA
|
||||
bool "Meta 2.1 FPGA"
|
||||
select METAG_META21
|
||||
help
|
||||
This is a Meta 2.1 FPGA bitstream, just a bare CPU.
|
||||
|
||||
config SOC_TZ1090
|
||||
bool "Toumaz Xenif TZ1090 SoC (Comet)"
|
||||
select IMGPDC_IRQ
|
||||
select METAG_LNKGET_AROUND_CACHE
|
||||
select METAG_META21
|
||||
select METAG_SMP_WRITE_REORDERING
|
||||
select PINCTRL
|
||||
select PINCTRL_TZ1090
|
||||
select PINCTRL_TZ1090_PDC
|
||||
help
|
||||
This is a Toumaz Technology Xenif TZ1090 (A.K.A. Comet) SoC containing
|
||||
a 2-threaded HTP.
|
||||
|
||||
endchoice
|
||||
|
||||
menu "SoC configuration"
|
||||
|
||||
if METAG_META21
|
||||
|
||||
# Meta 2.x specific options
|
||||
|
||||
config METAG_META21_MMU
|
||||
bool "Meta 2.x MMU mode"
|
||||
default y
|
||||
help
|
||||
Use the Meta 2.x MMU in extended mode.
|
||||
|
||||
config METAG_UNALIGNED
|
||||
bool "Meta 2.x unaligned access checking"
|
||||
default y
|
||||
help
|
||||
All memory accesses will be checked for alignment and an exception
|
||||
raised on unaligned accesses. This feature does cost performance
|
||||
but without it there will be no notification of this type of error.
|
||||
|
||||
config METAG_USER_TCM
|
||||
bool "Meta on-chip memory support for userland"
|
||||
select GENERIC_ALLOCATOR
|
||||
default y
|
||||
help
|
||||
Allow the on-chip memories of Meta SoCs to be used by user
|
||||
applications.
|
||||
|
||||
endif
|
||||
|
||||
config METAG_HALT_ON_PANIC
|
||||
bool "Halt the core on panic"
|
||||
help
|
||||
Halt the core when a panic occurs. This is useful when running
|
||||
pre-production silicon or in an FPGA environment.
|
||||
|
||||
endmenu
|
@ -1,89 +0,0 @@
|
||||
#
|
||||
# metag/Makefile
|
||||
#
|
||||
# This file is included by the global makefile so that you can add your own
|
||||
# architecture-specific flags and dependencies. Remember to do have actions
|
||||
# for "archclean" cleaning up for this architecture.
|
||||
#
|
||||
# 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) 1994 by Linus Torvalds
|
||||
# 2007,2008,2012 by Imagination Technologies Ltd.
|
||||
#
|
||||
|
||||
LDFLAGS :=
|
||||
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
|
||||
|
||||
checkflags-$(CONFIG_METAG_META12) += -DMETAC_1_2
|
||||
checkflags-$(CONFIG_METAG_META21) += -DMETAC_2_1
|
||||
CHECKFLAGS += -D__metag__ $(checkflags-y)
|
||||
|
||||
KBUILD_DEFCONFIG := tz1090_defconfig
|
||||
|
||||
sflags-$(CONFIG_METAG_META12) += -mmetac=1.2
|
||||
ifeq ($(CONFIG_METAG_META12),y)
|
||||
# Only use TBI API 1.4 if DSP is enabled for META12 cores
|
||||
sflags-$(CONFIG_METAG_DSP) += -DTBI_1_4
|
||||
endif
|
||||
sflags-$(CONFIG_METAG_META21) += -mmetac=2.1 -DTBI_1_4
|
||||
|
||||
cflags-$(CONFIG_METAG_FUNCTION_TRACE) += -mhwtrace-leaf -mhwtrace-retpc
|
||||
cflags-$(CONFIG_METAG_META21) += -mextensions=bex
|
||||
|
||||
KBUILD_CFLAGS += -pipe
|
||||
KBUILD_CFLAGS += -ffunction-sections
|
||||
|
||||
KBUILD_CFLAGS += $(sflags-y) $(cflags-y)
|
||||
KBUILD_AFLAGS += $(sflags-y)
|
||||
|
||||
LDFLAGS_vmlinux := $(ldflags-y)
|
||||
|
||||
head-y := arch/metag/kernel/head.o
|
||||
|
||||
core-y += arch/metag/boot/dts/
|
||||
core-y += arch/metag/kernel/
|
||||
core-y += arch/metag/mm/
|
||||
|
||||
libs-y += arch/metag/lib/
|
||||
libs-y += arch/metag/tbx/
|
||||
|
||||
drivers-$(CONFIG_OPROFILE) += arch/metag/oprofile/
|
||||
|
||||
boot := arch/metag/boot
|
||||
|
||||
boot_targets += uImage
|
||||
boot_targets += uImage.gz
|
||||
boot_targets += uImage.bz2
|
||||
boot_targets += uImage.xz
|
||||
boot_targets += uImage.lzo
|
||||
boot_targets += uImage.bin
|
||||
boot_targets += vmlinux.bin
|
||||
|
||||
PHONY += $(boot_targets)
|
||||
|
||||
all: vmlinux.bin
|
||||
|
||||
$(boot_targets): vmlinux
|
||||
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
||||
|
||||
%.dtb %.dtb.S %.dtb.o: scripts
|
||||
$(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@
|
||||
|
||||
dtbs: scripts
|
||||
$(Q)$(MAKE) $(build)=$(boot)/dts
|
||||
|
||||
archclean:
|
||||
$(Q)$(MAKE) $(clean)=$(boot)
|
||||
|
||||
define archhelp
|
||||
echo '* vmlinux.bin - Binary kernel image (arch/$(ARCH)/boot/vmlinux.bin)'
|
||||
@echo ' uImage - Alias to bootable U-Boot image'
|
||||
@echo ' uImage.bin - Kernel-only image for U-Boot (bin)'
|
||||
@echo ' uImage.gz - Kernel-only image for U-Boot (gzip)'
|
||||
@echo ' uImage.bz2 - Kernel-only image for U-Boot (bzip2)'
|
||||
@echo ' uImage.xz - Kernel-only image for U-Boot (xz)'
|
||||
@echo ' uImage.lzo - Kernel-only image for U-Boot (lzo)'
|
||||
@echo ' dtbs - Build device tree blobs for enabled boards'
|
||||
endef
|
3
arch/metag/boot/.gitignore
vendored
3
arch/metag/boot/.gitignore
vendored
@ -1,3 +0,0 @@
|
||||
vmlinux*
|
||||
uImage*
|
||||
ramdisk.*
|
@ -1,68 +0,0 @@
|
||||
#
|
||||
# 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) 2007,2012 Imagination Technologies Ltd.
|
||||
#
|
||||
|
||||
suffix-y := bin
|
||||
suffix-$(CONFIG_KERNEL_GZIP) := gz
|
||||
suffix-$(CONFIG_KERNEL_BZIP2) := bz2
|
||||
suffix-$(CONFIG_KERNEL_XZ) := xz
|
||||
suffix-$(CONFIG_KERNEL_LZO) := lzo
|
||||
|
||||
targets += vmlinux.bin
|
||||
targets += uImage
|
||||
targets += uImage.gz
|
||||
targets += uImage.bz2
|
||||
targets += uImage.xz
|
||||
targets += uImage.lzo
|
||||
targets += uImage.bin
|
||||
|
||||
extra-y += vmlinux.bin
|
||||
extra-y += vmlinux.bin.gz
|
||||
extra-y += vmlinux.bin.bz2
|
||||
extra-y += vmlinux.bin.xz
|
||||
extra-y += vmlinux.bin.lzo
|
||||
|
||||
UIMAGE_LOADADDR = $(CONFIG_PAGE_OFFSET)
|
||||
|
||||
ifeq ($(CONFIG_FUNCTION_TRACER),y)
|
||||
orig_cflags := $(KBUILD_CFLAGS)
|
||||
KBUILD_CFLAGS = $(subst -pg, , $(orig_cflags))
|
||||
endif
|
||||
|
||||
$(obj)/vmlinux.bin: vmlinux FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
|
||||
$(call if_changed,gzip)
|
||||
|
||||
$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
|
||||
$(call if_changed,bzip2)
|
||||
|
||||
$(obj)/vmlinux.bin.xz: $(obj)/vmlinux.bin FORCE
|
||||
$(call if_changed,xzkern)
|
||||
|
||||
$(obj)/vmlinux.bin.lzo: $(obj)/vmlinux.bin FORCE
|
||||
$(call if_changed,lzo)
|
||||
|
||||
$(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE
|
||||
$(call if_changed,uimage,gzip)
|
||||
|
||||
$(obj)/uImage.bz2: $(obj)/vmlinux.bin.bz2 FORCE
|
||||
$(call if_changed,uimage,bzip2)
|
||||
|
||||
$(obj)/uImage.xz: $(obj)/vmlinux.bin.xz FORCE
|
||||
$(call if_changed,uimage,xz)
|
||||
|
||||
$(obj)/uImage.lzo: $(obj)/vmlinux.bin.lzo FORCE
|
||||
$(call if_changed,uimage,lzo)
|
||||
|
||||
$(obj)/uImage.bin: $(obj)/vmlinux.bin FORCE
|
||||
$(call if_changed,uimage,none)
|
||||
|
||||
$(obj)/uImage: $(obj)/uImage.$(suffix-y)
|
||||
@ln -sf $(notdir $<) $@
|
||||
@echo ' Image $@ is ready'
|
@ -1,16 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
dtb-y += skeleton.dtb
|
||||
dtb-y += tz1090_generic.dtb
|
||||
|
||||
# Built-in dtb
|
||||
builtindtb-y := skeleton
|
||||
builtindtb-$(CONFIG_SOC_TZ1090) := tz1090_generic
|
||||
|
||||
ifneq ($(CONFIG_METAG_BUILTIN_DTB_NAME),"")
|
||||
builtindtb-y := $(patsubst "%",%,$(CONFIG_METAG_BUILTIN_DTB_NAME))
|
||||
endif
|
||||
|
||||
dtb-$(CONFIG_METAG_BUILTIN_DTB) += $(builtindtb-y).dtb
|
||||
obj-$(CONFIG_METAG_BUILTIN_DTB) += $(builtindtb-y).dtb.o
|
||||
|
||||
.SECONDARY: $(obj)/$(builtindtb-y).dtb.S
|
@ -1,10 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Imagination Technologies Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
/dts-v1/;
|
||||
|
||||
#include "skeleton.dtsi"
|
@ -1,15 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Skeleton device tree; the bare minimum needed to boot; just include and
|
||||
* add a compatible value. The bootloader will typically populate the memory
|
||||
* node.
|
||||
*/
|
||||
|
||||
/ {
|
||||
compatible = "img,meta";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
chosen { };
|
||||
aliases { };
|
||||
memory { device_type = "memory"; reg = <0 0>; };
|
||||
};
|
@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Imagination Technologies Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include "skeleton.dtsi"
|
||||
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
/ {
|
||||
compatible = "toumaz,tz1090", "img,meta";
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
|
||||
intc: interrupt-controller {
|
||||
compatible = "img,meta-intc";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
num-banks = <2>;
|
||||
};
|
||||
|
||||
soc {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
pdc: pdc@0x02006000 {
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
reg = <0x02006000 0x1000>;
|
||||
compatible = "img,pdc-intc";
|
||||
|
||||
num-perips = <3>;
|
||||
num-syswakes = <3>;
|
||||
|
||||
interrupts = <18 IRQ_TYPE_LEVEL_HIGH>, /* Syswakes */
|
||||
<30 IRQ_TYPE_LEVEL_HIGH>, /* Perip 0 (RTC) */
|
||||
<29 IRQ_TYPE_LEVEL_HIGH>, /* Perip 1 (IR) */
|
||||
<31 IRQ_TYPE_LEVEL_HIGH>; /* Perip 2 (WDT) */
|
||||
};
|
||||
|
||||
pinctrl: pinctrl@02005800 {
|
||||
#gpio-range-cells = <3>;
|
||||
compatible = "img,tz1090-pinctrl";
|
||||
reg = <0x02005800 0xe4>;
|
||||
};
|
||||
|
||||
pdc_pinctrl: pinctrl@02006500 {
|
||||
#gpio-range-cells = <3>;
|
||||
compatible = "img,tz1090-pdc-pinctrl";
|
||||
reg = <0x02006500 0x100>;
|
||||
};
|
||||
|
||||
gpios: gpios@02005800 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "img,tz1090-gpio";
|
||||
reg = <0x02005800 0x90>;
|
||||
|
||||
gpios0: bank@0 {
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#gpio-cells = <2>;
|
||||
#interrupt-cells = <2>;
|
||||
reg = <0>;
|
||||
interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
|
||||
gpio-ranges = <&pinctrl 0 0 30>;
|
||||
};
|
||||
gpios1: bank@1 {
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#gpio-cells = <2>;
|
||||
#interrupt-cells = <2>;
|
||||
reg = <1>;
|
||||
interrupts = <14 IRQ_TYPE_LEVEL_HIGH>;
|
||||
gpio-ranges = <&pinctrl 0 30 30>;
|
||||
};
|
||||
gpios2: bank@2 {
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#gpio-cells = <2>;
|
||||
#interrupt-cells = <2>;
|
||||
reg = <2>;
|
||||
interrupts = <15 IRQ_TYPE_LEVEL_HIGH>;
|
||||
gpio-ranges = <&pinctrl 0 60 30>;
|
||||
};
|
||||
};
|
||||
|
||||
pdc_gpios: gpios@02006500 {
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
compatible = "img,tz1090-pdc-gpio";
|
||||
reg = <0x02006500 0x100>;
|
||||
|
||||
interrupt-parent = <&pdc>;
|
||||
interrupts = <8 IRQ_TYPE_NONE>,
|
||||
<9 IRQ_TYPE_NONE>,
|
||||
<10 IRQ_TYPE_NONE>;
|
||||
gpio-ranges = <&pdc_pinctrl 0 0 7>;
|
||||
};
|
||||
};
|
||||
};
|
@ -1,10 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Imagination Technologies Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
/dts-v1/;
|
||||
|
||||
#include "tz1090.dtsi"
|
@ -1,39 +0,0 @@
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
# CONFIG_SWAP is not set
|
||||
CONFIG_SYSFS_DEPRECATED=y
|
||||
CONFIG_SYSFS_DEPRECATED_V2=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
# CONFIG_ELF_CORE is not set
|
||||
CONFIG_SLAB=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
# CONFIG_MSDOS_PARTITION is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_FLATMEM_MANUAL=y
|
||||
CONFIG_META12_FPGA=y
|
||||
CONFIG_METAG_DA=y
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
# CONFIG_STANDALONE is not set
|
||||
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
|
||||
# CONFIG_FW_LOADER is not set
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=1
|
||||
CONFIG_BLK_DEV_RAM_SIZE=16384
|
||||
# CONFIG_INPUT is not set
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
CONFIG_DA_TTY=y
|
||||
CONFIG_DA_CONSOLE=y
|
||||
# CONFIG_DEVKMEM is not set
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_HWMON is not set
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
# CONFIG_DNOTIFY is not set
|
||||
CONFIG_TMPFS=y
|
||||
# CONFIG_MISC_FILESYSTEMS is not set
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
CONFIG_DEBUG_INFO=y
|
@ -1,40 +0,0 @@
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
# CONFIG_SWAP is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_SYSFS_DEPRECATED=y
|
||||
CONFIG_SYSFS_DEPRECATED_V2=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
# CONFIG_ELF_CORE is not set
|
||||
CONFIG_SLAB=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
# CONFIG_MSDOS_PARTITION is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_METAG_L2C=y
|
||||
CONFIG_FLATMEM_MANUAL=y
|
||||
CONFIG_METAG_HALT_ON_PANIC=y
|
||||
CONFIG_METAG_DA=y
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
# CONFIG_STANDALONE is not set
|
||||
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
|
||||
# CONFIG_FW_LOADER is not set
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=1
|
||||
CONFIG_BLK_DEV_RAM_SIZE=16384
|
||||
# CONFIG_INPUT is not set
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
CONFIG_DA_TTY=y
|
||||
CONFIG_DA_CONSOLE=y
|
||||
# CONFIG_DEVKMEM is not set
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_HWMON is not set
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
# CONFIG_DNOTIFY is not set
|
||||
CONFIG_TMPFS=y
|
||||
# CONFIG_MISC_FILESYSTEMS is not set
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
CONFIG_DEBUG_INFO=y
|
@ -1,41 +0,0 @@
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
# CONFIG_SWAP is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_SYSFS_DEPRECATED=y
|
||||
CONFIG_SYSFS_DEPRECATED_V2=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
# CONFIG_ELF_CORE is not set
|
||||
CONFIG_SLAB=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
# CONFIG_MSDOS_PARTITION is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_METAG_L2C=y
|
||||
CONFIG_FLATMEM_MANUAL=y
|
||||
CONFIG_METAG_HALT_ON_PANIC=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_METAG_DA=y
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
# CONFIG_STANDALONE is not set
|
||||
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
|
||||
# CONFIG_FW_LOADER is not set
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=1
|
||||
CONFIG_BLK_DEV_RAM_SIZE=16384
|
||||
# CONFIG_INPUT is not set
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
CONFIG_DA_TTY=y
|
||||
CONFIG_DA_CONSOLE=y
|
||||
# CONFIG_DEVKMEM is not set
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_HWMON is not set
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
# CONFIG_DNOTIFY is not set
|
||||
CONFIG_TMPFS=y
|
||||
# CONFIG_MISC_FILESYSTEMS is not set
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
CONFIG_DEBUG_INFO=y
|
@ -1,42 +0,0 @@
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
# CONFIG_SWAP is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_SYSFS_DEPRECATED=y
|
||||
CONFIG_SYSFS_DEPRECATED_V2=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
# CONFIG_ELF_CORE is not set
|
||||
CONFIG_SLAB=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
# CONFIG_MSDOS_PARTITION is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_FLATMEM_MANUAL=y
|
||||
CONFIG_SOC_TZ1090=y
|
||||
CONFIG_METAG_HALT_ON_PANIC=y
|
||||
# CONFIG_METAG_FPU is not set
|
||||
CONFIG_METAG_DA=y
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
# CONFIG_STANDALONE is not set
|
||||
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
|
||||
# CONFIG_FW_LOADER is not set
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=1
|
||||
CONFIG_BLK_DEV_RAM_SIZE=16384
|
||||
# CONFIG_INPUT is not set
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
CONFIG_DA_TTY=y
|
||||
CONFIG_DA_CONSOLE=y
|
||||
# CONFIG_DEVKMEM is not set
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
CONFIG_GPIOLIB=y
|
||||
# CONFIG_HWMON is not set
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
# CONFIG_DNOTIFY is not set
|
||||
CONFIG_TMPFS=y
|
||||
# CONFIG_MISC_FILESYSTEMS is not set
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
CONFIG_DEBUG_INFO=y
|
@ -1,33 +0,0 @@
|
||||
generic-y += bugs.h
|
||||
generic-y += current.h
|
||||
generic-y += device.h
|
||||
generic-y += dma.h
|
||||
generic-y += emergency-restart.h
|
||||
generic-y += exec.h
|
||||
generic-y += extable.h
|
||||
generic-y += fb.h
|
||||
generic-y += futex.h
|
||||
generic-y += hardirq.h
|
||||
generic-y += hw_irq.h
|
||||
generic-y += irq_regs.h
|
||||
generic-y += irq_work.h
|
||||
generic-y += kdebug.h
|
||||
generic-y += kmap_types.h
|
||||
generic-y += kprobes.h
|
||||
generic-y += local.h
|
||||
generic-y += local64.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += mm-arch-hooks.h
|
||||
generic-y += pci.h
|
||||
generic-y += percpu.h
|
||||
generic-y += preempt.h
|
||||
generic-y += sections.h
|
||||
generic-y += serial.h
|
||||
generic-y += switch_to.h
|
||||
generic-y += timex.h
|
||||
generic-y += trace_clock.h
|
||||
generic-y += unaligned.h
|
||||
generic-y += user.h
|
||||
generic-y += vga.h
|
||||
generic-y += word-at-a-time.h
|
||||
generic-y += xor.h
|
@ -1,49 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_ATOMIC_H
|
||||
#define __ASM_METAG_ATOMIC_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/cmpxchg.h>
|
||||
#include <asm/barrier.h>
|
||||
|
||||
#if defined(CONFIG_METAG_ATOMICITY_IRQSOFF)
|
||||
/* The simple UP case. */
|
||||
#include <asm-generic/atomic.h>
|
||||
#else
|
||||
|
||||
#if defined(CONFIG_METAG_ATOMICITY_LOCK1)
|
||||
#include <asm/atomic_lock1.h>
|
||||
#else
|
||||
#include <asm/atomic_lnkget.h>
|
||||
#endif
|
||||
|
||||
#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
|
||||
|
||||
#define atomic_dec_return(v) atomic_sub_return(1, (v))
|
||||
#define atomic_inc_return(v) atomic_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 atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
|
||||
#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
|
||||
|
||||
#define atomic_inc(v) atomic_add(1, (v))
|
||||
#define atomic_dec(v) atomic_sub(1, (v))
|
||||
|
||||
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
|
||||
#define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v)
|
||||
|
||||
#endif
|
||||
|
||||
#include <asm-generic/atomic64.h>
|
||||
|
||||
#endif /* __ASM_METAG_ATOMIC_H */
|
@ -1,204 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_ATOMIC_LNKGET_H
|
||||
#define __ASM_METAG_ATOMIC_LNKGET_H
|
||||
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
|
||||
#define atomic_set(v, i) WRITE_ONCE((v)->counter, (i))
|
||||
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#include <asm/barrier.h>
|
||||
|
||||
/*
|
||||
* None of these asm statements clobber memory as LNKSET writes around
|
||||
* the cache so the memory it modifies cannot safely be read by any means
|
||||
* other than these accessors.
|
||||
*/
|
||||
|
||||
static inline int atomic_read(const atomic_t *v)
|
||||
{
|
||||
int temp;
|
||||
|
||||
asm volatile (
|
||||
"LNKGETD %0, [%1]\n"
|
||||
: "=da" (temp)
|
||||
: "da" (&v->counter));
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
#define ATOMIC_OP(op) \
|
||||
static inline void atomic_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
int temp; \
|
||||
\
|
||||
asm volatile ( \
|
||||
"1: LNKGETD %0, [%1]\n" \
|
||||
" " #op " %0, %0, %2\n" \
|
||||
" LNKSETD [%1], %0\n" \
|
||||
" DEFR %0, TXSTAT\n" \
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n" \
|
||||
" CMPT %0, #HI(0x02000000)\n" \
|
||||
" BNZ 1b\n" \
|
||||
: "=&d" (temp) \
|
||||
: "da" (&v->counter), "bd" (i) \
|
||||
: "cc"); \
|
||||
} \
|
||||
|
||||
#define ATOMIC_OP_RETURN(op) \
|
||||
static inline int atomic_##op##_return(int i, atomic_t *v) \
|
||||
{ \
|
||||
int result, temp; \
|
||||
\
|
||||
smp_mb(); \
|
||||
\
|
||||
asm volatile ( \
|
||||
"1: LNKGETD %1, [%2]\n" \
|
||||
" " #op " %1, %1, %3\n" \
|
||||
" LNKSETD [%2], %1\n" \
|
||||
" DEFR %0, TXSTAT\n" \
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n" \
|
||||
" CMPT %0, #HI(0x02000000)\n" \
|
||||
" BNZ 1b\n" \
|
||||
: "=&d" (temp), "=&da" (result) \
|
||||
: "da" (&v->counter), "br" (i) \
|
||||
: "cc"); \
|
||||
\
|
||||
smp_mb(); \
|
||||
\
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define ATOMIC_FETCH_OP(op) \
|
||||
static inline int atomic_fetch_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
int result, temp; \
|
||||
\
|
||||
smp_mb(); \
|
||||
\
|
||||
asm volatile ( \
|
||||
"1: LNKGETD %1, [%2]\n" \
|
||||
" " #op " %0, %1, %3\n" \
|
||||
" LNKSETD [%2], %0\n" \
|
||||
" DEFR %0, TXSTAT\n" \
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n" \
|
||||
" CMPT %0, #HI(0x02000000)\n" \
|
||||
" BNZ 1b\n" \
|
||||
: "=&d" (temp), "=&d" (result) \
|
||||
: "da" (&v->counter), "bd" (i) \
|
||||
: "cc"); \
|
||||
\
|
||||
smp_mb(); \
|
||||
\
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) ATOMIC_FETCH_OP(op)
|
||||
|
||||
ATOMIC_OPS(add)
|
||||
ATOMIC_OPS(sub)
|
||||
|
||||
#undef ATOMIC_OPS
|
||||
#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_FETCH_OP(op)
|
||||
|
||||
ATOMIC_OPS(and)
|
||||
ATOMIC_OPS(or)
|
||||
ATOMIC_OPS(xor)
|
||||
|
||||
#undef ATOMIC_OPS
|
||||
#undef ATOMIC_FETCH_OP
|
||||
#undef ATOMIC_OP_RETURN
|
||||
#undef ATOMIC_OP
|
||||
|
||||
static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
|
||||
{
|
||||
int result, temp;
|
||||
|
||||
smp_mb();
|
||||
|
||||
asm volatile (
|
||||
"1: LNKGETD %1, [%2]\n"
|
||||
" CMP %1, %3\n"
|
||||
" LNKSETDEQ [%2], %4\n"
|
||||
" BNE 2f\n"
|
||||
" DEFR %0, TXSTAT\n"
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n"
|
||||
" CMPT %0, #HI(0x02000000)\n"
|
||||
" BNZ 1b\n"
|
||||
"2:\n"
|
||||
: "=&d" (temp), "=&d" (result)
|
||||
: "da" (&v->counter), "bd" (old), "da" (new)
|
||||
: "cc");
|
||||
|
||||
smp_mb();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline int atomic_xchg(atomic_t *v, int new)
|
||||
{
|
||||
int temp, old;
|
||||
|
||||
asm volatile (
|
||||
"1: LNKGETD %1, [%2]\n"
|
||||
" LNKSETD [%2], %3\n"
|
||||
" DEFR %0, TXSTAT\n"
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n"
|
||||
" CMPT %0, #HI(0x02000000)\n"
|
||||
" BNZ 1b\n"
|
||||
: "=&d" (temp), "=&d" (old)
|
||||
: "da" (&v->counter), "da" (new)
|
||||
: "cc");
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
|
||||
{
|
||||
int result, temp;
|
||||
|
||||
smp_mb();
|
||||
|
||||
asm volatile (
|
||||
"1: LNKGETD %1, [%2]\n"
|
||||
" CMP %1, %3\n"
|
||||
" ADD %0, %1, %4\n"
|
||||
" LNKSETDNE [%2], %0\n"
|
||||
" BEQ 2f\n"
|
||||
" DEFR %0, TXSTAT\n"
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n"
|
||||
" CMPT %0, #HI(0x02000000)\n"
|
||||
" BNZ 1b\n"
|
||||
"2:\n"
|
||||
: "=&d" (temp), "=&d" (result)
|
||||
: "da" (&v->counter), "bd" (u), "bd" (a)
|
||||
: "cc");
|
||||
|
||||
smp_mb();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline int atomic_sub_if_positive(int i, atomic_t *v)
|
||||
{
|
||||
int result, temp;
|
||||
|
||||
asm volatile (
|
||||
"1: LNKGETD %1, [%2]\n"
|
||||
" SUBS %1, %1, %3\n"
|
||||
" LNKSETDGE [%2], %1\n"
|
||||
" BLT 2f\n"
|
||||
" DEFR %0, TXSTAT\n"
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n"
|
||||
" CMPT %0, #HI(0x02000000)\n"
|
||||
" BNZ 1b\n"
|
||||
"2:\n"
|
||||
: "=&d" (temp), "=&da" (result)
|
||||
: "da" (&v->counter), "bd" (i)
|
||||
: "cc");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* __ASM_METAG_ATOMIC_LNKGET_H */
|
@ -1,157 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_ATOMIC_LOCK1_H
|
||||
#define __ASM_METAG_ATOMIC_LOCK1_H
|
||||
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/global_lock.h>
|
||||
|
||||
static inline int atomic_read(const atomic_t *v)
|
||||
{
|
||||
return READ_ONCE((v)->counter);
|
||||
}
|
||||
|
||||
/*
|
||||
* atomic_set needs to be take the lock to protect atomic_add_unless from a
|
||||
* possible race, as it reads the counter twice:
|
||||
*
|
||||
* CPU0 CPU1
|
||||
* atomic_add_unless(1, 0)
|
||||
* ret = v->counter (non-zero)
|
||||
* if (ret != u) v->counter = 0
|
||||
* v->counter += 1 (counter set to 1)
|
||||
*
|
||||
* Making atomic_set take the lock ensures that ordering and logical
|
||||
* consistency is preserved.
|
||||
*/
|
||||
static inline int atomic_set(atomic_t *v, int i)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
__global_lock1(flags);
|
||||
fence();
|
||||
v->counter = i;
|
||||
__global_unlock1(flags);
|
||||
return i;
|
||||
}
|
||||
|
||||
#define atomic_set_release(v, i) atomic_set((v), (i))
|
||||
|
||||
#define ATOMIC_OP(op, c_op) \
|
||||
static inline void atomic_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned long flags; \
|
||||
\
|
||||
__global_lock1(flags); \
|
||||
fence(); \
|
||||
v->counter c_op i; \
|
||||
__global_unlock1(flags); \
|
||||
} \
|
||||
|
||||
#define ATOMIC_OP_RETURN(op, c_op) \
|
||||
static inline int atomic_##op##_return(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned long result; \
|
||||
unsigned long flags; \
|
||||
\
|
||||
__global_lock1(flags); \
|
||||
result = v->counter; \
|
||||
result c_op i; \
|
||||
fence(); \
|
||||
v->counter = result; \
|
||||
__global_unlock1(flags); \
|
||||
\
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define ATOMIC_FETCH_OP(op, c_op) \
|
||||
static inline int atomic_fetch_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned long result; \
|
||||
unsigned long flags; \
|
||||
\
|
||||
__global_lock1(flags); \
|
||||
result = v->counter; \
|
||||
fence(); \
|
||||
v->counter c_op i; \
|
||||
__global_unlock1(flags); \
|
||||
\
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define ATOMIC_OPS(op, c_op) \
|
||||
ATOMIC_OP(op, c_op) \
|
||||
ATOMIC_OP_RETURN(op, c_op) \
|
||||
ATOMIC_FETCH_OP(op, c_op)
|
||||
|
||||
ATOMIC_OPS(add, +=)
|
||||
ATOMIC_OPS(sub, -=)
|
||||
|
||||
#undef ATOMIC_OPS
|
||||
#define ATOMIC_OPS(op, c_op) \
|
||||
ATOMIC_OP(op, c_op) \
|
||||
ATOMIC_FETCH_OP(op, c_op)
|
||||
|
||||
ATOMIC_OPS(and, &=)
|
||||
ATOMIC_OPS(or, |=)
|
||||
ATOMIC_OPS(xor, ^=)
|
||||
|
||||
#undef ATOMIC_OPS
|
||||
#undef ATOMIC_FETCH_OP
|
||||
#undef ATOMIC_OP_RETURN
|
||||
#undef ATOMIC_OP
|
||||
|
||||
static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
|
||||
{
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
__global_lock1(flags);
|
||||
ret = v->counter;
|
||||
if (ret == old) {
|
||||
fence();
|
||||
v->counter = new;
|
||||
}
|
||||
__global_unlock1(flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
|
||||
|
||||
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
|
||||
{
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
__global_lock1(flags);
|
||||
ret = v->counter;
|
||||
if (ret != u) {
|
||||
fence();
|
||||
v->counter += a;
|
||||
}
|
||||
__global_unlock1(flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int atomic_sub_if_positive(int i, atomic_t *v)
|
||||
{
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
__global_lock1(flags);
|
||||
ret = v->counter - 1;
|
||||
if (ret >= 0) {
|
||||
fence();
|
||||
v->counter = ret;
|
||||
}
|
||||
__global_unlock1(flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* __ASM_METAG_ATOMIC_LOCK1_H */
|
@ -1,85 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_METAG_BARRIER_H
|
||||
#define _ASM_METAG_BARRIER_H
|
||||
|
||||
#include <asm/metag_mem.h>
|
||||
|
||||
#define nop() asm volatile ("NOP")
|
||||
|
||||
#ifdef CONFIG_METAG_META21
|
||||
|
||||
/* HTP and above have a system event to fence writes */
|
||||
static inline void wr_fence(void)
|
||||
{
|
||||
volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_FENCE;
|
||||
barrier();
|
||||
*flushptr = 0;
|
||||
barrier();
|
||||
}
|
||||
|
||||
#else /* CONFIG_METAG_META21 */
|
||||
|
||||
/*
|
||||
* ATP doesn't have system event to fence writes, so it is necessary to flush
|
||||
* the processor write queues as well as possibly the write combiner (depending
|
||||
* on the page being written).
|
||||
* To ensure the write queues are flushed we do 4 writes to a system event
|
||||
* register (in this case write combiner flush) which will also flush the write
|
||||
* combiner.
|
||||
*/
|
||||
static inline void wr_fence(void)
|
||||
{
|
||||
volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_COMBINE_FLUSH;
|
||||
barrier();
|
||||
*flushptr = 0;
|
||||
*flushptr = 0;
|
||||
*flushptr = 0;
|
||||
*flushptr = 0;
|
||||
barrier();
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_METAG_META21 */
|
||||
|
||||
/* flush writes through the write combiner */
|
||||
#define mb() wr_fence()
|
||||
#define rmb() barrier()
|
||||
#define wmb() mb()
|
||||
|
||||
#ifdef CONFIG_METAG_SMP_WRITE_REORDERING
|
||||
/*
|
||||
* Write to the atomic memory unlock system event register (command 0). This is
|
||||
* needed before a write to shared memory in a critical section, to prevent
|
||||
* external reordering of writes before the fence on other threads with writes
|
||||
* after the fence on this thread (and to prevent the ensuing cache-memory
|
||||
* incoherence). It is therefore ineffective if used after and on the same
|
||||
* thread as a write.
|
||||
*/
|
||||
static inline void metag_fence(void)
|
||||
{
|
||||
volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_ATOMIC_UNLOCK;
|
||||
barrier();
|
||||
*flushptr = 0;
|
||||
barrier();
|
||||
}
|
||||
#define __smp_mb() metag_fence()
|
||||
#define __smp_rmb() metag_fence()
|
||||
#define __smp_wmb() barrier()
|
||||
#else
|
||||
#define metag_fence() do { } while (0)
|
||||
#define __smp_mb() barrier()
|
||||
#define __smp_rmb() barrier()
|
||||
#define __smp_wmb() barrier()
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define fence() metag_fence()
|
||||
#else
|
||||
#define fence() do { } while (0)
|
||||
#endif
|
||||
|
||||
#define __smp_mb__before_atomic() barrier()
|
||||
#define __smp_mb__after_atomic() barrier()
|
||||
|
||||
#include <asm-generic/barrier.h>
|
||||
|
||||
#endif /* _ASM_METAG_BARRIER_H */
|
@ -1,127 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_BITOPS_H
|
||||
#define __ASM_METAG_BITOPS_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/global_lock.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* These functions are the basis of our bit ops.
|
||||
*/
|
||||
static inline void set_bit(unsigned int bit, volatile unsigned long *p)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long mask = 1UL << (bit & 31);
|
||||
|
||||
p += bit >> 5;
|
||||
|
||||
__global_lock1(flags);
|
||||
fence();
|
||||
*p |= mask;
|
||||
__global_unlock1(flags);
|
||||
}
|
||||
|
||||
static inline void clear_bit(unsigned int bit, volatile unsigned long *p)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long mask = 1UL << (bit & 31);
|
||||
|
||||
p += bit >> 5;
|
||||
|
||||
__global_lock1(flags);
|
||||
fence();
|
||||
*p &= ~mask;
|
||||
__global_unlock1(flags);
|
||||
}
|
||||
|
||||
static inline void change_bit(unsigned int bit, volatile unsigned long *p)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long mask = 1UL << (bit & 31);
|
||||
|
||||
p += bit >> 5;
|
||||
|
||||
__global_lock1(flags);
|
||||
fence();
|
||||
*p ^= mask;
|
||||
__global_unlock1(flags);
|
||||
}
|
||||
|
||||
static inline int test_and_set_bit(unsigned int bit, volatile unsigned long *p)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long old;
|
||||
unsigned long mask = 1UL << (bit & 31);
|
||||
|
||||
p += bit >> 5;
|
||||
|
||||
__global_lock1(flags);
|
||||
old = *p;
|
||||
if (!(old & mask)) {
|
||||
fence();
|
||||
*p = old | mask;
|
||||
}
|
||||
__global_unlock1(flags);
|
||||
|
||||
return (old & mask) != 0;
|
||||
}
|
||||
|
||||
static inline int test_and_clear_bit(unsigned int bit,
|
||||
volatile unsigned long *p)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long old;
|
||||
unsigned long mask = 1UL << (bit & 31);
|
||||
|
||||
p += bit >> 5;
|
||||
|
||||
__global_lock1(flags);
|
||||
old = *p;
|
||||
if (old & mask) {
|
||||
fence();
|
||||
*p = old & ~mask;
|
||||
}
|
||||
__global_unlock1(flags);
|
||||
|
||||
return (old & mask) != 0;
|
||||
}
|
||||
|
||||
static inline int test_and_change_bit(unsigned int bit,
|
||||
volatile unsigned long *p)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long old;
|
||||
unsigned long mask = 1UL << (bit & 31);
|
||||
|
||||
p += bit >> 5;
|
||||
|
||||
__global_lock1(flags);
|
||||
fence();
|
||||
old = *p;
|
||||
*p = old ^ mask;
|
||||
__global_unlock1(flags);
|
||||
|
||||
return (old & mask) != 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#include <asm-generic/bitops/atomic.h>
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#include <asm-generic/bitops/non-atomic.h>
|
||||
#include <asm-generic/bitops/find.h>
|
||||
#include <asm-generic/bitops/ffs.h>
|
||||
#include <asm-generic/bitops/__ffs.h>
|
||||
#include <asm-generic/bitops/ffz.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/sched.h>
|
||||
#include <asm-generic/bitops/le.h>
|
||||
#include <asm-generic/bitops/ext2-atomic.h>
|
||||
|
||||
#endif /* __ASM_METAG_BITOPS_H */
|
@ -1,13 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_METAG_BUG_H
|
||||
#define _ASM_METAG_BUG_H
|
||||
|
||||
#include <asm-generic/bug.h>
|
||||
|
||||
struct pt_regs;
|
||||
|
||||
extern const char *trap_name(int trapno);
|
||||
extern void __noreturn die(const char *str, struct pt_regs *regs, long err,
|
||||
unsigned long addr);
|
||||
|
||||
#endif
|
@ -1,24 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_CACHE_H
|
||||
#define __ASM_METAG_CACHE_H
|
||||
|
||||
/* L1 cache line size (64 bytes) */
|
||||
#define L1_CACHE_SHIFT 6
|
||||
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
|
||||
|
||||
/* Meta requires large data items to be 8 byte aligned. */
|
||||
#define ARCH_SLAB_MINALIGN 8
|
||||
|
||||
/*
|
||||
* With an L2 cache, we may invalidate dirty lines, so we need to ensure DMA
|
||||
* buffers have cache line alignment.
|
||||
*/
|
||||
#ifdef CONFIG_METAG_L2C
|
||||
#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
|
||||
#else
|
||||
#define ARCH_DMA_MINALIGN 8
|
||||
#endif
|
||||
|
||||
#define __read_mostly __attribute__((__section__(".data..read_mostly")))
|
||||
|
||||
#endif
|
@ -1,251 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _METAG_CACHEFLUSH_H
|
||||
#define _METAG_CACHEFLUSH_H
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/l2cache.h>
|
||||
#include <asm/metag_isa.h>
|
||||
#include <asm/metag_mem.h>
|
||||
|
||||
void metag_cache_probe(void);
|
||||
|
||||
void metag_data_cache_flush_all(const void *start);
|
||||
void metag_code_cache_flush_all(const void *start);
|
||||
|
||||
/*
|
||||
* Routines to flush physical cache lines that may be used to cache data or code
|
||||
* normally accessed via the linear address range supplied. The region flushed
|
||||
* must either lie in local or global address space determined by the top bit of
|
||||
* the pStart address. If Bytes is >= 4K then the whole of the related cache
|
||||
* state will be flushed rather than a limited range.
|
||||
*/
|
||||
void metag_data_cache_flush(const void *start, int bytes);
|
||||
void metag_code_cache_flush(const void *start, int bytes);
|
||||
|
||||
#ifdef CONFIG_METAG_META12
|
||||
|
||||
/* Write through, virtually tagged, split I/D cache. */
|
||||
|
||||
static inline void __flush_cache_all(void)
|
||||
{
|
||||
metag_code_cache_flush_all((void *) PAGE_OFFSET);
|
||||
metag_data_cache_flush_all((void *) PAGE_OFFSET);
|
||||
}
|
||||
|
||||
#define flush_cache_all() __flush_cache_all()
|
||||
|
||||
/* flush the entire user address space referenced in this mm structure */
|
||||
static inline void flush_cache_mm(struct mm_struct *mm)
|
||||
{
|
||||
if (mm == current->mm)
|
||||
__flush_cache_all();
|
||||
}
|
||||
|
||||
#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
|
||||
|
||||
/* flush a range of addresses from this mm */
|
||||
static inline void flush_cache_range(struct vm_area_struct *vma,
|
||||
unsigned long start, unsigned long end)
|
||||
{
|
||||
flush_cache_mm(vma->vm_mm);
|
||||
}
|
||||
|
||||
static inline void flush_cache_page(struct vm_area_struct *vma,
|
||||
unsigned long vmaddr, unsigned long pfn)
|
||||
{
|
||||
flush_cache_mm(vma->vm_mm);
|
||||
}
|
||||
|
||||
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
|
||||
static inline void flush_dcache_page(struct page *page)
|
||||
{
|
||||
metag_data_cache_flush_all((void *) PAGE_OFFSET);
|
||||
}
|
||||
|
||||
#define flush_dcache_mmap_lock(mapping) do { } while (0)
|
||||
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
|
||||
|
||||
static inline void flush_icache_page(struct vm_area_struct *vma,
|
||||
struct page *page)
|
||||
{
|
||||
metag_code_cache_flush(page_to_virt(page), PAGE_SIZE);
|
||||
}
|
||||
|
||||
static inline void flush_cache_vmap(unsigned long start, unsigned long end)
|
||||
{
|
||||
metag_data_cache_flush_all((void *) PAGE_OFFSET);
|
||||
}
|
||||
|
||||
static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
|
||||
{
|
||||
metag_data_cache_flush_all((void *) PAGE_OFFSET);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Write through, physically tagged, split I/D cache. */
|
||||
|
||||
#define flush_cache_all() do { } while (0)
|
||||
#define flush_cache_mm(mm) do { } while (0)
|
||||
#define flush_cache_dup_mm(mm) do { } while (0)
|
||||
#define flush_cache_range(vma, start, end) do { } while (0)
|
||||
#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
|
||||
#define flush_dcache_mmap_lock(mapping) do { } while (0)
|
||||
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
|
||||
#define flush_icache_page(vma, pg) do { } while (0)
|
||||
#define flush_cache_vmap(start, end) do { } while (0)
|
||||
#define flush_cache_vunmap(start, end) do { } while (0)
|
||||
|
||||
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
|
||||
static inline void flush_dcache_page(struct page *page)
|
||||
{
|
||||
/* FIXME: We can do better than this. All we are trying to do is
|
||||
* make the i-cache coherent, we should use the PG_arch_1 bit like
|
||||
* e.g. powerpc.
|
||||
*/
|
||||
#ifdef CONFIG_SMP
|
||||
metag_out32(1, SYSC_ICACHE_FLUSH);
|
||||
#else
|
||||
metag_code_cache_flush_all((void *) PAGE_OFFSET);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Push n pages at kernel virtual address and clear the icache */
|
||||
static inline void flush_icache_range(unsigned long address,
|
||||
unsigned long endaddr)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
metag_out32(1, SYSC_ICACHE_FLUSH);
|
||||
#else
|
||||
metag_code_cache_flush((void *) address, endaddr - address);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void flush_cache_sigtramp(unsigned long addr, int size)
|
||||
{
|
||||
/*
|
||||
* Flush the icache in case there was previously some code
|
||||
* fetched from this address, perhaps a previous sigtramp.
|
||||
*
|
||||
* We don't need to flush the dcache, it's write through and
|
||||
* we just wrote the sigtramp code through it.
|
||||
*/
|
||||
#ifdef CONFIG_SMP
|
||||
metag_out32(1, SYSC_ICACHE_FLUSH);
|
||||
#else
|
||||
metag_code_cache_flush((void *) addr, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_METAG_L2C
|
||||
|
||||
/*
|
||||
* Perform a single specific CACHEWD operation on an address, masking lower bits
|
||||
* of address first.
|
||||
*/
|
||||
static inline void cachewd_line(void *addr, unsigned int data)
|
||||
{
|
||||
unsigned long masked = (unsigned long)addr & -0x40;
|
||||
__builtin_meta2_cachewd((void *)masked, data);
|
||||
}
|
||||
|
||||
/* Perform a certain CACHEW op on each cache line in a range */
|
||||
static inline void cachew_region_op(void *start, unsigned long size,
|
||||
unsigned int op)
|
||||
{
|
||||
unsigned long offset = (unsigned long)start & 0x3f;
|
||||
int i;
|
||||
if (offset) {
|
||||
size += offset;
|
||||
start -= offset;
|
||||
}
|
||||
i = (size - 1) >> 6;
|
||||
do {
|
||||
__builtin_meta2_cachewd(start, op);
|
||||
start += 0x40;
|
||||
} while (i--);
|
||||
}
|
||||
|
||||
/* prevent write fence and flushbacks being reordered in L2 */
|
||||
static inline void l2c_fence_flush(void *addr)
|
||||
{
|
||||
/*
|
||||
* Synchronise by reading back and re-flushing.
|
||||
* It is assumed this access will miss, as the caller should have just
|
||||
* flushed the cache line.
|
||||
*/
|
||||
(void)(volatile u8 *)addr;
|
||||
cachewd_line(addr, CACHEW_FLUSH_L1D_L2);
|
||||
}
|
||||
|
||||
/* prevent write fence and writebacks being reordered in L2 */
|
||||
static inline void l2c_fence(void *addr)
|
||||
{
|
||||
/*
|
||||
* A write back has occurred, but not necessarily an invalidate, so the
|
||||
* readback in l2c_fence_flush() would hit in the cache and have no
|
||||
* effect. Therefore fully flush the line first.
|
||||
*/
|
||||
cachewd_line(addr, CACHEW_FLUSH_L1D_L2);
|
||||
l2c_fence_flush(addr);
|
||||
}
|
||||
|
||||
/* Used to keep memory consistent when doing DMA. */
|
||||
static inline void flush_dcache_region(void *start, unsigned long size)
|
||||
{
|
||||
/* metag_data_cache_flush won't flush L2 cache lines if size >= 4096 */
|
||||
if (meta_l2c_is_enabled()) {
|
||||
cachew_region_op(start, size, CACHEW_FLUSH_L1D_L2);
|
||||
if (meta_l2c_is_writeback())
|
||||
l2c_fence_flush(start + size - 1);
|
||||
} else {
|
||||
metag_data_cache_flush(start, size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write back dirty lines to memory (or do nothing if no writeback caches) */
|
||||
static inline void writeback_dcache_region(void *start, unsigned long size)
|
||||
{
|
||||
if (meta_l2c_is_enabled() && meta_l2c_is_writeback()) {
|
||||
cachew_region_op(start, size, CACHEW_WRITEBACK_L1D_L2);
|
||||
l2c_fence(start + size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Invalidate (may also write back if necessary) */
|
||||
static inline void invalidate_dcache_region(void *start, unsigned long size)
|
||||
{
|
||||
if (meta_l2c_is_enabled())
|
||||
cachew_region_op(start, size, CACHEW_INVALIDATE_L1D_L2);
|
||||
else
|
||||
metag_data_cache_flush(start, size);
|
||||
}
|
||||
#else
|
||||
#define flush_dcache_region(s, l) metag_data_cache_flush((s), (l))
|
||||
#define writeback_dcache_region(s, l) do {} while (0)
|
||||
#define invalidate_dcache_region(s, l) flush_dcache_region((s), (l))
|
||||
#endif
|
||||
|
||||
static inline void copy_to_user_page(struct vm_area_struct *vma,
|
||||
struct page *page, unsigned long vaddr,
|
||||
void *dst, const void *src,
|
||||
unsigned long len)
|
||||
{
|
||||
memcpy(dst, src, len);
|
||||
flush_icache_range((unsigned long)dst, (unsigned long)dst + len);
|
||||
}
|
||||
|
||||
static inline void copy_from_user_page(struct vm_area_struct *vma,
|
||||
struct page *page, unsigned long vaddr,
|
||||
void *dst, const void *src,
|
||||
unsigned long len)
|
||||
{
|
||||
memcpy(dst, src, len);
|
||||
}
|
||||
|
||||
#endif /* _METAG_CACHEFLUSH_H */
|
@ -1,43 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Meta cache partition manipulation.
|
||||
*
|
||||
* Copyright 2010 Imagination Technologies Ltd.
|
||||
*/
|
||||
|
||||
#ifndef _METAG_CACHEPART_H_
|
||||
#define _METAG_CACHEPART_H_
|
||||
|
||||
/**
|
||||
* get_dcache_size() - Get size of data cache.
|
||||
*/
|
||||
unsigned int get_dcache_size(void);
|
||||
|
||||
/**
|
||||
* get_icache_size() - Get size of code cache.
|
||||
*/
|
||||
unsigned int get_icache_size(void);
|
||||
|
||||
/**
|
||||
* get_global_dcache_size() - Get the thread's global dcache.
|
||||
*
|
||||
* Returns the size of the current thread's global dcache partition.
|
||||
*/
|
||||
unsigned int get_global_dcache_size(void);
|
||||
|
||||
/**
|
||||
* get_global_icache_size() - Get the thread's global icache.
|
||||
*
|
||||
* Returns the size of the current thread's global icache partition.
|
||||
*/
|
||||
unsigned int get_global_icache_size(void);
|
||||
|
||||
/**
|
||||
* check_for_dache_aliasing() - Ensure that the bootloader has configured the
|
||||
* dache and icache properly to avoid aliasing
|
||||
* @thread_id: Hardware thread ID
|
||||
*
|
||||
*/
|
||||
void check_for_cache_aliasing(int thread_id);
|
||||
|
||||
#endif
|
@ -1,93 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _METAG_CHECKSUM_H
|
||||
#define _METAG_CHECKSUM_H
|
||||
|
||||
/*
|
||||
* computes the checksum of a memory block at buff, length len,
|
||||
* and adds in "sum" (32-bit)
|
||||
*
|
||||
* returns a 32-bit number suitable for feeding into itself
|
||||
* or csum_tcpudp_magic
|
||||
*
|
||||
* this function must be called with even lengths, except
|
||||
* for the last fragment, which may be odd
|
||||
*
|
||||
* it's best to have buff aligned on a 32-bit boundary
|
||||
*/
|
||||
extern __wsum csum_partial(const void *buff, int len, __wsum sum);
|
||||
|
||||
/*
|
||||
* the same as csum_partial, but copies from src while it
|
||||
* checksums
|
||||
*
|
||||
* here even more important to align src and dst on a 32-bit (or even
|
||||
* better 64-bit) boundary
|
||||
*/
|
||||
extern __wsum csum_partial_copy(const void *src, void *dst, int len,
|
||||
__wsum sum);
|
||||
|
||||
/*
|
||||
* the same as csum_partial_copy, but copies from user space.
|
||||
*
|
||||
* here even more important to align src and dst on a 32-bit (or even
|
||||
* better 64-bit) boundary
|
||||
*/
|
||||
extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
|
||||
int len, __wsum sum, int *csum_err);
|
||||
|
||||
#define csum_partial_copy_nocheck(src, dst, len, sum) \
|
||||
csum_partial_copy((src), (dst), (len), (sum))
|
||||
|
||||
/*
|
||||
* Fold a partial checksum
|
||||
*/
|
||||
static inline __sum16 csum_fold(__wsum csum)
|
||||
{
|
||||
u32 sum = (__force u32)csum;
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
return (__force __sum16)~sum;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a version of ip_compute_csum() optimized for IP headers,
|
||||
* which always checksum on 4 octet boundaries.
|
||||
*/
|
||||
extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
|
||||
|
||||
/*
|
||||
* computes the checksum of the TCP/UDP pseudo-header
|
||||
* returns a 16-bit checksum, already complemented
|
||||
*/
|
||||
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
|
||||
__u32 len, __u8 proto,
|
||||
__wsum sum)
|
||||
{
|
||||
unsigned long len_proto = (proto + len) << 8;
|
||||
asm ("ADDS %0, %0, %1\n"
|
||||
"ADDCS %0, %0, #1\n"
|
||||
"ADDS %0, %0, %2\n"
|
||||
"ADDCS %0, %0, #1\n"
|
||||
"ADDS %0, %0, %3\n"
|
||||
"ADDCS %0, %0, #1\n"
|
||||
: "=d" (sum)
|
||||
: "d" (daddr), "d" (saddr), "d" (len_proto),
|
||||
"0" (sum)
|
||||
: "cc");
|
||||
return sum;
|
||||
}
|
||||
|
||||
static inline __sum16
|
||||
csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
|
||||
__u8 proto, __wsum sum)
|
||||
{
|
||||
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
|
||||
}
|
||||
|
||||
/*
|
||||
* this routine is used for miscellaneous IP-like checksums, mainly
|
||||
* in icmp.c
|
||||
*/
|
||||
extern __sum16 ip_compute_csum(const void *buff, int len);
|
||||
|
||||
#endif /* _METAG_CHECKSUM_H */
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* arch/metag/include/asm/clock.h
|
||||
*
|
||||
* Copyright (C) 2012 Imagination Technologies Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _METAG_CLOCK_H_
|
||||
#define _METAG_CLOCK_H_
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
/**
|
||||
* struct meta_clock_desc - Meta Core clock callbacks.
|
||||
* @get_core_freq: Get the frequency of the Meta core. If this is NULL, the
|
||||
* core frequency will be determined like this:
|
||||
* Meta 1: based on loops_per_jiffy.
|
||||
* Meta 2: (EXPAND_TIMER_DIV + 1) MHz.
|
||||
* If a "core" clock is provided by the device tree, it
|
||||
* will override this function.
|
||||
*/
|
||||
struct meta_clock_desc {
|
||||
unsigned long (*get_core_freq)(void);
|
||||
};
|
||||
|
||||
extern struct meta_clock_desc _meta_clock;
|
||||
|
||||
/*
|
||||
* Perform platform clock initialisation, reading clocks from device tree etc.
|
||||
* Only accessible during boot.
|
||||
*/
|
||||
void init_metag_clocks(void);
|
||||
|
||||
/*
|
||||
* Set up the default clock, ensuring all callbacks are valid - only accessible
|
||||
* during boot.
|
||||
*/
|
||||
void setup_meta_clocks(struct meta_clock_desc *desc);
|
||||
|
||||
/**
|
||||
* get_coreclock() - Get the frequency of the Meta core clock.
|
||||
*
|
||||
* Returns: The Meta core clock frequency in Hz.
|
||||
*/
|
||||
static inline unsigned long get_coreclock(void)
|
||||
{
|
||||
/*
|
||||
* Use the current clock callback. If set correctly this will provide
|
||||
* the most accurate frequency as it can be calculated directly from the
|
||||
* PLL configuration. otherwise a default callback will have been set
|
||||
* instead.
|
||||
*/
|
||||
return _meta_clock.get_core_freq();
|
||||
}
|
||||
|
||||
#endif /* _METAG_CLOCK_H_ */
|
@ -1,64 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_CMPXCHG_H
|
||||
#define __ASM_METAG_CMPXCHG_H
|
||||
|
||||
#include <asm/barrier.h>
|
||||
|
||||
#if defined(CONFIG_METAG_ATOMICITY_IRQSOFF)
|
||||
#include <asm/cmpxchg_irq.h>
|
||||
#elif defined(CONFIG_METAG_ATOMICITY_LOCK1)
|
||||
#include <asm/cmpxchg_lock1.h>
|
||||
#elif defined(CONFIG_METAG_ATOMICITY_LNKGET)
|
||||
#include <asm/cmpxchg_lnkget.h>
|
||||
#endif
|
||||
|
||||
extern void __xchg_called_with_bad_pointer(void);
|
||||
|
||||
#define __xchg(ptr, x, size) \
|
||||
({ \
|
||||
unsigned long __xchg__res; \
|
||||
volatile void *__xchg_ptr = (ptr); \
|
||||
switch (size) { \
|
||||
case 4: \
|
||||
__xchg__res = xchg_u32(__xchg_ptr, x); \
|
||||
break; \
|
||||
case 1: \
|
||||
__xchg__res = xchg_u8(__xchg_ptr, x); \
|
||||
break; \
|
||||
default: \
|
||||
__xchg_called_with_bad_pointer(); \
|
||||
__xchg__res = x; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
__xchg__res; \
|
||||
})
|
||||
|
||||
#define xchg(ptr, x) \
|
||||
((__typeof__(*(ptr)))__xchg((ptr), (unsigned long)(x), sizeof(*(ptr))))
|
||||
|
||||
/* This function doesn't exist, so you'll get a linker error
|
||||
* if something tries to do an invalid cmpxchg(). */
|
||||
extern 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);
|
||||
}
|
||||
__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))); \
|
||||
})
|
||||
|
||||
#endif /* __ASM_METAG_CMPXCHG_H */
|
@ -1,43 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_CMPXCHG_IRQ_H
|
||||
#define __ASM_METAG_CMPXCHG_IRQ_H
|
||||
|
||||
#include <linux/irqflags.h>
|
||||
|
||||
static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val)
|
||||
{
|
||||
unsigned long flags, retval;
|
||||
|
||||
local_irq_save(flags);
|
||||
retval = *m;
|
||||
*m = val;
|
||||
local_irq_restore(flags);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val)
|
||||
{
|
||||
unsigned long flags, retval;
|
||||
|
||||
local_irq_save(flags);
|
||||
retval = *m;
|
||||
*m = val & 0xff;
|
||||
local_irq_restore(flags);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old,
|
||||
unsigned long new)
|
||||
{
|
||||
__u32 retval;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
retval = *m;
|
||||
if (retval == old)
|
||||
*m = new;
|
||||
local_irq_restore(flags); /* implies memory barrier */
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* __ASM_METAG_CMPXCHG_IRQ_H */
|
@ -1,87 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_CMPXCHG_LNKGET_H
|
||||
#define __ASM_METAG_CMPXCHG_LNKGET_H
|
||||
|
||||
static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val)
|
||||
{
|
||||
int temp, old;
|
||||
|
||||
smp_mb();
|
||||
|
||||
asm volatile (
|
||||
"1: LNKGETD %1, [%2]\n"
|
||||
" LNKSETD [%2], %3\n"
|
||||
" DEFR %0, TXSTAT\n"
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n"
|
||||
" CMPT %0, #HI(0x02000000)\n"
|
||||
" BNZ 1b\n"
|
||||
#ifdef CONFIG_METAG_LNKGET_AROUND_CACHE
|
||||
" DCACHE [%2], %0\n"
|
||||
#endif
|
||||
: "=&d" (temp), "=&d" (old)
|
||||
: "da" (m), "da" (val)
|
||||
: "cc"
|
||||
);
|
||||
|
||||
smp_mb();
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val)
|
||||
{
|
||||
int temp, old;
|
||||
|
||||
smp_mb();
|
||||
|
||||
asm volatile (
|
||||
"1: LNKGETD %1, [%2]\n"
|
||||
" LNKSETD [%2], %3\n"
|
||||
" DEFR %0, TXSTAT\n"
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n"
|
||||
" CMPT %0, #HI(0x02000000)\n"
|
||||
" BNZ 1b\n"
|
||||
#ifdef CONFIG_METAG_LNKGET_AROUND_CACHE
|
||||
" DCACHE [%2], %0\n"
|
||||
#endif
|
||||
: "=&d" (temp), "=&d" (old)
|
||||
: "da" (m), "da" (val & 0xff)
|
||||
: "cc"
|
||||
);
|
||||
|
||||
smp_mb();
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old,
|
||||
unsigned long new)
|
||||
{
|
||||
__u32 retval, temp;
|
||||
|
||||
smp_mb();
|
||||
|
||||
asm volatile (
|
||||
"1: LNKGETD %1, [%2]\n"
|
||||
" CMP %1, %3\n"
|
||||
" LNKSETDEQ [%2], %4\n"
|
||||
" BNE 2f\n"
|
||||
" DEFR %0, TXSTAT\n"
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n"
|
||||
" CMPT %0, #HI(0x02000000)\n"
|
||||
" BNZ 1b\n"
|
||||
#ifdef CONFIG_METAG_LNKGET_AROUND_CACHE
|
||||
" DCACHE [%2], %0\n"
|
||||
#endif
|
||||
"2:\n"
|
||||
: "=&d" (temp), "=&d" (retval)
|
||||
: "da" (m), "bd" (old), "da" (new)
|
||||
: "cc"
|
||||
);
|
||||
|
||||
smp_mb();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* __ASM_METAG_CMPXCHG_LNKGET_H */
|
@ -1,49 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_CMPXCHG_LOCK1_H
|
||||
#define __ASM_METAG_CMPXCHG_LOCK1_H
|
||||
|
||||
#include <asm/global_lock.h>
|
||||
|
||||
/* Use LOCK2 as these have to be atomic w.r.t. ordinary accesses. */
|
||||
|
||||
static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val)
|
||||
{
|
||||
unsigned long flags, retval;
|
||||
|
||||
__global_lock2(flags);
|
||||
fence();
|
||||
retval = *m;
|
||||
*m = val;
|
||||
__global_unlock2(flags);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val)
|
||||
{
|
||||
unsigned long flags, retval;
|
||||
|
||||
__global_lock2(flags);
|
||||
fence();
|
||||
retval = *m;
|
||||
*m = val & 0xff;
|
||||
__global_unlock2(flags);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old,
|
||||
unsigned long new)
|
||||
{
|
||||
__u32 retval;
|
||||
unsigned long flags;
|
||||
|
||||
__global_lock2(flags);
|
||||
retval = *m;
|
||||
if (retval == old) {
|
||||
fence();
|
||||
*m = new;
|
||||
}
|
||||
__global_unlock2(flags);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* __ASM_METAG_CMPXCHG_LOCK1_H */
|
@ -1,36 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_CORE_REG_H_
|
||||
#define __ASM_METAG_CORE_REG_H_
|
||||
|
||||
#include <asm/metag_regs.h>
|
||||
|
||||
extern void core_reg_write(int unit, int reg, int thread, unsigned int val);
|
||||
extern unsigned int core_reg_read(int unit, int reg, int thread);
|
||||
|
||||
/*
|
||||
* These macros allow direct access from C to any register known to the
|
||||
* assembler. Example candidates are TXTACTCYC, TXIDLECYC, and TXPRIVEXT.
|
||||
*/
|
||||
|
||||
#define __core_reg_get(reg) ({ \
|
||||
unsigned int __grvalue; \
|
||||
asm volatile("MOV %0," #reg \
|
||||
: "=r" (__grvalue)); \
|
||||
__grvalue; \
|
||||
})
|
||||
|
||||
#define __core_reg_set(reg, value) do { \
|
||||
unsigned int __srvalue = (value); \
|
||||
asm volatile("MOV " #reg ",%0" \
|
||||
: \
|
||||
: "r" (__srvalue)); \
|
||||
} while (0)
|
||||
|
||||
#define __core_reg_swap(reg, value) do { \
|
||||
unsigned int __srvalue = (value); \
|
||||
asm volatile("SWAP " #reg ",%0" \
|
||||
: "+r" (__srvalue)); \
|
||||
(value) = __srvalue; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
@ -1,15 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_METAG_CPU_H
|
||||
#define _ASM_METAG_CPU_H
|
||||
|
||||
#include <linux/percpu.h>
|
||||
|
||||
struct cpuinfo_metag {
|
||||
struct cpu cpu;
|
||||
#ifdef CONFIG_SMP
|
||||
unsigned long loops_per_jiffy;
|
||||
#endif
|
||||
};
|
||||
|
||||
DECLARE_PER_CPU(struct cpuinfo_metag, cpu_data);
|
||||
#endif /* _ASM_METAG_CPU_H */
|
@ -1,44 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Meta DA JTAG debugger control.
|
||||
*
|
||||
* Copyright 2012 Imagination Technologies Ltd.
|
||||
*/
|
||||
|
||||
#ifndef _METAG_DA_H_
|
||||
#define _METAG_DA_H_
|
||||
|
||||
#ifdef CONFIG_METAG_DA
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
extern bool _metag_da_present;
|
||||
|
||||
/**
|
||||
* metag_da_enabled() - Find whether a DA is currently enabled.
|
||||
*
|
||||
* Returns: true if a DA was detected, false if not.
|
||||
*/
|
||||
static inline bool metag_da_enabled(void)
|
||||
{
|
||||
return _metag_da_present;
|
||||
}
|
||||
|
||||
/**
|
||||
* metag_da_probe() - Try and detect a connected DA.
|
||||
*
|
||||
* This is used at start up to detect whether a DA is active.
|
||||
*
|
||||
* Returns: 0 on detection, -err otherwise.
|
||||
*/
|
||||
int __init metag_da_probe(void);
|
||||
|
||||
#else /* !CONFIG_METAG_DA */
|
||||
|
||||
#define metag_da_enabled() false
|
||||
#define metag_da_probe() do {} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _METAG_DA_H_ */
|
@ -1,30 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _METAG_DELAY_H
|
||||
#define _METAG_DELAY_H
|
||||
|
||||
/*
|
||||
* Copyright (C) 1993 Linus Torvalds
|
||||
*
|
||||
* Delay routines calling functions in arch/metag/lib/delay.c
|
||||
*/
|
||||
|
||||
/* Undefined functions to get compile-time errors */
|
||||
extern void __bad_udelay(void);
|
||||
extern void __bad_ndelay(void);
|
||||
|
||||
extern void __udelay(unsigned long usecs);
|
||||
extern void __ndelay(unsigned long nsecs);
|
||||
extern void __const_udelay(unsigned long xloops);
|
||||
extern void __delay(unsigned long loops);
|
||||
|
||||
/* 0x10c7 is 2**32 / 1000000 (rounded up) */
|
||||
#define udelay(n) (__builtin_constant_p(n) ? \
|
||||
((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
|
||||
__udelay(n))
|
||||
|
||||
/* 0x5 is 2**32 / 1000000000 (rounded up) */
|
||||
#define ndelay(n) (__builtin_constant_p(n) ? \
|
||||
((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
|
||||
__ndelay(n))
|
||||
|
||||
#endif /* _METAG_DELAY_H */
|
@ -1,13 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_DIV64_H__
|
||||
#define __ASM_DIV64_H__
|
||||
|
||||
#include <asm-generic/div64.h>
|
||||
|
||||
extern u64 div_u64(u64 dividend, u64 divisor);
|
||||
extern s64 div_s64(s64 dividend, s64 divisor);
|
||||
|
||||
#define div_u64 div_u64
|
||||
#define div_s64 div_s64
|
||||
|
||||
#endif
|
@ -1,12 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_METAG_DMA_MAPPING_H
|
||||
#define _ASM_METAG_DMA_MAPPING_H
|
||||
|
||||
extern const struct dma_map_ops metag_dma_ops;
|
||||
|
||||
static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
|
||||
{
|
||||
return &metag_dma_ops;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,126 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_ELF_H
|
||||
#define __ASM_METAG_ELF_H
|
||||
|
||||
#define EM_METAG 174
|
||||
|
||||
/* Meta relocations */
|
||||
#define R_METAG_HIADDR16 0
|
||||
#define R_METAG_LOADDR16 1
|
||||
#define R_METAG_ADDR32 2
|
||||
#define R_METAG_NONE 3
|
||||
#define R_METAG_RELBRANCH 4
|
||||
#define R_METAG_GETSETOFF 5
|
||||
|
||||
/* Backward compatibility */
|
||||
#define R_METAG_REG32OP1 6
|
||||
#define R_METAG_REG32OP2 7
|
||||
#define R_METAG_REG32OP3 8
|
||||
#define R_METAG_REG16OP1 9
|
||||
#define R_METAG_REG16OP2 10
|
||||
#define R_METAG_REG16OP3 11
|
||||
#define R_METAG_REG32OP4 12
|
||||
|
||||
#define R_METAG_HIOG 13
|
||||
#define R_METAG_LOOG 14
|
||||
|
||||
/* GNU */
|
||||
#define R_METAG_GNU_VTINHERIT 30
|
||||
#define R_METAG_GNU_VTENTRY 31
|
||||
|
||||
/* PIC relocations */
|
||||
#define R_METAG_HI16_GOTOFF 32
|
||||
#define R_METAG_LO16_GOTOFF 33
|
||||
#define R_METAG_GETSET_GOTOFF 34
|
||||
#define R_METAG_GETSET_GOT 35
|
||||
#define R_METAG_HI16_GOTPC 36
|
||||
#define R_METAG_LO16_GOTPC 37
|
||||
#define R_METAG_HI16_PLT 38
|
||||
#define R_METAG_LO16_PLT 39
|
||||
#define R_METAG_RELBRANCH_PLT 40
|
||||
#define R_METAG_GOTOFF 41
|
||||
#define R_METAG_PLT 42
|
||||
#define R_METAG_COPY 43
|
||||
#define R_METAG_JMP_SLOT 44
|
||||
#define R_METAG_RELATIVE 45
|
||||
#define R_METAG_GLOB_DAT 46
|
||||
|
||||
/*
|
||||
* ELF register definitions.
|
||||
*/
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/user.h>
|
||||
|
||||
typedef unsigned long elf_greg_t;
|
||||
|
||||
#define ELF_NGREG (sizeof(struct user_gp_regs) / sizeof(elf_greg_t))
|
||||
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||
|
||||
typedef unsigned long elf_fpregset_t;
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch(x) ((x)->e_machine == EM_METAG)
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
*/
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_DATA ELFDATA2LSB
|
||||
#define ELF_ARCH EM_METAG
|
||||
|
||||
#define ELF_PLAT_INIT(_r, load_addr) \
|
||||
do { _r->ctx.AX[0].U0 = 0; } while (0)
|
||||
|
||||
#define USE_ELF_CORE_DUMP
|
||||
#define CORE_DUMP_USE_REGSET
|
||||
#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 0x08000000UL
|
||||
|
||||
#define ELF_CORE_COPY_REGS(_dest, _regs) \
|
||||
memcpy((char *)&_dest, (char *)_regs, sizeof(struct pt_regs));
|
||||
|
||||
/* This yields a mask that user programs can use to figure out what
|
||||
instruction set this cpu supports. */
|
||||
|
||||
#define ELF_HWCAP (0)
|
||||
|
||||
/* This yields a string that ld.so will use to load implementation
|
||||
specific libraries for optimization. This is more specific in
|
||||
intent than poking at uname or /proc/cpuinfo. */
|
||||
|
||||
#define ELF_PLATFORM (NULL)
|
||||
|
||||
#define STACK_RND_MASK (0)
|
||||
|
||||
#ifdef CONFIG_METAG_USER_TCM
|
||||
|
||||
struct elf32_phdr;
|
||||
struct file;
|
||||
|
||||
unsigned long __metag_elf_map(struct file *filep, unsigned long addr,
|
||||
struct elf32_phdr *eppnt, int prot, int type,
|
||||
unsigned long total_size);
|
||||
|
||||
static inline unsigned long metag_elf_map(struct file *filep,
|
||||
unsigned long addr,
|
||||
struct elf32_phdr *eppnt, int prot,
|
||||
int type, unsigned long total_size)
|
||||
{
|
||||
return __metag_elf_map(filep, addr, eppnt, prot, type, total_size);
|
||||
}
|
||||
#define elf_map metag_elf_map
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* fixmap.h: compile-time virtual memory allocation
|
||||
*
|
||||
* 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) 1998 Ingo Molnar
|
||||
*
|
||||
* Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
|
||||
*/
|
||||
|
||||
#ifndef _ASM_FIXMAP_H
|
||||
#define _ASM_FIXMAP_H
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
#include <linux/threads.h>
|
||||
#include <asm/kmap_types.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Here we define all the compile-time 'special' virtual
|
||||
* addresses. The point is to have a constant address at
|
||||
* compile time, but to set the physical address only
|
||||
* in the boot process. We allocate these special addresses
|
||||
* from the end of the consistent memory region backwards.
|
||||
* Also this lets us do fail-safe vmalloc(), we
|
||||
* can guarantee that these special addresses and
|
||||
* vmalloc()-ed addresses never overlap.
|
||||
*
|
||||
* these 'compile-time allocated' memory buffers are
|
||||
* fixed-size 4k pages. (or larger if used with an increment
|
||||
* higher than 1) use fixmap_set(idx,phys) to associate
|
||||
* physical memory with fixmap indices.
|
||||
*
|
||||
* TLB entries of such buffers will not be flushed across
|
||||
* task switches.
|
||||
*/
|
||||
enum fixed_addresses {
|
||||
#define FIX_N_COLOURS 8
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
/* reserved pte's for temporary kernel mappings */
|
||||
FIX_KMAP_BEGIN,
|
||||
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
|
||||
#endif
|
||||
__end_of_fixed_addresses
|
||||
};
|
||||
|
||||
#define FIXADDR_TOP (CONSISTENT_START - PAGE_SIZE)
|
||||
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
|
||||
#define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK)
|
||||
|
||||
#include <asm-generic/fixmap.h>
|
||||
|
||||
#define kmap_get_fixmap_pte(vaddr) \
|
||||
pte_offset_kernel( \
|
||||
pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), \
|
||||
(vaddr) \
|
||||
)
|
||||
|
||||
/*
|
||||
* Called from pgtable_init()
|
||||
*/
|
||||
extern void fixrange_init(unsigned long start, unsigned long end,
|
||||
pgd_t *pgd_base);
|
||||
|
||||
|
||||
#endif
|
@ -1,24 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_METAG_FTRACE
|
||||
#define _ASM_METAG_FTRACE
|
||||
|
||||
#ifdef CONFIG_FUNCTION_TRACER
|
||||
#define MCOUNT_INSN_SIZE 8 /* sizeof mcount call */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern void mcount_wrapper(void);
|
||||
#define MCOUNT_ADDR ((unsigned long)(mcount_wrapper))
|
||||
|
||||
static inline unsigned long ftrace_call_adjust(unsigned long addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
struct dyn_arch_ftrace {
|
||||
/* No extra data needed on metag */
|
||||
};
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* CONFIG_FUNCTION_TRACER */
|
||||
|
||||
#endif /* _ASM_METAG_FTRACE */
|
@ -1,101 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_GLOBAL_LOCK_H
|
||||
#define __ASM_METAG_GLOBAL_LOCK_H
|
||||
|
||||
#include <asm/metag_mem.h>
|
||||
|
||||
/**
|
||||
* __global_lock1() - Acquire global voluntary lock (LOCK1).
|
||||
* @flags: Variable to store flags into.
|
||||
*
|
||||
* Acquires the Meta global voluntary lock (LOCK1), also taking care to disable
|
||||
* all triggers so we cannot be interrupted, and to enforce a compiler barrier
|
||||
* so that the compiler cannot reorder memory accesses across the lock.
|
||||
*
|
||||
* No other hardware thread will be able to acquire the voluntary or exclusive
|
||||
* locks until the voluntary lock is released with @__global_unlock1, but they
|
||||
* may continue to execute as long as they aren't trying to acquire either of
|
||||
* the locks.
|
||||
*/
|
||||
#define __global_lock1(flags) do { \
|
||||
unsigned int __trval; \
|
||||
asm volatile("MOV %0,#0\n\t" \
|
||||
"SWAP %0,TXMASKI\n\t" \
|
||||
"LOCK1" \
|
||||
: "=r" (__trval) \
|
||||
: \
|
||||
: "memory"); \
|
||||
(flags) = __trval; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* __global_unlock1() - Release global voluntary lock (LOCK1).
|
||||
* @flags: Variable to restore flags from.
|
||||
*
|
||||
* Releases the Meta global voluntary lock (LOCK1) acquired with
|
||||
* @__global_lock1, also taking care to re-enable triggers, and to enforce a
|
||||
* compiler barrier so that the compiler cannot reorder memory accesses across
|
||||
* the unlock.
|
||||
*
|
||||
* This immediately allows another hardware thread to acquire the voluntary or
|
||||
* exclusive locks.
|
||||
*/
|
||||
#define __global_unlock1(flags) do { \
|
||||
unsigned int __trval = (flags); \
|
||||
asm volatile("LOCK0\n\t" \
|
||||
"MOV TXMASKI,%0" \
|
||||
: \
|
||||
: "r" (__trval) \
|
||||
: "memory"); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* __global_lock2() - Acquire global exclusive lock (LOCK2).
|
||||
* @flags: Variable to store flags into.
|
||||
*
|
||||
* Acquires the Meta global voluntary lock and global exclusive lock (LOCK2),
|
||||
* also taking care to disable all triggers so we cannot be interrupted, to take
|
||||
* the atomic lock (system event) and to enforce a compiler barrier so that the
|
||||
* compiler cannot reorder memory accesses across the lock.
|
||||
*
|
||||
* No other hardware thread will be able to execute code until the locks are
|
||||
* released with @__global_unlock2.
|
||||
*/
|
||||
#define __global_lock2(flags) do { \
|
||||
unsigned int __trval; \
|
||||
unsigned int __aloc_hi = LINSYSEVENT_WR_ATOMIC_LOCK & 0xFFFF0000; \
|
||||
asm volatile("MOV %0,#0\n\t" \
|
||||
"SWAP %0,TXMASKI\n\t" \
|
||||
"LOCK2\n\t" \
|
||||
"SETD [%1+#0x40],D1RtP" \
|
||||
: "=r&" (__trval) \
|
||||
: "u" (__aloc_hi) \
|
||||
: "memory"); \
|
||||
(flags) = __trval; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* __global_unlock2() - Release global exclusive lock (LOCK2).
|
||||
* @flags: Variable to restore flags from.
|
||||
*
|
||||
* Releases the Meta global exclusive lock (LOCK2) and global voluntary lock
|
||||
* acquired with @__global_lock2, also taking care to release the atomic lock
|
||||
* (system event), re-enable triggers, and to enforce a compiler barrier so that
|
||||
* the compiler cannot reorder memory accesses across the unlock.
|
||||
*
|
||||
* This immediately allows other hardware threads to continue executing and one
|
||||
* of them to acquire locks.
|
||||
*/
|
||||
#define __global_unlock2(flags) do { \
|
||||
unsigned int __trval = (flags); \
|
||||
unsigned int __alock_hi = LINSYSEVENT_WR_ATOMIC_LOCK & 0xFFFF0000; \
|
||||
asm volatile("SETD [%1+#0x00],D1RtP\n\t" \
|
||||
"LOCK0\n\t" \
|
||||
"MOV TXMASKI,%0" \
|
||||
: \
|
||||
: "r" (__trval), \
|
||||
"u" (__alock_hi) \
|
||||
: "memory"); \
|
||||
} while (0)
|
||||
|
||||
#endif /* __ASM_METAG_GLOBAL_LOCK_H */
|
@ -1,62 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_HIGHMEM_H
|
||||
#define _ASM_HIGHMEM_H
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/kmap_types.h>
|
||||
#include <asm/fixmap.h>
|
||||
|
||||
/*
|
||||
* Right now we initialize only a single pte table. It can be extended
|
||||
* easily, subsequent pte tables have to be allocated in one physical
|
||||
* chunk of RAM.
|
||||
*/
|
||||
/*
|
||||
* Ordering is (from lower to higher memory addresses):
|
||||
*
|
||||
* high_memory
|
||||
* Persistent kmap area
|
||||
* PKMAP_BASE
|
||||
* fixed_addresses
|
||||
* FIXADDR_START
|
||||
* FIXADDR_TOP
|
||||
* Vmalloc area
|
||||
* VMALLOC_START
|
||||
* VMALLOC_END
|
||||
*/
|
||||
#define PKMAP_BASE (FIXADDR_START - PMD_SIZE)
|
||||
#define LAST_PKMAP PTRS_PER_PTE
|
||||
#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
|
||||
#define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT)
|
||||
#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
|
||||
|
||||
#define kmap_prot PAGE_KERNEL
|
||||
|
||||
static inline void flush_cache_kmaps(void)
|
||||
{
|
||||
flush_cache_all();
|
||||
}
|
||||
|
||||
/* declarations for highmem.c */
|
||||
extern unsigned long highstart_pfn, highend_pfn;
|
||||
|
||||
extern pte_t *pkmap_page_table;
|
||||
|
||||
extern void *kmap_high(struct page *page);
|
||||
extern void kunmap_high(struct page *page);
|
||||
|
||||
extern void kmap_init(void);
|
||||
|
||||
/*
|
||||
* The following functions are already defined by <linux/highmem.h>
|
||||
* when CONFIG_HIGHMEM is not set.
|
||||
*/
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
extern void *kmap(struct page *page);
|
||||
extern void kunmap(struct page *page);
|
||||
extern void *kmap_atomic(struct page *page);
|
||||
extern void __kunmap_atomic(void *kvaddr);
|
||||
extern void *kmap_atomic_pfn(unsigned long pfn);
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,75 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_METAG_HUGETLB_H
|
||||
#define _ASM_METAG_HUGETLB_H
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm-generic/hugetlb.h>
|
||||
|
||||
|
||||
static inline int is_hugepage_only_range(struct mm_struct *mm,
|
||||
unsigned long addr,
|
||||
unsigned long len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int prepare_hugepage_range(struct file *file, unsigned long addr,
|
||||
unsigned long len);
|
||||
|
||||
static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
|
||||
unsigned long addr, unsigned long end,
|
||||
unsigned long floor,
|
||||
unsigned long ceiling)
|
||||
{
|
||||
free_pgd_range(tlb, addr, end, floor, ceiling);
|
||||
}
|
||||
|
||||
static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep, pte_t pte)
|
||||
{
|
||||
set_pte_at(mm, addr, ptep, pte);
|
||||
}
|
||||
|
||||
static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
return ptep_get_and_clear(mm, addr, ptep);
|
||||
}
|
||||
|
||||
static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int huge_pte_none(pte_t pte)
|
||||
{
|
||||
return pte_none(pte);
|
||||
}
|
||||
|
||||
static inline pte_t huge_pte_wrprotect(pte_t pte)
|
||||
{
|
||||
return pte_wrprotect(pte);
|
||||
}
|
||||
|
||||
static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
ptep_set_wrprotect(mm, addr, ptep);
|
||||
}
|
||||
|
||||
static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep,
|
||||
pte_t pte, int dirty)
|
||||
{
|
||||
return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
|
||||
}
|
||||
|
||||
static inline pte_t huge_ptep_get(pte_t *ptep)
|
||||
{
|
||||
return *ptep;
|
||||
}
|
||||
|
||||
static inline void arch_clear_hugepage_flags(struct page *page)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* _ASM_METAG_HUGETLB_H */
|
@ -1,41 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2008 Imagination Technologies
|
||||
*/
|
||||
#ifndef __METAG_HWTHREAD_H
|
||||
#define __METAG_HWTHREAD_H
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/metag_mem.h>
|
||||
|
||||
#define BAD_HWTHREAD_ID (0xFFU)
|
||||
#define BAD_CPU_ID (0xFFU)
|
||||
|
||||
extern u8 cpu_2_hwthread_id[];
|
||||
extern u8 hwthread_id_2_cpu[];
|
||||
|
||||
/*
|
||||
* Each hardware thread's Control Unit registers are memory-mapped
|
||||
* and can therefore be accessed by any other hardware thread.
|
||||
*
|
||||
* This helper function returns the memory address where "thread"'s
|
||||
* register "regnum" is mapped.
|
||||
*/
|
||||
static inline
|
||||
void __iomem *__CU_addr(unsigned int thread, unsigned int regnum)
|
||||
{
|
||||
unsigned int base, thread_offset, thread_regnum;
|
||||
|
||||
WARN_ON(thread == BAD_HWTHREAD_ID);
|
||||
|
||||
base = T0UCTREG0; /* Control unit base */
|
||||
|
||||
thread_offset = TnUCTRX_STRIDE * thread;
|
||||
thread_regnum = TXUCTREGn_STRIDE * regnum;
|
||||
|
||||
return (void __iomem *)(base + thread_offset + thread_regnum);
|
||||
}
|
||||
|
||||
#endif /* __METAG_HWTHREAD_H */
|
@ -1,170 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_METAG_IO_H
|
||||
#define _ASM_METAG_IO_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/pgtable-bits.h>
|
||||
|
||||
#define IO_SPACE_LIMIT 0
|
||||
|
||||
#define page_to_bus page_to_phys
|
||||
#define bus_to_page phys_to_page
|
||||
|
||||
/*
|
||||
* Generic I/O
|
||||
*/
|
||||
|
||||
#define __raw_readb __raw_readb
|
||||
static inline u8 __raw_readb(const volatile void __iomem *addr)
|
||||
{
|
||||
u8 ret;
|
||||
asm volatile("GETB %0,[%1]"
|
||||
: "=da" (ret)
|
||||
: "da" (addr)
|
||||
: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define __raw_readw __raw_readw
|
||||
static inline u16 __raw_readw(const volatile void __iomem *addr)
|
||||
{
|
||||
u16 ret;
|
||||
asm volatile("GETW %0,[%1]"
|
||||
: "=da" (ret)
|
||||
: "da" (addr)
|
||||
: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define __raw_readl __raw_readl
|
||||
static inline u32 __raw_readl(const volatile void __iomem *addr)
|
||||
{
|
||||
u32 ret;
|
||||
asm volatile("GETD %0,[%1]"
|
||||
: "=da" (ret)
|
||||
: "da" (addr)
|
||||
: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define __raw_readq __raw_readq
|
||||
static inline u64 __raw_readq(const volatile void __iomem *addr)
|
||||
{
|
||||
u64 ret;
|
||||
asm volatile("GETL %0,%t0,[%1]"
|
||||
: "=da" (ret)
|
||||
: "da" (addr)
|
||||
: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define __raw_writeb __raw_writeb
|
||||
static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
|
||||
{
|
||||
asm volatile("SETB [%0],%1"
|
||||
:
|
||||
: "da" (addr),
|
||||
"da" (b)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#define __raw_writew __raw_writew
|
||||
static inline void __raw_writew(u16 b, volatile void __iomem *addr)
|
||||
{
|
||||
asm volatile("SETW [%0],%1"
|
||||
:
|
||||
: "da" (addr),
|
||||
"da" (b)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#define __raw_writel __raw_writel
|
||||
static inline void __raw_writel(u32 b, volatile void __iomem *addr)
|
||||
{
|
||||
asm volatile("SETD [%0],%1"
|
||||
:
|
||||
: "da" (addr),
|
||||
"da" (b)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#define __raw_writeq __raw_writeq
|
||||
static inline void __raw_writeq(u64 b, volatile void __iomem *addr)
|
||||
{
|
||||
asm volatile("SETL [%0],%1,%t1"
|
||||
:
|
||||
: "da" (addr),
|
||||
"da" (b)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
/*
|
||||
* The generic io.h can define all the other generic accessors
|
||||
*/
|
||||
|
||||
#include <asm-generic/io.h>
|
||||
|
||||
/*
|
||||
* Despite being a 32bit architecture, Meta can do 64bit memory accesses
|
||||
* (assuming the bus supports it).
|
||||
*/
|
||||
|
||||
#define readq __raw_readq
|
||||
#define writeq __raw_writeq
|
||||
|
||||
/*
|
||||
* Meta specific I/O for accessing non-MMU areas.
|
||||
*
|
||||
* These can be provided with a physical address rather than an __iomem pointer
|
||||
* and should only be used by core architecture code for accessing fixed core
|
||||
* registers. Generic drivers should use ioremap and the generic I/O accessors.
|
||||
*/
|
||||
|
||||
#define metag_in8(addr) __raw_readb((volatile void __iomem *)(addr))
|
||||
#define metag_in16(addr) __raw_readw((volatile void __iomem *)(addr))
|
||||
#define metag_in32(addr) __raw_readl((volatile void __iomem *)(addr))
|
||||
#define metag_in64(addr) __raw_readq((volatile void __iomem *)(addr))
|
||||
|
||||
#define metag_out8(b, addr) __raw_writeb(b, (volatile void __iomem *)(addr))
|
||||
#define metag_out16(b, addr) __raw_writew(b, (volatile void __iomem *)(addr))
|
||||
#define metag_out32(b, addr) __raw_writel(b, (volatile void __iomem *)(addr))
|
||||
#define metag_out64(b, addr) __raw_writeq(b, (volatile void __iomem *)(addr))
|
||||
|
||||
/*
|
||||
* io remapping functions
|
||||
*/
|
||||
|
||||
extern void __iomem *__ioremap(unsigned long offset,
|
||||
size_t size, unsigned long flags);
|
||||
extern void __iounmap(void __iomem *addr);
|
||||
|
||||
/**
|
||||
* ioremap - map bus memory into CPU space
|
||||
* @offset: bus address of the memory
|
||||
* @size: size of the resource to map
|
||||
*
|
||||
* ioremap performs a platform specific sequence of operations to
|
||||
* make bus memory CPU accessible via the readb/readw/readl/writeb/
|
||||
* writew/writel functions and the other mmio helpers. The returned
|
||||
* address is not guaranteed to be usable directly as a virtual
|
||||
* address.
|
||||
*/
|
||||
#define ioremap(offset, size) \
|
||||
__ioremap((offset), (size), 0)
|
||||
|
||||
#define ioremap_nocache(offset, size) \
|
||||
__ioremap((offset), (size), 0)
|
||||
|
||||
#define ioremap_cached(offset, size) \
|
||||
__ioremap((offset), (size), _PAGE_CACHEABLE)
|
||||
|
||||
#define ioremap_wc(offset, size) \
|
||||
__ioremap((offset), (size), _PAGE_WR_COMBINE)
|
||||
|
||||
#define ioremap_wt(offset, size) \
|
||||
__ioremap((offset), (size), 0)
|
||||
|
||||
#define iounmap(addr) \
|
||||
__iounmap(addr)
|
||||
|
||||
#endif /* _ASM_METAG_IO_H */
|
@ -1,38 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_IRQ_H
|
||||
#define __ASM_METAG_IRQ_H
|
||||
|
||||
#ifdef CONFIG_4KSTACKS
|
||||
extern void irq_ctx_init(int cpu);
|
||||
extern void irq_ctx_exit(int cpu);
|
||||
# define __ARCH_HAS_DO_SOFTIRQ
|
||||
#else
|
||||
static inline void irq_ctx_init(int cpu)
|
||||
{
|
||||
}
|
||||
static inline void irq_ctx_exit(int cpu)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void tbi_startup_interrupt(int);
|
||||
void tbi_shutdown_interrupt(int);
|
||||
|
||||
struct pt_regs;
|
||||
|
||||
int tbisig_map(unsigned int hw);
|
||||
extern void do_IRQ(int irq, struct pt_regs *regs);
|
||||
extern void init_IRQ(void);
|
||||
|
||||
#ifdef CONFIG_METAG_SUSPEND_MEM
|
||||
int traps_save_context(void);
|
||||
int traps_restore_context(void);
|
||||
#endif
|
||||
|
||||
#include <asm-generic/irq.h>
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
extern void migrate_irqs(void);
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_METAG_IRQ_H */
|
@ -1,94 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* IRQ flags handling
|
||||
*
|
||||
* This file gets included from lowlevel asm headers too, to provide
|
||||
* wrapped versions of the local_irq_*() APIs, based on the
|
||||
* raw_local_irq_*() functions from the lowlevel headers.
|
||||
*/
|
||||
#ifndef _ASM_IRQFLAGS_H
|
||||
#define _ASM_IRQFLAGS_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <asm/core_reg.h>
|
||||
#include <asm/metag_regs.h>
|
||||
|
||||
#define INTS_OFF_MASK TXSTATI_BGNDHALT_BIT
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
extern unsigned int get_trigger_mask(void);
|
||||
#else
|
||||
|
||||
extern unsigned int global_trigger_mask;
|
||||
|
||||
static inline unsigned int get_trigger_mask(void)
|
||||
{
|
||||
return global_trigger_mask;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline unsigned long arch_local_save_flags(void)
|
||||
{
|
||||
return __core_reg_get(TXMASKI);
|
||||
}
|
||||
|
||||
static inline int arch_irqs_disabled_flags(unsigned long flags)
|
||||
{
|
||||
return (flags & ~INTS_OFF_MASK) == 0;
|
||||
}
|
||||
|
||||
static inline int arch_irqs_disabled(void)
|
||||
{
|
||||
unsigned long flags = arch_local_save_flags();
|
||||
|
||||
return arch_irqs_disabled_flags(flags);
|
||||
}
|
||||
|
||||
static inline unsigned long __irqs_disabled(void)
|
||||
{
|
||||
/*
|
||||
* We shouldn't enable exceptions if they are not already
|
||||
* enabled. This is required for chancalls to work correctly.
|
||||
*/
|
||||
return arch_local_save_flags() & INTS_OFF_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* For spinlocks, etc:
|
||||
*/
|
||||
static inline unsigned long arch_local_irq_save(void)
|
||||
{
|
||||
unsigned long flags = __irqs_disabled();
|
||||
|
||||
asm volatile("SWAP %0,TXMASKI\n" : "=r" (flags) : "0" (flags)
|
||||
: "memory");
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static inline void arch_local_irq_restore(unsigned long flags)
|
||||
{
|
||||
asm volatile("MOV TXMASKI,%0\n" : : "r" (flags) : "memory");
|
||||
}
|
||||
|
||||
static inline void arch_local_irq_disable(void)
|
||||
{
|
||||
unsigned long flags = __irqs_disabled();
|
||||
|
||||
asm volatile("MOV TXMASKI,%0\n" : : "r" (flags) : "memory");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Avoid circular include dependencies through <linux/preempt.h> */
|
||||
void arch_local_irq_enable(void);
|
||||
#else
|
||||
static inline void arch_local_irq_enable(void)
|
||||
{
|
||||
arch_local_irq_restore(get_trigger_mask());
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* (__ASSEMBLY__) */
|
||||
|
||||
#endif /* !(_ASM_IRQFLAGS_H) */
|
@ -1,259 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _METAG_L2CACHE_H
|
||||
#define _METAG_L2CACHE_H
|
||||
|
||||
#ifdef CONFIG_METAG_L2C
|
||||
|
||||
#include <asm/global_lock.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/*
|
||||
* Store the last known value of pfenable (we don't want prefetch enabled while
|
||||
* L2 is off).
|
||||
*/
|
||||
extern int l2c_pfenable;
|
||||
|
||||
/* defined in arch/metag/drivers/core-sysfs.c */
|
||||
extern struct sysdev_class cache_sysclass;
|
||||
|
||||
static inline void wr_fence(void);
|
||||
|
||||
/*
|
||||
* Functions for reading of L2 cache configuration.
|
||||
*/
|
||||
|
||||
/* Get raw L2 config register (CORE_CONFIG3) */
|
||||
static inline unsigned int meta_l2c_config(void)
|
||||
{
|
||||
const unsigned int *corecfg3 = (const unsigned int *)METAC_CORE_CONFIG3;
|
||||
return *corecfg3;
|
||||
}
|
||||
|
||||
/* Get whether the L2 is present */
|
||||
static inline int meta_l2c_is_present(void)
|
||||
{
|
||||
return meta_l2c_config() & METAC_CORECFG3_L2C_HAVE_L2C_BIT;
|
||||
}
|
||||
|
||||
/* Get whether the L2 is configured for write-back instead of write-through */
|
||||
static inline int meta_l2c_is_writeback(void)
|
||||
{
|
||||
return meta_l2c_config() & METAC_CORECFG3_L2C_MODE_BIT;
|
||||
}
|
||||
|
||||
/* Get whether the L2 is unified instead of separated code/data */
|
||||
static inline int meta_l2c_is_unified(void)
|
||||
{
|
||||
return meta_l2c_config() & METAC_CORECFG3_L2C_UNIFIED_BIT;
|
||||
}
|
||||
|
||||
/* Get the L2 cache size in bytes */
|
||||
static inline unsigned int meta_l2c_size(void)
|
||||
{
|
||||
unsigned int size_s;
|
||||
if (!meta_l2c_is_present())
|
||||
return 0;
|
||||
size_s = (meta_l2c_config() & METAC_CORECFG3_L2C_SIZE_BITS)
|
||||
>> METAC_CORECFG3_L2C_SIZE_S;
|
||||
/* L2CSIZE is in KiB */
|
||||
return 1024 << size_s;
|
||||
}
|
||||
|
||||
/* Get the number of ways in the L2 cache */
|
||||
static inline unsigned int meta_l2c_ways(void)
|
||||
{
|
||||
unsigned int ways_s;
|
||||
if (!meta_l2c_is_present())
|
||||
return 0;
|
||||
ways_s = (meta_l2c_config() & METAC_CORECFG3_L2C_NUM_WAYS_BITS)
|
||||
>> METAC_CORECFG3_L2C_NUM_WAYS_S;
|
||||
return 0x1 << ways_s;
|
||||
}
|
||||
|
||||
/* Get the line size of the L2 cache */
|
||||
static inline unsigned int meta_l2c_linesize(void)
|
||||
{
|
||||
unsigned int line_size;
|
||||
if (!meta_l2c_is_present())
|
||||
return 0;
|
||||
line_size = (meta_l2c_config() & METAC_CORECFG3_L2C_LINE_SIZE_BITS)
|
||||
>> METAC_CORECFG3_L2C_LINE_SIZE_S;
|
||||
switch (line_size) {
|
||||
case METAC_CORECFG3_L2C_LINE_SIZE_64B:
|
||||
return 64;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the revision ID of the L2 cache */
|
||||
static inline unsigned int meta_l2c_revision(void)
|
||||
{
|
||||
return (meta_l2c_config() & METAC_CORECFG3_L2C_REV_ID_BITS)
|
||||
>> METAC_CORECFG3_L2C_REV_ID_S;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Start an initialisation of the L2 cachelines and wait for completion.
|
||||
* This should only be done in a LOCK1 or LOCK2 critical section while the L2
|
||||
* is disabled.
|
||||
*/
|
||||
static inline void _meta_l2c_init(void)
|
||||
{
|
||||
metag_out32(SYSC_L2C_INIT_INIT, SYSC_L2C_INIT);
|
||||
while (metag_in32(SYSC_L2C_INIT) == SYSC_L2C_INIT_IN_PROGRESS)
|
||||
/* do nothing */;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start a writeback of dirty L2 cachelines and wait for completion.
|
||||
* This should only be done in a LOCK1 or LOCK2 critical section.
|
||||
*/
|
||||
static inline void _meta_l2c_purge(void)
|
||||
{
|
||||
metag_out32(SYSC_L2C_PURGE_PURGE, SYSC_L2C_PURGE);
|
||||
while (metag_in32(SYSC_L2C_PURGE) == SYSC_L2C_PURGE_IN_PROGRESS)
|
||||
/* do nothing */;
|
||||
}
|
||||
|
||||
/* Set whether the L2 cache is enabled. */
|
||||
static inline void _meta_l2c_enable(int enabled)
|
||||
{
|
||||
unsigned int enable;
|
||||
|
||||
enable = metag_in32(SYSC_L2C_ENABLE);
|
||||
if (enabled)
|
||||
enable |= SYSC_L2C_ENABLE_ENABLE_BIT;
|
||||
else
|
||||
enable &= ~SYSC_L2C_ENABLE_ENABLE_BIT;
|
||||
metag_out32(enable, SYSC_L2C_ENABLE);
|
||||
}
|
||||
|
||||
/* Set whether the L2 cache prefetch is enabled. */
|
||||
static inline void _meta_l2c_pf_enable(int pfenabled)
|
||||
{
|
||||
unsigned int enable;
|
||||
|
||||
enable = metag_in32(SYSC_L2C_ENABLE);
|
||||
if (pfenabled)
|
||||
enable |= SYSC_L2C_ENABLE_PFENABLE_BIT;
|
||||
else
|
||||
enable &= ~SYSC_L2C_ENABLE_PFENABLE_BIT;
|
||||
metag_out32(enable, SYSC_L2C_ENABLE);
|
||||
}
|
||||
|
||||
/* Return whether the L2 cache is enabled */
|
||||
static inline int _meta_l2c_is_enabled(void)
|
||||
{
|
||||
return metag_in32(SYSC_L2C_ENABLE) & SYSC_L2C_ENABLE_ENABLE_BIT;
|
||||
}
|
||||
|
||||
/* Return whether the L2 cache prefetch is enabled */
|
||||
static inline int _meta_l2c_pf_is_enabled(void)
|
||||
{
|
||||
return metag_in32(SYSC_L2C_ENABLE) & SYSC_L2C_ENABLE_PFENABLE_BIT;
|
||||
}
|
||||
|
||||
|
||||
/* Return whether the L2 cache is enabled */
|
||||
static inline int meta_l2c_is_enabled(void)
|
||||
{
|
||||
int en;
|
||||
|
||||
/*
|
||||
* There is no need to lock at the moment, as the enable bit is never
|
||||
* intermediately changed, so we will never see an intermediate result.
|
||||
*/
|
||||
en = _meta_l2c_is_enabled();
|
||||
|
||||
return en;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure the L2 cache is disabled.
|
||||
* Return whether the L2 was previously disabled.
|
||||
*/
|
||||
int meta_l2c_disable(void);
|
||||
|
||||
/*
|
||||
* Ensure the L2 cache is enabled.
|
||||
* Return whether the L2 was previously enabled.
|
||||
*/
|
||||
int meta_l2c_enable(void);
|
||||
|
||||
/* Return whether the L2 cache prefetch is enabled */
|
||||
static inline int meta_l2c_pf_is_enabled(void)
|
||||
{
|
||||
return l2c_pfenable;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set whether the L2 cache prefetch is enabled.
|
||||
* Return whether the L2 prefetch was previously enabled.
|
||||
*/
|
||||
int meta_l2c_pf_enable(int pfenable);
|
||||
|
||||
/*
|
||||
* Flush the L2 cache.
|
||||
* Return 1 if the L2 is disabled.
|
||||
*/
|
||||
int meta_l2c_flush(void);
|
||||
|
||||
/*
|
||||
* Write back all dirty cache lines in the L2 cache.
|
||||
* Return 1 if the L2 is disabled or there isn't any writeback.
|
||||
*/
|
||||
static inline int meta_l2c_writeback(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
int en;
|
||||
|
||||
/* no need to purge if it's not a writeback cache */
|
||||
if (!meta_l2c_is_writeback())
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Purge only works if the L2 is enabled, and involves reading back to
|
||||
* detect completion, so keep this operation atomic with other threads.
|
||||
*/
|
||||
__global_lock1(flags);
|
||||
en = meta_l2c_is_enabled();
|
||||
if (likely(en)) {
|
||||
wr_fence();
|
||||
_meta_l2c_purge();
|
||||
}
|
||||
__global_unlock1(flags);
|
||||
|
||||
return !en;
|
||||
}
|
||||
|
||||
#else /* CONFIG_METAG_L2C */
|
||||
|
||||
#define meta_l2c_config() 0
|
||||
#define meta_l2c_is_present() 0
|
||||
#define meta_l2c_is_writeback() 0
|
||||
#define meta_l2c_is_unified() 0
|
||||
#define meta_l2c_size() 0
|
||||
#define meta_l2c_ways() 0
|
||||
#define meta_l2c_linesize() 0
|
||||
#define meta_l2c_revision() 0
|
||||
|
||||
#define meta_l2c_is_enabled() 0
|
||||
#define _meta_l2c_pf_is_enabled() 0
|
||||
#define meta_l2c_pf_is_enabled() 0
|
||||
#define meta_l2c_disable() 1
|
||||
#define meta_l2c_enable() 0
|
||||
#define meta_l2c_pf_enable(X) 0
|
||||
static inline int meta_l2c_flush(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static inline int meta_l2c_writeback(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_METAG_L2C */
|
||||
|
||||
#endif /* _METAG_L2CACHE_H */
|
@ -1,8 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_LINKAGE_H
|
||||
#define __ASM_LINKAGE_H
|
||||
|
||||
#define __ALIGN .p2align 2
|
||||
#define __ALIGN_STR ".p2align 2"
|
||||
|
||||
#endif
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* arch/metag/include/asm/mach/arch.h
|
||||
*
|
||||
* Copyright (C) 2012 Imagination Technologies Ltd.
|
||||
*
|
||||
* based on the ARM version:
|
||||
* Copyright (C) 2000 Russell King
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _METAG_MACH_ARCH_H_
|
||||
#define _METAG_MACH_ARCH_H_
|
||||
|
||||
#include <linux/stddef.h>
|
||||
|
||||
#include <asm/clock.h>
|
||||
|
||||
/**
|
||||
* struct machine_desc - Describes a board controlled by a Meta.
|
||||
* @name: Board/SoC name.
|
||||
* @dt_compat: Array of device tree 'compatible' strings.
|
||||
* @clocks: Clock callbacks.
|
||||
*
|
||||
* @nr_irqs: Maximum number of IRQs.
|
||||
* If 0, defaults to NR_IRQS in asm-generic/irq.h.
|
||||
*
|
||||
* @init_early: Early init callback.
|
||||
* @init_irq: IRQ init callback for setting up IRQ controllers.
|
||||
* @init_machine: Arch init callback for setting up devices.
|
||||
* @init_late: Late init callback.
|
||||
*
|
||||
* This structure is provided by each board which can be controlled by a Meta.
|
||||
* It is chosen by matching the compatible strings in the device tree provided
|
||||
* by the bootloader with the strings in @dt_compat, and sets up any aspects of
|
||||
* the machine that aren't configured with device tree (yet).
|
||||
*/
|
||||
struct machine_desc {
|
||||
const char *name;
|
||||
const char **dt_compat;
|
||||
struct meta_clock_desc *clocks;
|
||||
|
||||
unsigned int nr_irqs;
|
||||
|
||||
void (*init_early)(void);
|
||||
void (*init_irq)(void);
|
||||
void (*init_machine)(void);
|
||||
void (*init_late)(void);
|
||||
};
|
||||
|
||||
/*
|
||||
* Current machine - only accessible during boot.
|
||||
*/
|
||||
extern const struct machine_desc *machine_desc;
|
||||
|
||||
/*
|
||||
* Machine type table - also only accessible during boot
|
||||
*/
|
||||
extern struct machine_desc __arch_info_begin[], __arch_info_end[];
|
||||
#define for_each_machine_desc(p) \
|
||||
for (p = __arch_info_begin; p < __arch_info_end; p++)
|
||||
|
||||
static inline struct machine_desc *default_machine_desc(void)
|
||||
{
|
||||
/* the default machine is the last one linked in */
|
||||
if (__arch_info_end - 1 < __arch_info_begin)
|
||||
return NULL;
|
||||
return __arch_info_end - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set of macros to define architecture features. This is built into
|
||||
* a table by the linker.
|
||||
*/
|
||||
#define MACHINE_START(_type, _name) \
|
||||
static const struct machine_desc __mach_desc_##_type \
|
||||
__used \
|
||||
__attribute__((__section__(".arch.info.init"))) = { \
|
||||
.name = _name,
|
||||
|
||||
#define MACHINE_END \
|
||||
};
|
||||
|
||||
#endif /* _METAG_MACH_ARCH_H_ */
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* asm/metag_isa.h
|
||||
*
|
||||
* Copyright (C) 2000-2007, 2012 Imagination Technologies.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License version 2 as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* Various defines for Meta instruction set.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_METAG_ISA_H_
|
||||
#define _ASM_METAG_ISA_H_
|
||||
|
||||
|
||||
/* L1 cache layout */
|
||||
|
||||
/* Data cache line size as bytes and shift */
|
||||
#define DCACHE_LINE_BYTES 64
|
||||
#define DCACHE_LINE_S 6
|
||||
|
||||
/* Number of ways in the data cache */
|
||||
#define DCACHE_WAYS 4
|
||||
|
||||
/* Instruction cache line size as bytes and shift */
|
||||
#define ICACHE_LINE_BYTES 64
|
||||
#define ICACHE_LINE_S 6
|
||||
|
||||
/* Number of ways in the instruction cache */
|
||||
#define ICACHE_WAYS 4
|
||||
|
||||
|
||||
/*
|
||||
* CACHEWD/CACHEWL instructions use the bottom 8 bits of the data presented to
|
||||
* control the operation actually achieved.
|
||||
*/
|
||||
/* Use of these two bits should be discouraged since the bits dont have
|
||||
* consistent meanings
|
||||
*/
|
||||
#define CACHEW_ICACHE_BIT 0x01
|
||||
#define CACHEW_TLBFLUSH_BIT 0x02
|
||||
|
||||
#define CACHEW_FLUSH_L1D_L2 0x0
|
||||
#define CACHEW_INVALIDATE_L1I 0x1
|
||||
#define CACHEW_INVALIDATE_L1DTLB 0x2
|
||||
#define CACHEW_INVALIDATE_L1ITLB 0x3
|
||||
#define CACHEW_WRITEBACK_L1D_L2 0x4
|
||||
#define CACHEW_INVALIDATE_L1D 0x8
|
||||
#define CACHEW_INVALIDATE_L1D_L2 0xC
|
||||
|
||||
/*
|
||||
* CACHERD/CACHERL instructions use bits 3:5 of the address presented to
|
||||
* control the operation achieved and hence the specific result.
|
||||
*/
|
||||
#define CACHER_ADDR_BITS 0xFFFFFFC0
|
||||
#define CACHER_OPER_BITS 0x00000030
|
||||
#define CACHER_OPER_S 4
|
||||
#define CACHER_OPER_LINPHY 0
|
||||
#define CACHER_ICACHE_BIT 0x00000008
|
||||
#define CACHER_ICACHE_S 3
|
||||
|
||||
/*
|
||||
* CACHERD/CACHERL LINPHY Oper result is one/two 32-bit words
|
||||
*
|
||||
* If CRLINPHY0_VAL_BIT (Bit 0) set then,
|
||||
* Lower 32-bits corresponds to MMCU_ENTRY_* above.
|
||||
* Upper 32-bits corresponds to CRLINPHY1_* values below (if requested).
|
||||
* else
|
||||
* Lower 32-bits corresponds to CRLINPHY0_* values below.
|
||||
* Upper 32-bits undefined.
|
||||
*/
|
||||
#define CRLINPHY0_VAL_BIT 0x00000001
|
||||
#define CRLINPHY0_FIRST_BIT 0x00000004 /* Set if VAL=0 due to first level */
|
||||
|
||||
#define CRLINPHY1_READ_BIT 0x00000001 /* Set if reads permitted */
|
||||
#define CRLINPHY1_SINGLE_BIT 0x00000004 /* Set if TLB does not cache entry */
|
||||
#define CRLINPHY1_PAGEMSK_BITS 0x0000FFF0 /* Set to ((2^n-1)>>12) value */
|
||||
#define CRLINPHY1_PAGEMSK_S 4
|
||||
|
||||
#endif /* _ASM_METAG_ISA_H_ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,12 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __METAG_MMAN_H__
|
||||
#define __METAG_MMAN_H__
|
||||
|
||||
#include <uapi/asm/mman.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#define arch_mmap_check metag_mmap_check
|
||||
int metag_mmap_check(unsigned long addr, unsigned long len,
|
||||
unsigned long flags);
|
||||
#endif
|
||||
#endif /* __METAG_MMAN_H__ */
|
@ -1,78 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __MMU_H
|
||||
#define __MMU_H
|
||||
|
||||
#ifdef CONFIG_METAG_USER_TCM
|
||||
#include <linux/list.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
#include <asm/page.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
/* Software pgd base pointer used for Meta 1.x MMU. */
|
||||
unsigned long pgd_base;
|
||||
#ifdef CONFIG_METAG_USER_TCM
|
||||
struct list_head tcm;
|
||||
#endif
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
#if HPAGE_SHIFT < HUGEPT_SHIFT
|
||||
/* last partially filled huge page table address */
|
||||
unsigned long part_huge;
|
||||
#endif
|
||||
#endif
|
||||
} mm_context_t;
|
||||
|
||||
/* Given a virtual address, return the pte for the top level 4meg entry
|
||||
* that maps that address.
|
||||
* Returns 0 (an empty pte) if that range is not mapped.
|
||||
*/
|
||||
unsigned long mmu_read_first_level_page(unsigned long vaddr);
|
||||
|
||||
/* Given a linear (virtual) address, return the second level 4k pte
|
||||
* that maps that address. Returns 0 if the address is not mapped.
|
||||
*/
|
||||
unsigned long mmu_read_second_level_page(unsigned long vaddr);
|
||||
|
||||
/* Get the virtual base address of the MMU */
|
||||
unsigned long mmu_get_base(void);
|
||||
|
||||
/* Initialize the MMU. */
|
||||
void mmu_init(unsigned long mem_end);
|
||||
|
||||
#ifdef CONFIG_METAG_META21_MMU
|
||||
/*
|
||||
* For cpu "cpu" calculate and return the address of the
|
||||
* MMCU_TnLOCAL_TABLE_PHYS0 if running in local-space or
|
||||
* MMCU_TnGLOBAL_TABLE_PHYS0 if running in global-space.
|
||||
*/
|
||||
static inline unsigned long mmu_phys0_addr(unsigned int cpu)
|
||||
{
|
||||
unsigned long phys0;
|
||||
|
||||
phys0 = (MMCU_T0LOCAL_TABLE_PHYS0 +
|
||||
(MMCU_TnX_TABLE_PHYSX_STRIDE * cpu)) +
|
||||
(MMCU_TXG_TABLE_PHYSX_OFFSET * is_global_space(PAGE_OFFSET));
|
||||
|
||||
return phys0;
|
||||
}
|
||||
|
||||
/*
|
||||
* For cpu "cpu" calculate and return the address of the
|
||||
* MMCU_TnLOCAL_TABLE_PHYS1 if running in local-space or
|
||||
* MMCU_TnGLOBAL_TABLE_PHYS1 if running in global-space.
|
||||
*/
|
||||
static inline unsigned long mmu_phys1_addr(unsigned int cpu)
|
||||
{
|
||||
unsigned long phys1;
|
||||
|
||||
phys1 = (MMCU_T0LOCAL_TABLE_PHYS1 +
|
||||
(MMCU_TnX_TABLE_PHYSX_STRIDE * cpu)) +
|
||||
(MMCU_TXG_TABLE_PHYSX_OFFSET * is_global_space(PAGE_OFFSET));
|
||||
|
||||
return phys1;
|
||||
}
|
||||
#endif /* CONFIG_METAG_META21_MMU */
|
||||
|
||||
#endif
|
@ -1,115 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __METAG_MMU_CONTEXT_H
|
||||
#define __METAG_MMU_CONTEXT_H
|
||||
|
||||
#include <asm-generic/mm_hooks.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/mm_types.h>
|
||||
|
||||
static inline void enter_lazy_tlb(struct mm_struct *mm,
|
||||
struct task_struct *tsk)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int init_new_context(struct task_struct *tsk,
|
||||
struct mm_struct *mm)
|
||||
{
|
||||
#ifndef CONFIG_METAG_META21_MMU
|
||||
/* We use context to store a pointer to the page holding the
|
||||
* pgd of a process while it is running. While a process is not
|
||||
* running the pgd and context fields should be equal.
|
||||
*/
|
||||
mm->context.pgd_base = (unsigned long) mm->pgd;
|
||||
#endif
|
||||
#ifdef CONFIG_METAG_USER_TCM
|
||||
INIT_LIST_HEAD(&mm->context.tcm);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_METAG_USER_TCM
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <asm/tcm.h>
|
||||
|
||||
static inline void destroy_context(struct mm_struct *mm)
|
||||
{
|
||||
struct tcm_allocation *pos, *n;
|
||||
|
||||
list_for_each_entry_safe(pos, n, &mm->context.tcm, list) {
|
||||
tcm_free(pos->tag, pos->addr, pos->size);
|
||||
list_del(&pos->list);
|
||||
kfree(pos);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define destroy_context(mm) do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_METAG_META21_MMU
|
||||
static inline void load_pgd(pgd_t *pgd, int thread)
|
||||
{
|
||||
unsigned long phys0 = mmu_phys0_addr(thread);
|
||||
unsigned long phys1 = mmu_phys1_addr(thread);
|
||||
|
||||
/*
|
||||
* 0x900 2Gb address space
|
||||
* The permission bits apply to MMU table region which gives a 2MB
|
||||
* window into physical memory. We especially don't want userland to be
|
||||
* able to access this.
|
||||
*/
|
||||
metag_out32(0x900 | _PAGE_CACHEABLE | _PAGE_PRIV | _PAGE_WRITE |
|
||||
_PAGE_PRESENT, phys0);
|
||||
/* Set new MMU base address */
|
||||
metag_out32(__pa(pgd) & MMCU_TBLPHYS1_ADDR_BITS, phys1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void switch_mmu(struct mm_struct *prev, struct mm_struct *next)
|
||||
{
|
||||
#ifdef CONFIG_METAG_META21_MMU
|
||||
load_pgd(next->pgd, hard_processor_id());
|
||||
#else
|
||||
unsigned int i;
|
||||
|
||||
/* prev->context == prev->pgd in the case where we are initially
|
||||
switching from the init task to the first process. */
|
||||
if (prev->context.pgd_base != (unsigned long) prev->pgd) {
|
||||
for (i = FIRST_USER_PGD_NR; i < USER_PTRS_PER_PGD; i++)
|
||||
((pgd_t *) prev->context.pgd_base)[i] = prev->pgd[i];
|
||||
} else
|
||||
prev->pgd = (pgd_t *)mmu_get_base();
|
||||
|
||||
next->pgd = prev->pgd;
|
||||
prev->pgd = (pgd_t *) prev->context.pgd_base;
|
||||
|
||||
for (i = FIRST_USER_PGD_NR; i < USER_PTRS_PER_PGD; i++)
|
||||
next->pgd[i] = ((pgd_t *) next->context.pgd_base)[i];
|
||||
|
||||
flush_cache_all();
|
||||
#endif
|
||||
flush_tlb_all();
|
||||
}
|
||||
|
||||
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
struct task_struct *tsk)
|
||||
{
|
||||
if (prev != next)
|
||||
switch_mmu(prev, next);
|
||||
}
|
||||
|
||||
static inline void activate_mm(struct mm_struct *prev_mm,
|
||||
struct mm_struct *next_mm)
|
||||
{
|
||||
switch_mmu(prev_mm, next_mm);
|
||||
}
|
||||
|
||||
#define deactivate_mm(tsk, mm) do { } while (0)
|
||||
|
||||
#endif
|
@ -1,43 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_MMZONE_H
|
||||
#define __ASM_METAG_MMZONE_H
|
||||
|
||||
#ifdef CONFIG_NEED_MULTIPLE_NODES
|
||||
#include <linux/numa.h>
|
||||
|
||||
extern struct pglist_data *node_data[];
|
||||
#define NODE_DATA(nid) (node_data[nid])
|
||||
|
||||
static inline int pfn_to_nid(unsigned long pfn)
|
||||
{
|
||||
int nid;
|
||||
|
||||
for (nid = 0; nid < MAX_NUMNODES; nid++)
|
||||
if (pfn >= node_start_pfn(nid) && pfn <= node_end_pfn(nid))
|
||||
break;
|
||||
|
||||
return nid;
|
||||
}
|
||||
|
||||
static inline struct pglist_data *pfn_to_pgdat(unsigned long pfn)
|
||||
{
|
||||
return NODE_DATA(pfn_to_nid(pfn));
|
||||
}
|
||||
|
||||
/* arch/metag/mm/numa.c */
|
||||
void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end);
|
||||
#else
|
||||
static inline void
|
||||
setup_bootmem_node(int nid, unsigned long start, unsigned long end)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_NEED_MULTIPLE_NODES */
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
/* SoC specific mem init */
|
||||
void __init soc_mem_setup(void);
|
||||
#else
|
||||
static inline void __init soc_mem_setup(void) {};
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_METAG_MMZONE_H */
|
@ -1,38 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_METAG_MODULE_H
|
||||
#define _ASM_METAG_MODULE_H
|
||||
|
||||
#include <asm-generic/module.h>
|
||||
|
||||
struct metag_plt_entry {
|
||||
/* Indirect jump instruction sequence. */
|
||||
unsigned long tramp[2];
|
||||
};
|
||||
|
||||
struct mod_arch_specific {
|
||||
/* Indices of PLT sections within module. */
|
||||
unsigned int core_plt_section, init_plt_section;
|
||||
};
|
||||
|
||||
#if defined CONFIG_METAG_META12
|
||||
#define MODULE_PROC_FAMILY "META 1.2 "
|
||||
#elif defined CONFIG_METAG_META21
|
||||
#define MODULE_PROC_FAMILY "META 2.1 "
|
||||
#else
|
||||
#define MODULE_PROC_FAMILY ""
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_4KSTACKS
|
||||
#define MODULE_STACKSIZE "4KSTACKS "
|
||||
#else
|
||||
#define MODULE_STACKSIZE ""
|
||||
#endif
|
||||
|
||||
#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
|
||||
|
||||
#ifdef MODULE
|
||||
asm(".section .plt,\"ax\",@progbits; .balign 8; .previous");
|
||||
asm(".section .init.plt,\"ax\",@progbits; .balign 8; .previous");
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_METAG_MODULE_H */
|
@ -1,129 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _METAG_PAGE_H
|
||||
#define _METAG_PAGE_H
|
||||
|
||||
#include <linux/const.h>
|
||||
|
||||
#include <asm/metag_mem.h>
|
||||
|
||||
/* PAGE_SHIFT determines the page size */
|
||||
#if defined(CONFIG_PAGE_SIZE_4K)
|
||||
#define PAGE_SHIFT 12
|
||||
#elif defined(CONFIG_PAGE_SIZE_8K)
|
||||
#define PAGE_SHIFT 13
|
||||
#elif defined(CONFIG_PAGE_SIZE_16K)
|
||||
#define PAGE_SHIFT 14
|
||||
#endif
|
||||
|
||||
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
|
||||
#define PAGE_MASK (~(PAGE_SIZE-1))
|
||||
|
||||
#if defined(CONFIG_HUGETLB_PAGE_SIZE_8K)
|
||||
# define HPAGE_SHIFT 13
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_16K)
|
||||
# define HPAGE_SHIFT 14
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_32K)
|
||||
# define HPAGE_SHIFT 15
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
|
||||
# define HPAGE_SHIFT 16
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_128K)
|
||||
# define HPAGE_SHIFT 17
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K)
|
||||
# define HPAGE_SHIFT 18
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
|
||||
# define HPAGE_SHIFT 19
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_1M)
|
||||
# define HPAGE_SHIFT 20
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_2M)
|
||||
# define HPAGE_SHIFT 21
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_4M)
|
||||
# define HPAGE_SHIFT 22
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
# define HPAGE_SIZE (1UL << HPAGE_SHIFT)
|
||||
# define HPAGE_MASK (~(HPAGE_SIZE-1))
|
||||
# define HUGETLB_PAGE_ORDER (HPAGE_SHIFT-PAGE_SHIFT)
|
||||
/*
|
||||
* We define our own hugetlb_get_unmapped_area so we don't corrupt 2nd level
|
||||
* page tables with normal pages in them.
|
||||
*/
|
||||
# define HUGEPT_SHIFT (22)
|
||||
# define HUGEPT_ALIGN (1 << HUGEPT_SHIFT)
|
||||
# define HUGEPT_MASK (HUGEPT_ALIGN - 1)
|
||||
# define ALIGN_HUGEPT(x) ALIGN(x, HUGEPT_ALIGN)
|
||||
# define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* On the Meta, we would like to know if the address (heap) we have is
|
||||
* in local or global space.
|
||||
*/
|
||||
#define is_global_space(addr) ((addr) > 0x7fffffff)
|
||||
#define is_local_space(addr) (!is_global_space(addr))
|
||||
|
||||
extern void clear_page(void *to);
|
||||
extern void copy_page(void *to, void *from);
|
||||
|
||||
#define clear_user_page(page, vaddr, pg) clear_page(page)
|
||||
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
|
||||
|
||||
/*
|
||||
* These are used to make use of C type-checking..
|
||||
*/
|
||||
typedef struct { unsigned long pte; } pte_t;
|
||||
typedef struct { unsigned long pgd; } pgd_t;
|
||||
typedef struct { unsigned long pgprot; } pgprot_t;
|
||||
typedef struct page *pgtable_t;
|
||||
|
||||
#define pte_val(x) ((x).pte)
|
||||
#define pgd_val(x) ((x).pgd)
|
||||
#define pgprot_val(x) ((x).pgprot)
|
||||
|
||||
#define __pte(x) ((pte_t) { (x) })
|
||||
#define __pgd(x) ((pgd_t) { (x) })
|
||||
#define __pgprot(x) ((pgprot_t) { (x) })
|
||||
|
||||
/* The kernel must now ALWAYS live at either 0xC0000000 or 0x40000000 - that
|
||||
* being either global or local space.
|
||||
*/
|
||||
#define PAGE_OFFSET (CONFIG_PAGE_OFFSET)
|
||||
|
||||
#if PAGE_OFFSET >= LINGLOBAL_BASE
|
||||
#define META_MEMORY_BASE LINGLOBAL_BASE
|
||||
#define META_MEMORY_LIMIT LINGLOBAL_LIMIT
|
||||
#else
|
||||
#define META_MEMORY_BASE LINLOCAL_BASE
|
||||
#define META_MEMORY_LIMIT LINLOCAL_LIMIT
|
||||
#endif
|
||||
|
||||
/* Offset between physical and virtual mapping of kernel memory. */
|
||||
extern unsigned int meta_memoffset;
|
||||
|
||||
#define __pa(x) ((unsigned long)(((unsigned long)(x)) - meta_memoffset))
|
||||
#define __va(x) ((void *)((unsigned long)(((unsigned long)(x)) + meta_memoffset)))
|
||||
|
||||
extern unsigned long pfn_base;
|
||||
#define ARCH_PFN_OFFSET (pfn_base)
|
||||
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
|
||||
#define page_to_virt(page) __va(page_to_pfn(page) << PAGE_SHIFT)
|
||||
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
|
||||
#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
|
||||
#ifdef CONFIG_FLATMEM
|
||||
extern unsigned long max_pfn;
|
||||
extern unsigned long min_low_pfn;
|
||||
#define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_pfn)
|
||||
#endif
|
||||
|
||||
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
|
||||
|
||||
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
|
||||
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
|
||||
|
||||
#include <asm-generic/memory_model.h>
|
||||
#include <asm-generic/getorder.h>
|
||||
|
||||
#endif /* __ASSMEBLY__ */
|
||||
|
||||
#endif /* _METAG_PAGE_H */
|
@ -1,4 +0,0 @@
|
||||
#ifndef __ASM_METAG_PERF_EVENT_H
|
||||
#define __ASM_METAG_PERF_EVENT_H
|
||||
|
||||
#endif /* __ASM_METAG_PERF_EVENT_H */
|
@ -1,83 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _METAG_PGALLOC_H
|
||||
#define _METAG_PGALLOC_H
|
||||
|
||||
#include <linux/threads.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#define pmd_populate_kernel(mm, pmd, pte) \
|
||||
set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
|
||||
|
||||
#define pmd_populate(mm, pmd, pte) \
|
||||
set_pmd(pmd, __pmd(_PAGE_TABLE | page_to_phys(pte)))
|
||||
|
||||
#define pmd_pgtable(pmd) pmd_page(pmd)
|
||||
|
||||
/*
|
||||
* Allocate and free page tables.
|
||||
*/
|
||||
#ifdef CONFIG_METAG_META21_MMU
|
||||
static inline void pgd_ctor(pgd_t *pgd)
|
||||
{
|
||||
memcpy(pgd + USER_PTRS_PER_PGD,
|
||||
swapper_pg_dir + USER_PTRS_PER_PGD,
|
||||
(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
|
||||
}
|
||||
#else
|
||||
#define pgd_ctor(x) do { } while (0)
|
||||
#endif
|
||||
|
||||
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
|
||||
{
|
||||
pgd_t *pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL);
|
||||
if (pgd)
|
||||
pgd_ctor(pgd);
|
||||
return pgd;
|
||||
}
|
||||
|
||||
static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
|
||||
{
|
||||
free_page((unsigned long)pgd);
|
||||
}
|
||||
|
||||
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
|
||||
unsigned long address)
|
||||
{
|
||||
pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
|
||||
return pte;
|
||||
}
|
||||
|
||||
static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
|
||||
unsigned long address)
|
||||
{
|
||||
struct page *pte;
|
||||
pte = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0);
|
||||
if (!pte)
|
||||
return NULL;
|
||||
if (!pgtable_page_ctor(pte)) {
|
||||
__free_page(pte);
|
||||
return NULL;
|
||||
}
|
||||
return pte;
|
||||
}
|
||||
|
||||
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
|
||||
{
|
||||
free_page((unsigned long)pte);
|
||||
}
|
||||
|
||||
static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
|
||||
{
|
||||
pgtable_page_dtor(pte);
|
||||
__free_page(pte);
|
||||
}
|
||||
|
||||
#define __pte_free_tlb(tlb, pte, addr) \
|
||||
do { \
|
||||
pgtable_page_dtor(pte); \
|
||||
tlb_remove_page((tlb), (pte)); \
|
||||
} while (0)
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
||||
#endif
|
@ -1,105 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Meta page table definitions.
|
||||
*/
|
||||
|
||||
#ifndef _METAG_PGTABLE_BITS_H
|
||||
#define _METAG_PGTABLE_BITS_H
|
||||
|
||||
#include <asm/metag_mem.h>
|
||||
|
||||
/*
|
||||
* Definitions for MMU descriptors
|
||||
*
|
||||
* These are the hardware bits in the MMCU pte entries.
|
||||
* Derived from the Meta toolkit headers.
|
||||
*/
|
||||
#define _PAGE_PRESENT MMCU_ENTRY_VAL_BIT
|
||||
#define _PAGE_WRITE MMCU_ENTRY_WR_BIT
|
||||
#define _PAGE_PRIV MMCU_ENTRY_PRIV_BIT
|
||||
/* Write combine bit - this can cause writes to occur out of order */
|
||||
#define _PAGE_WR_COMBINE MMCU_ENTRY_WRC_BIT
|
||||
/* Sys coherent bit - this bit is never used by Linux */
|
||||
#define _PAGE_SYS_COHERENT MMCU_ENTRY_SYS_BIT
|
||||
#define _PAGE_ALWAYS_ZERO_1 0x020
|
||||
#define _PAGE_CACHE_CTRL0 0x040
|
||||
#define _PAGE_CACHE_CTRL1 0x080
|
||||
#define _PAGE_ALWAYS_ZERO_2 0x100
|
||||
#define _PAGE_ALWAYS_ZERO_3 0x200
|
||||
#define _PAGE_ALWAYS_ZERO_4 0x400
|
||||
#define _PAGE_ALWAYS_ZERO_5 0x800
|
||||
|
||||
/* These are software bits that we stuff into the gaps in the hardware
|
||||
* pte entries that are not used. Note, these DO get stored in the actual
|
||||
* hardware, but the hardware just does not use them.
|
||||
*/
|
||||
#define _PAGE_ACCESSED _PAGE_ALWAYS_ZERO_1
|
||||
#define _PAGE_DIRTY _PAGE_ALWAYS_ZERO_2
|
||||
|
||||
/* Pages owned, and protected by, the kernel. */
|
||||
#define _PAGE_KERNEL _PAGE_PRIV
|
||||
|
||||
/* No cacheing of this page */
|
||||
#define _PAGE_CACHE_WIN0 (MMCU_CWIN_UNCACHED << MMCU_ENTRY_CWIN_S)
|
||||
/* burst cacheing - good for data streaming */
|
||||
#define _PAGE_CACHE_WIN1 (MMCU_CWIN_BURST << MMCU_ENTRY_CWIN_S)
|
||||
/* One cache way per thread */
|
||||
#define _PAGE_CACHE_WIN2 (MMCU_CWIN_C1SET << MMCU_ENTRY_CWIN_S)
|
||||
/* Full on cacheing */
|
||||
#define _PAGE_CACHE_WIN3 (MMCU_CWIN_CACHED << MMCU_ENTRY_CWIN_S)
|
||||
|
||||
#define _PAGE_CACHEABLE (_PAGE_CACHE_WIN3 | _PAGE_WR_COMBINE)
|
||||
|
||||
/* which bits are used for cache control ... */
|
||||
#define _PAGE_CACHE_MASK (_PAGE_CACHE_CTRL0 | _PAGE_CACHE_CTRL1 | \
|
||||
_PAGE_WR_COMBINE)
|
||||
|
||||
/* This is a mask of the bits that pte_modify is allowed to change. */
|
||||
#define _PAGE_CHG_MASK (PAGE_MASK)
|
||||
|
||||
#define _PAGE_SZ_SHIFT 1
|
||||
#define _PAGE_SZ_4K (0x0)
|
||||
#define _PAGE_SZ_8K (0x1 << _PAGE_SZ_SHIFT)
|
||||
#define _PAGE_SZ_16K (0x2 << _PAGE_SZ_SHIFT)
|
||||
#define _PAGE_SZ_32K (0x3 << _PAGE_SZ_SHIFT)
|
||||
#define _PAGE_SZ_64K (0x4 << _PAGE_SZ_SHIFT)
|
||||
#define _PAGE_SZ_128K (0x5 << _PAGE_SZ_SHIFT)
|
||||
#define _PAGE_SZ_256K (0x6 << _PAGE_SZ_SHIFT)
|
||||
#define _PAGE_SZ_512K (0x7 << _PAGE_SZ_SHIFT)
|
||||
#define _PAGE_SZ_1M (0x8 << _PAGE_SZ_SHIFT)
|
||||
#define _PAGE_SZ_2M (0x9 << _PAGE_SZ_SHIFT)
|
||||
#define _PAGE_SZ_4M (0xa << _PAGE_SZ_SHIFT)
|
||||
#define _PAGE_SZ_MASK (0xf << _PAGE_SZ_SHIFT)
|
||||
|
||||
#if defined(CONFIG_PAGE_SIZE_4K)
|
||||
#define _PAGE_SZ (_PAGE_SZ_4K)
|
||||
#elif defined(CONFIG_PAGE_SIZE_8K)
|
||||
#define _PAGE_SZ (_PAGE_SZ_8K)
|
||||
#elif defined(CONFIG_PAGE_SIZE_16K)
|
||||
#define _PAGE_SZ (_PAGE_SZ_16K)
|
||||
#endif
|
||||
#define _PAGE_TABLE (_PAGE_SZ | _PAGE_PRESENT)
|
||||
|
||||
#if defined(CONFIG_HUGETLB_PAGE_SIZE_8K)
|
||||
# define _PAGE_SZHUGE (_PAGE_SZ_8K)
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_16K)
|
||||
# define _PAGE_SZHUGE (_PAGE_SZ_16K)
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_32K)
|
||||
# define _PAGE_SZHUGE (_PAGE_SZ_32K)
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
|
||||
# define _PAGE_SZHUGE (_PAGE_SZ_64K)
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_128K)
|
||||
# define _PAGE_SZHUGE (_PAGE_SZ_128K)
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K)
|
||||
# define _PAGE_SZHUGE (_PAGE_SZ_256K)
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
|
||||
# define _PAGE_SZHUGE (_PAGE_SZ_512K)
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_1M)
|
||||
# define _PAGE_SZHUGE (_PAGE_SZ_1M)
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_2M)
|
||||
# define _PAGE_SZHUGE (_PAGE_SZ_2M)
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_4M)
|
||||
# define _PAGE_SZHUGE (_PAGE_SZ_4M)
|
||||
#endif
|
||||
|
||||
#endif /* _METAG_PGTABLE_BITS_H */
|
@ -1,270 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Macros and functions to manipulate Meta page tables.
|
||||
*/
|
||||
|
||||
#ifndef _METAG_PGTABLE_H
|
||||
#define _METAG_PGTABLE_H
|
||||
|
||||
#include <asm/pgtable-bits.h>
|
||||
#define __ARCH_USE_5LEVEL_HACK
|
||||
#include <asm-generic/pgtable-nopmd.h>
|
||||
|
||||
/* Invalid regions on Meta: 0x00000000-0x001FFFFF and 0xFFFF0000-0xFFFFFFFF */
|
||||
#if PAGE_OFFSET >= LINGLOBAL_BASE
|
||||
#define CONSISTENT_START 0xF7000000
|
||||
#define CONSISTENT_END 0xF73FFFFF
|
||||
#define VMALLOC_START 0xF8000000
|
||||
#define VMALLOC_END 0xFFFEFFFF
|
||||
#else
|
||||
#define CONSISTENT_START 0x77000000
|
||||
#define CONSISTENT_END 0x773FFFFF
|
||||
#define VMALLOC_START 0x78000000
|
||||
#define VMALLOC_END 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The Linux memory management assumes a three-level page table setup. On
|
||||
* Meta, we use that, but "fold" the mid level into the top-level page
|
||||
* table.
|
||||
*/
|
||||
|
||||
/* PGDIR_SHIFT determines the size of the area a second-level page table can
|
||||
* map. This is always 4MB.
|
||||
*/
|
||||
|
||||
#define PGDIR_SHIFT 22
|
||||
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
|
||||
#define PGDIR_MASK (~(PGDIR_SIZE-1))
|
||||
|
||||
/*
|
||||
* Entries per page directory level: we use a two-level, so
|
||||
* we don't really have any PMD directory physically. First level tables
|
||||
* always map 2Gb (local or global) at a granularity of 4MB, second-level
|
||||
* tables map 4MB with a granularity between 4MB and 4kB (between 1 and
|
||||
* 1024 entries).
|
||||
*/
|
||||
#define PTRS_PER_PTE (PGDIR_SIZE/PAGE_SIZE)
|
||||
#define HPTRS_PER_PTE (PGDIR_SIZE/HPAGE_SIZE)
|
||||
#define PTRS_PER_PGD 512
|
||||
|
||||
#define USER_PTRS_PER_PGD 256
|
||||
#define FIRST_USER_ADDRESS META_MEMORY_BASE
|
||||
#define FIRST_USER_PGD_NR pgd_index(FIRST_USER_ADDRESS)
|
||||
|
||||
#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
|
||||
_PAGE_CACHEABLE)
|
||||
|
||||
#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
|
||||
_PAGE_ACCESSED | _PAGE_CACHEABLE)
|
||||
#define PAGE_SHARED_C PAGE_SHARED
|
||||
#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
|
||||
_PAGE_CACHEABLE)
|
||||
#define PAGE_COPY_C PAGE_COPY
|
||||
|
||||
#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
|
||||
_PAGE_CACHEABLE)
|
||||
#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | \
|
||||
_PAGE_ACCESSED | _PAGE_WRITE | \
|
||||
_PAGE_CACHEABLE | _PAGE_KERNEL)
|
||||
|
||||
#define __P000 PAGE_NONE
|
||||
#define __P001 PAGE_READONLY
|
||||
#define __P010 PAGE_COPY
|
||||
#define __P011 PAGE_COPY
|
||||
#define __P100 PAGE_READONLY
|
||||
#define __P101 PAGE_READONLY
|
||||
#define __P110 PAGE_COPY_C
|
||||
#define __P111 PAGE_COPY_C
|
||||
|
||||
#define __S000 PAGE_NONE
|
||||
#define __S001 PAGE_READONLY
|
||||
#define __S010 PAGE_SHARED
|
||||
#define __S011 PAGE_SHARED
|
||||
#define __S100 PAGE_READONLY
|
||||
#define __S101 PAGE_READONLY
|
||||
#define __S110 PAGE_SHARED_C
|
||||
#define __S111 PAGE_SHARED_C
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <asm/page.h>
|
||||
|
||||
/* zero page used for uninitialized stuff */
|
||||
extern unsigned long empty_zero_page;
|
||||
#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
|
||||
|
||||
/* Certain architectures need to do special things when pte's
|
||||
* within a page table are directly modified. Thus, the following
|
||||
* hook is made available.
|
||||
*/
|
||||
#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
|
||||
#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
|
||||
|
||||
#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
|
||||
|
||||
#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
|
||||
|
||||
#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
|
||||
|
||||
#define pte_none(x) (!pte_val(x))
|
||||
#define pte_present(x) (pte_val(x) & _PAGE_PRESENT)
|
||||
#define pte_clear(mm, addr, xp) do { pte_val(*(xp)) = 0; } while (0)
|
||||
|
||||
#define pmd_none(x) (!pmd_val(x))
|
||||
#define pmd_bad(x) ((pmd_val(x) & ~(PAGE_MASK | _PAGE_SZ_MASK)) \
|
||||
!= (_PAGE_TABLE & ~_PAGE_SZ_MASK))
|
||||
#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
|
||||
#define pmd_clear(xp) do { pmd_val(*(xp)) = 0; } while (0)
|
||||
|
||||
#define pte_page(x) pfn_to_page(pte_pfn(x))
|
||||
|
||||
/*
|
||||
* The following only work if pte_present() is true.
|
||||
* Undefined behaviour if not..
|
||||
*/
|
||||
|
||||
static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
|
||||
static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
|
||||
static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
|
||||
static inline int pte_special(pte_t pte) { return 0; }
|
||||
|
||||
static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= (~_PAGE_WRITE); return pte; }
|
||||
static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
|
||||
static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
|
||||
static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return pte; }
|
||||
static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; }
|
||||
static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
|
||||
static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
|
||||
static inline pte_t pte_mkhuge(pte_t pte) { return pte; }
|
||||
|
||||
/*
|
||||
* Macro and implementation to make a page protection as uncacheable.
|
||||
*/
|
||||
#define pgprot_writecombine(prot) \
|
||||
__pgprot(pgprot_val(prot) & ~(_PAGE_CACHE_CTRL1 | _PAGE_CACHE_CTRL0))
|
||||
|
||||
#define pgprot_noncached(prot) \
|
||||
__pgprot(pgprot_val(prot) & ~_PAGE_CACHEABLE)
|
||||
|
||||
|
||||
/*
|
||||
* Conversion functions: convert a page and protection to a page entry,
|
||||
* and a page entry and page directory to the page they refer to.
|
||||
*/
|
||||
|
||||
#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
|
||||
|
||||
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
||||
{
|
||||
pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
|
||||
return pte;
|
||||
}
|
||||
|
||||
static inline unsigned long pmd_page_vaddr(pmd_t pmd)
|
||||
{
|
||||
unsigned long paddr = pmd_val(pmd) & PAGE_MASK;
|
||||
if (!paddr)
|
||||
return 0;
|
||||
return (unsigned long)__va(paddr);
|
||||
}
|
||||
|
||||
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
|
||||
#define pmd_page_shift(pmd) (12 + ((pmd_val(pmd) & _PAGE_SZ_MASK) \
|
||||
>> _PAGE_SZ_SHIFT))
|
||||
#define pmd_num_ptrs(pmd) (PGDIR_SIZE >> pmd_page_shift(pmd))
|
||||
|
||||
/*
|
||||
* Each pgd is only 2k, mapping 2Gb (local or global). If we're in global
|
||||
* space drop the top bit before indexing the pgd.
|
||||
*/
|
||||
#if PAGE_OFFSET >= LINGLOBAL_BASE
|
||||
#define pgd_index(address) ((((address) & ~0x80000000) >> PGDIR_SHIFT) \
|
||||
& (PTRS_PER_PGD-1))
|
||||
#else
|
||||
#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
|
||||
#endif
|
||||
|
||||
#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
|
||||
|
||||
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
|
||||
|
||||
#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
|
||||
|
||||
/* Find an entry in the second-level page table.. */
|
||||
#if !defined(CONFIG_HUGETLB_PAGE)
|
||||
/* all pages are of size (1 << PAGE_SHIFT), so no need to read 1st level pt */
|
||||
# define pte_index(pmd, address) \
|
||||
(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
|
||||
#else
|
||||
/* some pages are huge, so read 1st level pt to find out */
|
||||
# define pte_index(pmd, address) \
|
||||
(((address) >> pmd_page_shift(pmd)) & (pmd_num_ptrs(pmd) - 1))
|
||||
#endif
|
||||
#define pte_offset_kernel(dir, address) \
|
||||
((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(*(dir), address))
|
||||
#define pte_offset_map(dir, address) pte_offset_kernel(dir, address)
|
||||
#define pte_offset_map_nested(dir, address) pte_offset_kernel(dir, address)
|
||||
|
||||
#define pte_unmap(pte) do { } while (0)
|
||||
#define pte_unmap_nested(pte) do { } while (0)
|
||||
|
||||
#define pte_ERROR(e) \
|
||||
pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
|
||||
#define pgd_ERROR(e) \
|
||||
pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
|
||||
|
||||
/*
|
||||
* Meta doesn't have any external MMU info: the kernel page
|
||||
* tables contain all the necessary information.
|
||||
*/
|
||||
static inline void update_mmu_cache(struct vm_area_struct *vma,
|
||||
unsigned long address, pte_t *pte)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode and decode a swap entry (must be !pte_none(e) && !pte_present(e))
|
||||
* Since PAGE_PRESENT is bit 1, we can use the bits above that.
|
||||
*/
|
||||
#define __swp_type(x) (((x).val >> 1) & 0xff)
|
||||
#define __swp_offset(x) ((x).val >> 10)
|
||||
#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 1) | \
|
||||
((offset) << 10) })
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
|
||||
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
|
||||
|
||||
#define kern_addr_valid(addr) (1)
|
||||
|
||||
/*
|
||||
* No page table caches to initialise
|
||||
*/
|
||||
#define pgtable_cache_init() do { } while (0)
|
||||
|
||||
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
|
||||
void paging_init(unsigned long mem_end);
|
||||
|
||||
#ifdef CONFIG_METAG_META12
|
||||
/* This is a workaround for an issue in Meta 1 cores. These cores cache
|
||||
* invalid entries in the TLB so we always need to flush whenever we add
|
||||
* a new pte. Unfortunately we can only flush the whole TLB not shoot down
|
||||
* single entries so this is sub-optimal. This implementation ensures that
|
||||
* we will get a flush at the second attempt, so we may still get repeated
|
||||
* faults, we just don't overflow the kernel stack handling them.
|
||||
*/
|
||||
#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
|
||||
#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
|
||||
({ \
|
||||
int __changed = !pte_same(*(__ptep), __entry); \
|
||||
if (__changed) { \
|
||||
set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry); \
|
||||
} \
|
||||
flush_tlb_page(__vma, __address); \
|
||||
__changed; \
|
||||
})
|
||||
#endif
|
||||
|
||||
#include <asm-generic/pgtable.h>
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* _METAG_PGTABLE_H */
|
@ -1,201 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2005,2006,2007,2008 Imagination Technologies
|
||||
*/
|
||||
|
||||
#ifndef __ASM_METAG_PROCESSOR_H
|
||||
#define __ASM_METAG_PROCESSOR_H
|
||||
|
||||
#include <linux/atomic.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/metag_regs.h>
|
||||
|
||||
/*
|
||||
* Default implementation of macro that returns current
|
||||
* instruction pointer ("program counter").
|
||||
*/
|
||||
#define current_text_addr() ({ __label__ _l; _l: &&_l; })
|
||||
|
||||
/* The task stops where the kernel starts */
|
||||
#define TASK_SIZE PAGE_OFFSET
|
||||
/* Add an extra page of padding at the top of the stack for the guard page. */
|
||||
#define STACK_TOP (TASK_SIZE - PAGE_SIZE)
|
||||
#define STACK_TOP_MAX STACK_TOP
|
||||
/* Maximum virtual space for stack */
|
||||
#define STACK_SIZE_MAX (CONFIG_MAX_STACK_SIZE_MB*1024*1024)
|
||||
|
||||
/* This decides where the kernel will search for a free chunk of vm
|
||||
* space during mmap's.
|
||||
*/
|
||||
#define TASK_UNMAPPED_BASE META_MEMORY_BASE
|
||||
|
||||
typedef struct {
|
||||
unsigned long seg;
|
||||
} mm_segment_t;
|
||||
|
||||
#ifdef CONFIG_METAG_FPU
|
||||
struct meta_fpu_context {
|
||||
TBICTXEXTFPU fpstate;
|
||||
union {
|
||||
struct {
|
||||
TBICTXEXTBB4 fx8_15;
|
||||
TBICTXEXTFPACC fpacc;
|
||||
} fx8_15;
|
||||
struct {
|
||||
TBICTXEXTFPACC fpacc;
|
||||
TBICTXEXTBB4 unused;
|
||||
} nofx8_15;
|
||||
} extfpstate;
|
||||
bool needs_restore;
|
||||
};
|
||||
#else
|
||||
struct meta_fpu_context {};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_METAG_DSP
|
||||
struct meta_ext_context {
|
||||
struct {
|
||||
TBIEXTCTX ctx;
|
||||
TBICTXEXTBB8 bb8;
|
||||
TBIDUAL ax[TBICTXEXTAXX_BYTES / sizeof(TBIDUAL)];
|
||||
TBICTXEXTHL2 hl2;
|
||||
TBICTXEXTTDPR ext;
|
||||
TBICTXEXTRP6 rp;
|
||||
} regs;
|
||||
|
||||
/* DSPRAM A and B save areas. */
|
||||
void *ram[2];
|
||||
|
||||
/* ECH encoded size of DSPRAM save areas. */
|
||||
unsigned int ram_sz[2];
|
||||
};
|
||||
#else
|
||||
struct meta_ext_context {};
|
||||
#endif
|
||||
|
||||
struct thread_struct {
|
||||
PTBICTX kernel_context;
|
||||
/* A copy of the user process Sig.SaveMask. */
|
||||
unsigned int user_flags;
|
||||
struct meta_fpu_context *fpu_context;
|
||||
void __user *tls_ptr;
|
||||
unsigned short int_depth;
|
||||
unsigned short txdefr_failure;
|
||||
struct meta_ext_context *dsp_context;
|
||||
};
|
||||
|
||||
#define INIT_THREAD { \
|
||||
NULL, /* kernel_context */ \
|
||||
0, /* user_flags */ \
|
||||
NULL, /* fpu_context */ \
|
||||
NULL, /* tls_ptr */ \
|
||||
1, /* int_depth - we start in kernel */ \
|
||||
0, /* txdefr_failure */ \
|
||||
NULL, /* dsp_context */ \
|
||||
}
|
||||
|
||||
/* Needed to make #define as we are referencing 'current', that is not visible
|
||||
* yet.
|
||||
*
|
||||
* Stack layout is as below.
|
||||
|
||||
argc argument counter (integer)
|
||||
argv[0] program name (pointer)
|
||||
argv[1...N] program args (pointers)
|
||||
argv[argc-1] end of args (integer)
|
||||
NULL
|
||||
env[0...N] environment variables (pointers)
|
||||
NULL
|
||||
|
||||
*/
|
||||
#define start_thread(regs, pc, usp) do { \
|
||||
unsigned int *argc = (unsigned int *) bprm->exec; \
|
||||
current->thread.int_depth = 1; \
|
||||
/* Force this process down to user land */ \
|
||||
regs->ctx.SaveMask = TBICTX_PRIV_BIT; \
|
||||
regs->ctx.CurrPC = pc; \
|
||||
regs->ctx.AX[0].U0 = usp; \
|
||||
regs->ctx.DX[3].U1 = *((int *)argc); /* argc */ \
|
||||
regs->ctx.DX[3].U0 = (int)((int *)argc + 1); /* argv */ \
|
||||
regs->ctx.DX[2].U1 = (int)((int *)argc + \
|
||||
regs->ctx.DX[3].U1 + 2); /* envp */ \
|
||||
regs->ctx.DX[2].U0 = 0; /* rtld_fini */ \
|
||||
} while (0)
|
||||
|
||||
/* Forward declaration, a strange C thing */
|
||||
struct task_struct;
|
||||
|
||||
/* Free all resources held by a thread. */
|
||||
static inline void release_thread(struct task_struct *dead_task)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Return saved PC of a blocked thread.
|
||||
*/
|
||||
#define thread_saved_pc(tsk) \
|
||||
((unsigned long)(tsk)->thread.kernel_context->CurrPC)
|
||||
#define thread_saved_sp(tsk) \
|
||||
((unsigned long)(tsk)->thread.kernel_context->AX[0].U0)
|
||||
#define thread_saved_fp(tsk) \
|
||||
((unsigned long)(tsk)->thread.kernel_context->AX[1].U0)
|
||||
|
||||
unsigned long get_wchan(struct task_struct *p);
|
||||
|
||||
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->ctx.CurrPC)
|
||||
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->ctx.AX[0].U0)
|
||||
|
||||
#define user_stack_pointer(regs) ((regs)->ctx.AX[0].U0)
|
||||
|
||||
#define cpu_relax() barrier()
|
||||
|
||||
extern void setup_priv(void);
|
||||
|
||||
static inline unsigned int hard_processor_id(void)
|
||||
{
|
||||
unsigned int id;
|
||||
|
||||
asm volatile ("MOV %0, TXENABLE\n"
|
||||
"AND %0, %0, %1\n"
|
||||
"LSR %0, %0, %2\n"
|
||||
: "=&d" (id)
|
||||
: "I" (TXENABLE_THREAD_BITS),
|
||||
"K" (TXENABLE_THREAD_S)
|
||||
);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
#define OP3_EXIT 0
|
||||
|
||||
#define HALT_OK 0
|
||||
#define HALT_PANIC -1
|
||||
|
||||
/*
|
||||
* Halt (stop) the hardware thread. This instruction sequence is the
|
||||
* standard way to cause a Meta hardware thread to exit. The exit code
|
||||
* is pushed onto the stack which is interpreted by the debug adapter.
|
||||
*/
|
||||
static inline void hard_processor_halt(int exit_code)
|
||||
{
|
||||
asm volatile ("MOV D1Ar1, %0\n"
|
||||
"MOV D0Ar6, %1\n"
|
||||
"MSETL [A0StP],D0Ar6,D0Ar4,D0Ar2\n"
|
||||
"1:\n"
|
||||
"SWITCH #0xC30006\n"
|
||||
"B 1b\n"
|
||||
: : "r" (exit_code), "K" (OP3_EXIT));
|
||||
}
|
||||
|
||||
/* Set these hooks to call SoC specific code to restart/halt/power off. */
|
||||
extern void (*soc_restart)(char *cmd);
|
||||
extern void (*soc_halt)(void);
|
||||
|
||||
extern void show_trace(struct task_struct *tsk, unsigned long *sp,
|
||||
struct pt_regs *regs);
|
||||
|
||||
extern const struct seq_operations cpuinfo_op;
|
||||
|
||||
#endif
|
@ -1,61 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _METAG_PTRACE_H
|
||||
#define _METAG_PTRACE_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <uapi/asm/ptrace.h>
|
||||
#include <asm/tbx.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* this struct defines the way the registers are stored on the
|
||||
stack during a system call. */
|
||||
|
||||
struct pt_regs {
|
||||
TBICTX ctx;
|
||||
TBICTXEXTCB0 extcb0[5];
|
||||
};
|
||||
|
||||
#define user_mode(regs) (((regs)->ctx.SaveMask & TBICTX_PRIV_BIT) > 0)
|
||||
|
||||
#define instruction_pointer(regs) ((unsigned long)(regs)->ctx.CurrPC)
|
||||
#define profile_pc(regs) instruction_pointer(regs)
|
||||
|
||||
#define task_pt_regs(task) \
|
||||
((struct pt_regs *)(task_stack_page(task) + \
|
||||
sizeof(struct thread_info)))
|
||||
|
||||
#define current_pt_regs() \
|
||||
((struct pt_regs *)((char *)current_thread_info() + \
|
||||
sizeof(struct thread_info)))
|
||||
|
||||
int syscall_trace_enter(struct pt_regs *regs);
|
||||
void syscall_trace_leave(struct pt_regs *regs);
|
||||
|
||||
/* copy a struct user_gp_regs out to user */
|
||||
int metag_gp_regs_copyout(const struct pt_regs *regs,
|
||||
unsigned int pos, unsigned int count,
|
||||
void *kbuf, void __user *ubuf);
|
||||
/* copy a struct user_gp_regs in from user */
|
||||
int metag_gp_regs_copyin(struct pt_regs *regs,
|
||||
unsigned int pos, unsigned int count,
|
||||
const void *kbuf, const void __user *ubuf);
|
||||
/* copy a struct user_cb_regs out to user */
|
||||
int metag_cb_regs_copyout(const struct pt_regs *regs,
|
||||
unsigned int pos, unsigned int count,
|
||||
void *kbuf, void __user *ubuf);
|
||||
/* copy a struct user_cb_regs in from user */
|
||||
int metag_cb_regs_copyin(struct pt_regs *regs,
|
||||
unsigned int pos, unsigned int count,
|
||||
const void *kbuf, const void __user *ubuf);
|
||||
/* copy a struct user_rp_state out to user */
|
||||
int metag_rp_state_copyout(const struct pt_regs *regs,
|
||||
unsigned int pos, unsigned int count,
|
||||
void *kbuf, void __user *ubuf);
|
||||
/* copy a struct user_rp_state in from user */
|
||||
int metag_rp_state_copyin(struct pt_regs *regs,
|
||||
unsigned int pos, unsigned int count,
|
||||
const void *kbuf, const void __user *ubuf);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* _METAG_PTRACE_H */
|
@ -1,10 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_METAG_SETUP_H
|
||||
#define _ASM_METAG_SETUP_H
|
||||
|
||||
#include <uapi/asm/setup.h>
|
||||
|
||||
extern const struct machine_desc *setup_machine_fdt(void *dt);
|
||||
void per_cpu_trap_init(unsigned long);
|
||||
extern void __init dump_machine_table(void);
|
||||
#endif /* _ASM_METAG_SETUP_H */
|
@ -1,28 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_SMP_H
|
||||
#define __ASM_SMP_H
|
||||
|
||||
#include <linux/cpumask.h>
|
||||
|
||||
#define raw_smp_processor_id() (current_thread_info()->cpu)
|
||||
|
||||
enum ipi_msg_type {
|
||||
IPI_CALL_FUNC,
|
||||
IPI_RESCHEDULE,
|
||||
};
|
||||
|
||||
extern void arch_send_call_function_single_ipi(int cpu);
|
||||
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
|
||||
|
||||
asmlinkage void secondary_start_kernel(void);
|
||||
|
||||
extern void secondary_startup(void);
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
extern void __cpu_die(unsigned int cpu);
|
||||
extern int __cpu_disable(void);
|
||||
extern void cpu_die(void);
|
||||
#endif
|
||||
|
||||
extern void smp_init_cpus(void);
|
||||
#endif /* __ASM_SMP_H */
|
@ -1,14 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_SPARSEMEM_H
|
||||
#define __ASM_METAG_SPARSEMEM_H
|
||||
|
||||
/*
|
||||
* SECTION_SIZE_BITS 2^N: how big each section will be
|
||||
* MAX_PHYSADDR_BITS 2^N: how much physical address space we have
|
||||
* MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space
|
||||
*/
|
||||
#define SECTION_SIZE_BITS 26
|
||||
#define MAX_PHYSADDR_BITS 32
|
||||
#define MAX_PHYSMEM_BITS 32
|
||||
|
||||
#endif /* __ASM_METAG_SPARSEMEM_H */
|
@ -1,19 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_SPINLOCK_H
|
||||
#define __ASM_SPINLOCK_H
|
||||
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
#ifdef CONFIG_METAG_ATOMICITY_LOCK1
|
||||
#include <asm/spinlock_lock1.h>
|
||||
#else
|
||||
#include <asm/spinlock_lnkget.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* both lock1 and lnkget are test-and-set spinlocks with 0 unlocked and 1
|
||||
* locked.
|
||||
*/
|
||||
|
||||
#endif /* __ASM_SPINLOCK_H */
|
@ -1,213 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_SPINLOCK_LNKGET_H
|
||||
#define __ASM_SPINLOCK_LNKGET_H
|
||||
|
||||
/*
|
||||
* None of these asm statements clobber memory as LNKSET writes around
|
||||
* the cache so the memory it modifies cannot safely be read by any means
|
||||
* other than these accessors.
|
||||
*/
|
||||
|
||||
static inline int arch_spin_is_locked(arch_spinlock_t *lock)
|
||||
{
|
||||
int ret;
|
||||
|
||||
asm volatile ("LNKGETD %0, [%1]\n"
|
||||
"TST %0, #1\n"
|
||||
"MOV %0, #1\n"
|
||||
"XORZ %0, %0, %0\n"
|
||||
: "=&d" (ret)
|
||||
: "da" (&lock->lock)
|
||||
: "cc");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void arch_spin_lock(arch_spinlock_t *lock)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
asm volatile ("1: LNKGETD %0,[%1]\n"
|
||||
" TST %0, #1\n"
|
||||
" ADD %0, %0, #1\n"
|
||||
" LNKSETDZ [%1], %0\n"
|
||||
" BNZ 1b\n"
|
||||
" DEFR %0, TXSTAT\n"
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n"
|
||||
" CMPT %0, #HI(0x02000000)\n"
|
||||
" BNZ 1b\n"
|
||||
: "=&d" (tmp)
|
||||
: "da" (&lock->lock)
|
||||
: "cc");
|
||||
|
||||
smp_mb();
|
||||
}
|
||||
|
||||
/* Returns 0 if failed to acquire lock */
|
||||
static inline int arch_spin_trylock(arch_spinlock_t *lock)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
asm volatile (" LNKGETD %0,[%1]\n"
|
||||
" TST %0, #1\n"
|
||||
" ADD %0, %0, #1\n"
|
||||
" LNKSETDZ [%1], %0\n"
|
||||
" BNZ 1f\n"
|
||||
" DEFR %0, TXSTAT\n"
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n"
|
||||
" CMPT %0, #HI(0x02000000)\n"
|
||||
" MOV %0, #1\n"
|
||||
"1: XORNZ %0, %0, %0\n"
|
||||
: "=&d" (tmp)
|
||||
: "da" (&lock->lock)
|
||||
: "cc");
|
||||
|
||||
smp_mb();
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static inline void arch_spin_unlock(arch_spinlock_t *lock)
|
||||
{
|
||||
smp_mb();
|
||||
|
||||
asm volatile (" SETD [%0], %1\n"
|
||||
:
|
||||
: "da" (&lock->lock), "da" (0)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
/*
|
||||
* RWLOCKS
|
||||
*
|
||||
*
|
||||
* Write locks are easy - we just set bit 31. When unlocking, we can
|
||||
* just write zero since the lock is exclusively held.
|
||||
*/
|
||||
|
||||
static inline void arch_write_lock(arch_rwlock_t *rw)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
asm volatile ("1: LNKGETD %0,[%1]\n"
|
||||
" CMP %0, #0\n"
|
||||
" ADD %0, %0, %2\n"
|
||||
" LNKSETDZ [%1], %0\n"
|
||||
" BNZ 1b\n"
|
||||
" DEFR %0, TXSTAT\n"
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n"
|
||||
" CMPT %0, #HI(0x02000000)\n"
|
||||
" BNZ 1b\n"
|
||||
: "=&d" (tmp)
|
||||
: "da" (&rw->lock), "bd" (0x80000000)
|
||||
: "cc");
|
||||
|
||||
smp_mb();
|
||||
}
|
||||
|
||||
static inline int arch_write_trylock(arch_rwlock_t *rw)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
asm volatile (" LNKGETD %0,[%1]\n"
|
||||
" CMP %0, #0\n"
|
||||
" ADD %0, %0, %2\n"
|
||||
" LNKSETDZ [%1], %0\n"
|
||||
" BNZ 1f\n"
|
||||
" DEFR %0, TXSTAT\n"
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n"
|
||||
" CMPT %0, #HI(0x02000000)\n"
|
||||
" MOV %0,#1\n"
|
||||
"1: XORNZ %0, %0, %0\n"
|
||||
: "=&d" (tmp)
|
||||
: "da" (&rw->lock), "bd" (0x80000000)
|
||||
: "cc");
|
||||
|
||||
smp_mb();
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static inline void arch_write_unlock(arch_rwlock_t *rw)
|
||||
{
|
||||
smp_mb();
|
||||
|
||||
asm volatile (" SETD [%0], %1\n"
|
||||
:
|
||||
: "da" (&rw->lock), "da" (0)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
/*
|
||||
* Read locks are a bit more hairy:
|
||||
* - Exclusively load the lock value.
|
||||
* - Increment it.
|
||||
* - Store new lock value if positive, and we still own this location.
|
||||
* If the value is negative, we've already failed.
|
||||
* - If we failed to store the value, we want a negative result.
|
||||
* - If we failed, try again.
|
||||
* Unlocking is similarly hairy. We may have multiple read locks
|
||||
* currently active. However, we know we won't have any write
|
||||
* locks.
|
||||
*/
|
||||
static inline void arch_read_lock(arch_rwlock_t *rw)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
asm volatile ("1: LNKGETD %0,[%1]\n"
|
||||
" ADDS %0, %0, #1\n"
|
||||
" LNKSETDPL [%1], %0\n"
|
||||
" BMI 1b\n"
|
||||
" DEFR %0, TXSTAT\n"
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n"
|
||||
" CMPT %0, #HI(0x02000000)\n"
|
||||
" BNZ 1b\n"
|
||||
: "=&d" (tmp)
|
||||
: "da" (&rw->lock)
|
||||
: "cc");
|
||||
|
||||
smp_mb();
|
||||
}
|
||||
|
||||
static inline void arch_read_unlock(arch_rwlock_t *rw)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
smp_mb();
|
||||
|
||||
asm volatile ("1: LNKGETD %0,[%1]\n"
|
||||
" SUB %0, %0, #1\n"
|
||||
" LNKSETD [%1], %0\n"
|
||||
" DEFR %0, TXSTAT\n"
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n"
|
||||
" CMPT %0, #HI(0x02000000)\n"
|
||||
" BNZ 1b\n"
|
||||
: "=&d" (tmp)
|
||||
: "da" (&rw->lock)
|
||||
: "cc", "memory");
|
||||
}
|
||||
|
||||
static inline int arch_read_trylock(arch_rwlock_t *rw)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
asm volatile (" LNKGETD %0,[%1]\n"
|
||||
" ADDS %0, %0, #1\n"
|
||||
" LNKSETDPL [%1], %0\n"
|
||||
" BMI 1f\n"
|
||||
" DEFR %0, TXSTAT\n"
|
||||
" ANDT %0, %0, #HI(0x3f000000)\n"
|
||||
" CMPT %0, #HI(0x02000000)\n"
|
||||
" MOV %0,#1\n"
|
||||
" BZ 2f\n"
|
||||
"1: MOV %0,#0\n"
|
||||
"2:\n"
|
||||
: "=&d" (tmp)
|
||||
: "da" (&rw->lock)
|
||||
: "cc");
|
||||
|
||||
smp_mb();
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
#endif /* __ASM_SPINLOCK_LNKGET_H */
|
@ -1,165 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_SPINLOCK_LOCK1_H
|
||||
#define __ASM_SPINLOCK_LOCK1_H
|
||||
|
||||
#include <asm/bug.h>
|
||||
#include <asm/global_lock.h>
|
||||
|
||||
static inline int arch_spin_is_locked(arch_spinlock_t *lock)
|
||||
{
|
||||
int ret;
|
||||
|
||||
barrier();
|
||||
ret = lock->lock;
|
||||
WARN_ON(ret != 0 && ret != 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void arch_spin_lock(arch_spinlock_t *lock)
|
||||
{
|
||||
unsigned int we_won = 0;
|
||||
unsigned long flags;
|
||||
|
||||
again:
|
||||
__global_lock1(flags);
|
||||
if (lock->lock == 0) {
|
||||
fence();
|
||||
lock->lock = 1;
|
||||
we_won = 1;
|
||||
}
|
||||
__global_unlock1(flags);
|
||||
if (we_won == 0)
|
||||
goto again;
|
||||
WARN_ON(lock->lock != 1);
|
||||
}
|
||||
|
||||
/* Returns 0 if failed to acquire lock */
|
||||
static inline int arch_spin_trylock(arch_spinlock_t *lock)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int ret;
|
||||
|
||||
__global_lock1(flags);
|
||||
ret = lock->lock;
|
||||
if (ret == 0) {
|
||||
fence();
|
||||
lock->lock = 1;
|
||||
}
|
||||
__global_unlock1(flags);
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
static inline void arch_spin_unlock(arch_spinlock_t *lock)
|
||||
{
|
||||
barrier();
|
||||
WARN_ON(!lock->lock);
|
||||
lock->lock = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* RWLOCKS
|
||||
*
|
||||
*
|
||||
* Write locks are easy - we just set bit 31. When unlocking, we can
|
||||
* just write zero since the lock is exclusively held.
|
||||
*/
|
||||
|
||||
static inline void arch_write_lock(arch_rwlock_t *rw)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int we_won = 0;
|
||||
|
||||
again:
|
||||
__global_lock1(flags);
|
||||
if (rw->lock == 0) {
|
||||
fence();
|
||||
rw->lock = 0x80000000;
|
||||
we_won = 1;
|
||||
}
|
||||
__global_unlock1(flags);
|
||||
if (we_won == 0)
|
||||
goto again;
|
||||
WARN_ON(rw->lock != 0x80000000);
|
||||
}
|
||||
|
||||
static inline int arch_write_trylock(arch_rwlock_t *rw)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int ret;
|
||||
|
||||
__global_lock1(flags);
|
||||
ret = rw->lock;
|
||||
if (ret == 0) {
|
||||
fence();
|
||||
rw->lock = 0x80000000;
|
||||
}
|
||||
__global_unlock1(flags);
|
||||
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
static inline void arch_write_unlock(arch_rwlock_t *rw)
|
||||
{
|
||||
barrier();
|
||||
WARN_ON(rw->lock != 0x80000000);
|
||||
rw->lock = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read locks are a bit more hairy:
|
||||
* - Exclusively load the lock value.
|
||||
* - Increment it.
|
||||
* - Store new lock value if positive, and we still own this location.
|
||||
* If the value is negative, we've already failed.
|
||||
* - If we failed to store the value, we want a negative result.
|
||||
* - If we failed, try again.
|
||||
* Unlocking is similarly hairy. We may have multiple read locks
|
||||
* currently active. However, we know we won't have any write
|
||||
* locks.
|
||||
*/
|
||||
static inline void arch_read_lock(arch_rwlock_t *rw)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int we_won = 0, ret;
|
||||
|
||||
again:
|
||||
__global_lock1(flags);
|
||||
ret = rw->lock;
|
||||
if (ret < 0x80000000) {
|
||||
fence();
|
||||
rw->lock = ret + 1;
|
||||
we_won = 1;
|
||||
}
|
||||
__global_unlock1(flags);
|
||||
if (!we_won)
|
||||
goto again;
|
||||
}
|
||||
|
||||
static inline void arch_read_unlock(arch_rwlock_t *rw)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int ret;
|
||||
|
||||
__global_lock1(flags);
|
||||
fence();
|
||||
ret = rw->lock--;
|
||||
__global_unlock1(flags);
|
||||
WARN_ON(ret == 0);
|
||||
}
|
||||
|
||||
static inline int arch_read_trylock(arch_rwlock_t *rw)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int ret;
|
||||
|
||||
__global_lock1(flags);
|
||||
ret = rw->lock;
|
||||
if (ret < 0x80000000) {
|
||||
fence();
|
||||
rw->lock = ret + 1;
|
||||
}
|
||||
__global_unlock1(flags);
|
||||
return (ret < 0x80000000);
|
||||
}
|
||||
|
||||
#endif /* __ASM_SPINLOCK_LOCK1_H */
|
@ -1,21 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_METAG_SPINLOCK_TYPES_H
|
||||
#define _ASM_METAG_SPINLOCK_TYPES_H
|
||||
|
||||
#ifndef __LINUX_SPINLOCK_TYPES_H
|
||||
# error "please don't include this file directly"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned int lock;
|
||||
} arch_spinlock_t;
|
||||
|
||||
#define __ARCH_SPIN_LOCK_UNLOCKED { 0 }
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned int lock;
|
||||
} arch_rwlock_t;
|
||||
|
||||
#define __ARCH_RW_LOCK_UNLOCKED { 0 }
|
||||
|
||||
#endif /* _ASM_METAG_SPINLOCK_TYPES_H */
|
@ -1,21 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_STACKTRACE_H
|
||||
#define __ASM_STACKTRACE_H
|
||||
|
||||
struct stackframe {
|
||||
unsigned long fp;
|
||||
unsigned long sp;
|
||||
unsigned long lr;
|
||||
unsigned long pc;
|
||||
};
|
||||
|
||||
struct metag_frame {
|
||||
unsigned long fp;
|
||||
unsigned long lr;
|
||||
};
|
||||
|
||||
extern int unwind_frame(struct stackframe *frame);
|
||||
extern void walk_stackframe(struct stackframe *frame,
|
||||
int (*fn)(struct stackframe *, void *), void *data);
|
||||
|
||||
#endif /* __ASM_STACKTRACE_H */
|
@ -1,14 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _METAG_STRING_H_
|
||||
#define _METAG_STRING_H_
|
||||
|
||||
#define __HAVE_ARCH_MEMSET
|
||||
extern void *memset(void *__s, int __c, size_t __count);
|
||||
|
||||
#define __HAVE_ARCH_MEMCPY
|
||||
void *memcpy(void *__to, __const__ void *__from, size_t __n);
|
||||
|
||||
#define __HAVE_ARCH_MEMMOVE
|
||||
extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
|
||||
|
||||
#endif /* _METAG_STRING_H_ */
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Imagination Technologies Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_METAG_SWITCH_H
|
||||
#define _ASM_METAG_SWITCH_H
|
||||
|
||||
/* metag SWITCH codes */
|
||||
#define __METAG_SW_PERM_BREAK 0x400002 /* compiled in breakpoint */
|
||||
#define __METAG_SW_SYS_LEGACY 0x440000 /* legacy system calls */
|
||||
#define __METAG_SW_SYS 0x440001 /* system calls */
|
||||
|
||||
/* metag SWITCH instruction encoding */
|
||||
#define __METAG_SW_ENCODING(TYPE) (0xaf000000 | (__METAG_SW_##TYPE))
|
||||
|
||||
#endif /* _ASM_METAG_SWITCH_H */
|
@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Access to user system call parameters and results
|
||||
*
|
||||
* Copyright (C) 2008 Imagination Technologies Ltd.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU General Public License v.2.
|
||||
*
|
||||
* See asm-generic/syscall.h for descriptions of what we must do here.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_METAG_SYSCALL_H
|
||||
#define _ASM_METAG_SYSCALL_H
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/switch.h>
|
||||
|
||||
static inline long syscall_get_nr(struct task_struct *task,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
unsigned long insn;
|
||||
|
||||
/*
|
||||
* FIXME there's no way to find out how we got here other than to
|
||||
* examine the memory at the PC to see if it is a syscall
|
||||
* SWITCH instruction.
|
||||
*/
|
||||
if (get_user(insn, (unsigned long *)(regs->ctx.CurrPC - 4)))
|
||||
return -1;
|
||||
|
||||
if (insn == __METAG_SW_ENCODING(SYS))
|
||||
return regs->ctx.DX[0].U1;
|
||||
else
|
||||
return -1L;
|
||||
}
|
||||
|
||||
static inline void syscall_rollback(struct task_struct *task,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
static inline long syscall_get_error(struct task_struct *task,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
unsigned long error = regs->ctx.DX[0].U0;
|
||||
return IS_ERR_VALUE(error) ? error : 0;
|
||||
}
|
||||
|
||||
static inline long syscall_get_return_value(struct task_struct *task,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
return regs->ctx.DX[0].U0;
|
||||
}
|
||||
|
||||
static inline void syscall_set_return_value(struct task_struct *task,
|
||||
struct pt_regs *regs,
|
||||
int error, long val)
|
||||
{
|
||||
regs->ctx.DX[0].U0 = (long) error ?: val;
|
||||
}
|
||||
|
||||
static inline void syscall_get_arguments(struct task_struct *task,
|
||||
struct pt_regs *regs,
|
||||
unsigned int i, unsigned int n,
|
||||
unsigned long *args)
|
||||
{
|
||||
unsigned int reg, j;
|
||||
BUG_ON(i + n > 6);
|
||||
|
||||
for (j = i, reg = 6 - i; j < (i + n); j++, reg--) {
|
||||
if (reg % 2)
|
||||
args[j] = regs->ctx.DX[(reg + 1) / 2].U0;
|
||||
else
|
||||
args[j] = regs->ctx.DX[reg / 2].U1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void syscall_set_arguments(struct task_struct *task,
|
||||
struct pt_regs *regs,
|
||||
unsigned int i, unsigned int n,
|
||||
const unsigned long *args)
|
||||
{
|
||||
unsigned int reg;
|
||||
BUG_ON(i + n > 6);
|
||||
|
||||
for (reg = 6 - i; i < (i + n); i++, reg--) {
|
||||
if (reg % 2)
|
||||
regs->ctx.DX[(reg + 1) / 2].U0 = args[i];
|
||||
else
|
||||
regs->ctx.DX[reg / 2].U1 = args[i];
|
||||
}
|
||||
}
|
||||
|
||||
#define NR_syscalls __NR_syscalls
|
||||
|
||||
/* generic syscall table */
|
||||
extern const void *sys_call_table[];
|
||||
|
||||
#endif /* _ASM_METAG_SYSCALL_H */
|
@ -1,40 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_METAG_SYSCALLS_H
|
||||
#define _ASM_METAG_SYSCALLS_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/signal.h>
|
||||
|
||||
/* kernel/signal.c */
|
||||
#define sys_rt_sigreturn sys_rt_sigreturn
|
||||
asmlinkage long sys_rt_sigreturn(void);
|
||||
|
||||
#include <asm-generic/syscalls.h>
|
||||
|
||||
/* kernel/sys_metag.c */
|
||||
asmlinkage int sys_metag_setglobalbit(char __user *, int);
|
||||
asmlinkage void sys_metag_set_fpu_flags(unsigned int);
|
||||
asmlinkage int sys_metag_set_tls(void __user *);
|
||||
asmlinkage void *sys_metag_get_tls(void);
|
||||
|
||||
asmlinkage long sys_truncate64_metag(const char __user *, unsigned long,
|
||||
unsigned long);
|
||||
asmlinkage long sys_ftruncate64_metag(unsigned int, unsigned long,
|
||||
unsigned long);
|
||||
asmlinkage long sys_fadvise64_64_metag(int, unsigned long, unsigned long,
|
||||
unsigned long, unsigned long, int);
|
||||
asmlinkage long sys_readahead_metag(int, unsigned long, unsigned long, size_t);
|
||||
asmlinkage ssize_t sys_pread64_metag(unsigned long, char __user *, size_t,
|
||||
unsigned long, unsigned long);
|
||||
asmlinkage ssize_t sys_pwrite64_metag(unsigned long, char __user *, size_t,
|
||||
unsigned long, unsigned long);
|
||||
asmlinkage long sys_sync_file_range_metag(int, unsigned long, unsigned long,
|
||||
unsigned long, unsigned long,
|
||||
unsigned int);
|
||||
|
||||
int do_work_pending(struct pt_regs *regs, unsigned int thread_flags,
|
||||
int syscall);
|
||||
|
||||
#endif /* _ASM_METAG_SYSCALLS_H */
|
File diff suppressed because it is too large
Load Diff
@ -1,31 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_TCM_H__
|
||||
#define __ASM_TCM_H__
|
||||
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
struct tcm_allocation {
|
||||
struct list_head list;
|
||||
unsigned int tag;
|
||||
unsigned long addr;
|
||||
unsigned long size;
|
||||
};
|
||||
|
||||
/*
|
||||
* TCM memory region descriptor.
|
||||
*/
|
||||
struct tcm_region {
|
||||
unsigned int tag;
|
||||
struct resource res;
|
||||
};
|
||||
|
||||
#define TCM_INVALID_TAG 0xffffffff
|
||||
|
||||
unsigned long tcm_alloc(unsigned int tag, size_t len);
|
||||
void tcm_free(unsigned int tag, unsigned long addr, size_t len);
|
||||
unsigned int tcm_lookup_tag(unsigned long p);
|
||||
|
||||
int tcm_add_region(struct tcm_region *reg);
|
||||
|
||||
#endif
|
@ -1,141 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* thread_info.h: Meta low-level thread information
|
||||
*
|
||||
* Copyright (C) 2002 David Howells (dhowells@redhat.com)
|
||||
* - Incorporating suggestions made by Linus Torvalds and Dave Miller
|
||||
*
|
||||
* Meta port by Imagination Technologies
|
||||
*/
|
||||
|
||||
#ifndef _ASM_THREAD_INFO_H
|
||||
#define _ASM_THREAD_INFO_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm/processor.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* low level task data that entry.S needs immediate access to
|
||||
* - this struct should fit entirely inside of one cache line
|
||||
* - this struct shares the supervisor stack pages
|
||||
* - if the contents of this structure are changed, the assembly constants must
|
||||
* also be changed
|
||||
*/
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* This must be 8 byte aligned so we can ensure stack alignment. */
|
||||
struct thread_info {
|
||||
struct task_struct *task; /* main task structure */
|
||||
unsigned long flags; /* low level flags */
|
||||
unsigned long status; /* thread-synchronous flags */
|
||||
u32 cpu; /* current CPU */
|
||||
int preempt_count; /* 0 => preemptable, <0 => BUG */
|
||||
|
||||
mm_segment_t addr_limit; /* thread address space */
|
||||
|
||||
u8 supervisor_stack[0] __aligned(8);
|
||||
};
|
||||
|
||||
#else /* !__ASSEMBLY__ */
|
||||
|
||||
#include <generated/asm-offsets.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_4KSTACKS
|
||||
#define THREAD_SHIFT 12
|
||||
#else
|
||||
#define THREAD_SHIFT 13
|
||||
#endif
|
||||
|
||||
#if THREAD_SHIFT >= PAGE_SHIFT
|
||||
#define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT)
|
||||
#else
|
||||
#define THREAD_SIZE_ORDER 0
|
||||
#endif
|
||||
|
||||
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
|
||||
|
||||
#define STACK_WARN (THREAD_SIZE/8)
|
||||
/*
|
||||
* macros/functions for gaining access to the thread information structure
|
||||
*/
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define INIT_THREAD_INFO(tsk) \
|
||||
{ \
|
||||
.task = &tsk, \
|
||||
.flags = 0, \
|
||||
.cpu = 0, \
|
||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||
.addr_limit = KERNEL_DS, \
|
||||
}
|
||||
|
||||
/* how to get the current stack pointer from C */
|
||||
register unsigned long current_stack_pointer asm("A0StP") __used;
|
||||
|
||||
/* how to get the thread information struct from C */
|
||||
static inline struct thread_info *current_thread_info(void)
|
||||
{
|
||||
return (struct thread_info *)(current_stack_pointer &
|
||||
~(THREAD_SIZE - 1));
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_KSTACK_END
|
||||
static inline int kstack_end(void *addr)
|
||||
{
|
||||
return addr == (void *) (((unsigned long) addr & ~(THREAD_SIZE - 1))
|
||||
+ sizeof(struct thread_info));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* thread information flags
|
||||
* - these are process state flags that various assembly files may need to
|
||||
* access
|
||||
* - pending work-to-be-done flags are in LSW
|
||||
* - other flags in MSW
|
||||
*/
|
||||
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
|
||||
#define TIF_SIGPENDING 1 /* signal pending */
|
||||
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
|
||||
#define TIF_SINGLESTEP 3 /* restore singlestep on return to user
|
||||
mode */
|
||||
#define TIF_SYSCALL_AUDIT 4 /* syscall auditing active */
|
||||
#define TIF_SECCOMP 5 /* secure computing */
|
||||
#define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */
|
||||
#define TIF_NOTIFY_RESUME 7 /* callback before returning to user */
|
||||
#define TIF_MEMDIE 8 /* is terminating due to OOM killer */
|
||||
#define TIF_SYSCALL_TRACEPOINT 9 /* syscall tracepoint instrumentation */
|
||||
|
||||
|
||||
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
|
||||
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
|
||||
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
|
||||
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
|
||||
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
|
||||
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
|
||||
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
|
||||
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
|
||||
#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
|
||||
|
||||
/* work to do in syscall trace */
|
||||
#define _TIF_WORK_SYSCALL_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
|
||||
_TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
|
||||
_TIF_SYSCALL_TRACEPOINT)
|
||||
|
||||
/* work to do on any return to u-space */
|
||||
#define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \
|
||||
_TIF_NEED_RESCHED | _TIF_SYSCALL_AUDIT | \
|
||||
_TIF_SINGLESTEP | _TIF_RESTORE_SIGMASK | \
|
||||
_TIF_NOTIFY_RESUME)
|
||||
|
||||
/* work to do on interrupt/exception return */
|
||||
#define _TIF_WORK_MASK (_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \
|
||||
_TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP))
|
||||
|
||||
#endif /* _ASM_THREAD_INFO_H */
|
@ -1,37 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_TLB_H
|
||||
#define __ASM_METAG_TLB_H
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
/* Note, read http://lkml.org/lkml/2004/1/15/6 */
|
||||
|
||||
#ifdef CONFIG_METAG_META12
|
||||
|
||||
#define tlb_start_vma(tlb, vma) \
|
||||
do { \
|
||||
if (!tlb->fullmm) \
|
||||
flush_cache_range(vma, vma->vm_start, vma->vm_end); \
|
||||
} while (0)
|
||||
|
||||
#define tlb_end_vma(tlb, vma) \
|
||||
do { \
|
||||
if (!tlb->fullmm) \
|
||||
flush_tlb_range(vma, vma->vm_start, vma->vm_end); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define tlb_start_vma(tlb, vma) do { } while (0)
|
||||
#define tlb_end_vma(tlb, vma) do { } while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#define __tlb_remove_tlb_entry(tlb, pte, addr) do { } while (0)
|
||||
#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
|
||||
|
||||
#include <asm-generic/tlb.h>
|
||||
|
||||
#endif
|
@ -1,78 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_METAG_TLBFLUSH_H
|
||||
#define __ASM_METAG_TLBFLUSH_H
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/sched.h>
|
||||
#include <asm/metag_mem.h>
|
||||
#include <asm/pgalloc.h>
|
||||
|
||||
/*
|
||||
* TLB flushing:
|
||||
*
|
||||
* - flush_tlb() flushes the current mm struct TLBs
|
||||
* - flush_tlb_all() flushes all processes TLBs
|
||||
* - flush_tlb_mm(mm) flushes the specified mm context TLB's
|
||||
* - flush_tlb_page(vma, vmaddr) flushes one page
|
||||
* - flush_tlb_range(mm, start, end) flushes a range of pages
|
||||
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
|
||||
* - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
|
||||
*
|
||||
* FIXME: Meta 2 can flush single TLB entries.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_METAG_META21) && !defined(CONFIG_SMP)
|
||||
static inline void __flush_tlb(void)
|
||||
{
|
||||
/* flush TLB entries for just the current hardware thread */
|
||||
int thread = hard_processor_id();
|
||||
metag_out32(0, (LINSYSCFLUSH_TxMMCU_BASE +
|
||||
LINSYSCFLUSH_TxMMCU_STRIDE * thread));
|
||||
}
|
||||
#else
|
||||
static inline void __flush_tlb(void)
|
||||
{
|
||||
/* flush TLB entries for all hardware threads */
|
||||
metag_out32(0, LINSYSCFLUSH_MMCU);
|
||||
}
|
||||
#endif /* defined(CONFIG_METAG_META21) && !defined(CONFIG_SMP) */
|
||||
|
||||
#define flush_tlb() __flush_tlb()
|
||||
|
||||
#define flush_tlb_all() __flush_tlb()
|
||||
|
||||
#define local_flush_tlb_all() __flush_tlb()
|
||||
|
||||
static inline void flush_tlb_mm(struct mm_struct *mm)
|
||||
{
|
||||
if (mm == current->active_mm)
|
||||
__flush_tlb();
|
||||
}
|
||||
|
||||
static inline void flush_tlb_page(struct vm_area_struct *vma,
|
||||
unsigned long addr)
|
||||
{
|
||||
flush_tlb_mm(vma->vm_mm);
|
||||
}
|
||||
|
||||
static inline void flush_tlb_range(struct vm_area_struct *vma,
|
||||
unsigned long start, unsigned long end)
|
||||
{
|
||||
flush_tlb_mm(vma->vm_mm);
|
||||
}
|
||||
|
||||
static inline void flush_tlb_pgtables(struct mm_struct *mm,
|
||||
unsigned long start, unsigned long end)
|
||||
{
|
||||
flush_tlb_mm(mm);
|
||||
}
|
||||
|
||||
static inline void flush_tlb_kernel_range(unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
flush_tlb_all();
|
||||
}
|
||||
|
||||
#endif /* __ASM_METAG_TLBFLUSH_H */
|
||||
|
@ -1,28 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_METAG_TOPOLOGY_H
|
||||
#define _ASM_METAG_TOPOLOGY_H
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
|
||||
#define cpu_to_node(cpu) ((void)(cpu), 0)
|
||||
|
||||
#define cpumask_of_node(node) ((void)node, cpu_online_mask)
|
||||
|
||||
#define pcibus_to_node(bus) ((void)(bus), -1)
|
||||
#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \
|
||||
cpu_all_mask : \
|
||||
cpumask_of_node(pcibus_to_node(bus)))
|
||||
|
||||
#endif
|
||||
|
||||
#define mc_capable() (1)
|
||||
|
||||
const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
|
||||
|
||||
extern cpumask_t cpu_core_map[NR_CPUS];
|
||||
|
||||
#define topology_core_cpumask(cpu) (&cpu_core_map[cpu])
|
||||
|
||||
#include <asm-generic/topology.h>
|
||||
|
||||
#endif /* _ASM_METAG_TOPOLOGY_H */
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005,2008 Imagination Technologies
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef _METAG_TBIVECTORS_H
|
||||
#define _METAG_TBIVECTORS_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <asm/tbx.h>
|
||||
|
||||
typedef TBIRES (*kick_irq_func_t)(TBIRES, int, int, int, PTBI, int *);
|
||||
|
||||
extern TBIRES kick_handler(TBIRES, int, int, int, PTBI);
|
||||
struct kick_irq_handler {
|
||||
struct list_head list;
|
||||
kick_irq_func_t func;
|
||||
};
|
||||
|
||||
extern void kick_register_func(struct kick_irq_handler *);
|
||||
extern void kick_unregister_func(struct kick_irq_handler *);
|
||||
|
||||
extern void head_end(TBIRES, unsigned long);
|
||||
extern void restart_critical_section(TBIRES State);
|
||||
extern TBIRES tail_end_sys(TBIRES, int, int *);
|
||||
static inline TBIRES tail_end(TBIRES state)
|
||||
{
|
||||
return tail_end_sys(state, -1, NULL);
|
||||
}
|
||||
|
||||
DECLARE_PER_CPU(PTBI, pTBI);
|
||||
extern PTBI pTBI_get(unsigned int);
|
||||
|
||||
extern int ret_from_fork(TBIRES arg);
|
||||
|
||||
extern int do_page_fault(struct pt_regs *regs, unsigned long address,
|
||||
unsigned int write_access, unsigned int trapno);
|
||||
|
||||
extern TBIRES __TBIUnExpXXX(TBIRES State, int SigNum, int Triggers, int Inst,
|
||||
PTBI pTBI);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _METAG_TBIVECTORS_H */
|
@ -1,213 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __METAG_UACCESS_H
|
||||
#define __METAG_UACCESS_H
|
||||
|
||||
/*
|
||||
* User space memory access functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* The fs value determines whether argument validity checking should be
|
||||
* performed or not. If get_fs() == USER_DS, checking is performed, with
|
||||
* get_fs() == KERNEL_DS, checking is bypassed.
|
||||
*
|
||||
* For historical reasons, these macros are grossly misnamed.
|
||||
*/
|
||||
|
||||
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
|
||||
|
||||
#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
|
||||
#define USER_DS MAKE_MM_SEG(PAGE_OFFSET)
|
||||
|
||||
#define get_ds() (KERNEL_DS)
|
||||
#define get_fs() (current_thread_info()->addr_limit)
|
||||
#define set_fs(x) (current_thread_info()->addr_limit = (x))
|
||||
|
||||
#define segment_eq(a, b) ((a).seg == (b).seg)
|
||||
|
||||
static inline int __access_ok(unsigned long addr, unsigned long size)
|
||||
{
|
||||
/*
|
||||
* Allow access to the user mapped memory area, but not the system area
|
||||
* before it. The check extends to the top of the address space when
|
||||
* kernel access is allowed (there's no real reason to user copy to the
|
||||
* system area in any case).
|
||||
*/
|
||||
if (likely(addr >= META_MEMORY_BASE && addr < get_fs().seg &&
|
||||
size <= get_fs().seg - addr))
|
||||
return true;
|
||||
/*
|
||||
* Explicitly allow NULL pointers here. Parts of the kernel such
|
||||
* as readv/writev use access_ok to validate pointers, but want
|
||||
* to allow NULL pointers for various reasons. NULL pointers are
|
||||
* safe to allow through because the first page is not mappable on
|
||||
* Meta.
|
||||
*/
|
||||
if (!addr)
|
||||
return true;
|
||||
/* Allow access to core code memory area... */
|
||||
if (addr >= LINCORE_CODE_BASE && addr <= LINCORE_CODE_LIMIT &&
|
||||
size <= LINCORE_CODE_LIMIT + 1 - addr)
|
||||
return true;
|
||||
/* ... but no other areas. */
|
||||
return false;
|
||||
}
|
||||
|
||||
#define access_ok(type, addr, size) __access_ok((unsigned long)(addr), \
|
||||
(unsigned long)(size))
|
||||
|
||||
#include <asm/extable.h>
|
||||
|
||||
/*
|
||||
* These are the main single-value transfer routines. They automatically
|
||||
* use the right size if we just have the right pointer type.
|
||||
*/
|
||||
|
||||
#define put_user(x, ptr) \
|
||||
__put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
|
||||
#define __put_user(x, ptr) \
|
||||
__put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
|
||||
|
||||
extern void __put_user_bad(void);
|
||||
|
||||
#define __put_user_nocheck(x, ptr, size) \
|
||||
({ \
|
||||
long __pu_err; \
|
||||
__put_user_size((x), (ptr), (size), __pu_err); \
|
||||
__pu_err; \
|
||||
})
|
||||
|
||||
#define __put_user_check(x, ptr, size) \
|
||||
({ \
|
||||
long __pu_err = -EFAULT; \
|
||||
__typeof__(*(ptr)) __user *__pu_addr = (ptr); \
|
||||
if (access_ok(VERIFY_WRITE, __pu_addr, size)) \
|
||||
__put_user_size((x), __pu_addr, (size), __pu_err); \
|
||||
__pu_err; \
|
||||
})
|
||||
|
||||
extern long __put_user_asm_b(unsigned int x, void __user *addr);
|
||||
extern long __put_user_asm_w(unsigned int x, void __user *addr);
|
||||
extern long __put_user_asm_d(unsigned int x, void __user *addr);
|
||||
extern long __put_user_asm_l(unsigned long long x, void __user *addr);
|
||||
|
||||
#define __put_user_size(x, ptr, size, retval) \
|
||||
do { \
|
||||
retval = 0; \
|
||||
switch (size) { \
|
||||
case 1: \
|
||||
retval = __put_user_asm_b((__force unsigned int)x, ptr);\
|
||||
break; \
|
||||
case 2: \
|
||||
retval = __put_user_asm_w((__force unsigned int)x, ptr);\
|
||||
break; \
|
||||
case 4: \
|
||||
retval = __put_user_asm_d((__force unsigned int)x, ptr);\
|
||||
break; \
|
||||
case 8: \
|
||||
retval = __put_user_asm_l((__force unsigned long long)x,\
|
||||
ptr); \
|
||||
break; \
|
||||
default: \
|
||||
__put_user_bad(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define get_user(x, ptr) \
|
||||
__get_user_check((x), (ptr), sizeof(*(ptr)))
|
||||
#define __get_user(x, ptr) \
|
||||
__get_user_nocheck((x), (ptr), sizeof(*(ptr)))
|
||||
|
||||
extern long __get_user_bad(void);
|
||||
|
||||
#define __get_user_nocheck(x, ptr, size) \
|
||||
({ \
|
||||
long __gu_err; \
|
||||
long long __gu_val; \
|
||||
__get_user_size(__gu_val, (ptr), (size), __gu_err); \
|
||||
(x) = (__force __typeof__(*(ptr)))__gu_val; \
|
||||
__gu_err; \
|
||||
})
|
||||
|
||||
#define __get_user_check(x, ptr, size) \
|
||||
({ \
|
||||
long __gu_err = -EFAULT; \
|
||||
long long __gu_val = 0; \
|
||||
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
|
||||
if (access_ok(VERIFY_READ, __gu_addr, size)) \
|
||||
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
|
||||
(x) = (__force __typeof__(*(ptr)))__gu_val; \
|
||||
__gu_err; \
|
||||
})
|
||||
|
||||
extern unsigned char __get_user_asm_b(const void __user *addr, long *err);
|
||||
extern unsigned short __get_user_asm_w(const void __user *addr, long *err);
|
||||
extern unsigned int __get_user_asm_d(const void __user *addr, long *err);
|
||||
extern unsigned long long __get_user_asm_l(const void __user *addr, long *err);
|
||||
|
||||
#define __get_user_size(x, ptr, size, retval) \
|
||||
do { \
|
||||
retval = 0; \
|
||||
switch (size) { \
|
||||
case 1: \
|
||||
x = __get_user_asm_b(ptr, &retval); break; \
|
||||
case 2: \
|
||||
x = __get_user_asm_w(ptr, &retval); break; \
|
||||
case 4: \
|
||||
x = __get_user_asm_d(ptr, &retval); break; \
|
||||
case 8: \
|
||||
x = __get_user_asm_l(ptr, &retval); break; \
|
||||
default: \
|
||||
(x) = __get_user_bad(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Copy a null terminated string from userspace.
|
||||
*
|
||||
* Must return:
|
||||
* -EFAULT for an exception
|
||||
* count if we hit the buffer limit
|
||||
* bytes copied if we hit a null byte
|
||||
* (without the null byte)
|
||||
*/
|
||||
|
||||
extern long __must_check __strncpy_from_user(char *dst, const char __user *src,
|
||||
long count);
|
||||
|
||||
static inline long
|
||||
strncpy_from_user(char *dst, const char __user *src, long count)
|
||||
{
|
||||
if (!access_ok(VERIFY_READ, src, 1))
|
||||
return -EFAULT;
|
||||
return __strncpy_from_user(dst, src, count);
|
||||
}
|
||||
/*
|
||||
* Return the size of a string (including the ending 0)
|
||||
*
|
||||
* Return 0 on exception, a value greater than N if too long
|
||||
*/
|
||||
extern long __must_check strnlen_user(const char __user *src, long count);
|
||||
|
||||
extern unsigned long raw_copy_from_user(void *to, const void __user *from,
|
||||
unsigned long n);
|
||||
extern unsigned long raw_copy_to_user(void __user *to, const void *from,
|
||||
unsigned long n);
|
||||
|
||||
/*
|
||||
* Zero Userspace
|
||||
*/
|
||||
|
||||
extern unsigned long __must_check __do_clear_user(void __user *to,
|
||||
unsigned long n);
|
||||
|
||||
static inline unsigned long clear_user(void __user *to, unsigned long n)
|
||||
{
|
||||
if (access_ok(VERIFY_WRITE, to, n))
|
||||
return __do_clear_user(to, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
#define __clear_user(to, n) __do_clear_user(to, n)
|
||||
|
||||
#endif /* _METAG_UACCESS_H */
|
@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Imagination Technologies Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <uapi/asm/unistd.h>
|
||||
|
||||
#define __ARCH_WANT_SYS_CLONE
|
@ -1,45 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2010 Imagination Technologies
|
||||
*/
|
||||
|
||||
#ifndef __ASM_METAG_USER_GATEWAY_H
|
||||
#define __ASM_METAG_USER_GATEWAY_H
|
||||
|
||||
#include <asm/page.h>
|
||||
|
||||
/* Page of kernel code accessible to userspace. */
|
||||
#define USER_GATEWAY_PAGE 0x6ffff000
|
||||
/* Offset of TLS pointer array in gateway page. */
|
||||
#define USER_GATEWAY_TLS 0x100
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
extern char __user_gateway_start;
|
||||
extern char __user_gateway_end;
|
||||
|
||||
/* Kernel mapping of the gateway page. */
|
||||
extern void *gateway_page;
|
||||
|
||||
static inline void set_gateway_tls(void __user *tls_ptr)
|
||||
{
|
||||
void **gateway_tls = (void **)(gateway_page + USER_GATEWAY_TLS +
|
||||
hard_processor_id() * 4);
|
||||
|
||||
*gateway_tls = (__force void *)tls_ptr;
|
||||
#ifdef CONFIG_METAG_META12
|
||||
/* Avoid cache aliases on virtually tagged cache. */
|
||||
__builtin_dcache_flush((void *)USER_GATEWAY_PAGE + USER_GATEWAY_TLS +
|
||||
hard_processor_id() * sizeof(void *));
|
||||
#endif
|
||||
}
|
||||
|
||||
extern int __kuser_get_tls(void);
|
||||
extern char *__kuser_get_tls_end[];
|
||||
|
||||
extern int __kuser_cmpxchg(int, int, unsigned long *);
|
||||
extern char *__kuser_cmpxchg_end[];
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,31 +0,0 @@
|
||||
# UAPI Header export list
|
||||
include include/uapi/asm-generic/Kbuild.asm
|
||||
|
||||
generic-y += auxvec.h
|
||||
generic-y += bitsperlong.h
|
||||
generic-y += bpf_perf_event.h
|
||||
generic-y += errno.h
|
||||
generic-y += fcntl.h
|
||||
generic-y += ioctl.h
|
||||
generic-y += ioctls.h
|
||||
generic-y += ipcbuf.h
|
||||
generic-y += kvm_para.h
|
||||
generic-y += mman.h
|
||||
generic-y += msgbuf.h
|
||||
generic-y += param.h
|
||||
generic-y += poll.h
|
||||
generic-y += posix_types.h
|
||||
generic-y += resource.h
|
||||
generic-y += sembuf.h
|
||||
generic-y += setup.h
|
||||
generic-y += shmbuf.h
|
||||
generic-y += shmparam.h
|
||||
generic-y += signal.h
|
||||
generic-y += socket.h
|
||||
generic-y += sockios.h
|
||||
generic-y += stat.h
|
||||
generic-y += statfs.h
|
||||
generic-y += termbits.h
|
||||
generic-y += termios.h
|
||||
generic-y += types.h
|
||||
generic-y += ucontext.h
|
@ -1,2 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#include <linux/byteorder/little_endian.h>
|
@ -1,16 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#ifndef _UAPI_METAG_ECH_H
|
||||
#define _UAPI_METAG_ECH_H
|
||||
|
||||
/*
|
||||
* These bits can be set in the top half of the D0.8 register when DSP context
|
||||
* switching is enabled, in order to support partial DSP context save/restore.
|
||||
*/
|
||||
|
||||
#define TBICTX_XEXT_BIT 0x1000 /* Enable extended context save */
|
||||
#define TBICTX_XTDP_BIT 0x0800 /* DSP accumulators/RAM/templates */
|
||||
#define TBICTX_XHL2_BIT 0x0400 /* Hardware loops */
|
||||
#define TBICTX_XAXX_BIT 0x0200 /* Extended AX registers (A*.4-7) */
|
||||
#define TBICTX_XDX8_BIT 0x0100 /* Extended DX registers (D*.8-15) */
|
||||
|
||||
#endif /* _UAPI_METAG_ECH_H */
|
@ -1,114 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#ifndef _UAPI_METAG_PTRACE_H
|
||||
#define _UAPI_METAG_PTRACE_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* These are the layouts of the regsets returned by the GETREGSET ptrace call
|
||||
*/
|
||||
|
||||
/* user_gp_regs::status */
|
||||
|
||||
/* CBMarker bit (indicates catch state / catch replay) */
|
||||
#define USER_GP_REGS_STATUS_CATCH_BIT (1 << 22)
|
||||
#define USER_GP_REGS_STATUS_CATCH_S 22
|
||||
/* LSM_STEP field (load/store multiple step) */
|
||||
#define USER_GP_REGS_STATUS_LSM_STEP_BITS (0x7 << 8)
|
||||
#define USER_GP_REGS_STATUS_LSM_STEP_S 8
|
||||
/* SCC bit (indicates split 16x16 condition flags) */
|
||||
#define USER_GP_REGS_STATUS_SCC_BIT (1 << 4)
|
||||
#define USER_GP_REGS_STATUS_SCC_S 4
|
||||
|
||||
/* normal condition flags */
|
||||
/* CF_Z bit (Zero flag) */
|
||||
#define USER_GP_REGS_STATUS_CF_Z_BIT (1 << 3)
|
||||
#define USER_GP_REGS_STATUS_CF_Z_S 3
|
||||
/* CF_N bit (Negative flag) */
|
||||
#define USER_GP_REGS_STATUS_CF_N_BIT (1 << 2)
|
||||
#define USER_GP_REGS_STATUS_CF_N_S 2
|
||||
/* CF_V bit (oVerflow flag) */
|
||||
#define USER_GP_REGS_STATUS_CF_V_BIT (1 << 1)
|
||||
#define USER_GP_REGS_STATUS_CF_V_S 1
|
||||
/* CF_C bit (Carry flag) */
|
||||
#define USER_GP_REGS_STATUS_CF_C_BIT (1 << 0)
|
||||
#define USER_GP_REGS_STATUS_CF_C_S 0
|
||||
|
||||
/* split 16x16 condition flags */
|
||||
/* SCF_LZ bit (Low Zero flag) */
|
||||
#define USER_GP_REGS_STATUS_SCF_LZ_BIT (1 << 3)
|
||||
#define USER_GP_REGS_STATUS_SCF_LZ_S 3
|
||||
/* SCF_HZ bit (High Zero flag) */
|
||||
#define USER_GP_REGS_STATUS_SCF_HZ_BIT (1 << 2)
|
||||
#define USER_GP_REGS_STATUS_SCF_HZ_S 2
|
||||
/* SCF_HC bit (High Carry flag) */
|
||||
#define USER_GP_REGS_STATUS_SCF_HC_BIT (1 << 1)
|
||||
#define USER_GP_REGS_STATUS_SCF_HC_S 1
|
||||
/* SCF_LC bit (Low Carry flag) */
|
||||
#define USER_GP_REGS_STATUS_SCF_LC_BIT (1 << 0)
|
||||
#define USER_GP_REGS_STATUS_SCF_LC_S 0
|
||||
|
||||
/**
|
||||
* struct user_gp_regs - User general purpose registers
|
||||
* @dx: GP data unit regs (dx[reg][unit] = D{unit:0-1}.{reg:0-7})
|
||||
* @ax: GP address unit regs (ax[reg][unit] = A{unit:0-1}.{reg:0-3})
|
||||
* @pc: PC register
|
||||
* @status: TXSTATUS register (condition flags, LSM_STEP etc)
|
||||
* @rpt: TXRPT registers (branch repeat counter)
|
||||
* @bpobits: TXBPOBITS register ("branch prediction other" bits)
|
||||
* @mode: TXMODE register
|
||||
* @_pad1: Reserved padding to make sizeof obviously 64bit aligned
|
||||
*
|
||||
* This is the user-visible general purpose register state structure.
|
||||
*
|
||||
* It can be accessed through PTRACE_GETREGSET with NT_PRSTATUS.
|
||||
*
|
||||
* It is also used in the signal context.
|
||||
*/
|
||||
struct user_gp_regs {
|
||||
unsigned long dx[8][2];
|
||||
unsigned long ax[4][2];
|
||||
unsigned long pc;
|
||||
unsigned long status;
|
||||
unsigned long rpt;
|
||||
unsigned long bpobits;
|
||||
unsigned long mode;
|
||||
unsigned long _pad1;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct user_cb_regs - User catch buffer registers
|
||||
* @flags: TXCATCH0 register (fault flags)
|
||||
* @addr: TXCATCH1 register (fault address)
|
||||
* @data: TXCATCH2 and TXCATCH3 registers (low and high data word)
|
||||
*
|
||||
* This is the user-visible catch buffer register state structure containing
|
||||
* information about a failed memory access, and allowing the access to be
|
||||
* modified and replayed.
|
||||
*
|
||||
* It can be accessed through PTRACE_GETREGSET with NT_METAG_CBUF.
|
||||
*/
|
||||
struct user_cb_regs {
|
||||
unsigned long flags;
|
||||
unsigned long addr;
|
||||
unsigned long long data;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct user_rp_state - User read pipeline state
|
||||
* @entries: Read pipeline entries
|
||||
* @mask: Mask of valid pipeline entries (RPMask from TXDIVTIME register)
|
||||
*
|
||||
* This is the user-visible read pipeline state structure containing the entries
|
||||
* currently in the read pipeline and the mask of valid entries.
|
||||
*
|
||||
* It can be accessed through PTRACE_GETREGSET with NT_METAG_RPIPE.
|
||||
*/
|
||||
struct user_rp_state {
|
||||
unsigned long long entries[6];
|
||||
unsigned long mask;
|
||||
};
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _UAPI_METAG_PTRACE_H */
|
@ -1,32 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#ifndef _ASM_METAG_SIGCONTEXT_H
|
||||
#define _ASM_METAG_SIGCONTEXT_H
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
/*
|
||||
* In a sigcontext structure we need to store the active state of the
|
||||
* user process so that it does not get trashed when we call the signal
|
||||
* handler. That not really the same as a user context that we are
|
||||
* going to store on syscall etc.
|
||||
*/
|
||||
struct sigcontext {
|
||||
struct user_gp_regs regs; /* needs to be first */
|
||||
|
||||
/*
|
||||
* Catch registers describing a memory fault.
|
||||
* If USER_GP_REGS_STATUS_CATCH_BIT is set in regs.status then catch
|
||||
* buffers have been saved and will be replayed on sigreturn.
|
||||
* Clear that bit to discard the catch state instead of replaying it.
|
||||
*/
|
||||
struct user_cb_regs cb;
|
||||
|
||||
/*
|
||||
* Read pipeline state. This will get restored on sigreturn.
|
||||
*/
|
||||
struct user_rp_state rp;
|
||||
|
||||
unsigned long oldmask;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,16 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#ifndef _METAG_SIGINFO_H
|
||||
#define _METAG_SIGINFO_H
|
||||
|
||||
#define __ARCH_SI_TRAPNO
|
||||
|
||||
#include <asm-generic/siginfo.h>
|
||||
|
||||
/*
|
||||
* SIGFPE si_codes
|
||||
*/
|
||||
#ifdef __KERNEL__
|
||||
#define FPE_FIXME 0 /* Broken dup of SI_USER */
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif
|
@ -1,27 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#ifndef __ASM_METAG_SWAB_H
|
||||
#define __ASM_METAG_SWAB_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm-generic/swab.h>
|
||||
|
||||
static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
|
||||
{
|
||||
return __builtin_metag_bswaps(x);
|
||||
}
|
||||
#define __arch_swab16 __arch_swab16
|
||||
|
||||
static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
|
||||
{
|
||||
return __builtin_metag_bswap(x);
|
||||
}
|
||||
#define __arch_swab32 __arch_swab32
|
||||
|
||||
static inline __attribute_const__ __u64 __arch_swab64(__u64 x)
|
||||
{
|
||||
return __builtin_metag_bswapll(x);
|
||||
}
|
||||
#define __arch_swab64 __arch_swab64
|
||||
|
||||
#endif /* __ASM_METAG_SWAB_H */
|
@ -1,24 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright (C) 2012 Imagination Technologies Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define __ARCH_WANT_RENAMEAT
|
||||
|
||||
/* Use the standard ABI for syscalls. */
|
||||
#include <asm-generic/unistd.h>
|
||||
|
||||
/* metag-specific syscalls. */
|
||||
#define __NR_metag_setglobalbit (__NR_arch_specific_syscall + 1)
|
||||
__SYSCALL(__NR_metag_setglobalbit, sys_metag_setglobalbit)
|
||||
#define __NR_metag_set_fpu_flags (__NR_arch_specific_syscall + 2)
|
||||
__SYSCALL(__NR_metag_set_fpu_flags, sys_metag_set_fpu_flags)
|
||||
#define __NR_metag_set_tls (__NR_arch_specific_syscall + 3)
|
||||
__SYSCALL(__NR_metag_set_tls, sys_metag_set_tls)
|
||||
#define __NR_metag_get_tls (__NR_arch_specific_syscall + 4)
|
||||
__SYSCALL(__NR_metag_get_tls, sys_metag_get_tls)
|
1
arch/metag/kernel/.gitignore
vendored
1
arch/metag/kernel/.gitignore
vendored
@ -1 +0,0 @@
|
||||
vmlinux.lds
|
@ -1,40 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Makefile for the Linux/Meta kernel.
|
||||
#
|
||||
|
||||
extra-y += head.o
|
||||
extra-y += vmlinux.lds
|
||||
|
||||
obj-y += cachepart.o
|
||||
obj-y += clock.o
|
||||
obj-y += core_reg.o
|
||||
obj-y += devtree.o
|
||||
obj-y += dma.o
|
||||
obj-y += irq.o
|
||||
obj-y += kick.o
|
||||
obj-y += machines.o
|
||||
obj-y += process.o
|
||||
obj-y += ptrace.o
|
||||
obj-y += setup.o
|
||||
obj-y += signal.o
|
||||
obj-y += stacktrace.o
|
||||
obj-y += sys_metag.o
|
||||
obj-y += tbiunexp.o
|
||||
obj-y += time.o
|
||||
obj-y += topology.o
|
||||
obj-y += traps.o
|
||||
obj-y += user_gateway.o
|
||||
|
||||
obj-$(CONFIG_PERF_EVENTS) += perf/
|
||||
|
||||
obj-$(CONFIG_METAG_COREMEM) += coremem.o
|
||||
obj-$(CONFIG_METAG_DA) += da.o
|
||||
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
|
||||
obj-$(CONFIG_FUNCTION_TRACER) += ftrace_stub.o
|
||||
obj-$(CONFIG_MODULES) += metag_ksyms.o
|
||||
obj-$(CONFIG_MODULES) += module.o
|
||||
obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o
|
||||
obj-$(CONFIG_SMP) += smp.o
|
||||
obj-$(CONFIG_METAG_SUSPEND_MEM) += suspend.o
|
||||
obj-$(CONFIG_METAG_USER_TCM) += tcm.o
|
@ -1,15 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* This program is used to generate definitions needed by
|
||||
* assembly language modules.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kbuild.h>
|
||||
#include <linux/thread_info.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
DEFINE(THREAD_INFO_SIZE, sizeof(struct thread_info));
|
||||
return 0;
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Meta cache partition manipulation.
|
||||
*
|
||||
* Copyright 2010 Imagination Technologies Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/cachepart.h>
|
||||
#include <asm/metag_isa.h>
|
||||
#include <asm/metag_mem.h>
|
||||
|
||||
#define SYSC_DCPART(n) (SYSC_DCPART0 + SYSC_xCPARTn_STRIDE * (n))
|
||||
#define SYSC_ICPART(n) (SYSC_ICPART0 + SYSC_xCPARTn_STRIDE * (n))
|
||||
|
||||
#define CACHE_ASSOCIATIVITY 4 /* 4 way set-associative */
|
||||
#define ICACHE 0
|
||||
#define DCACHE 1
|
||||
|
||||
/* The CORE_CONFIG2 register is not available on Meta 1 */
|
||||
#ifdef CONFIG_METAG_META21
|
||||
unsigned int get_dcache_size(void)
|
||||
{
|
||||
unsigned int config2 = metag_in32(METAC_CORE_CONFIG2);
|
||||
unsigned int sz = 0x1000 << ((config2 & METAC_CORECFG2_DCSZ_BITS)
|
||||
>> METAC_CORECFG2_DCSZ_S);
|
||||
if (config2 & METAC_CORECFG2_DCSMALL_BIT)
|
||||
sz >>= 6;
|
||||
return sz;
|
||||
}
|
||||
|
||||
unsigned int get_icache_size(void)
|
||||
{
|
||||
unsigned int config2 = metag_in32(METAC_CORE_CONFIG2);
|
||||
unsigned int sz = 0x1000 << ((config2 & METAC_CORE_C2ICSZ_BITS)
|
||||
>> METAC_CORE_C2ICSZ_S);
|
||||
if (config2 & METAC_CORECFG2_ICSMALL_BIT)
|
||||
sz >>= 6;
|
||||
return sz;
|
||||
}
|
||||
|
||||
unsigned int get_global_dcache_size(void)
|
||||
{
|
||||
unsigned int cpart = metag_in32(SYSC_DCPART(hard_processor_id()));
|
||||
unsigned int temp = cpart & SYSC_xCPARTG_AND_BITS;
|
||||
return (get_dcache_size() * ((temp >> SYSC_xCPARTG_AND_S) + 1)) >> 4;
|
||||
}
|
||||
|
||||
unsigned int get_global_icache_size(void)
|
||||
{
|
||||
unsigned int cpart = metag_in32(SYSC_ICPART(hard_processor_id()));
|
||||
unsigned int temp = cpart & SYSC_xCPARTG_AND_BITS;
|
||||
return (get_icache_size() * ((temp >> SYSC_xCPARTG_AND_S) + 1)) >> 4;
|
||||
}
|
||||
|
||||
static int get_thread_cache_size(unsigned int cache, int thread_id)
|
||||
{
|
||||
unsigned int cache_size;
|
||||
unsigned int t_cache_part;
|
||||
unsigned int isEnabled;
|
||||
unsigned int offset = 0;
|
||||
isEnabled = (cache == DCACHE ? metag_in32(MMCU_DCACHE_CTRL_ADDR) & 0x1 :
|
||||
metag_in32(MMCU_ICACHE_CTRL_ADDR) & 0x1);
|
||||
if (!isEnabled)
|
||||
return 0;
|
||||
#if PAGE_OFFSET >= LINGLOBAL_BASE
|
||||
/* Checking for global cache */
|
||||
cache_size = (cache == DCACHE ? get_global_dcache_size() :
|
||||
get_global_icache_size());
|
||||
offset = 8;
|
||||
#else
|
||||
cache_size = (cache == DCACHE ? get_dcache_size() :
|
||||
get_icache_size());
|
||||
#endif
|
||||
t_cache_part = (cache == DCACHE ?
|
||||
(metag_in32(SYSC_DCPART(thread_id)) >> offset) & 0xF :
|
||||
(metag_in32(SYSC_ICPART(thread_id)) >> offset) & 0xF);
|
||||
switch (t_cache_part) {
|
||||
case 0xF:
|
||||
return cache_size;
|
||||
case 0x7:
|
||||
return cache_size / 2;
|
||||
case 0x3:
|
||||
return cache_size / 4;
|
||||
case 0x1:
|
||||
return cache_size / 8;
|
||||
case 0:
|
||||
return cache_size / 16;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void check_for_cache_aliasing(int thread_id)
|
||||
{
|
||||
int thread_cache_size;
|
||||
unsigned int cache_type;
|
||||
for (cache_type = ICACHE; cache_type <= DCACHE; cache_type++) {
|
||||
thread_cache_size =
|
||||
get_thread_cache_size(cache_type, thread_id);
|
||||
if (thread_cache_size < 0)
|
||||
pr_emerg("Can't read %s cache size\n",
|
||||
cache_type ? "DCACHE" : "ICACHE");
|
||||
else if (thread_cache_size == 0)
|
||||
/* Cache is off. No need to check for aliasing */
|
||||
continue;
|
||||
if (thread_cache_size / CACHE_ASSOCIATIVITY > PAGE_SIZE) {
|
||||
pr_emerg("Potential cache aliasing detected in %s on Thread %d\n",
|
||||
cache_type ? "DCACHE" : "ICACHE", thread_id);
|
||||
pr_warn("Total %s size: %u bytes\n",
|
||||
cache_type ? "DCACHE" : "ICACHE",
|
||||
cache_type ? get_dcache_size()
|
||||
: get_icache_size());
|
||||
pr_warn("Thread %s size: %d bytes\n",
|
||||
cache_type ? "CACHE" : "ICACHE",
|
||||
thread_cache_size);
|
||||
pr_warn("Page Size: %lu bytes\n", PAGE_SIZE);
|
||||
panic("Potential cache aliasing detected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void check_for_cache_aliasing(int thread_id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,110 +0,0 @@
|
||||
/*
|
||||
* arch/metag/kernel/clock.c
|
||||
*
|
||||
* Copyright (C) 2012 Imagination Technologies Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <asm/param.h>
|
||||
#include <asm/clock.h>
|
||||
|
||||
struct meta_clock_desc _meta_clock;
|
||||
|
||||
/* Default machine get_core_freq callback. */
|
||||
static unsigned long get_core_freq_default(void)
|
||||
{
|
||||
#ifdef CONFIG_METAG_META21
|
||||
/*
|
||||
* Meta 2 cores divide down the core clock for the Meta timers, so we
|
||||
* can estimate the core clock from the divider.
|
||||
*/
|
||||
return (metag_in32(EXPAND_TIMER_DIV) + 1) * 1000000;
|
||||
#else
|
||||
/*
|
||||
* On Meta 1 we don't know the core clock, but assuming the Meta timer
|
||||
* is correct it can be estimated based on loops_per_jiffy.
|
||||
*/
|
||||
return (loops_per_jiffy * HZ * 5) >> 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct clk *clk_core;
|
||||
|
||||
/* Clk based get_core_freq callback. */
|
||||
static unsigned long get_core_freq_clk(void)
|
||||
{
|
||||
return clk_get_rate(clk_core);
|
||||
}
|
||||
|
||||
/**
|
||||
* init_metag_core_clock() - Set up core clock from devicetree.
|
||||
*
|
||||
* Checks to see if a "core" clock is provided in the device tree, and overrides
|
||||
* the get_core_freq callback to use it.
|
||||
*/
|
||||
static void __init init_metag_core_clock(void)
|
||||
{
|
||||
/*
|
||||
* See if a core clock is provided by the devicetree (and
|
||||
* registered by the init callback above).
|
||||
*/
|
||||
struct device_node *node;
|
||||
node = of_find_compatible_node(NULL, NULL, "img,meta");
|
||||
if (!node) {
|
||||
pr_warn("%s: no compatible img,meta DT node found\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
clk_core = of_clk_get_by_name(node, "core");
|
||||
if (IS_ERR(clk_core)) {
|
||||
pr_warn("%s: no core clock found in DT\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Override the core frequency callback to use
|
||||
* this clk.
|
||||
*/
|
||||
_meta_clock.get_core_freq = get_core_freq_clk;
|
||||
}
|
||||
|
||||
/**
|
||||
* init_metag_clocks() - Set up clocks from devicetree.
|
||||
*
|
||||
* Set up important clocks from device tree. In particular any needed for clock
|
||||
* sources.
|
||||
*/
|
||||
void __init init_metag_clocks(void)
|
||||
{
|
||||
init_metag_core_clock();
|
||||
|
||||
pr_info("Core clock frequency: %lu Hz\n", get_coreclock());
|
||||
}
|
||||
|
||||
/**
|
||||
* setup_meta_clocks() - Early set up of the Meta clock.
|
||||
* @desc: Clock descriptor usually provided by machine description
|
||||
*
|
||||
* Ensures all callbacks are valid.
|
||||
*/
|
||||
void __init setup_meta_clocks(struct meta_clock_desc *desc)
|
||||
{
|
||||
/* copy callbacks */
|
||||
if (desc)
|
||||
_meta_clock = *desc;
|
||||
|
||||
/* set fallback functions */
|
||||
if (!_meta_clock.get_core_freq)
|
||||
_meta_clock.get_core_freq = get_core_freq_default;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user