You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'for-linus' of git://github.com/openrisc/linux
Pull OpenRISC updates from Stafford Horne:
"The OpenRISC work is a bit more interesting this time, adding SMP
support and a few general cleanups.
Small Things:
- Move OpenRISC docs into Documentation and clean them up
- Document previously undocumented devicetree bindings
- Update the or1ksim dts to use stdout-path
OpenRISC SMP support details:
- First the "use shadow registers" and "define CPU_BIG_ENDIAN as
true" get the architecture ready for SMP.
- The "add 1 and 2 byte cmpxchg support" and "use qspinlocks and
qrwlocks" add the SMP locking infrastructure as needed. Using the
qspinlocks and qrwlocks as suggested by Peter Z while reviewing the
original spinlocks implementation.
- The "support for ompic" adds a new irqchip device which is used for
IPI communication to support SMP.
- The "initial SMP support" adds smp.c and makes changes to all of
the necessary data-structures to be per-cpu.
The remaining patches are bug fixes and debug helpers which I wanted
to keep separate from the "initial SMP support" in order to allow them
to be reviewed on their own. This includes:
- add cacheflush support to fix icache aliasing
- fix initial preempt state for secondary cpu tasks
- sleep instead of spin on secondary wait
- support framepointers and STACKTRACE_SUPPORT
- enable LOCKDEP_SUPPORT and irqflags tracing
- timer sync: Add tick timer sync logic
- fix possible deadlock in timer sync, pointed out by mips guys
Note: the irqchip patch was reviewed with Marc and we agreed to push
it together with these patches"
* tag 'for-linus' of git://github.com/openrisc/linux:
openrisc: fix possible deadlock scenario during timer sync
openrisc: pass endianness info to sparse
openrisc: add tick timer multi-core sync logic
openrisc: enable LOCKDEP_SUPPORT and irqflags tracing
openrisc: support framepointers and STACKTRACE_SUPPORT
openrisc: add simple_smp dts and defconfig for simulators
openrisc: add cacheflush support to fix icache aliasing
openrisc: sleep instead of spin on secondary wait
openrisc: fix initial preempt state for secondary cpu tasks
openrisc: initial SMP support
irqchip: add initial support for ompic
dt-bindings: add openrisc to vendor prefixes list
openrisc: use qspinlocks and qrwlocks
openrisc: add 1 and 2 byte cmpxchg support
openrisc: use shadow registers to save regs on exception
dt-bindings: openrisc: Add OpenRISC platform SoC
Documentation: openrisc: Updates to README
Documentation: Move OpenRISC docs out of arch/
MAINTAINERS: Add OpenRISC pic maintainer
openrisc: dts: or1ksim: Add stdout-path
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
Open Multi-Processor Interrupt Controller
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : This should be "openrisc,ompic"
|
||||
- reg : Specifies base physical address and size of the register space. The
|
||||
size is based on the number of cores the controller has been configured
|
||||
to handle, this should be set to 8 bytes per cpu core.
|
||||
- interrupt-controller : Identifies the node as an interrupt controller.
|
||||
- #interrupt-cells : This should be set to 0 as this will not be an irq
|
||||
parent.
|
||||
- interrupts : Specifies the interrupt line to which the ompic is wired.
|
||||
|
||||
Example:
|
||||
|
||||
ompic: interrupt-controller@98000000 {
|
||||
compatible = "openrisc,ompic";
|
||||
reg = <0x98000000 16>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <0>;
|
||||
interrupts = <1>;
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
OpenRISC Generic SoC
|
||||
====================
|
||||
|
||||
Boards and FPGA SoC's which support the OpenRISC standard platform. The
|
||||
platform essentially follows the conventions of the OpenRISC architecture
|
||||
specification, however some aspects, such as the boot protocol have been defined
|
||||
by the Linux port.
|
||||
|
||||
Required properties
|
||||
-------------------
|
||||
- compatible: Must include "opencores,or1ksim"
|
||||
|
||||
CPU nodes:
|
||||
----------
|
||||
A "cpus" node is required. Required properties:
|
||||
- #address-cells: Must be 1.
|
||||
- #size-cells: Must be 0.
|
||||
A CPU sub-node is also required for at least CPU 0. Since the topology may
|
||||
be probed via CPS, it is not necessary to specify secondary CPUs. Required
|
||||
properties:
|
||||
- compatible: Must be "opencores,or1200-rtlsvn481".
|
||||
- reg: CPU number.
|
||||
- clock-frequency: The CPU clock frequency in Hz.
|
||||
Example:
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
cpu@0 {
|
||||
compatible = "opencores,or1200-rtlsvn481";
|
||||
reg = <0>;
|
||||
clock-frequency = <20000000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Boot protocol
|
||||
-------------
|
||||
The bootloader may pass the following arguments to the kernel:
|
||||
- r3: address of a flattened device-tree blob or 0x0.
|
||||
@@ -246,6 +246,7 @@ onion Onion Corporation
|
||||
onnn ON Semiconductor Corp.
|
||||
ontat On Tat Industrial Company
|
||||
opencores OpenCores.org
|
||||
openrisc OpenRISC.io
|
||||
option Option NV
|
||||
ORCL Oracle Corporation
|
||||
ortustech Ortus Technology Co., Ltd.
|
||||
|
||||
@@ -7,13 +7,7 @@ target architecture, specifically, is the 32-bit OpenRISC 1000 family (or1k).
|
||||
For information about OpenRISC processors and ongoing development:
|
||||
|
||||
website http://openrisc.io
|
||||
|
||||
For more information about Linux on OpenRISC, please contact South Pole AB.
|
||||
|
||||
email: info@southpole.se
|
||||
|
||||
website: http://southpole.se
|
||||
http://southpoleconsulting.com
|
||||
email openrisc@lists.librecores.org
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
@@ -24,37 +18,54 @@ In order to build and run Linux for OpenRISC, you'll need at least a basic
|
||||
toolchain and, perhaps, the architectural simulator. Steps to get these bits
|
||||
in place are outlined here.
|
||||
|
||||
1) The toolchain can be obtained from openrisc.io. Instructions for building
|
||||
a toolchain can be found at:
|
||||
1) Toolchain
|
||||
|
||||
https://github.com/openrisc/tutorials
|
||||
Toolchain binaries can be obtained from openrisc.io or our github releases page.
|
||||
Instructions for building the different toolchains can be found on openrisc.io
|
||||
or Stafford's toolchain build and release scripts.
|
||||
|
||||
2) or1ksim (optional)
|
||||
binaries https://github.com/openrisc/or1k-gcc/releases
|
||||
toolchains https://openrisc.io/software
|
||||
building https://github.com/stffrdhrn/or1k-toolchain-build
|
||||
|
||||
or1ksim is the architectural simulator which will allow you to actually run
|
||||
your OpenRISC Linux kernel if you don't have an OpenRISC processor at hand.
|
||||
2) Building
|
||||
|
||||
git clone https://github.com/openrisc/or1ksim.git
|
||||
|
||||
cd or1ksim
|
||||
./configure --prefix=$OPENRISC_PREFIX
|
||||
make
|
||||
make install
|
||||
|
||||
3) Linux kernel
|
||||
|
||||
Build the kernel as usual
|
||||
Build the Linux kernel as usual
|
||||
|
||||
make ARCH=openrisc defconfig
|
||||
make ARCH=openrisc
|
||||
|
||||
4) Run in architectural simulator
|
||||
3) Running on FPGA (optional)
|
||||
|
||||
Grab the or1ksim platform configuration file (from the or1ksim source) and
|
||||
together with your freshly built vmlinux, run your kernel with the following
|
||||
incantation:
|
||||
The OpenRISC community typically uses FuseSoC to manage building and programming
|
||||
an SoC into an FPGA. The below is an example of programming a De0 Nano
|
||||
development board with the OpenRISC SoC. During the build FPGA RTL is code
|
||||
downloaded from the FuseSoC IP cores repository and built using the FPGA vendor
|
||||
tools. Binaries are loaded onto the board with openocd.
|
||||
|
||||
sim -f arch/openrisc/or1ksim.cfg vmlinux
|
||||
git clone https://github.com/olofk/fusesoc
|
||||
cd fusesoc
|
||||
sudo pip install -e .
|
||||
|
||||
fusesoc init
|
||||
fusesoc build de0_nano
|
||||
fusesoc pgm de0_nano
|
||||
|
||||
openocd -f interface/altera-usb-blaster.cfg \
|
||||
-f board/or1k_generic.cfg
|
||||
|
||||
telnet localhost 4444
|
||||
> init
|
||||
> halt; load_image vmlinux ; reset
|
||||
|
||||
4) Running on a Simulator (optional)
|
||||
|
||||
QEMU is a processor emulator which we recommend for simulating the OpenRISC
|
||||
platform. Please follow the OpenRISC instructions on the QEMU website to get
|
||||
Linux running on QEMU. You can build QEMU yourself, but your Linux distribution
|
||||
likely provides binary packages to support OpenRISC.
|
||||
|
||||
qemu openrisc https://wiki.qemu.org/Documentation/Platforms/OpenRISC
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
@@ -10037,7 +10037,11 @@ T: git git://github.com/openrisc/linux.git
|
||||
L: openrisc@lists.librecores.org
|
||||
W: http://openrisc.io
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/openrisc/
|
||||
F: Documentation/openrisc/
|
||||
F: arch/openrisc/
|
||||
F: drivers/irqchip/irq-ompic.c
|
||||
F: drivers/irqchip/irq-or1k-*
|
||||
|
||||
OPENVSWITCH
|
||||
M: Pravin Shelar <pshelar@nicira.com>
|
||||
|
||||
+47
-2
@@ -22,13 +22,19 @@ config OPENRISC
|
||||
select HAVE_UID16
|
||||
select GENERIC_ATOMIC64
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_CLOCKEVENTS_BROADCAST
|
||||
select GENERIC_STRNCPY_FROM_USER
|
||||
select GENERIC_STRNLEN_USER
|
||||
select GENERIC_SMP_IDLE_THREAD
|
||||
select MODULES_USE_ELF_RELA
|
||||
select HAVE_DEBUG_STACKOVERFLOW
|
||||
select OR1K_PIC
|
||||
select CPU_NO_EFFICIENT_FFS if !OPENRISC_HAVE_INST_FF1
|
||||
select NO_BOOTMEM
|
||||
select ARCH_USE_QUEUED_SPINLOCKS
|
||||
select ARCH_USE_QUEUED_RWLOCKS
|
||||
select OMPIC if SMP
|
||||
select ARCH_WANT_FRAME_POINTERS
|
||||
|
||||
config CPU_BIG_ENDIAN
|
||||
def_bool y
|
||||
@@ -56,6 +62,12 @@ config TRACE_IRQFLAGS_SUPPORT
|
||||
config GENERIC_CSUM
|
||||
def_bool y
|
||||
|
||||
config STACKTRACE_SUPPORT
|
||||
def_bool y
|
||||
|
||||
config LOCKDEP_SUPPORT
|
||||
def_bool y
|
||||
|
||||
source "init/Kconfig"
|
||||
|
||||
source "kernel/Kconfig.freezer"
|
||||
@@ -73,6 +85,17 @@ config OR1K_1200
|
||||
|
||||
endchoice
|
||||
|
||||
config DCACHE_WRITETHROUGH
|
||||
bool "Have write through data caches"
|
||||
default n
|
||||
help
|
||||
Select this if your implementation features write through data caches.
|
||||
Selecting 'N' here will allow the kernel to force flushing of data
|
||||
caches at relevant times. Most OpenRISC implementations support write-
|
||||
through data caches.
|
||||
|
||||
If unsure say N here
|
||||
|
||||
config OPENRISC_BUILTIN_DTB
|
||||
string "Builtin DTB"
|
||||
default ""
|
||||
@@ -105,8 +128,19 @@ config OPENRISC_HAVE_INST_DIV
|
||||
endmenu
|
||||
|
||||
config NR_CPUS
|
||||
int
|
||||
default "1"
|
||||
int "Maximum number of CPUs (2-32)"
|
||||
range 2 32
|
||||
depends on SMP
|
||||
default "2"
|
||||
|
||||
config SMP
|
||||
bool "Symmetric Multi-Processing support"
|
||||
help
|
||||
This enables support for systems with more than one CPU. If you have
|
||||
a system with only one CPU, say N. If you have a system with more
|
||||
than one CPU, say Y.
|
||||
|
||||
If you don't know what to do here, say N.
|
||||
|
||||
source kernel/Kconfig.hz
|
||||
source kernel/Kconfig.preempt
|
||||
@@ -125,6 +159,17 @@ config OPENRISC_NO_SPR_SR_DSX
|
||||
Say N here if you know that your OpenRISC processor has
|
||||
SPR_SR_DSX bit implemented. Say Y if you are unsure.
|
||||
|
||||
config OPENRISC_HAVE_SHADOW_GPRS
|
||||
bool "Support for shadow gpr files" if !SMP
|
||||
default y if SMP
|
||||
help
|
||||
Say Y here if your OpenRISC processor features shadowed
|
||||
register files. They will in such case be used as a
|
||||
scratch reg storage on exception entry.
|
||||
|
||||
On SMP systems, this feature is mandatory.
|
||||
On a unicore system it's safe to say N here if you are unsure.
|
||||
|
||||
config CMDLINE
|
||||
string "Default kernel command string"
|
||||
default ""
|
||||
|
||||
@@ -25,6 +25,7 @@ LDFLAGS_vmlinux :=
|
||||
LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
|
||||
|
||||
KBUILD_CFLAGS += -pipe -ffixed-r10 -D__linux__
|
||||
CHECKFLAGS += -mbig-endian
|
||||
|
||||
ifeq ($(CONFIG_OPENRISC_HAVE_INST_MUL),y)
|
||||
KBUILD_CFLAGS += $(call cc-option,-mhard-mul)
|
||||
|
||||
@@ -6,8 +6,13 @@
|
||||
#size-cells = <1>;
|
||||
interrupt-parent = <&pic>;
|
||||
|
||||
aliases {
|
||||
uart0 = &serial0;
|
||||
};
|
||||
|
||||
chosen {
|
||||
bootargs = "console=uart,mmio,0x90000000,115200";
|
||||
bootargs = "earlycon";
|
||||
stdout-path = "uart0:115200";
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/dts-v1/;
|
||||
/ {
|
||||
compatible = "opencores,or1ksim";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
interrupt-parent = <&pic>;
|
||||
|
||||
aliases {
|
||||
uart0 = &serial0;
|
||||
};
|
||||
|
||||
chosen {
|
||||
bootargs = "earlycon";
|
||||
stdout-path = "uart0:115200";
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x00000000 0x02000000>;
|
||||
};
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
cpu@0 {
|
||||
compatible = "opencores,or1200-rtlsvn481";
|
||||
reg = <0>;
|
||||
clock-frequency = <20000000>;
|
||||
};
|
||||
cpu@1 {
|
||||
compatible = "opencores,or1200-rtlsvn481";
|
||||
reg = <1>;
|
||||
clock-frequency = <20000000>;
|
||||
};
|
||||
};
|
||||
|
||||
ompic: ompic@98000000 {
|
||||
compatible = "openrisc,ompic";
|
||||
reg = <0x98000000 16>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <0>;
|
||||
interrupts = <1>;
|
||||
};
|
||||
|
||||
/*
|
||||
* OR1K PIC is built into CPU and accessed via special purpose
|
||||
* registers. It is not addressable and, hence, has no 'reg'
|
||||
* property.
|
||||
*/
|
||||
pic: pic {
|
||||
compatible = "opencores,or1k-pic-level";
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
|
||||
serial0: serial@90000000 {
|
||||
compatible = "opencores,uart16550-rtlsvn105", "ns16550a";
|
||||
reg = <0x90000000 0x100>;
|
||||
interrupts = <2>;
|
||||
clock-frequency = <20000000>;
|
||||
};
|
||||
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
CONFIG_CROSS_COMPILE="or1k-linux-"
|
||||
CONFIG_LOCALVERSION="-simple-smp"
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_RD_GZIP is not set
|
||||
# CONFIG_RD_BZIP2 is not set
|
||||
# CONFIG_RD_LZMA is not set
|
||||
# CONFIG_RD_XZ is not set
|
||||
# CONFIG_RD_LZO is not set
|
||||
# CONFIG_RD_LZ4 is not set
|
||||
CONFIG_EXPERT=y
|
||||
# CONFIG_KALLSYMS is not set
|
||||
# CONFIG_EPOLL is not set
|
||||
# CONFIG_TIMERFD is not set
|
||||
# CONFIG_EVENTFD is not set
|
||||
# CONFIG_AIO is not set
|
||||
# CONFIG_VM_EVENT_COUNTERS is not set
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_SLOB=y
|
||||
CONFIG_MODULES=y
|
||||
# CONFIG_BLOCK is not set
|
||||
CONFIG_OPENRISC_BUILTIN_DTB="simple_smp"
|
||||
CONFIG_SMP=y
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_OPENRISC_HAVE_SHADOW_GPRS=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_INET=y
|
||||
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
|
||||
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
|
||||
# CONFIG_INET_XFRM_MODE_BEET is not set
|
||||
# CONFIG_INET_DIAG is not set
|
||||
CONFIG_TCP_CONG_ADVANCED=y
|
||||
# CONFIG_TCP_CONG_BIC is not set
|
||||
# CONFIG_TCP_CONG_CUBIC is not set
|
||||
# CONFIG_TCP_CONG_WESTWOOD is not set
|
||||
# CONFIG_TCP_CONG_HTCP is not set
|
||||
# CONFIG_IPV6 is not set
|
||||
# CONFIG_WIRELESS is not set
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
|
||||
# CONFIG_FW_LOADER is not set
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_ETHOC=y
|
||||
CONFIG_MICREL_PHY=y
|
||||
# CONFIG_WLAN is not set
|
||||
# CONFIG_INPUT is not set
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
# 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_NFS_FS=y
|
||||
CONFIG_XZ_DEC=y
|
||||
# CONFIG_ENABLE_WARN_DEPRECATED is not set
|
||||
# CONFIG_ENABLE_MUST_CHECK is not set
|
||||
# CONFIG_RCU_TRACE is not set
|
||||
@@ -1,7 +1,6 @@
|
||||
generic-y += barrier.h
|
||||
generic-y += bug.h
|
||||
generic-y += bugs.h
|
||||
generic-y += cacheflush.h
|
||||
generic-y += checksum.h
|
||||
generic-y += clkdev.h
|
||||
generic-y += current.h
|
||||
@@ -28,6 +27,10 @@ generic-y += module.h
|
||||
generic-y += pci.h
|
||||
generic-y += percpu.h
|
||||
generic-y += preempt.h
|
||||
generic-y += qspinlock_types.h
|
||||
generic-y += qspinlock.h
|
||||
generic-y += qrwlock_types.h
|
||||
generic-y += qrwlock.h
|
||||
generic-y += sections.h
|
||||
generic-y += segment.h
|
||||
generic-y += string.h
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* OpenRISC Linux
|
||||
*
|
||||
* Linux architectural port borrowing liberally from similar works of
|
||||
* others. All original copyrights apply as per the original source
|
||||
* declaration.
|
||||
*
|
||||
* OpenRISC implementation:
|
||||
* Copyright (C) Jan Henrik Weinstock <jan.weinstock@rwth-aachen.de>
|
||||
* et al.
|
||||
*
|
||||
* 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_CACHEFLUSH_H
|
||||
#define __ASM_CACHEFLUSH_H
|
||||
|
||||
#include <linux/mm.h>
|
||||
|
||||
/*
|
||||
* Helper function for flushing or invalidating entire pages from data
|
||||
* and instruction caches. SMP needs a little extra work, since we need
|
||||
* to flush the pages on all cpus.
|
||||
*/
|
||||
extern void local_dcache_page_flush(struct page *page);
|
||||
extern void local_icache_page_inv(struct page *page);
|
||||
|
||||
/*
|
||||
* Data cache flushing always happen on the local cpu. Instruction cache
|
||||
* invalidations need to be broadcasted to all other cpu in the system in
|
||||
* case of SMP configurations.
|
||||
*/
|
||||
#ifndef CONFIG_SMP
|
||||
#define dcache_page_flush(page) local_dcache_page_flush(page)
|
||||
#define icache_page_inv(page) local_icache_page_inv(page)
|
||||
#else /* CONFIG_SMP */
|
||||
#define dcache_page_flush(page) local_dcache_page_flush(page)
|
||||
#define icache_page_inv(page) smp_icache_page_inv(page)
|
||||
extern void smp_icache_page_inv(struct page *page);
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
/*
|
||||
* Synchronizes caches. Whenever a cpu writes executable code to memory, this
|
||||
* should be called to make sure the processor sees the newly written code.
|
||||
*/
|
||||
static inline void sync_icache_dcache(struct page *page)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_DCACHE_WRITETHROUGH))
|
||||
dcache_page_flush(page);
|
||||
icache_page_inv(page);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pages with this bit set need not be flushed/invalidated, since
|
||||
* they have not changed since last flush. New pages start with
|
||||
* PG_arch_1 not set and are therefore dirty by default.
|
||||
*/
|
||||
#define PG_dc_clean PG_arch_1
|
||||
|
||||
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
|
||||
static inline void flush_dcache_page(struct page *page)
|
||||
{
|
||||
clear_bit(PG_dc_clean, &page->flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Other interfaces are not required since we do not have virtually
|
||||
* indexed or tagged caches. So we can use the default here.
|
||||
*/
|
||||
#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_range(start, end) do { } while (0)
|
||||
#define flush_icache_page(vma, pg) do { } while (0)
|
||||
#define flush_icache_user_range(vma, pg, adr, len) do { } while (0)
|
||||
#define flush_cache_vmap(start, end) do { } while (0)
|
||||
#define flush_cache_vunmap(start, end) do { } while (0)
|
||||
|
||||
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
|
||||
do { \
|
||||
memcpy(dst, src, len); \
|
||||
if (vma->vm_flags & VM_EXEC) \
|
||||
sync_icache_dcache(page); \
|
||||
} while (0)
|
||||
|
||||
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
|
||||
memcpy(dst, src, len)
|
||||
|
||||
#endif /* __ASM_CACHEFLUSH_H */
|
||||
@@ -1,32 +1,29 @@
|
||||
/*
|
||||
* 1,2 and 4 byte cmpxchg and xchg implementations for OpenRISC.
|
||||
*
|
||||
* Copyright (C) 2014 Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
|
||||
* Copyright (C) 2017 Stafford Horne <shorne@gmail.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*
|
||||
* Note:
|
||||
* The portable implementations of 1 and 2 byte xchg and cmpxchg using a 4
|
||||
* byte cmpxchg is sourced heavily from the sh and mips implementations.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_OPENRISC_CMPXCHG_H
|
||||
#define __ASM_OPENRISC_CMPXCHG_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* 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);
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#define __HAVE_ARCH_CMPXCHG 1
|
||||
|
||||
static inline unsigned long
|
||||
__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
|
||||
static inline unsigned long cmpxchg_u32(volatile void *ptr,
|
||||
unsigned long old, unsigned long new)
|
||||
{
|
||||
if (size != 4) {
|
||||
__cmpxchg_called_with_bad_pointer();
|
||||
return old;
|
||||
}
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: l.lwa %0, 0(%1) \n"
|
||||
" l.sfeq %0, %2 \n"
|
||||
@@ -43,28 +40,9 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
|
||||
return old;
|
||||
}
|
||||
|
||||
#define cmpxchg(ptr, o, n) \
|
||||
({ \
|
||||
(__typeof__(*(ptr))) __cmpxchg((ptr), \
|
||||
(unsigned long)(o), \
|
||||
(unsigned long)(n), \
|
||||
sizeof(*(ptr))); \
|
||||
})
|
||||
|
||||
/*
|
||||
* This function doesn't exist, so you'll get a linker error if
|
||||
* something tries to do an invalidly-sized xchg().
|
||||
*/
|
||||
extern void __xchg_called_with_bad_pointer(void);
|
||||
|
||||
static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
|
||||
int size)
|
||||
static inline unsigned long xchg_u32(volatile void *ptr,
|
||||
unsigned long val)
|
||||
{
|
||||
if (size != 4) {
|
||||
__xchg_called_with_bad_pointer();
|
||||
return val;
|
||||
}
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: l.lwa %0, 0(%1) \n"
|
||||
" l.swa 0(%1), %2 \n"
|
||||
@@ -77,10 +55,115 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline u32 cmpxchg_small(volatile void *ptr, u32 old, u32 new,
|
||||
int size)
|
||||
{
|
||||
int off = (unsigned long)ptr % sizeof(u32);
|
||||
volatile u32 *p = ptr - off;
|
||||
#ifdef __BIG_ENDIAN
|
||||
int bitoff = (sizeof(u32) - size - off) * BITS_PER_BYTE;
|
||||
#else
|
||||
int bitoff = off * BITS_PER_BYTE;
|
||||
#endif
|
||||
u32 bitmask = ((0x1 << size * BITS_PER_BYTE) - 1) << bitoff;
|
||||
u32 load32, old32, new32;
|
||||
u32 ret;
|
||||
|
||||
load32 = READ_ONCE(*p);
|
||||
|
||||
while (true) {
|
||||
ret = (load32 & bitmask) >> bitoff;
|
||||
if (old != ret)
|
||||
return ret;
|
||||
|
||||
old32 = (load32 & ~bitmask) | (old << bitoff);
|
||||
new32 = (load32 & ~bitmask) | (new << bitoff);
|
||||
|
||||
/* Do 32 bit cmpxchg */
|
||||
load32 = cmpxchg_u32(p, old32, new32);
|
||||
if (load32 == old32)
|
||||
return old;
|
||||
}
|
||||
}
|
||||
|
||||
/* xchg */
|
||||
|
||||
static inline u32 xchg_small(volatile void *ptr, u32 x, int size)
|
||||
{
|
||||
int off = (unsigned long)ptr % sizeof(u32);
|
||||
volatile u32 *p = ptr - off;
|
||||
#ifdef __BIG_ENDIAN
|
||||
int bitoff = (sizeof(u32) - size - off) * BITS_PER_BYTE;
|
||||
#else
|
||||
int bitoff = off * BITS_PER_BYTE;
|
||||
#endif
|
||||
u32 bitmask = ((0x1 << size * BITS_PER_BYTE) - 1) << bitoff;
|
||||
u32 oldv, newv;
|
||||
u32 ret;
|
||||
|
||||
do {
|
||||
oldv = READ_ONCE(*p);
|
||||
ret = (oldv & bitmask) >> bitoff;
|
||||
newv = (oldv & ~bitmask) | (x << bitoff);
|
||||
} while (cmpxchg_u32(p, oldv, newv) != oldv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function doesn't exist, so you'll get a linker error
|
||||
* if something tries to do an invalid cmpxchg().
|
||||
*/
|
||||
extern unsigned long __cmpxchg_called_with_bad_pointer(void)
|
||||
__compiletime_error("Bad argument size for cmpxchg");
|
||||
|
||||
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
||||
unsigned long new, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
case 2:
|
||||
return cmpxchg_small(ptr, old, new, size);
|
||||
case 4:
|
||||
return cmpxchg_u32(ptr, old, new);
|
||||
default:
|
||||
return __cmpxchg_called_with_bad_pointer();
|
||||
}
|
||||
}
|
||||
|
||||
#define cmpxchg(ptr, o, n) \
|
||||
({ \
|
||||
(__typeof__(*(ptr))) __cmpxchg((ptr), \
|
||||
(unsigned long)(o), \
|
||||
(unsigned long)(n), \
|
||||
sizeof(*(ptr))); \
|
||||
})
|
||||
|
||||
/*
|
||||
* This function doesn't exist, so you'll get a linker error if
|
||||
* something tries to do an invalidly-sized xchg().
|
||||
*/
|
||||
extern unsigned long __xchg_called_with_bad_pointer(void)
|
||||
__compiletime_error("Bad argument size for xchg");
|
||||
|
||||
static inline unsigned long __xchg(volatile void *ptr, unsigned long with,
|
||||
int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
case 2:
|
||||
return xchg_small(ptr, with, size);
|
||||
case 4:
|
||||
return xchg_u32(ptr, with);
|
||||
default:
|
||||
return __xchg_called_with_bad_pointer();
|
||||
}
|
||||
}
|
||||
|
||||
#define xchg(ptr, with) \
|
||||
({ \
|
||||
(__typeof__(*(ptr))) __xchg((unsigned long)(with), \
|
||||
(ptr), \
|
||||
(__typeof__(*(ptr))) __xchg((ptr), \
|
||||
(unsigned long)(with), \
|
||||
sizeof(*(ptr))); \
|
||||
})
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#ifndef __ASM_OPENRISC_CPUINFO_H
|
||||
#define __ASM_OPENRISC_CPUINFO_H
|
||||
|
||||
struct cpuinfo {
|
||||
struct cpuinfo_or1k {
|
||||
u32 clock_frequency;
|
||||
|
||||
u32 icache_size;
|
||||
@@ -29,8 +29,11 @@ struct cpuinfo {
|
||||
u32 dcache_size;
|
||||
u32 dcache_block_size;
|
||||
u32 dcache_ways;
|
||||
|
||||
u16 coreid;
|
||||
};
|
||||
|
||||
extern struct cpuinfo cpuinfo;
|
||||
extern struct cpuinfo_or1k cpuinfo_or1k[NR_CPUS];
|
||||
extern void setup_cpuinfo(void);
|
||||
|
||||
#endif /* __ASM_OPENRISC_CPUINFO_H */
|
||||
|
||||
@@ -34,7 +34,7 @@ extern void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
* registers like cr3 on the i386
|
||||
*/
|
||||
|
||||
extern volatile pgd_t *current_pgd; /* defined in arch/openrisc/mm/fault.c */
|
||||
extern volatile pgd_t *current_pgd[]; /* defined in arch/openrisc/mm/fault.c */
|
||||
|
||||
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
|
||||
{
|
||||
|
||||
@@ -94,7 +94,7 @@ extern void paging_init(void);
|
||||
* 64 MB of vmalloc area is comparable to what's available on other arches.
|
||||
*/
|
||||
|
||||
#define VMALLOC_START (PAGE_OFFSET-0x04000000)
|
||||
#define VMALLOC_START (PAGE_OFFSET-0x04000000UL)
|
||||
#define VMALLOC_END (PAGE_OFFSET)
|
||||
#define VMALLOC_VMADDR(x) ((unsigned long)(x))
|
||||
|
||||
@@ -416,15 +416,19 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* defined in head.S */
|
||||
|
||||
struct vm_area_struct;
|
||||
|
||||
/*
|
||||
* or32 doesn't have any external MMU info: the kernel page
|
||||
* tables contain all the necessary information.
|
||||
*
|
||||
* Actually I am not sure on what this could be used for.
|
||||
*/
|
||||
static inline void update_tlb(struct vm_area_struct *vma,
|
||||
unsigned long address, pte_t *pte)
|
||||
{
|
||||
}
|
||||
|
||||
extern void update_cache(struct vm_area_struct *vma,
|
||||
unsigned long address, pte_t *pte);
|
||||
|
||||
static inline void update_mmu_cache(struct vm_area_struct *vma,
|
||||
unsigned long address, pte_t *pte)
|
||||
{
|
||||
update_tlb(vma, address, pte);
|
||||
update_cache(vma, address, pte);
|
||||
}
|
||||
|
||||
/* __PHX__ FIXME, SWAP, this probably doesn't work */
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
* it needs to be correct to get the early console working.
|
||||
*/
|
||||
|
||||
#define BASE_BAUD (cpuinfo.clock_frequency/16)
|
||||
#define BASE_BAUD (cpuinfo_or1k[smp_processor_id()].clock_frequency/16)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_OPENRISC_SMP_H
|
||||
#define __ASM_OPENRISC_SMP_H
|
||||
|
||||
#include <asm/spr.h>
|
||||
#include <asm/spr_defs.h>
|
||||
|
||||
#define raw_smp_processor_id() (current_thread_info()->cpu)
|
||||
#define hard_smp_processor_id() mfspr(SPR_COREID)
|
||||
|
||||
extern void smp_init_cpus(void);
|
||||
|
||||
extern void arch_send_call_function_single_ipi(int cpu);
|
||||
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
|
||||
|
||||
extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int));
|
||||
extern void handle_IPI(unsigned int ipi_msg);
|
||||
|
||||
#endif /* __ASM_OPENRISC_SMP_H */
|
||||
@@ -19,6 +19,16 @@
|
||||
#ifndef __ASM_OPENRISC_SPINLOCK_H
|
||||
#define __ASM_OPENRISC_SPINLOCK_H
|
||||
|
||||
#error "or32 doesn't do SMP yet"
|
||||
#include <asm/qspinlock.h>
|
||||
|
||||
#include <asm/qrwlock.h>
|
||||
|
||||
#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
|
||||
#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
|
||||
|
||||
#define arch_spin_relax(lock) cpu_relax()
|
||||
#define arch_read_relax(lock) cpu_relax()
|
||||
#define arch_write_relax(lock) cpu_relax()
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user