Commit 7ae77150 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'powerpc-5.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

Pull powerpc updates from Michael Ellerman:

 - Support for userspace to send requests directly to the on-chip GZIP
   accelerator on Power9.

 - Rework of our lockless page table walking (__find_linux_pte()) to
   make it safe against parallel page table manipulations without
   relying on an IPI for serialisation.

 - A series of fixes & enhancements to make our machine check handling
   more robust.

 - Lots of plumbing to add support for "prefixed" (64-bit) instructions
   on Power10.

 - Support for using huge pages for the linear mapping on 8xx (32-bit).

 - Remove obsolete Xilinx PPC405/PPC440 support, and an associated sound
   driver.

 - Removal of some obsolete 40x platforms and associated cruft.

 - Initial support for booting on Power10.

 - Lots of other small features, cleanups & fixes.

Thanks to: Alexey Kardashevskiy, Alistair Popple, Andrew Donnellan,
Andrey Abramov, Aneesh Kumar K.V, Balamuruhan S, Bharata B Rao, Bulent
Abali, Cédric Le Goater, Chen Zhou, Christian Zigotzky, Christophe
JAILLET, Christophe Leroy, Dmitry Torokhov, Emmanuel Nicolet, Erhard F.,
Gautham R. Shenoy, Geoff Levand, George Spelvin, Greg Kurz, Gustavo A.
R. Silva, Gustavo Walbon, Haren Myneni, Hari Bathini, Joel Stanley,
Jordan Niethe, Kajol Jain, Kees Cook, Leonardo Bras, Madhavan
Srinivasan., Mahesh Salgaonkar, Markus Elfring, Michael Neuling, Michal
Simek, Nathan Chancellor, Nathan Lynch, Naveen N. Rao, Nicholas Piggin,
Oliver O'Halloran, Paul Mackerras, Pingfan Liu, Qian Cai, Ram Pai,
Raphael Moreira Zinsly, Ravi Bangoria, Sam Bobroff, Sandipan Das, Segher
Boessenkool, Stephen Rothwell, Sukadev Bhattiprolu, Tyrel Datwyler,
Wolfram Sang, Xiongfeng Wang.

* tag 'powerpc-5.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (299 commits)
  powerpc/pseries: Make vio and ibmebus initcalls pseries specific
  cxl: Remove dead Kconfig options
  powerpc: Add POWER10 architected mode
  powerpc/dt_cpu_ftrs: Add MMA feature
  powerpc/dt_cpu_ftrs: Enable Prefixed Instructions
  powerpc/dt_cpu_ftrs: Advertise support for ISA v3.1 if selected
  powerpc: Add support for ISA v3.1
  powerpc: Add new HWCAP bits
  powerpc/64s: Don't set FSCR bits in INIT_THREAD
  powerpc/64s: Save FSCR to init_task.thread.fscr after feature init
  powerpc/64s: Don't let DT CPU features set FSCR_DSCR
  powerpc/64s: Don't init FSCR_DSCR in __init_FSCR()
  powerpc/32s: Fix another build failure with CONFIG_PPC_KUAP_DEBUG
  powerpc/module_64: Use special stub for _mcount() with -mprofile-kernel
  powerpc/module_64: Simplify check for -mprofile-kernel ftrace relocations
  powerpc/module_64: Consolidate ftrace code
  powerpc/32: Disable KASAN with pages bigger than 16k
  powerpc/uaccess: Don't set KUEP by default on book3s/32
  powerpc/uaccess: Don't set KUAP by default on book3s/32
  powerpc/8xx: Reduce time spent in allow_user_access() and friends
  ...
parents 084623e4 1395375c
......@@ -22,6 +22,27 @@ Description:
Exposes the "version" field of the 24x7 catalog. This is also
extractable from the provided binary "catalog" sysfs entry.
What: /sys/devices/hv_24x7/interface/sockets
Date: May 2020
Contact: Linux on PowerPC Developer List <linuxppc-dev@lists.ozlabs.org>
Description: read only
This sysfs interface exposes the number of sockets present in the
system.
What: /sys/devices/hv_24x7/interface/chipspersocket
Date: May 2020
Contact: Linux on PowerPC Developer List <linuxppc-dev@lists.ozlabs.org>
Description: read only
This sysfs interface exposes the number of chips per socket
present in the system.
What: /sys/devices/hv_24x7/interface/coresperchip
Date: May 2020
Contact: Linux on PowerPC Developer List <linuxppc-dev@lists.ozlabs.org>
Description: read only
This sysfs interface exposes the number of cores per chip
present in the system.
What: /sys/bus/event_source/devices/hv_24x7/event_descs/<event-name>
Date: February 2014
Contact: Linux on PowerPC Developer List <linuxppc-dev@lists.ozlabs.org>
......
......@@ -574,3 +574,42 @@ Description: Secure Virtual Machine
If 1, it means the system is using the Protected Execution
Facility in POWER9 and newer processors. i.e., it is a Secure
Virtual Machine.
What: /sys/devices/system/cpu/cpuX/purr
Date: Apr 2005
Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
Description: PURR ticks for this CPU since the system boot.
The Processor Utilization Resources Register (PURR) is
a 64-bit counter which provides an estimate of the
resources used by the CPU thread. The contents of this
register increases monotonically. This sysfs interface
exposes the number of PURR ticks for cpuX.
What: /sys/devices/system/cpu/cpuX/spurr
Date: Dec 2006
Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
Description: SPURR ticks for this CPU since the system boot.
The Scaled Processor Utilization Resources Register
(SPURR) is a 64-bit counter that provides a frequency
invariant estimate of the resources used by the CPU
thread. The contents of this register increases
monotonically. This sysfs interface exposes the number
of SPURR ticks for cpuX.
What: /sys/devices/system/cpu/cpuX/idle_purr
Date: Apr 2020
Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
Description: PURR ticks for cpuX when it was idle.
This sysfs interface exposes the number of PURR ticks
for cpuX when it was idle.
What: /sys/devices/system/cpu/cpuX/idle_spurr
Date: Apr 2020
Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
Description: SPURR ticks for cpuX when it was idle.
This sysfs interface exposes the number of SPURR ticks
for cpuX when it was idle.
......@@ -874,6 +874,11 @@
can be useful when debugging issues that require an SLB
miss to occur.
stress_slb [PPC]
Limits the number of kernel SLB entries, and flushes
them frequently to increase the rate of SLB faults
on kernel addresses.
disable= [IPV6]
See Documentation/networking/ipv6.rst.
......
......@@ -86,149 +86,6 @@
xlnx,use-parity = <0>;
};
Some IP cores actually implement 2 or more logical devices. In
this case, the device should still describe the whole IP core with
a single node and add a child node for each logical device. The
ranges property can be used to translate from parent IP-core to the
registers of each device. In addition, the parent node should be
compatible with the bus type 'xlnx,compound', and should contain
#address-cells and #size-cells, as with any other bus. (Note: this
makes the assumption that both logical devices have the same bus
binding. If this is not true, then separate nodes should be used
for each logical device). The 'cell-index' property can be used to
enumerate logical devices within an IP core. For example, the
following is the system.mhs entry for the dual ps2 controller found
on the ml403 reference design.
BEGIN opb_ps2_dual_ref
PARAMETER INSTANCE = opb_ps2_dual_ref_0
PARAMETER HW_VER = 1.00.a
PARAMETER C_BASEADDR = 0xA9000000
PARAMETER C_HIGHADDR = 0xA9001FFF
BUS_INTERFACE SOPB = opb_v20_0
PORT Sys_Intr1 = ps2_1_intr
PORT Sys_Intr2 = ps2_2_intr
PORT Clkin1 = ps2_clk_rx_1
PORT Clkin2 = ps2_clk_rx_2
PORT Clkpd1 = ps2_clk_tx_1
PORT Clkpd2 = ps2_clk_tx_2
PORT Rx1 = ps2_d_rx_1
PORT Rx2 = ps2_d_rx_2
PORT Txpd1 = ps2_d_tx_1
PORT Txpd2 = ps2_d_tx_2
END
It would result in the following device tree nodes:
opb_ps2_dual_ref_0: opb-ps2-dual-ref@a9000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "xlnx,compound";
ranges = <0 a9000000 2000>;
// If this device had extra parameters, then they would
// go here.
ps2@0 {
compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
reg = <0 40>;
interrupt-parent = <&opb_intc_0>;
interrupts = <3 0>;
cell-index = <0>;
};
ps2@1000 {
compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
reg = <1000 40>;
interrupt-parent = <&opb_intc_0>;
interrupts = <3 0>;
cell-index = <0>;
};
};
Also, the system.mhs file defines bus attachments from the processor
to the devices. The device tree structure should reflect the bus
attachments. Again an example; this system.mhs fragment:
BEGIN ppc405_virtex4
PARAMETER INSTANCE = ppc405_0
PARAMETER HW_VER = 1.01.a
BUS_INTERFACE DPLB = plb_v34_0
BUS_INTERFACE IPLB = plb_v34_0
END
BEGIN opb_intc
PARAMETER INSTANCE = opb_intc_0
PARAMETER HW_VER = 1.00.c
PARAMETER C_BASEADDR = 0xD1000FC0
PARAMETER C_HIGHADDR = 0xD1000FDF
BUS_INTERFACE SOPB = opb_v20_0
END
BEGIN opb_uart16550
PARAMETER INSTANCE = opb_uart16550_0
PARAMETER HW_VER = 1.00.d
PARAMETER C_BASEADDR = 0xa0000000
PARAMETER C_HIGHADDR = 0xa0001FFF
BUS_INTERFACE SOPB = opb_v20_0
END
BEGIN plb_v34
PARAMETER INSTANCE = plb_v34_0
PARAMETER HW_VER = 1.02.a
END
BEGIN plb_bram_if_cntlr
PARAMETER INSTANCE = plb_bram_if_cntlr_0
PARAMETER HW_VER = 1.00.b
PARAMETER C_BASEADDR = 0xFFFF0000
PARAMETER C_HIGHADDR = 0xFFFFFFFF
BUS_INTERFACE SPLB = plb_v34_0
END
BEGIN plb2opb_bridge
PARAMETER INSTANCE = plb2opb_bridge_0
PARAMETER HW_VER = 1.01.a
PARAMETER C_RNG0_BASEADDR = 0x20000000
PARAMETER C_RNG0_HIGHADDR = 0x3FFFFFFF
PARAMETER C_RNG1_BASEADDR = 0x60000000
PARAMETER C_RNG1_HIGHADDR = 0x7FFFFFFF
PARAMETER C_RNG2_BASEADDR = 0x80000000
PARAMETER C_RNG2_HIGHADDR = 0xBFFFFFFF
PARAMETER C_RNG3_BASEADDR = 0xC0000000
PARAMETER C_RNG3_HIGHADDR = 0xDFFFFFFF
BUS_INTERFACE SPLB = plb_v34_0
BUS_INTERFACE MOPB = opb_v20_0
END
Gives this device tree (some properties removed for clarity):
plb@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "xlnx,plb-v34-1.02.a";
device_type = "ibm,plb";
ranges; // 1:1 translation
plb_bram_if_cntrl_0: bram@ffff0000 {
reg = <ffff0000 10000>;
}
opb@20000000 {
#address-cells = <1>;
#size-cells = <1>;
ranges = <20000000 20000000 20000000
60000000 60000000 20000000
80000000 80000000 40000000
c0000000 c0000000 20000000>;
opb_uart16550_0: serial@a0000000 {
reg = <a00000000 2000>;
};
opb_intc_0: interrupt-controller@d1000fc0 {
reg = <d1000fc0 20>;
};
};
};
That covers the general approach to binding xilinx IP cores into the
device tree. The following are bindings for specific devices:
......
......@@ -70,28 +70,6 @@ Currently, the following image format targets exist:
kernel with this image type and it depends entirely on
the embedded device tree for all information.
The simpleImage is useful for booting systems with
an unknown firmware interface or for booting from
a debugger when no firmware is present (such as on
the Xilinx Virtex platform). The only assumption that
simpleImage makes is that RAM is correctly initialized
and that the MMU is either off or has RAM mapped to
base address 0.
simpleImage also supports inserting special platform
specific initialization code to the start of the bootup
sequence. The virtex405 platform uses this feature to
ensure that the cache is invalidated before caching
is enabled. Platform specific initialization code is
added as part of the wrapper script and is keyed on
the image target name. For example, all
simpleImage.virtex405-* targets will add the
virtex405-head.S initialization code (This also means
that the dts file for virtex405 targets should be
named (virtex405-<board>.dts). Search the wrapper
script for 'virtex405' and see the file
arch/powerpc/boot/virtex405-head.S for details.
treeImage.%; Image format for used with OpenBIOS firmware found
on some ppc4xx hardware. This image embeds a device
tree blob inside the image.
......@@ -116,10 +94,8 @@ Image types which embed a device tree blob (simpleImage, dtbImage, treeImage,
and cuImage) all generate the device tree blob from a file in the
arch/powerpc/boot/dts/ directory. The Makefile selects the correct device
tree source based on the name of the target. Therefore, if the kernel is
built with 'make treeImage.walnut simpleImage.virtex405-ml403', then the
build system will use arch/powerpc/boot/dts/walnut.dts to build
treeImage.walnut and arch/powerpc/boot/dts/virtex405-ml403.dts to build
the simpleImage.virtex405-ml403.
built with 'make treeImage.walnut', then the build system will use
arch/powerpc/boot/dts/walnut.dts to build treeImage.walnut.
Two special targets called 'zImage' and 'zImage.initrd' also exist. These
targets build all the default images as selected by the kernel configuration.
......
......@@ -30,6 +30,7 @@ powerpc
syscall64-abi
transactional_memory
ultravisor
vas-api
.. only:: subproject and html
......
......@@ -245,3 +245,30 @@ POWER9N DD2.2.
Guest migration from POWER8 to POWER9 will work with POWER9N DD2.2 and
POWER9C DD1.2. Since earlier POWER9 processors don't support TM
emulation, migration from POWER8 to POWER9 is not supported there.
Kernel implementation
=====================
h/rfid mtmsrd quirk
-------------------
As defined in the ISA, rfid has a quirk which is useful in early
exception handling. When in a userspace transaction and we enter the
kernel via some exception, MSR will end up as TM=0 and TS=01 (ie. TM
off but TM suspended). Regularly the kernel will want change bits in
the MSR and will perform an rfid to do this. In this case rfid can
have SRR0 TM = 0 and TS = 00 (ie. TM off and non transaction) and the
resulting MSR will retain TM = 0 and TS=01 from before (ie. stay in
suspend). This is a quirk in the architecture as this would normally
be a transition from TS=01 to TS=00 (ie. suspend -> non transactional)
which is an illegal transition.
This quirk is described the architecture in the definition of rfid
with these lines:
if (MSR 29:31 ¬ = 0b010 | SRR1 29:31 ¬ = 0b000) then
MSR 29:31 <- SRR1 29:31
hrfid and mtmsrd have the same quirk.
The Linux kernel uses this quirk in it's early exception handling.
This diff is collapsed.
......@@ -287,6 +287,7 @@ Code Seq# Include File Comments
'v' 00-1F linux/fs.h conflict!
'v' 00-0F linux/sonypi.h conflict!
'v' 00-0F media/v4l2-subdev.h conflict!
'v' 20-27 arch/powerpc/include/uapi/asm/vas-api.h VAS API
'v' C0-FF linux/meye.h conflict!
'w' all CERN SCI driver
'y' 00-1F packet based user level communications
......
......@@ -9874,7 +9874,7 @@ F: arch/powerpc/platforms/83xx/
F: arch/powerpc/platforms/85xx/
LINUX FOR POWERPC EMBEDDED PPC8XX
M: Christophe Leroy <christophe.leroy@c-s.fr>
M: Christophe Leroy <christophe.leroy@csgroup.eu>
L: linuxppc-dev@lists.ozlabs.org
S: Maintained
F: arch/powerpc/platforms/8xx/
......
......@@ -171,8 +171,8 @@ config PPC
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_HUGE_VMAP if PPC_BOOK3S_64 && PPC_RADIX_MMU
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_KASAN if PPC32
select HAVE_ARCH_KASAN_VMALLOC if PPC32
select HAVE_ARCH_KASAN if PPC32 && PPC_PAGE_SHIFT <= 14
select HAVE_ARCH_KASAN_VMALLOC if PPC32 && PPC_PAGE_SHIFT <= 14
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
......@@ -477,7 +477,7 @@ config LD_HEAD_STUB_CATCH
If unsure, say "N".
config MPROFILE_KERNEL
depends on PPC64 && CPU_LITTLE_ENDIAN
depends on PPC64 && CPU_LITTLE_ENDIAN && FUNCTION_TRACER
def_bool $(success,$(srctree)/arch/powerpc/tools/gcc-check-mprofile-kernel.sh $(CC) -I$(srctree)/include -D__KERNEL__)
config HOTPLUG_CPU
......@@ -764,41 +764,18 @@ config THREAD_SHIFT
range 13 15
default "15" if PPC_256K_PAGES
default "14" if PPC64
default "14" if KASAN
default "13"
help
Used to define the stack size. The default is almost always what you
want. Only change this if you know what you are doing.
config ETEXT_SHIFT_BOOL
bool "Set custom etext alignment" if STRICT_KERNEL_RWX && \
(PPC_BOOK3S_32 || PPC_8xx)
depends on ADVANCED_OPTIONS
help
This option allows you to set the kernel end of text alignment. When
RAM is mapped by blocks, the alignment needs to fit the size and
number of possible blocks. The default should be OK for most configs.
Say N here unless you know what you are doing.
config ETEXT_SHIFT
int "_etext shift" if ETEXT_SHIFT_BOOL
range 17 28 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
range 19 23 if STRICT_KERNEL_RWX && PPC_8xx
default 17 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
default 19 if STRICT_KERNEL_RWX && PPC_8xx
default PPC_PAGE_SHIFT
help
On Book3S 32 (603+), IBATs are used to map kernel text.
Smaller is the alignment, greater is the number of necessary IBATs.
On 8xx, large pages (512kb or 8M) are used to map kernel linear
memory. Aligning to 8M reduces TLB misses as only 8M pages are used
in that case.
config DATA_SHIFT_BOOL
bool "Set custom data alignment" if STRICT_KERNEL_RWX && \
(PPC_BOOK3S_32 || PPC_8xx)
bool "Set custom data alignment"
depends on ADVANCED_OPTIONS
depends on STRICT_KERNEL_RWX || DEBUG_PAGEALLOC
depends on PPC_BOOK3S_32 || (PPC_8xx && !PIN_TLB_DATA && \
(!PIN_TLB_TEXT || !STRICT_KERNEL_RWX))
help
This option allows you to set the kernel data alignment. When
RAM is mapped by blocks, the alignment needs to fit the size and
......@@ -809,10 +786,13 @@ config DATA_SHIFT_BOOL
config DATA_SHIFT
int "Data shift" if DATA_SHIFT_BOOL
default 24 if STRICT_KERNEL_RWX && PPC64
range 17 28 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
range 19 23 if STRICT_KERNEL_RWX && PPC_8xx
range 17 28 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC) && PPC_BOOK3S_32
range 19 23 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC) && PPC_8xx
default 22 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
default 18 if DEBUG_PAGEALLOC && PPC_BOOK3S_32
default 23 if STRICT_KERNEL_RWX && PPC_8xx
default 23 if DEBUG_PAGEALLOC && PPC_8xx && PIN_TLB_DATA
default 19 if DEBUG_PAGEALLOC && PPC_8xx
default PPC_PAGE_SHIFT
help
On Book3S 32 (603+), DBATs are used to map kernel text and rodata RO.
......@@ -820,7 +800,8 @@ config DATA_SHIFT
On 8xx, large pages (512kb or 8M) are used to map kernel linear
memory. Aligning to 8M reduces TLB misses as only 8M pages are used
in that case.
in that case. If PIN_TLB is selected, it must be aligned to 8M as
8M pages will be pinned.
config FORCE_MAX_ZONEORDER
int "Maximum zone order"
......@@ -1218,26 +1199,6 @@ config TASK_SIZE
hex "Size of user task space" if TASK_SIZE_BOOL
default "0x80000000" if PPC_8xx
default "0xc0000000"
config PIN_TLB
bool "Pinned Kernel TLBs (860 ONLY)"
depends on ADVANCED_OPTIONS && PPC_8xx && \
!DEBUG_PAGEALLOC && !STRICT_KERNEL_RWX
config PIN_TLB_DATA
bool "Pinned TLB for DATA"
depends on PIN_TLB
default y
config PIN_TLB_IMMR
bool "Pinned TLB for IMMR"
depends on PIN_TLB || PPC_EARLY_DEBUG_CPM
default y
config PIN_TLB_TEXT
bool "Pinned TLB for TEXT"
depends on PIN_TLB
default y
endmenu
if PPC64
......
......@@ -230,7 +230,7 @@ config PPC_EARLY_DEBUG_40x
help
Select this to enable early debugging for IBM 40x chips via the
inbuilt serial port. This works on chips with a 16550 compatible
UART. Xilinx chips with uartlite cannot use this option.
UART.
config PPC_EARLY_DEBUG_CPM
bool "Early serial debugging for Freescale CPM-based serial ports"
......
......@@ -75,11 +75,9 @@ $(obj)/cuboot-hotfoot.o: BOOTCFLAGS += -mcpu=405
$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405
$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405
$(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405
$(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
$(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405
$(obj)/treeboot-currituck.o: BOOTCFLAGS += -mcpu=405
$(obj)/treeboot-akebono.o: BOOTCFLAGS += -mcpu=405
$(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405
# The pre-boot decompressors pull in a lot of kernel headers and other source
# files. This creates a bit of a dependency headache since we need to copy
......@@ -129,14 +127,12 @@ src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c
src-wlib-$(CONFIG_PPC_8xx) += mpc8xx.c planetcore.c fsl-soc.c
src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c
src-wlib-$(CONFIG_EMBEDDED6xx) += ugecon.c fsl-soc.c
src-wlib-$(CONFIG_XILINX_VIRTEX) += uartlite.c
src-wlib-$(CONFIG_CPM) += cpm-serial.c
src-plat-y := of.c epapr.c
src-plat-$(CONFIG_40x) += fixed-head.S ep405.c cuboot-hotfoot.c \
treeboot-walnut.c cuboot-acadia.c \
cuboot-kilauea.c simpleboot.c \
virtex405-head.S virtex.c
src-plat-$(CONFIG_40x) += fixed-head.S cuboot-hotfoot.c \
cuboot-acadia.c \
cuboot-kilauea.c simpleboot.c
src-plat-$(CONFIG_44x) += treeboot-ebony.c cuboot-ebony.c treeboot-bamboo.c \
cuboot-bamboo.c cuboot-sam440ep.c \
cuboot-sequoia.c cuboot-rainier.c \
......@@ -144,7 +140,7 @@ src-plat-$(CONFIG_44x) += treeboot-ebony.c cuboot-ebony.c treeboot-bamboo.c \
cuboot-warp.c cuboot-yosemite.c \
treeboot-iss4xx.c treeboot-currituck.c \
treeboot-akebono.c \
simpleboot.c fixed-head.S virtex.c
simpleboot.c fixed-head.S
src-plat-$(CONFIG_PPC_8xx) += cuboot-8xx.c fixed-head.S ep88xc.c redboot-8xx.c
src-plat-$(CONFIG_PPC_MPC52xx) += cuboot-52xx.c
src-plat-$(CONFIG_PPC_82xx) += cuboot-pq2.c fixed-head.S ep8248e.c cuboot-824x.c
......@@ -279,9 +275,7 @@ image-$(CONFIG_EPAPR_BOOT) += zImage.epapr
#
# Board ports in arch/powerpc/platform/40x/Kconfig
image-$(CONFIG_EP405) += dtbImage.ep405
image-$(CONFIG_HOTFOOT) += cuImage.hotfoot
image-$(CONFIG_WALNUT) += treeImage.walnut
image-$(CONFIG_ACADIA) += cuImage.acadia
image-$(CONFIG_OBS600) += uImage.obs600
......
......@@ -4,4 +4,3 @@ subdir-y += fsl
dtstree := $(srctree)/$(src)
dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
dtb-$(CONFIG_XILINX_VIRTEX440_GENERIC_BOARD) += virtex440-ml507.dtb virtex440-ml510.dtb
/*
* Device Tree Source for EP405
*
* Copyright 2007 IBM Corp.
* Benjamin Herrenschmidt <benh@kernel.crashing.org>
*
* 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.
*/
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
model = "ep405";
compatible = "ep405";
dcr-parent = <&{/cpus/cpu@0}>;
aliases {
ethernet0 = &EMAC;
serial0 = &UART0;
serial1 = &UART1;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
device_type = "cpu";
model = "PowerPC,405GP";
reg = <0x00000000>;
clock-frequency = <200000000>; /* Filled in by zImage */
timebase-frequency = <0>; /* Filled in by zImage */
i-cache-line-size = <32>;
d-cache-line-size = <32>;
i-cache-size = <16384>;
d-cache-size = <16384>;
dcr-controller;
dcr-access-method = "native";
};
};
memory {
device_type = "memory";
reg = <0x00000000 0x00000000>; /* Filled in by zImage */
};
UIC0: interrupt-controller {
compatible = "ibm,uic";
interrupt-controller;
cell-index = <0>;
dcr-reg = <0x0c0 0x009>;
#address-cells = <0>;
#size-cells = <0>;
#interrupt-cells = <2>;
};
plb {
compatible = "ibm,plb3";
#address-cells = <1>;
#size-cells = <1>;
ranges;
clock-frequency = <0>; /* Filled in by zImage */
SDRAM0: memory-controller {
compatible = "ibm,sdram-405gp";
dcr-reg = <0x010 0x002>;
};
MAL: mcmal {
compatible = "ibm,mcmal-405gp", "ibm,mcmal";
dcr-reg = <0x180 0x062>;
num-tx-chans = <1>;
num-rx-chans = <1>;
interrupt-parent = <&UIC0>;
interrupts = <
0xb 0x4 /* TXEOB */
0xc 0x4 /* RXEOB */
0xa 0x4 /* SERR */
0xd 0x4 /* TXDE */
0xe 0x4 /* RXDE */>;
};
POB0: opb {
compatible = "ibm,opb-405gp", "ibm,opb";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0xef600000 0xef600000 0x00a00000>;
dcr-reg = <0x0a0 0x005>;
clock-frequency = <0>; /* Filled in by zImage */
UART0: serial@ef600300 {
device_type = "serial";
compatible = "ns16550";
reg = <0xef600300 0x00000008>;
virtual-reg = <0xef600300>;
clock-frequency = <0>; /* Filled in by zImage */
current-speed = <9600>;
interrupt-parent = <&UIC0>;
interrupts = <0x0 0x4>;
};
UART1: serial@ef600400 {
device_type = "serial";
compatible = "ns16550";
reg = <0xef600400 0x00000008>;
virtual-reg = <0xef600400>;
clock-frequency = <0>; /* Filled in by zImage */
current-speed = <9600>;
interrupt-parent = <&UIC0>;
interrupts = <0x1 0x4>;
};
IIC: i2c@ef600500 {
compatible = "ibm,iic-405gp", "ibm,iic";
reg = <0xef600500 0x00000011>;
interrupt-parent = <&UIC0>;
interrupts = <0x2 0x4>;
};
GPIO: gpio@ef600700 {
compatible = "ibm,gpio-405gp";
reg = <0xef600700 0x00000020>;
};
EMAC: ethernet@ef600800 {
linux,network-index = <0x0>;
device_type = "network";
compatible = "ibm,emac-405gp", "ibm,emac";
interrupt-parent = <&UIC0>;
interrupts = <
0xf 0x4 /* Ethernet */
0x9 0x4 /* Ethernet Wake Up */>;
local-mac-address = [000000000000]; /* Filled in by zImage */
reg = <0xef600800 0x00000070>;
mal-device = <&MAL>;
mal-tx-channel = <0>;
mal-rx-channel = <0>;
cell-index = <0>;
max-frame-size = <1500>;
rx-fifo-size = <4096>;
tx-fifo-size = <2048>;
phy-mode = "rmii";
phy-map = <0x00000000>;
};
};
EBC0: ebc {
compatible = "ibm,ebc-405gp", "ibm,ebc";
dcr-reg = <0x012 0x002>;
#address-cells = <2>;
#size-cells = <1>;
/* The ranges property is supplied by the bootwrapper
* and is based on the firmware's configuration of the
* EBC bridge
*/
clock-frequency = <0>; /* Filled in by zImage */
/* NVRAM and RTC */
nvrtc@4,200000 {
compatible = "ds1742";
reg = <0x00000004 0x00200000 0x00000000>; /* size fixed up by zImage */
};
/* "BCSR" CPLD contains a PCI irq controller */
bcsr@4,0 {
compatible = "ep405-bcsr";
reg = <0x00000004 0x00000000 0x00000010>;
interrupt-controller;
/* Routing table */
irq-routing = [ 00 /* SYSERR */
01 /* STTM */
01 /* RTC */
01 /* FENET */
02 /* NB PCIIRQ mux ? */
03 /* SB Winbond 8259 ? */
04 /* Serial Ring */
05 /* USB (ep405pc) */
06 /* XIRQ 0 */
06 /* XIRQ 1 */
06 /* XIRQ 2 */
06 /* XIRQ 3 */
06 /* XIRQ 4 */
06 /* XIRQ 5 */
06 /* XIRQ 6 */
07]; /* Reserved */
};
};
PCI0: pci@ec000000 {
device_type = "pci";
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
compatible = "ibm,plb405gp-pci", "ibm,plb-pci";
primary;
reg = <0xeec00000 0x00000008 /* Config space access */
0xeed80000 0x00000004 /* IACK */
0xeed80000 0x00000004 /* Special cycle */
0xef480000 0x00000040>; /* Internal registers */
/* Outbound ranges, one memory and one IO,
* later cannot be changed. Chip supports a second
* IO range but we don't use it for now
*/
ranges = <0x02000000 0x00000000 0x80000000 0x80000000 0x00000000 0x20000000
0x01000000 0x00000000 0x00000000 0xe8000000 0x00000000 0x00010000>;
/* Inbound 2GB range starting at 0 */
dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>;
/* That's all I know about IRQs on that thing ... */
interrupt-map-mask = <0xf800 0x0 0x0 0x0>;
interrupt-map = <
/* USB */
0x7000 0x0 0x0 0x0 &UIC0 0x1e 0x8 /* IRQ5 */
>;
};
};
chosen {
stdout-path = "/plb/opb/serial@ef600300";
};
};
......@@ -3,9 +3,7 @@
* phyCORE-MPC5200B-IO (pcm032) board Device Tree Source
*
* Copyright (C) 2006-2009 Pengutronix
* Sascha Hauer <s.hauer@pengutronix.de>
* Juergen Beisert <j.beisert@pengutronix.de>
* Wolfram Sang <w.sang@pengutronix.de>
* Sascha Hauer, Juergen Beisert, Wolfram Sang <kernel@pengutronix.de>
*/
/include/ "mpc5200b.dtsi"
......
This diff is collapsed.
This diff is collapsed.
/*
* Device Tree Source for IBM Walnut
*
* Copyright 2007 IBM Corp.
* Josh Boyer <jwboyer@linux.vnet.ibm.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.
*/
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
model = "ibm,walnut";
compatible = "ibm,walnut";
dcr-parent = <&{/cpus/cpu@0}>;
aliases {
ethernet0 = &EMAC;
serial0 = &UART0;
serial1 = &UART1;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
device_type = "cpu";
model = "PowerPC,405GP";
reg = <0x00000000>;
clock-frequency = <200000000>; /* Filled in by zImage */
timebase-frequency = <0>; /* Filled in by zImage */
i-cache-line-size = <32>;
d-cache-line-size = <32>;
i-cache-size = <16384>;
d-cache-size = <16384>;
dcr-controller;
dcr-access-method = "native";
};
};
memory {
device_type = "memory";
reg = <0x00000000 0x00000000>; /* Filled in by zImage */
};
UIC0: interrupt-controller {
compatible = "ibm,uic";
interrupt-controller;
cell-index = <0>;
dcr-reg = <0x0c0 0x009>;
#address-cells = <0>;
#size-cells = <0>;
#interrupt-cells = <2>;
};
plb {
compatible = "ibm,plb3";
#address-cells = <1>;
#size-cells = <1>;
ranges;
clock-frequency = <0>; /* Filled in by zImage */
SDRAM0: memory-controller {
compatible = "ibm,sdram-405gp";
dcr-reg = <0x010 0x002>;
};
MAL: mcmal {
compatible = "ibm,mcmal-405gp", "ibm,mcmal";
dcr-reg = <0x180 0x062>;
num-tx-chans = <1>;
num-rx-chans = <1>;
interrupt-parent = <&UIC0>;
interrupts = <
0xb 0x4 /* TXEOB */
0xc 0x4 /* RXEOB */
0xa 0x4 /* SERR */
0xd 0x4 /* TXDE */
0xe 0x4 /* RXDE */>;
};
POB0: opb {
compatible = "ibm,opb-405gp", "ibm,opb";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0xef600000 0xef600000 0x00a00000>;
dcr-reg = <0x0a0 0x005>;
clock-frequency = <0>; /* Filled in by zImage */
UART0: serial@ef600300 {
device_type = "serial";
compatible = "ns16550";
reg = <0xef600300 0x00000008>;
virtual-reg = <0xef600300>;
clock-frequency = <0>; /* Filled in by zImage */
current-speed = <9600>;
interrupt-parent = <&UIC0>;
interrupts = <0x0 0x4>;
};
UART1: serial@ef600400 {
device_type = "serial";
compatible = "ns16550";
reg = <0xef600400 0x00000008>;
virtual-reg = <0xef600400>;
clock-frequency = <0>; /* Filled in by zImage */
current-speed = <9600>;
interrupt-parent = <&UIC0>;
interrupts = <0x1 0x4>;
};
IIC: i2c@ef600500 {
compatible = "ibm,iic-405gp", "ibm,iic";
reg = <0xef600500 0x00000011>;
interrupt-parent = <&UIC0>;
interrupts = <0x2 0x4>;
};
GPIO: gpio@ef600700 {
compatible = "ibm,gpio-405gp";
reg = <0xef600700 0x00000020>;
};
EMAC: ethernet@ef600800 {
device_type = "network";
compatible = "ibm,emac-405gp", "ibm,emac";
interrupt-parent = <&UIC0>;
interrupts = <
0xf 0x4 /* Ethernet */
0x9 0x4 /* Ethernet Wake Up */>;
local-mac-address = [000000000000]; /* Filled in by zImage */
reg = <0xef600800 0x00000070>;
mal-device = <&MAL>;
mal-tx-channel = <0>;
mal-rx-channel = <0>;
cell-index = <0>;
max-frame-size = <1500>;
rx-fifo-size = <4096>;
tx-fifo-size = <2048>;
phy-mode = "rmii";
phy-map = <0x00000001>;
};
};
EBC0: ebc {
compatible = "ibm,ebc-405gp", "ibm,ebc";
dcr-reg = <0x012 0x002>;
#address-cells = <2>;
#size-cells = <1>;
/* The ranges property is supplied by the bootwrapper
* and is based on the firmware's configuration of the
* EBC bridge
*/
clock-frequency = <0>; /* Filled in by zImage */
sram@0,0 {
reg = <0x00000000 0x00000000 0x00080000>;
};
flash@0,80000 {
compatible = "jedec-flash";
bank-width = <1>;
reg = <0x00000000 0x00080000 0x00080000>;
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "OpenBIOS";
reg = <0x00000000 0x00080000>;
read-only;
};
};
nvram@1,0 {
/* NVRAM and RTC */
compatible = "ds1743-nvram";
#bytes = <0x2000>;
reg = <0x00000001 0x00000000 0x00002000>;
};
keyboard@2,0 {
compatible = "intel,82C42PC";
reg = <0x00000002 0x00000000 0x00000002>;
};
ir@3,0 {
compatible = "ti,TIR2000PAG";
reg = <0x00000003 0x00000000 0x00000010>;
};
fpga@7,0 {
compatible = "Walnut-FPGA";
reg = <0x00000007 0x00000000 0x00000010>;
virtual-reg = <0xf0300005>;
};
};
PCI0: pci@ec000000 {
device_type = "pci";
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
compatible = "ibm,plb405gp-pci", "ibm,plb-pci";
primary;
reg = <0xeec00000 0x00000008 /* Config space access */
0xeed80000 0x00000004 /* IACK */
0xeed80000 0x00000004 /* Special cycle */
0xef480000 0x00000040>; /* Internal registers */
/* Outbound ranges, one memory and one IO,
* later cannot be changed. Chip supports a second
* IO range but we don't use it for now
*/
ranges = <0x02000000 0x00000000 0x80000000 0x80000000 0x00000000 0x20000000
0x01000000 0x00000000 0x00000000 0xe8000000 0x00000000 0x00010000>;
/* Inbound 2GB range starting at 0 */
dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>;
/* Walnut has all 4 IRQ pins tied together per slot */
interrupt-map-mask = <0xf800 0x0 0x0 0x0>;
interrupt-map = <
/* IDSEL 1 */
0x800 0x0 0x0 0x0 &UIC0 0x1c 0x8
/* IDSEL 2 */
0x1000 0x0 0x0 0x0 &UIC0 0x1d 0x8
/* IDSEL 3 */
0x1800 0x0 0x0 0x0 &UIC0 0x1e 0x8
/* IDSEL 4 */
0x2000 0x0 0x0 0x0 &UIC0 0x1f 0x8
>;
};
};
chosen {
stdout-path = "/plb/opb/serial@ef600300";
};
};
// SPDX-License-Identifier: GPL-2.0-only
/*
* Embedded Planet EP405 with PlanetCore firmware
*
* (c) Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp,\
*
* Based on ep88xc.c by
*
* Scott Wood <scottwood@freescale.com>
*
* Copyright (c) 2007 Freescale Semiconductor, Inc.
*/
#include "ops.h"
#include "stdio.h"
#include "planetcore.h"
#include "dcr.h"
#include "4xx.h"
#include "io.h"
static char *table;
static u64 mem_size;
static void platform_fixups(void)
{
u64 val;
void *nvrtc;
dt_fixup_memory(0, mem_size);
planetcore_set_mac_addrs(table);
if (!planetcore_get_decimal(table, PLANETCORE_KEY_CRYSTAL_HZ, &val)) {
printf("No PlanetCore crystal frequency key.\r\n");
return;
}
ibm405gp_fixup_clocks(val, 0xa8c000);
ibm4xx_quiesce_eth((u32 *)0xef600800, NULL);
ibm4xx_fixup_ebc_ranges("/plb/ebc");
if (!planetcore_get_decimal(table, PLANETCORE_KEY_KB_NVRAM, &val)) {
printf("No PlanetCore NVRAM size key.\r\n");
return;
}
nvrtc = finddevice("/plb/ebc/nvrtc@4,200000");
if (nvrtc != NULL) {
u32 reg[3] = { 4, 0x200000, 0};
getprop(nvrtc, "reg", reg, 3);
reg[2] = (val << 10) & 0xffffffff;
setprop(nvrtc, "reg", reg, 3);
}
}
void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
table = (char *)r3;
planetcore_prepare_table(table);
if (!planetcore_get_decimal(table, PLANETCORE_KEY_MB_RAM, &mem_size))
return;
mem_size *= 1024 * 1024;
simple_alloc_init(_end, mem_size - (unsigned long)_end, 32, 64);
fdt_init(_dtb_start);
planetcore_set_stdout_path(table);
serial_console_init();
platform_ops.fixups = platform_fixups;
}
......@@ -88,7 +88,6 @@ int serial_console_init(void);
int ns16550_console_init(void *devp, struct serial_console_data *scdp);
int cpm_console_init(void *devp, struct serial_console_data *scdp);
int mpc5200_psc_console_init(void *devp, struct serial_console_data *scdp);
int uartlite_console_init(void *devp, struct serial_console_data *scdp);
int opal_console_init(void *devp, struct serial_console_data *scdp);
void *simple_alloc_init(char *base, unsigned long heap_size,
unsigned long granularity, unsigned long max_allocs);
......
......@@ -132,11 +132,6 @@ int serial_console_init(void)
else if (dt_is_compatible(devp, "fsl,mpc5200-psc-uart"))
rc = mpc5200_psc_console_init(devp, &serial_cd);
#endif
#ifdef CONFIG_XILINX_VIRTEX
else if (dt_is_compatible(devp, "xlnx,opb-uartlite-1.00.b") ||
dt_is_compatible(devp, "xlnx,xps-uartlite-1.00.a"))
rc = uartlite_console_init(devp, &serial_cd);
#endif
#ifdef CONFIG_PPC64_BOOT_WRAPPER
else if (dt_is_compatible(devp, "ibm,opal-console-raw"))
rc = opal_console_init(devp, &serial_cd);
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Old U-boot compatibility for Walnut
*
* Author: Josh Boyer <jwboyer@linux.vnet.ibm.com>
*
* Copyright 2007 IBM Corporation
* Based on cuboot-83xx.c, which is:
* Copyright (c) 2007 Freescale Semiconductor, Inc.
*/
#include "ops.h"
#include "stdio.h"
#include "dcr.h"
#include "4xx.h"
#include "io.h"
BSS_STACK(4096);
static void walnut_flashsel_fixup(void)
{
void *devp, *sram;
u32 reg_flash[3] = {0x0, 0x0, 0x80000};
u32 reg_sram[3] = {0x0, 0x0, 0x80000};
u8 *fpga;
u8 fpga_brds1 = 0x0;
devp = finddevice("/plb/ebc/fpga");
if (!devp)
fatal("Couldn't locate FPGA node\n\r");
if (getprop(devp, "virtual-reg", &fpga, sizeof(fpga)) != sizeof(fpga))
fatal("no virtual-reg property\n\r");
fpga_brds1 = in_8(fpga);
devp = finddevice("/plb/ebc/flash");
if (!devp)
fatal("Couldn't locate flash node\n\r");
if (getprop(devp, "reg", reg_flash, sizeof(reg_flash)) != sizeof(reg_flash))
fatal("flash reg property has unexpected size\n\r");
sram = finddevice("/plb/ebc/sram");
if (!sram)
fatal("Couldn't locate sram node\n\r");
if (getprop(sram, "reg", reg_sram, sizeof(reg_sram)) != sizeof(reg_sram))
fatal("sram reg property has unexpected size\n\r");
if (fpga_brds1 & 0x1) {
reg_flash[1] ^= 0x80000;
reg_sram[1] ^= 0x80000;
}
setprop(devp, "reg", reg_flash, sizeof(reg_flash));
setprop(sram, "reg", reg_sram, sizeof(reg_sram));
}
#define WALNUT_OPENBIOS_MAC_OFF 0xfffffe0b
static void walnut_fixups(void)
{
ibm4xx_sdram_fixup_memsize();
ibm405gp_fixup_clocks(33330000, 0xa8c000);
ibm4xx_quiesce_eth((u32 *)0xef600800, NULL);
ibm4xx_fixup_ebc_ranges("/plb/ebc");
walnut_flashsel_fixup();
dt_fixup_mac_address_by_alias("ethernet0", (u8 *) WALNUT_OPENBIOS_MAC_OFF);
}
void platform_init(void)
{
unsigned long end_of_ram = 0x2000000;
unsigned long avail_ram = end_of_ram - (unsigned long) _end;
simple_alloc_init(_end, avail_ram, 32, 32);
platform_ops.fixups = walnut_fixups;
platform_ops.exit = ibm40x_dbcr_reset;
fdt_init(_dtb_start);
serial_console_init();
}
/*
* Xilinx UARTLITE bootloader driver
*
* Copyright (C) 2007 Secret Lab Technologies Ltd.
*
* 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.
*/
#include <stdarg.h>
#include <stddef.h>
#include "types.h"
#include "string.h"
#include "stdio.h"
#include "io.h"
#include "ops.h"
#define ULITE_RX 0x00
#define ULITE_TX 0x04
#define ULITE_STATUS 0x08
#define ULITE_CONTROL 0x0c
#define ULITE_STATUS_RXVALID 0x01
#define ULITE_STATUS_TXFULL 0x08
#define ULITE_CONTROL_RST_RX 0x02
static void * reg_base;
static int uartlite_open(void)
{
/* Clear the RX FIFO */
out_be32(reg_base + ULITE_CONTROL, ULITE_CONTROL_RST_RX);
return 0;
}
static void uartlite_putc(unsigned char c)
{
u32 reg = ULITE_STATUS_TXFULL;
while (reg & ULITE_STATUS_TXFULL) /* spin on TXFULL bit */
reg = in_be32(reg_base + ULITE_STATUS);
out_be32(reg_base + ULITE_TX, c);
}
static unsigned char uartlite_getc(void)
{
u32 reg = 0;
while (!(reg & ULITE_STATUS_RXVALID)) /* spin waiting for RXVALID bit */
reg = in_be32(reg_base + ULITE_STATUS);
return in_be32(reg_base + ULITE_RX);
}
static u8 uartlite_tstc(void)
{
u32 reg = in_be32(reg_base + ULITE_STATUS);
return reg & ULITE_STATUS_RXVALID;
}
int uartlite_console_init(void *devp, struct serial_console_data *scdp)
{
int n;
unsigned long reg_phys;
n = getprop(devp, "virtual-reg", &reg_base, sizeof(reg_base));
if (n != sizeof(reg_base)) {
if (!dt_xlate_reg(devp, 0, &reg_phys, NULL))
return -1;
reg_base = (void *)reg_phys;
}
scdp->open = uartlite_open;
scdp->putc = uartlite_putc;
scdp->getc = uartlite_getc;
scdp->tstc = uartlite_tstc;
scdp->close = NULL;
return 0;
}
// SPDX-License-Identifier: GPL-2.0-only
/*
* The platform specific code for virtex devices since a boot loader is not
* always used.
*
* (C) Copyright 2008 Xilinx, Inc.
*/
#include "ops.h"
#include "io.h"
#include "stdio.h"
#define UART_DLL 0 /* Out: Divisor Latch Low */
#define UART_DLM 1 /* Out: Divisor Latch High */
#define UART_FCR 2 /* Out: FIFO Control Register */
#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */
#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */
#define UART_LCR 3 /* Out: Line Control Register */
#define UART_MCR 4 /* Out: Modem Control Register */
#define UART_MCR_RTS 0x02 /* RTS complement */
#define UART_MCR_DTR 0x01 /* DTR complement */
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
static int virtex_ns16550_console_init(void *devp)
{
unsigned char *reg_base;
u32 reg_shift, reg_offset, clk, spd;
u16 divisor;
int n;
if (dt_get_virtual_reg(devp, (void **)&reg_base, 1) < 1)
return -1;
n = getprop(devp, "reg-offset", &reg_offset, sizeof(reg_offset));
if (n == sizeof(reg_offset))
reg_base += reg_offset;
n = getprop(devp, "reg-shift", &reg_shift, sizeof(reg_shift));
if (n != sizeof(reg_shift))
reg_shift = 0;
n = getprop(devp, "current-speed", (void *)&spd, sizeof(spd));
if (n != sizeof(spd))
spd = 9600;
/* should there be a default clock rate?*/
n = getprop(devp, "clock-frequency", (void *)&clk, sizeof(clk));
if (n != sizeof(clk))
return -1;
divisor = clk / (16 * spd);
/* Access baud rate */
out_8(reg_base + (UART_LCR << reg_shift), UART_LCR_DLAB);
/* Baud rate based on input clock */
out_8(reg_base + (UART_DLL << reg_shift), divisor & 0xFF);
out_8(reg_base + (UART_DLM << reg_shift), divisor >> 8);
/* 8 data, 1 stop, no parity */
out_8(reg_base + (UART_LCR << reg_shift), UART_LCR_WLEN8);
/* RTS/DTR */
out_8(reg_base + (UART_MCR << reg_shift), UART_MCR_RTS | UART_MCR_DTR);
/* Clear transmitter and receiver */
out_8(reg_base + (UART_FCR << reg_shift),
UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR);
return 0;
}
/* For virtex, the kernel may be loaded without using a bootloader and if so
some UARTs need more setup than is provided in the normal console init
*/
int platform_specific_init(void)
{
void *devp;
char devtype[MAX_PROP_LEN];
char path[MAX_PATH_LEN];
devp = finddevice("/chosen");
if (devp == NULL)
return -1;
if (getprop(devp, "linux,stdout-path", path, MAX_PATH_LEN) > 0) {
devp = finddevice(path);
if (devp == NULL)
return -1;
if ((getprop(devp, "device_type", devtype, sizeof(devtype)) > 0)
&& !strcmp(devtype, "serial")
&& (dt_is_compatible(devp, "ns16550")))
virtex_ns16550_console_init(devp);
}
return 0;
}
/* SPDX-License-Identifier: GPL-2.0 */
#include "ppc_asm.h"
.text
.global _zimage_start
_zimage_start:
/* PPC errata 213: needed by Virtex-4 FX */
mfccr0 0
oris 0,0,0x50000000@h
mtccr0 0
/*
* Invalidate the data cache if the data cache is turned off.
* - The 405 core does not invalidate the data cache on power-up
* or reset but does turn off the data cache. We cannot assume
* that the cache contents are valid.
* - If the data cache is turned on this must have been done by
* a bootloader and we assume that the cache contents are
* valid.
*/
mfdccr r9
cmplwi r9,0
bne 2f
lis r9,0
li r8,256
mtctr r8
1: dccci r0,r9
addi r9,r9,0x20
bdnz 1b
2: b _zimage_start_lib
......@@ -29,6 +29,7 @@ set -e
# Allow for verbose output
if [ "$V" = 1 ]; then
set -x
map="-Map wrapper.map"
fi
# defaults
......@@ -323,14 +324,6 @@ adder875-redboot)
platformo="$object/fixed-head.o $object/redboot-8xx.o"
binary=y
;;
simpleboot-virtex405-*)
platformo="$object/virtex405-head.o $object/simpleboot.o $object/virtex.o"
binary=y
;;
simpleboot-virtex440-*)
platformo="$object/fixed-head.o $object/simpleboot.o $object/virtex.o"
binary=y
;;
simpleboot-*)
platformo="$object/fixed-head.o $object/simpleboot.o"
binary=y
......@@ -500,7 +493,7 @@ if [ "$platform" != "miboot" ]; then
text_start="-Ttext $link_address"
fi
#link everything
${CROSS}ld -m $format -T $lds $text_start $pie $nodl -o "$ofile" \
${CROSS}ld -m $format -T $lds $text_start $pie $nodl -o "$ofile" $map \
$platformo $tmp $object/wrapper.a
rm $tmp
fi
......@@ -570,7 +563,18 @@ ps3)
count=$overlay_size bs=1
odir="$(dirname "$ofile.bin")"
rm -f "$odir/otheros.bld"
gzip -n --force -9 --stdout "$ofile.bin" > "$odir/otheros.bld"
# The ps3's flash loader has a size limit of 16 MiB for the uncompressed
# image. If a compressed image that exceeded this limit is written to
# flash the loader will decompress that image until the 16 MiB limit is
# reached, then enter the system reset vector of the partially decompressed
# image. No warning is issued.
rm -f "$odir"/{otheros,otheros-too-big}.bld
size=$(${CROSS}nm --no-sort --radix=d "$ofile" | egrep ' _end$' | cut -d' ' -f1)
bld="otheros.bld"
if [ $size -gt $((0x1000000)) ]; then
bld="otheros-too-big.bld"
fi
gzip -n --force -9 --stdout "$ofile.bin" > "$odir/$bld"
;;
esac
......@@ -9,7 +9,6 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_ACADIA=y
# CONFIG_WALNUT is not set
CONFIG_PCI=y
CONFIG_NET=y
CONFIG_PACKET=y
......
CONFIG_40x=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
CONFIG_KALLSYMS_ALL=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_EP405=y
# CONFIG_WALNUT is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IPV6 is not set
CONFIG_CONNECTOR=y
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_BLOCK=m
CONFIG_MTD_CFI=y
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=35000
CONFIG_NETDEVICES=y
CONFIG_IBM_EMAC=y
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_OF_PLATFORM=y
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
CONFIG_THERMAL=y
CONFIG_USB=y
CONFIG_USB_MON=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
CONFIG_EXT2_FS=y
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_CRAMFS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_PCBC=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_DES=y
......@@ -11,7 +11,6 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_KILAUEA=y
# CONFIG_WALNUT is not set
CONFIG_PCI=y
CONFIG_NET=y
CONFIG_PACKET=y
......
......@@ -8,7 +8,6 @@ CONFIG_EMBEDDED=y
CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_WALNUT is not set
CONFIG_APM8018X=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_MATH_EMULATION=y
......
......@@ -9,7 +9,6 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_MAKALU=y
# CONFIG_WALNUT is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
......
......@@ -10,7 +10,6 @@ CONFIG_KALLSYMS_ALL=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_WALNUT is not set
CONFIG_OBS600=y
CONFIG_MATH_EMULATION=y
CONFIG_NET=y
......
CONFIG_40x=y
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_WALNUT is not set
CONFIG_XILINX_VIRTEX_GENERIC_BOARD=y
CONFIG_PREEMPT=y
CONFIG_MATH_EMULATION=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE=""
CONFIG_PCI=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_NETFILTER=y
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_MANGLE=m
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_XILINX_SYSACE=y
CONFIG_NETDEVICES=y
# CONFIG_SERIO_SERPORT is not set
CONFIG_SERIO_XILINX_XPS_PS2=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_UARTLITE=y
CONFIG_SERIAL_UARTLITE_CONSOLE=y
CONFIG_XILINX_HWICAP=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_XILINX=y
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FB_XILINX=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
# CONFIG_USB_SUPPORT is not set
CONFIG_EXT2_FS=y
CONFIG_AUTOFS4_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_CRAMFS=y
CONFIG_ROMFS_FS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ASCII=m
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_UTF8=m
CONFIG_CRC_CCITT=y
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_KERNEL=y
CONFIG_44x=y
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_EBONY is not set
CONFIG_XILINX_VIRTEX440_GENERIC_BOARD=y
CONFIG_PREEMPT=y
CONFIG_MATH_EMULATION=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE=""
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_NETFILTER=y
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_MANGLE=m
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_XILINX_SYSACE=y
CONFIG_NETDEVICES=y
# CONFIG_SERIO_SERPORT is not set
CONFIG_SERIO_XILINX_XPS_PS2=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_UARTLITE=y
CONFIG_SERIAL_UARTLITE_CONSOLE=y
CONFIG_XILINX_HWICAP=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_XILINX=y
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FB_XILINX=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
# CONFIG_USB_SUPPORT is not set
CONFIG_EXT2_FS=y
CONFIG_AUTOFS4_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_CRAMFS=y
CONFIG_ROMFS_FS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ASCII=m
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_UTF8=m
CONFIG_CRC_CCITT=y
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_KERNEL=y
......@@ -10,7 +10,6 @@ CONFIG_EXPERT=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
CONFIG_PPC_ADDER875=y
CONFIG_8xx_COPYBACK=y
CONFIG_GEN_RTC=y
CONFIG_HZ_1000=y
# CONFIG_SECCOMP is not set
......
......@@ -12,7 +12,6 @@ CONFIG_EXPERT=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
CONFIG_PPC_EP88XC=y
CONFIG_8xx_COPYBACK=y
CONFIG_GEN_RTC=y
CONFIG_HZ_100=y
# CONFIG_SECCOMP is not set
......
......@@ -12,7 +12,6 @@ CONFIG_EXPERT=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
CONFIG_MPC86XADS=y
CONFIG_8xx_COPYBACK=y
CONFIG_GEN_RTC=y
CONFIG_HZ_1000=y
CONFIG_MATH_EMULATION=y
......
......@@ -11,7 +11,6 @@ CONFIG_EXPERT=y
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
CONFIG_8xx_COPYBACK=y
CONFIG_GEN_RTC=y
CONFIG_HZ_100=y
# CONFIG_SECCOMP is not set
......
......@@ -347,3 +347,4 @@ CONFIG_KVM_BOOK3S_64=m
CONFIG_KVM_BOOK3S_64_HV=m
CONFIG_VHOST_NET=m
CONFIG_PRINTK_TIME=y
CONFIG_PRINTK_CALLER=y
......@@ -10,11 +10,9 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PPC4xx_GPIO=y
CONFIG_ACADIA=y
CONFIG_EP405=y
CONFIG_HOTFOOT=y
CONFIG_KILAUEA=y
CONFIG_MAKALU=y
CONFIG_XILINX_VIRTEX_GENERIC_BOARD=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
......@@ -37,33 +35,26 @@ CONFIG_MTD_UBI=m
CONFIG_MTD_UBI_GLUEBI=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=35000
CONFIG_XILINX_SYSACE=m
CONFIG_NETDEVICES=y
CONFIG_IBM_EMAC=y
# CONFIG_INPUT is not set
CONFIG_SERIO=m
# CONFIG_SERIO_I8042 is not set
# CONFIG_SERIO_SERPORT is not set
CONFIG_SERIO_XILINX_XPS_PS2=m
# CONFIG_VT is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_UARTLITE=y
CONFIG_SERIAL_UARTLITE_CONSOLE=y
# CONFIG_HW_RANDOM is not set
CONFIG_XILINX_HWICAP=m
CONFIG_I2C=m
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_GPIO=m
CONFIG_I2C_IBM_IIC=m
CONFIG_GPIO_XILINX=y
# CONFIG_HWMON is not set
CONFIG_THERMAL=y
CONFIG_FB=m
CONFIG_FB_XILINX=m
CONFIG_EXT2_FS=y
CONFIG_EXT4_FS=m
CONFIG_VFAT_FS=m
......
......@@ -22,7 +22,6 @@ CONFIG_GLACIER=y
CONFIG_REDWOOD=y
CONFIG_EIGER=y
CONFIG_YOSEMITE=y
CONFIG_XILINX_VIRTEX440_GENERIC_BOARD=y
CONFIG_PPC4xx_GPIO=y
CONFIG_MATH_EMULATION=y
CONFIG_NET=y
......@@ -46,7 +45,6 @@ CONFIG_MTD_UBI=m
CONFIG_MTD_UBI_GLUEBI=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=35000
CONFIG_XILINX_SYSACE=m
CONFIG_SCSI=m
CONFIG_BLK_DEV_SD=m
# CONFIG_SCSI_LOWLEVEL is not set
......@@ -57,7 +55,6 @@ CONFIG_IBM_EMAC=y
CONFIG_SERIO=m
# CONFIG_SERIO_I8042 is not set
# CONFIG_SERIO_SERPORT is not set
CONFIG_SERIO_XILINX_XPS_PS2=m
# CONFIG_VT is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
......@@ -65,18 +62,13 @@ CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_UARTLITE=y
CONFIG_SERIAL_UARTLITE_CONSOLE=y
# CONFIG_HW_RANDOM is not set
CONFIG_XILINX_HWICAP=m
CONFIG_I2C=m
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_GPIO=m
CONFIG_I2C_IBM_IIC=m
CONFIG_GPIO_XILINX=y
# CONFIG_HWMON is not set
CONFIG_FB=m
CONFIG_FB_XILINX=m
CONFIG_USB=m
CONFIG_USB_EHCI_HCD=m
CONFIG_USB_OHCI_HCD=m
......
......@@ -281,6 +281,7 @@ CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_DS1307=y
CONFIG_VIRTIO_PCI=m
CONFIG_VIRTIO_BALLOON=m
CONFIG_LIBNVDIMM=y
CONFIG_RAS=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
......@@ -358,6 +359,7 @@ CONFIG_CRYPTO_DEV_NX=y
CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
CONFIG_CRYPTO_DEV_VMX=y
CONFIG_PRINTK_TIME=y
CONFIG_PRINTK_CALLER=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_STACK_USAGE=y
......
......@@ -322,3 +322,4 @@ CONFIG_KVM_BOOK3S_64=m
CONFIG_KVM_BOOK3S_64_HV=m
CONFIG_VHOST_NET=m
CONFIG_PRINTK_TIME=y
CONFIG_PRINTK_CALLER=y
......@@ -15,7 +15,6 @@ CONFIG_MODULE_SRCVERSION_ALL=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
CONFIG_TQM8XX=y
CONFIG_8xx_COPYBACK=y
# CONFIG_8xx_CPU15 is not set
CONFIG_GEN_RTC=y
CONFIG_HZ_100=y
......
#ifndef _ASM_POWERPC_ASM_405_H
#define _ASM_POWERPC_ASM_405_H
#include <asm/asm-const.h>
#ifdef __KERNEL__
#ifdef CONFIG_IBM405_ERR77
/* Erratum #77 on the 405 means we need a sync or dcbt before every
* stwcx. The old ATOMIC_SYNC_FIX covered some but not all of this.
*/
#define PPC405_ERR77(ra,rb) stringify_in_c(dcbt ra, rb;)
#define PPC405_ERR77_SYNC stringify_in_c(sync;)
#else
#define PPC405_ERR77(ra,rb)
#define PPC405_ERR77_SYNC
#endif
#endif
#endif /* _ASM_POWERPC_ASM_405_H */
......@@ -10,7 +10,6 @@
#include <linux/types.h>
#include <asm/cmpxchg.h>
#include <asm/barrier.h>
#include <asm/asm-405.h>
#define ATOMIC_INIT(i) { (i) }
......@@ -47,7 +46,6 @@ static __inline__ void atomic_##op(int a, atomic_t *v) \
__asm__ __volatile__( \
"1: lwarx %0,0,%3 # atomic_" #op "\n" \
#asm_op " %0,%2,%0\n" \
PPC405_ERR77(0,%3) \
" stwcx. %0,0,%3 \n" \
" bne- 1b\n" \
: "=&r" (t), "+m" (v->counter) \
......@@ -63,7 +61,6 @@ static inline int atomic_##op##_return_relaxed(int a, atomic_t *v) \
__asm__ __volatile__( \
"1: lwarx %0,0,%3 # atomic_" #op "_return_relaxed\n" \
#asm_op " %0,%2,%0\n" \
PPC405_ERR77(0, %3) \
" stwcx. %0,0,%3\n" \
" bne- 1b\n" \
: "=&r" (t), "+m" (v->counter) \
......@@ -81,7 +78,6 @@ static inline int atomic_fetch_##op##_relaxed(int a, atomic_t *v) \
__asm__ __volatile__( \
"1: lwarx %0,0,%4 # atomic_fetch_" #op "_relaxed\n" \
#asm_op " %1,%3,%0\n" \
PPC405_ERR77(0, %4) \
" stwcx. %1,0,%4\n" \
" bne- 1b\n" \
: "=&r" (res), "=&r" (t), "+m" (v->counter) \
......@@ -130,7 +126,6 @@ static __inline__ void atomic_inc(atomic_t *v)
__asm__ __volatile__(
"1: lwarx %0,0,%2 # atomic_inc\n\
addic %0,%0,1\n"
PPC405_ERR77(0,%2)
" stwcx. %0,0,%2 \n\
bne- 1b"
: "=&r" (t), "+m" (v->counter)
......@@ -146,7 +141,6 @@ static __inline__ int atomic_inc_return_relaxed(atomic_t *v)
__asm__ __volatile__(
"1: lwarx %0,0,%2 # atomic_inc_return_relaxed\n"
" addic %0,%0,1\n"
PPC405_ERR77(0, %2)
" stwcx. %0,0,%2\n"
" bne- 1b"
: "=&r" (t), "+m" (v->counter)
......@@ -163,7 +157,6 @@ static __inline__ void atomic_dec(atomic_t *v)
__asm__ __volatile__(
"1: lwarx %0,0,%2 # atomic_dec\n\
addic %0,%0,-1\n"
PPC405_ERR77(0,%2)\
" stwcx. %0,0,%2\n\
bne- 1b"
: "=&r" (t), "+m" (v->counter)
......@@ -179,7 +172,6 @@ static __inline__ int atomic_dec_return_relaxed(atomic_t *v)
__asm__ __volatile__(
"1: lwarx %0,0,%2 # atomic_dec_return_relaxed\n"
" addic %0,%0,-1\n"
PPC405_ERR77(0, %2)
" stwcx. %0,0,%2\n"
" bne- 1b"
: "=&r" (t), "+m" (v->counter)
......@@ -220,7 +212,6 @@ static __inline__ int atomic_fetch_add_unless(atomic_t *v, int a, int u)
cmpw 0,%0,%3 \n\
beq 2f \n\
add %0,%2,%0 \n"
PPC405_ERR77(0,%2)
" stwcx. %0,0,%1 \n\
bne- 1b \n"
PPC_ATOMIC_EXIT_BARRIER
......@@ -251,7 +242,6 @@ static __inline__ int atomic_inc_not_zero(atomic_t *v)
cmpwi 0,%0,0\n\
beq- 2f\n\
addic %1,%0,1\n"
PPC405_ERR77(0,%2)
" stwcx. %1,0,%2\n\
bne- 1b\n"
PPC_ATOMIC_EXIT_BARRIER
......@@ -280,7 +270,6 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v)
cmpwi %0,1\n\
addi %0,%0,-1\n\
blt- 2f\n"
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1\n\
bne- 1b"
PPC_ATOMIC_EXIT_BARRIER
......
......@@ -41,7 +41,6 @@
#include <linux/compiler.h>
#include <asm/asm-compat.h>
#include <asm/synch.h>
#include <asm/asm-405.h>
/* PPC bit number conversion */
#define PPC_BITLSHIFT(be) (BITS_PER_LONG - 1 - (be))
......@@ -73,7 +72,6 @@ static inline void fn(unsigned long mask, \
prefix \
"1:" PPC_LLARX(%0,0,%3,0) "\n" \
stringify_in_c(op) "%0,%0,%2\n" \
PPC405_ERR77(0,%3) \
PPC_STLCX "%0,0,%3\n" \
"bne- 1b\n" \
: "=&r" (old), "+m" (*p) \
......@@ -119,7 +117,6 @@ static inline unsigned long fn( \
prefix \
"1:" PPC_LLARX(%0,0,%3,eh) "\n" \
stringify_in_c(op) "%1,%0,%2\n" \
PPC405_ERR77(0,%3) \
PPC_STLCX "%1,0,%3\n" \
"bne- 1b\n" \
postfix \
......@@ -175,7 +172,6 @@ clear_bit_unlock_return_word(int nr, volatile unsigned long *addr)
PPC_RELEASE_BARRIER
"1:" PPC_LLARX(%0,0,%3,0) "\n"
"andc %1,%0,%2\n"
PPC405_ERR77(0,%3)
PPC_STLCX "%1,0,%3\n"
"bne- 1b\n"
: "=&r" (old), "=&r" (t)
......
......@@ -2,6 +2,7 @@
#ifndef _ASM_POWERPC_BOOK3S_32_KUP_H
#define _ASM_POWERPC_BOOK3S_32_KUP_H
#include <asm/bug.h>
#include <asm/book3s/32/mmu-hash.h>
#ifdef __ASSEMBLY__
......@@ -75,7 +76,7 @@
.macro kuap_check current, gpr
#ifdef CONFIG_PPC_KUAP_DEBUG
lwz \gpr, KUAP(thread)
lwz \gpr, THREAD + KUAP(\current)
999: twnei \gpr, 0
EMIT_BUG_ENTRY 999b, __FILE__, __LINE__, (BUGFLAG_WARNING | BUGFLAG_ONCE)
#endif
......@@ -108,7 +109,7 @@ static __always_inline void allow_user_access(void __user *to, const void __user
u32 addr, end;
BUILD_BUG_ON(!__builtin_constant_p(dir));
BUILD_BUG_ON(dir == KUAP_CURRENT);
BUILD_BUG_ON(dir & ~KUAP_READ_WRITE);
if (!(dir & KUAP_WRITE))
return;
......@@ -131,7 +132,7 @@ static __always_inline void prevent_user_access(void __user *to, const void __us
BUILD_BUG_ON(!__builtin_constant_p(dir));
if (dir == KUAP_CURRENT) {
if (dir & KUAP_CURRENT_WRITE) {
u32 kuap = current->thread.kuap;
if (unlikely(!kuap))
......
......@@ -187,14 +187,14 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
* memory shall not share segments.
*/
#if defined(CONFIG_STRICT_KERNEL_RWX) && defined(CONFIG_MODULES)
#define VMALLOC_START ((_ALIGN((long)high_memory, 256L << 20) + VMALLOC_OFFSET) & \
#define VMALLOC_START ((ALIGN((long)high_memory, 256L << 20) + VMALLOC_OFFSET) & \
~(VMALLOC_OFFSET - 1))
#else
#define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
#endif
#ifdef CONFIG_KASAN_VMALLOC
#define VMALLOC_END _ALIGN_DOWN(ioremap_bot, PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
#define VMALLOC_END ALIGN_DOWN(ioremap_bot, PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
#else
#define VMALLOC_END ioremap_bot
#endif
......@@ -217,7 +217,7 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
*/
#define pte_clear(mm, addr, ptep) \
do { pte_update(ptep, ~_PAGE_HASHPTE, 0); } while (0)
do { pte_update(mm, addr, ptep, ~_PAGE_HASHPTE, 0, 0); } while (0)
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD)
......@@ -252,84 +252,68 @@ extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep,
* and the PTE may be either 32 or 64 bit wide. In the later case,
* when using atomic updates, only the low part of the PTE is
* accessed atomically.
*
* In addition, on 44x, we also maintain a global flag indicating
* that an executable user mapping was modified, which is needed
* to properly flush the virtually tagged instruction cache of
* those implementations.
*/
#ifndef CONFIG_PTE_64BIT
static inline unsigned long pte_update(pte_t *p,
unsigned long clr,
unsigned long set)
static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *p,
unsigned long clr, unsigned long set, int huge)
{
unsigned long old, tmp;
__asm__ __volatile__("\
1: lwarx %0,0,%3\n\
andc %1,%0,%4\n\
or %1,%1,%5\n"
" stwcx. %1,0,%3\n\
bne- 1b"
: "=&r" (old), "=&r" (tmp), "=m" (*p)
: "r" (p), "r" (clr), "r" (set), "m" (*p)
: "cc" );
return old;
}
#else /* CONFIG_PTE_64BIT */
static inline unsigned long long pte_update(pte_t *p,
unsigned long clr,
unsigned long set)
{
unsigned long long old;
pte_basic_t old;
unsigned long tmp;
__asm__ __volatile__("\
1: lwarx %L0,0,%4\n\
lwzx %0,0,%3\n\
andc %1,%L0,%5\n\
or %1,%1,%6\n"
" stwcx. %1,0,%4\n\
bne- 1b"
__asm__ __volatile__(
#ifndef CONFIG_PTE_64BIT
"1: lwarx %0, 0, %3\n"
" andc %1, %0, %4\n"
#else
"1: lwarx %L0, 0, %3\n"
" lwz %0, -4(%3)\n"
" andc %1, %L0, %4\n"
#endif
" or %1, %1, %5\n"
" stwcx. %1, 0, %3\n"
" bne- 1b"
: "=&r" (old), "=&r" (tmp), "=m" (*p)
: "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p)
#ifndef CONFIG_PTE_64BIT
: "r" (p),
#else
: "b" ((unsigned long)(p) + 4),
#endif
"r" (clr), "r" (set), "m" (*p)
: "cc" );
return old;
}
#endif /* CONFIG_PTE_64BIT */
/*
* 2.6 calls this without flushing the TLB entry; this is wrong
* for our hash-based implementation, we fix that up here.
*/
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
static inline int __ptep_test_and_clear_young(unsigned int context, unsigned long addr, pte_t *ptep)
static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
unsigned long old;
old = pte_update(ptep, _PAGE_ACCESSED, 0);
old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0);
if (old & _PAGE_HASHPTE) {
unsigned long ptephys = __pa(ptep) & PAGE_MASK;
flush_hash_pages(context, addr, ptephys, 1);
flush_hash_pages(mm->context.id, addr, ptephys, 1);
}
return (old & _PAGE_ACCESSED) != 0;
}
#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
__ptep_test_and_clear_young((__vma)->vm_mm->context.id, __addr, __ptep)
__ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep)
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep)
{
return __pte(pte_update(ptep, ~_PAGE_HASHPTE, 0));
return __pte(pte_update(mm, addr, ptep, ~_PAGE_HASHPTE, 0, 0));
}
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
pte_t *ptep)
{
pte_update(ptep, _PAGE_RW, 0);
pte_update(mm, addr, ptep, _PAGE_RW, 0, 0);
}
static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
......@@ -340,7 +324,7 @@ static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long set = pte_val(entry) &
(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
pte_update(ptep, 0, set);
pte_update(vma->vm_mm, address, ptep, 0, set, 0);
flush_tlb_page(vma, address);
}
......@@ -538,7 +522,7 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
*ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
| (pte_val(pte) & ~_PAGE_HASHPTE));
else
pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte));
pte_update(mm, addr, ptep, ~_PAGE_HASHPTE, pte_val(pte), 0);
#elif defined(CONFIG_PTE_64BIT)
/* Second case is 32-bit with 64-bit PTE. In this case, we
......
......@@ -12,11 +12,17 @@
#ifdef __ASSEMBLY__
.macro kuap_restore_amr gpr
.macro kuap_restore_amr gpr1, gpr2
#ifdef CONFIG_PPC_KUAP
BEGIN_MMU_FTR_SECTION_NESTED(67)
ld \gpr, STACK_REGS_KUAP(r1)
mtspr SPRN_AMR, \gpr
mfspr \gpr1, SPRN_AMR
ld \gpr2, STACK_REGS_KUAP(r1)
cmpd \gpr1, \gpr2
beq 998f
isync
mtspr SPRN_AMR, \gpr2
/* No isync required, see kuap_restore_amr() */
998:
END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_RADIX_KUAP, 67)
#endif
.endm
......@@ -60,10 +66,28 @@
#include <asm/mmu.h>
#include <asm/ptrace.h>
static inline void kuap_restore_amr(struct pt_regs *regs)
static inline void kuap_restore_amr(struct pt_regs *regs, unsigned long amr)
{
if (mmu_has_feature(MMU_FTR_RADIX_KUAP))
if (mmu_has_feature(MMU_FTR_RADIX_KUAP) && unlikely(regs->kuap != amr)) {
isync();
mtspr(SPRN_AMR, regs->kuap);
/*
* No isync required here because we are about to RFI back to
* previous context before any user accesses would be made,
* which is a CSI.
*/
}
}
static inline unsigned long kuap_get_and_check_amr(void)
{
if (mmu_has_feature(MMU_FTR_RADIX_KUAP)) {
unsigned long amr = mfspr(SPRN_AMR);
if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG)) /* kuap_check_amr() */
WARN_ON_ONCE(amr != AMR_KUAP_BLOCKED);
return amr;
}
return 0;
}
static inline void kuap_check_amr(void)
......@@ -142,13 +166,18 @@ bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
"Bug: %s fault blocked by AMR!", is_write ? "Write" : "Read");
}
#else /* CONFIG_PPC_KUAP */
static inline void kuap_restore_amr(struct pt_regs *regs)
static inline void kuap_restore_amr(struct pt_regs *regs, unsigned long amr)
{
}
static inline void kuap_check_amr(void)
{
}
static inline unsigned long kuap_get_and_check_amr(void)
{
return 0;
}
#endif /* CONFIG_PPC_KUAP */
#endif /* __ASSEMBLY__ */
......
......@@ -116,6 +116,9 @@ typedef struct {
/* Number of users of the external (Nest) MMU */
atomic_t copros;
/* Number of user space windows opened in process mm_context */
atomic_t vas_windows;
struct hash_mm_context *hash_context;
unsigned long vdso_base;
......@@ -208,7 +211,7 @@ void hash__early_init_devtree(void);
void radix__early_init_devtree(void);
extern void hash__early_init_mmu(void);
extern void radix__early_init_mmu(void);
static inline void early_init_mmu(void)
static inline void __init early_init_mmu(void)
{
if (radix_enabled())
return radix__early_init_mmu();
......
......@@ -553,6 +553,12 @@ static inline pte_t pte_clear_savedwrite(pte_t pte)
}
#endif /* CONFIG_NUMA_BALANCING */
static inline bool pte_hw_valid(pte_t pte)
{
return (pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT | _PAGE_PTE)) ==
cpu_to_be64(_PAGE_PRESENT | _PAGE_PTE);
}
static inline int pte_present(pte_t pte)
{
/*
......@@ -561,12 +567,11 @@ static inline int pte_present(pte_t pte)
* invalid during ptep_set_access_flags. Hence we look for _PAGE_INVALID
* if we find _PAGE_PRESENT cleared.
*/
return !!(pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT | _PAGE_INVALID));
}
static inline bool pte_hw_valid(pte_t pte)
{
return !!(pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT));
if (pte_hw_valid(pte))
return true;
return (pte_raw(pte) & cpu_to_be64(_PAGE_INVALID | _PAGE_PTE)) ==
cpu_to_be64(_PAGE_INVALID | _PAGE_PTE);
}
#ifdef CONFIG_PPC_MEM_KEYS
......@@ -1004,10 +1009,25 @@ extern struct page *p4d_page(p4d_t p4d);
#define pud_page_vaddr(pud) __va(pud_val(pud) & ~PUD_MASKED_BITS)
#define p4d_page_vaddr(p4d) __va(p4d_val(p4d) & ~P4D_MASKED_BITS)
#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1))
#define pud_index(address) (((address) >> (PUD_SHIFT)) & (PTRS_PER_PUD - 1))
#define pmd_index(address) (((address) >> (PMD_SHIFT)) & (PTRS_PER_PMD - 1))
#define pte_index(address) (((address) >> (PAGE_SHIFT)) & (PTRS_PER_PTE - 1))
static inline unsigned long pgd_index(unsigned long address)
{
return (address >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1);
}
static inline unsigned long pud_index(unsigned long address)
{
return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
}
static inline unsigned long pmd_index(unsigned long address)
{
return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
}
static inline unsigned long pte_index(unsigned long address)
{
return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
}
/*
* Find an entry in a page-table-directory. We combine the address region
......@@ -1145,8 +1165,11 @@ extern pmd_t mk_pmd(struct page *page, pgprot_t pgprot);
extern pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot);
extern void set_pmd_at(struct mm_struct *mm, unsigned long addr,
pmd_t *pmdp, pmd_t pmd);
extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
pmd_t *pmd);
static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
unsigned long addr, pmd_t *pmd)
{
}
extern int hash__has_transparent_hugepage(void);
static inline int has_transparent_hugepage(void)
{
......@@ -1262,6 +1285,11 @@ static inline pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
}
#define pmdp_collapse_flush pmdp_collapse_flush
#define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR_FULL
pmd_t pmdp_huge_get_and_clear_full(struct vm_area_struct *vma,
unsigned long addr,
pmd_t *pmdp, int full);
#define __HAVE_ARCH_PGTABLE_DEPOSIT
static inline void pgtable_trans_huge_deposit(struct mm_struct *mm,
pmd_t *pmdp, pgtable_t pgtable)
......
......@@ -113,8 +113,7 @@ static inline void hash__flush_tlb_kernel_range(unsigned long start,
struct mmu_gather;
extern void hash__tlb_flush(struct mmu_gather *tlb);
/* Private function for use by PCI IO mapping code */
extern void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
unsigned long end);
extern void __flush_hash_table_range(unsigned long start, unsigned long end);
extern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd,
unsigned long addr);
#endif /* _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H */
......@@ -6,7 +6,7 @@
/* bytes per L1 cache line */
#if defined(CONFIG_PPC_8xx) || defined(CONFIG_403GCX)
#if defined(CONFIG_PPC_8xx)
#define L1_CACHE_SHIFT 4
#define MAX_COPY_PREFETCH 1
#define IFETCH_ALIGN_SHIFT 2
......
......@@ -6,7 +6,6 @@
#include <linux/compiler.h>
#include <asm/synch.h>
#include <linux/bug.h>
#include <asm/asm-405.h>
#ifdef __BIG_ENDIAN
#define BITOFF_CAL(size, off) ((sizeof(u32) - size - off) * BITS_PER_BYTE)
......@@ -29,7 +28,6 @@ static inline u32 __xchg_##type##sfx(volatile void *p, u32 val) \
"1: lwarx %0,0,%3\n" \
" andc %1,%0,%5\n" \
" or %1,%1,%4\n" \
PPC405_ERR77(0,%3) \
" stwcx. %1,0,%3\n" \
" bne- 1b\n" \
: "=&r" (prev), "=&r" (tmp), "+m" (*(u32*)p) \
......@@ -60,7 +58,6 @@ u32 __cmpxchg_##type##sfx(volatile void *p, u32 old, u32 new) \
" bne- 2f\n" \
" andc %1,%0,%6\n" \
" or %1,%1,%5\n" \
PPC405_ERR77(0,%3) \
" stwcx. %1,0,%3\n" \
" bne- 1b\n" \
br2 \
......@@ -92,7 +89,6 @@ __xchg_u32_local(volatile void *p, unsigned long val)
__asm__ __volatile__(
"1: lwarx %0,0,%2 \n"
PPC405_ERR77(0,%2)
" stwcx. %3,0,%2 \n\
bne- 1b"
: "=&r" (prev), "+m" (*(volatile unsigned int *)p)
......@@ -109,7 +105,6 @@ __xchg_u32_relaxed(u32 *p, unsigned long val)
__asm__ __volatile__(
"1: lwarx %0,0,%2\n"
PPC405_ERR77(0, %2)
" stwcx. %3,0,%2\n"
" bne- 1b"
: "=&r" (prev), "+m" (*p)
......@@ -127,7 +122,6 @@ __xchg_u64_local(volatile void *p, unsigned long val)
__asm__ __volatile__(
"1: ldarx %0,0,%2 \n"
PPC405_ERR77(0,%2)
" stdcx. %3,0,%2 \n\
bne- 1b"
: "=&r" (prev), "+m" (*(volatile unsigned long *)p)
......@@ -144,7 +138,6 @@ __xchg_u64_relaxed(u64 *p, unsigned long val)
__asm__ __volatile__(
"1: ldarx %0,0,%2\n"
PPC405_ERR77(0, %2)
" stdcx. %3,0,%2\n"
" bne- 1b"
: "=&r" (prev), "+m" (*p)
......@@ -229,7 +222,6 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
"1: lwarx %0,0,%2 # __cmpxchg_u32\n\
cmpw 0,%0,%3\n\
bne- 2f\n"
PPC405_ERR77(0,%2)
" stwcx. %4,0,%2\n\
bne- 1b"
PPC_ATOMIC_EXIT_BARRIER
......@@ -252,7 +244,6 @@ __cmpxchg_u32_local(volatile unsigned int *p, unsigned long old,
"1: lwarx %0,0,%2 # __cmpxchg_u32\n\
cmpw 0,%0,%3\n\
bne- 2f\n"
PPC405_ERR77(0,%2)
" stwcx. %4,0,%2\n\
bne- 1b"
"\n\
......@@ -273,7 +264,6 @@ __cmpxchg_u32_relaxed(u32 *p, unsigned long old, unsigned long new)
"1: lwarx %0,0,%2 # __cmpxchg_u32_relaxed\n"
" cmpw 0,%0,%3\n"
" bne- 2f\n"
PPC405_ERR77(0, %2)
" stwcx. %4,0,%2\n"
" bne- 1b\n"
"2:"
......@@ -301,7 +291,6 @@ __cmpxchg_u32_acquire(u32 *p, unsigned long old, unsigned long new)
"1: lwarx %0,0,%2 # __cmpxchg_u32_acquire\n"
" cmpw 0,%0,%3\n"
" bne- 2f\n"
PPC405_ERR77(0, %2)
" stwcx. %4,0,%2\n"
" bne- 1b\n"
PPC_ACQUIRE_BARRIER
......
......@@ -11,6 +11,7 @@
#include <linux/string.h>
#include <linux/kallsyms.h>
#include <asm/asm-compat.h>
#include <asm/inst.h>
/* Flags for create_branch:
* "b" == create_branch(addr, target, 0);
......@@ -22,33 +23,33 @@
#define BRANCH_ABSOLUTE 0x2
bool is_offset_in_branch_range(long offset);
unsigned int create_branch(const unsigned int *addr,
unsigned long target, int flags);
unsigned int create_cond_branch(const unsigned int *addr,
unsigned long target, int flags);
int patch_branch(unsigned int *addr, unsigned long target, int flags);
int patch_instruction(unsigned int *addr, unsigned int instr);
int raw_patch_instruction(unsigned int *addr, unsigned int instr);
int create_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
unsigned long target, int flags);
int create_cond_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
unsigned long target, int flags);
int patch_branch(struct ppc_inst *addr, unsigned long target, int flags);
int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
int raw_patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
static inline unsigned long patch_site_addr(s32 *site)
{
return (unsigned long)site + *site;
}
static inline int patch_instruction_site(s32 *site, unsigned int instr)
static inline int patch_instruction_site(s32 *site, struct ppc_inst instr)
{
return patch_instruction((unsigned int *)patch_site_addr(site), instr);
return patch_instruction((struct ppc_inst *)patch_site_addr(site), instr);
}
static inline int patch_branch_site(s32 *site, unsigned long target, int flags)
{
return patch_branch((unsigned int *)patch_site_addr(site), target, flags);
return patch_branch((struct ppc_inst *)patch_site_addr(site), target, flags);
}
static inline int modify_instruction(unsigned int *addr, unsigned int clr,
unsigned int set)
{
return patch_instruction(addr, (*addr & ~clr) | set);
return patch_instruction((struct ppc_inst *)addr, ppc_inst((*addr & ~clr) | set));
}
static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned int set)
......@@ -56,13 +57,13 @@ static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned
return modify_instruction((unsigned int *)patch_site_addr(site), clr, set);
}
int instr_is_relative_branch(unsigned int instr);
int instr_is_relative_link_branch(unsigned int instr);
int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr);
unsigned long branch_target(const unsigned int *instr);
unsigned int translate_branch(const unsigned int *dest,
const unsigned int *src);
extern bool is_conditional_branch(unsigned int instr);
int instr_is_relative_branch(struct ppc_inst instr);
int instr_is_relative_link_branch(struct ppc_inst instr);
int instr_is_branch_to_addr(const struct ppc_inst *instr, unsigned long addr);
unsigned long branch_target(const struct ppc_inst *instr);
int translate_branch(struct ppc_inst *instr, const struct ppc_inst *dest,
const struct ppc_inst *src);
extern bool is_conditional_branch(struct ppc_inst instr);
#ifdef CONFIG_PPC_BOOK3E_64
void __patch_exception(int exc, unsigned long addr);
#define patch_exception(exc, name) do { \
......
......@@ -213,6 +213,7 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTR_P9_TIDR LONG_ASM_CONST(0x0000800000000000)
#define CPU_FTR_P9_TLBIE_ERAT_BUG LONG_ASM_CONST(0x0001000000000000)
#define CPU_FTR_P9_RADIX_PREFETCH_BUG LONG_ASM_CONST(0x0002000000000000)
#define CPU_FTR_ARCH_31 LONG_ASM_CONST(0x0004000000000000)
#ifndef __ASSEMBLY__
......@@ -467,6 +468,17 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTRS_POWER9_DD2_2 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1 | \
CPU_FTR_P9_TM_HV_ASSIST | \
CPU_FTR_P9_TM_XER_SO_BUG)
#define CPU_FTRS_POWER10 (CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | \
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
CPU_FTR_DSCR | CPU_FTR_SAO | \
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_PKEY | \
CPU_FTR_ARCH_31)
#define CPU_FTRS_CELL (CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
......@@ -485,14 +497,14 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTRS_POSSIBLE \
(CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | CPU_FTRS_POWER8 | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_VSX_COMP | CPU_FTRS_POWER9 | \
CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2)
CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | CPU_FTRS_POWER10)
#else
#define CPU_FTRS_POSSIBLE \
(CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \
CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \
CPU_FTRS_POWER8 | CPU_FTRS_CELL | CPU_FTRS_PA6T | \
CPU_FTR_VSX_COMP | CPU_FTR_ALTIVEC_COMP | CPU_FTRS_POWER9 | \
CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2)
CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | CPU_FTRS_POWER10)
#endif /* CONFIG_CPU_LITTLE_ENDIAN */
#endif
#else
......@@ -614,7 +626,11 @@ enum {
};
#endif /* __powerpc64__ */
#define HBP_NUM 1
/*
* Maximum number of hw breakpoint supported on powerpc. Number of
* breakpoints supported by actual hw might be less than this.
*/
#define HBP_NUM_MAX 1
#endif /* !__ASSEMBLY__ */
......
......@@ -45,7 +45,7 @@ static inline int debugger_break_match(struct pt_regs *regs) { return 0; }
static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
#endif
void __set_breakpoint(struct arch_hw_breakpoint *brk);
void __set_breakpoint(int nr, struct arch_hw_breakpoint *brk);
bool ppc_breakpoint_available(void);
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
extern void do_send_trap(struct pt_regs *regs, unsigned long address,
......
......@@ -65,6 +65,7 @@ struct of_drconf_cell_v2 {
#define DRCONF_MEM_ASSIGNED 0x00000008
#define DRCONF_MEM_AI_INVALID 0x00000040
#define DRCONF_MEM_RESERVED 0x00000080
#define DRCONF_MEM_HOTREMOVABLE 0x00000100
static inline u32 drmem_lmb_size(void)
{
......
......@@ -64,12 +64,14 @@ struct fadump_memory_range {
};
/* fadump memory ranges info */
#define RNG_NAME_SZ 16
struct fadump_mrange_info {
char name[16];
char name[RNG_NAME_SZ];
struct fadump_memory_range *mem_ranges;
u32 mem_ranges_sz;
u32 mem_range_cnt;
u32 max_mem_ranges;
bool is_static;
};
/* Platform specific callback functions */
......
......@@ -128,6 +128,7 @@ extern void machine_check_fwnmi(void);
/* This is true if we are using the firmware NMI handler (typically LPAR) */
extern int fwnmi_active;
extern int ibm_nmi_interlock_token;
extern unsigned int __start___fw_ftr_fixup, __stop___fw_ftr_fixup;
......
......@@ -86,6 +86,10 @@ enum fixed_addresses {
#define __FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)
#define FIXMAP_ALIGNED_SIZE (ALIGN(FIXADDR_TOP, PGDIR_SIZE) - \
ALIGN_DOWN(FIXADDR_START, PGDIR_SIZE))
#define FIXMAP_PTE_SIZE (FIXMAP_ALIGNED_SIZE / PGDIR_SIZE * PTE_TABLE_SIZE)
#define FIXMAP_PAGE_NOCACHE PAGE_KERNEL_NCG
#define FIXMAP_PAGE_IO PAGE_KERNEL_NCG
......
......@@ -108,9 +108,23 @@ static inline void this_cpu_enable_ftrace(void)
{
get_paca()->ftrace_enabled = 1;
}
/* Disable ftrace on this CPU if possible (may not be implemented) */
static inline void this_cpu_set_ftrace_enabled(u8 ftrace_enabled)
{
get_paca()->ftrace_enabled = ftrace_enabled;
}
static inline u8 this_cpu_get_ftrace_enabled(void)
{
return get_paca()->ftrace_enabled;
}
#else /* CONFIG_PPC64 */
static inline void this_cpu_disable_ftrace(void) { }
static inline void this_cpu_enable_ftrace(void) { }
static inline void this_cpu_set_ftrace_enabled(u8 ftrace_enabled) { }
static inline u8 this_cpu_get_ftrace_enabled(void) { return 1; }
#endif /* CONFIG_PPC64 */
#endif /* !__ASSEMBLY__ */
......
......@@ -8,14 +8,12 @@
#include <linux/uaccess.h>
#include <asm/errno.h>
#include <asm/synch.h>
#include <asm/asm-405.h>
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
__asm__ __volatile ( \
PPC_ATOMIC_ENTRY_BARRIER \
"1: lwarx %0,0,%2\n" \
insn \
PPC405_ERR77(0, %2) \
"2: stwcx. %1,0,%2\n" \
"bne- 1b\n" \
PPC_ATOMIC_EXIT_BARRIER \
......@@ -82,7 +80,6 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
"1: lwarx %1,0,%3 # futex_atomic_cmpxchg_inatomic\n\
cmpw 0,%1,%4\n\
bne- 3f\n"
PPC405_ERR77(0,%3)
"2: stwcx. %5,0,%3\n\
bne- 1b\n"
PPC_ATOMIC_EXIT_BARRIER
......
......@@ -41,11 +41,7 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
#ifdef CONFIG_PPC64
return __pte(pte_update(mm, addr, ptep, ~0UL, 0, 1));
#else
return __pte(pte_update(ptep, ~0UL, 0));
#endif
}
#define __HAVE_ARCH_HUGE_PTEP_CLEAR_FLUSH
......
......@@ -34,15 +34,21 @@ struct arch_hw_breakpoint {
#define HW_BRK_TYPE_PRIV_ALL (HW_BRK_TYPE_USER | HW_BRK_TYPE_KERNEL | \
HW_BRK_TYPE_HYP)
/* Minimum granularity */
#ifdef CONFIG_PPC_8xx
#define HW_BREAKPOINT_ALIGN 0x3
#define HW_BREAKPOINT_SIZE 0x4
#else
#define HW_BREAKPOINT_ALIGN 0x7
#define HW_BREAKPOINT_SIZE 0x8
#endif
#define DABR_MAX_LEN 8
#define DAWR_MAX_LEN 512
static inline int nr_wp_slots(void)
{
return HBP_NUM_MAX;
}
#ifdef CONFIG_HAVE_HW_BREAKPOINT
#include <linux/kdebug.h>
#include <asm/reg.h>
......@@ -64,7 +70,6 @@ extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
unsigned long val, void *data);
int arch_install_hw_breakpoint(struct perf_event *bp);
void arch_uninstall_hw_breakpoint(struct perf_event *bp);
void arch_unregister_hw_breakpoint(struct perf_event *bp);
void hw_breakpoint_pmu_read(struct perf_event *bp);
extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
......@@ -73,14 +78,14 @@ extern void ptrace_triggered(struct perf_event *bp,
struct perf_sample_data *data, struct pt_regs *regs);
static inline void hw_breakpoint_disable(void)
{
struct arch_hw_breakpoint brk;
brk.address = 0;
brk.type = 0;
brk.len = 0;
brk.hw_len = 0;
if (ppc_breakpoint_available())
__set_breakpoint(&brk);
int i;
struct arch_hw_breakpoint null_brk = {0};
if (!ppc_breakpoint_available())
return;
for (i = 0; i < nr_wp_slots(); i++)
__set_breakpoint(i, &null_brk);
}
extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
int hw_breakpoint_handler(struct die_args *args);
......@@ -99,10 +104,10 @@ static inline bool dawr_enabled(void)
{
return dawr_force_enable;
}
int set_dawr(struct arch_hw_breakpoint *brk);
int set_dawr(int nr, struct arch_hw_breakpoint *brk);
#else
static inline bool dawr_enabled(void) { return false; }
static inline int set_dawr(struct arch_hw_breakpoint *brk) { return -1; }
static inline int set_dawr(int nr, struct arch_hw_breakpoint *brk) { return -1; }
#endif
#endif /* __KERNEL__ */
......
......@@ -108,6 +108,17 @@ struct data_descriptor_entry {
__be64 address;
} __packed __aligned(DDE_ALIGN);
/* 4.3.2 NX-stamped Fault CRB */
#define NX_STAMP_ALIGN (0x10)
struct nx_fault_stamp {
__be64 fault_storage_addr;
__be16 reserved;
__u8 flags;
__u8 fault_status;
__be32 pswid;
} __packed __aligned(NX_STAMP_ALIGN);
/* Chapter 6.5.2 Coprocessor-Request Block (CRB) */
......@@ -135,10 +146,15 @@ struct coprocessor_request_block {
struct coprocessor_completion_block ccb;
u8 reserved[48];
union {
struct nx_fault_stamp nx;
u8 reserved[16];
} stamp;
u8 reserved[32];
struct coprocessor_status_block csb;
} __packed __aligned(CRB_ALIGN);
} __packed;
/* RFC02167 Initiate Coprocessor Instructions document
......
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef _ASM_POWERPC_IDLE_H
#define _ASM_POWERPC_IDLE_H
#include <asm/runlatch.h>
#include <asm/paca.h>
#ifdef CONFIG_PPC_PSERIES
DECLARE_PER_CPU(u64, idle_spurr_cycles);
DECLARE_PER_CPU(u64, idle_entry_purr_snap);
DECLARE_PER_CPU(u64, idle_entry_spurr_snap);
static inline void snapshot_purr_idle_entry(void)
{
*this_cpu_ptr(&idle_entry_purr_snap) = mfspr(SPRN_PURR);
}
static inline void snapshot_spurr_idle_entry(void)
{
*this_cpu_ptr(&idle_entry_spurr_snap) = mfspr(SPRN_SPURR);
}
static inline void update_idle_purr_accounting(void)
{
u64 wait_cycles;
u64 in_purr = *this_cpu_ptr(&idle_entry_purr_snap);
wait_cycles = be64_to_cpu(get_lppaca()->wait_state_cycles);
wait_cycles += mfspr(SPRN_PURR) - in_purr;
get_lppaca()->wait_state_cycles = cpu_to_be64(wait_cycles);
}
static inline void update_idle_spurr_accounting(void)
{
u64 *idle_spurr_cycles_ptr = this_cpu_ptr(&idle_spurr_cycles);
u64 in_spurr = *this_cpu_ptr(&idle_entry_spurr_snap);
*idle_spurr_cycles_ptr += mfspr(SPRN_SPURR) - in_spurr;
}
static inline void pseries_idle_prolog(void)
{
ppc64_runlatch_off();
snapshot_purr_idle_entry();
snapshot_spurr_idle_entry();
/*
* Indicate to the HV that we are idle. Now would be
* a good time to find other work to dispatch.
*/
get_lppaca()->idle = 1;
}
static inline void pseries_idle_epilog(void)
{
update_idle_purr_accounting();
update_idle_spurr_accounting();
get_lppaca()->idle = 0;
ppc64_runlatch_on();
}
static inline u64 read_this_idle_purr(void)
{
/*
* If we are reading from an idle context, update the
* idle-purr cycles corresponding to the last idle period.
* Since the idle context is not yet over, take a fresh
* snapshot of the idle-purr.
*/
if (unlikely(get_lppaca()->idle == 1)) {
update_idle_purr_accounting();
snapshot_purr_idle_entry();
}
return be64_to_cpu(get_lppaca()->wait_state_cycles);
}
static inline u64 read_this_idle_spurr(void)
{
/*
* If we are reading from an idle context, update the
* idle-spurr cycles corresponding to the last idle period.
* Since the idle context is not yet over, take a fresh
* snapshot of the idle-spurr.
*/
if (get_lppaca()->idle == 1) {
update_idle_spurr_accounting();
snapshot_spurr_idle_entry();
}
return *this_cpu_ptr(&idle_spurr_cycles);
}
#endif /* CONFIG_PPC_PSERIES */
#endif
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef _ASM_POWERPC_INST_H
#define _ASM_POWERPC_INST_H
#include <asm/ppc-opcode.h>
/*
* Instruction data type for POWER
*/
struct ppc_inst {
u32 val;
#ifdef CONFIG_PPC64
u32 suffix;
#endif
} __packed;
static inline u32 ppc_inst_val(struct ppc_inst x)
{
return x.val;
}
static inline int ppc_inst_primary_opcode(struct ppc_inst x)
{
return ppc_inst_val(x) >> 26;
}
#ifdef CONFIG_PPC64
#define ppc_inst(x) ((struct ppc_inst){ .val = (x), .suffix = 0xff })
#define ppc_inst_prefix(x, y) ((struct ppc_inst){ .val = (x), .suffix = (y) })
static inline u32 ppc_inst_suffix(struct ppc_inst x)
{
return x.suffix;
}
static inline bool ppc_inst_prefixed(struct ppc_inst x)
{
return (ppc_inst_primary_opcode(x) == 1) && ppc_inst_suffix(x) != 0xff;
}
static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
{
return ppc_inst_prefix(swab32(ppc_inst_val(x)),
swab32(ppc_inst_suffix(x)));
}
static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
{
u32 val, suffix;
val = *(u32 *)ptr;
if ((val >> 26) == OP_PREFIX) {
suffix = *((u32 *)ptr + 1);
return ppc_inst_prefix(val, suffix);
} else {
return ppc_inst(val);
}
}
static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
{
return *(u64 *)&x == *(u64 *)&y;
}
#else
#define ppc_inst(x) ((struct ppc_inst){ .val = x })
static inline bool ppc_inst_prefixed(struct ppc_inst x)
{
return false;
}
static inline u32 ppc_inst_suffix(struct ppc_inst x)
{
return 0;
}
static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
{
return ppc_inst(swab32(ppc_inst_val(x)));
}
static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
{
return *ptr;
}
static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
{
return ppc_inst_val(x) == ppc_inst_val(y);
}
#endif /* CONFIG_PPC64 */
static inline int ppc_inst_len(struct ppc_inst x)
{
return ppc_inst_prefixed(x) ? 8 : 4;
}
/*
* Return the address of the next instruction, if the instruction @value was
* located at @location.
*/
static inline struct ppc_inst *ppc_inst_next(void *location, struct ppc_inst *value)
{
struct ppc_inst tmp;
tmp = ppc_inst_read(value);
return location + ppc_inst_len(tmp);
}
static inline u64 ppc_inst_as_u64(struct ppc_inst x)
{
#ifdef CONFIG_CPU_LITTLE_ENDIAN
return (u64)ppc_inst_suffix(x) << 32 | ppc_inst_val(x);
#else
return (u64)ppc_inst_val(x) << 32 | ppc_inst_suffix(x);
#endif
}
int probe_user_read_inst(struct ppc_inst *inst,
struct ppc_inst __user *nip);
int probe_kernel_read_inst(struct ppc_inst *inst,
struct ppc_inst *src);
#endif /* _ASM_POWERPC_INST_H */
......@@ -22,11 +22,11 @@
#define IOMMU_PAGE_SHIFT_4K 12
#define IOMMU_PAGE_SIZE_4K (ASM_CONST(1) << IOMMU_PAGE_SHIFT_4K)
#define IOMMU_PAGE_MASK_4K (~((1 << IOMMU_PAGE_SHIFT_4K) - 1))
#define IOMMU_PAGE_ALIGN_4K(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE_4K)
#define IOMMU_PAGE_ALIGN_4K(addr) ALIGN(addr, IOMMU_PAGE_SIZE_4K)
#define IOMMU_PAGE_SIZE(tblptr) (ASM_CONST(1) << (tblptr)->it_page_shift)
#define IOMMU_PAGE_MASK(tblptr) (~((1 << (tblptr)->it_page_shift) - 1))
#define IOMMU_PAGE_ALIGN(addr, tblptr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE(tblptr))
#define IOMMU_PAGE_ALIGN(addr, tblptr) ALIGN(addr, IOMMU_PAGE_SIZE(tblptr))
/* Boot time flags */
extern int iommu_is_off;
......
......@@ -23,20 +23,20 @@
#define KASAN_SHADOW_OFFSET ASM_CONST(CONFIG_KASAN_SHADOW_OFFSET)
#define KASAN_SHADOW_END 0UL
#define KASAN_SHADOW_SIZE (KASAN_SHADOW_END - KASAN_SHADOW_START)
#define KASAN_SHADOW_END (-(-KASAN_SHADOW_START >> KASAN_SHADOW_SCALE_SHIFT))
#ifdef CONFIG_KASAN
void kasan_early_init(void);
void kasan_mmu_init(void);
void kasan_init(void);
void kasan_late_init(void);
#else
static inline void kasan_init(void) { }
static inline void kasan_mmu_init(void) { }
static inline void kasan_late_init(void) { }
#endif
void kasan_update_early_region(unsigned long k_start, unsigned long k_end, pte_t pte);
int kasan_init_shadow_page_tables(unsigned long k_start, unsigned long k_end);
int kasan_init_region(void *start, size_t size);
#endif /* __ASSEMBLY */
#endif
......@@ -43,7 +43,7 @@ extern kprobe_opcode_t optprobe_template_ret[];
extern kprobe_opcode_t optprobe_template_end[];
/* Fixed instruction size for powerpc */
#define MAX_INSN_SIZE 1
#define MAX_INSN_SIZE 2
#define MAX_OPTIMIZED_LENGTH sizeof(kprobe_opcode_t) /* 4 bytes */
#define MAX_OPTINSN_SIZE (optprobe_template_end - optprobe_template_entry)
#define RELATIVEJUMP_SIZE sizeof(kprobe_opcode_t) /* 4 bytes */
......
......@@ -10,7 +10,9 @@
* Use the current saved situation instead of the to/from/size params.
* Used on book3s/32
*/
#define KUAP_CURRENT 4
#define KUAP_CURRENT_READ 4
#define KUAP_CURRENT_WRITE 8
#define KUAP_CURRENT (KUAP_CURRENT_READ | KUAP_CURRENT_WRITE)
#ifdef CONFIG_PPC64
#include <asm/book3s/64/kup-radix.h>
......@@ -101,6 +103,16 @@ static inline void prevent_current_access_user(void)
prevent_user_access(NULL, NULL, ~0UL, KUAP_CURRENT);
}
static inline void prevent_current_read_from_user(void)
{
prevent_user_access(NULL, NULL, ~0UL, KUAP_CURRENT_READ);
}
static inline void prevent_current_write_to_user(void)
{
prevent_user_access(NULL, NULL, ~0UL, KUAP_CURRENT_WRITE);
}
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_POWERPC_KUAP_H_ */
......@@ -198,7 +198,7 @@ extern void kvmppc_unmap_pte(struct kvm *kvm, pte_t *pte, unsigned long gpa,
unsigned int shift,
const struct kvm_memory_slot *memslot,
unsigned int lpid);
extern bool kvmppc_hv_handle_set_rc(struct kvm *kvm, pgd_t *pgtable,
extern bool kvmppc_hv_handle_set_rc(struct kvm *kvm, bool nested,
bool writing, unsigned long gpa,
unsigned int lpid);
extern int kvmppc_book3s_instantiate_page(struct kvm_vcpu *vcpu,
......
......@@ -14,6 +14,7 @@
#include <asm/book3s/64/mmu-hash.h>
#include <asm/cpu_has_feature.h>
#include <asm/ppc-opcode.h>
#include <asm/pte-walk.h>
#ifdef CONFIG_PPC_PSERIES
static inline bool kvmhv_on_pseries(void)
......@@ -434,7 +435,7 @@ static inline pte_t kvmppc_read_update_linux_pte(pte_t *ptep, int writing)
continue;
}
/* If pte is not present return None */
if (unlikely(!(pte_val(old_pte) & _PAGE_PRESENT)))
if (unlikely(!pte_present(old_pte)))
return __pte(0);
new_pte = pte_mkyoung(old_pte);
......@@ -634,6 +635,47 @@ extern void kvmhv_remove_nest_rmap_range(struct kvm *kvm,
unsigned long gpa, unsigned long hpa,
unsigned long nbytes);
static inline pte_t *
find_kvm_secondary_pte_unlocked(struct kvm *kvm, unsigned long ea,
unsigned *hshift)
{
pte_t *pte;
pte = __find_linux_pte(kvm->arch.pgtable, ea, NULL, hshift);
return pte;
}
static inline pte_t *find_kvm_secondary_pte(struct kvm *kvm, unsigned long ea,
unsigned *hshift)
{
pte_t *pte;
VM_WARN(!spin_is_locked(&kvm->mmu_lock),
"%s called with kvm mmu_lock not held \n", __func__);
pte = __find_linux_pte(kvm->arch.pgtable, ea, NULL, hshift);
return pte;
}
static inline pte_t *find_kvm_host_pte(struct kvm *kvm, unsigned long mmu_seq,
unsigned long ea, unsigned *hshift)
{
pte_t *pte;
VM_WARN(!spin_is_locked(&kvm->mmu_lock),
"%s called with kvm mmu_lock not held \n", __func__);
if (mmu_notifier_retry(kvm, mmu_seq))
return NULL;
pte = __find_linux_pte(kvm->mm->pgd, ea, NULL, hshift);
return pte;
}
extern pte_t *find_kvm_nested_guest_pte(struct kvm *kvm, unsigned long lpid,
unsigned long ea, unsigned *hshift);
#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */
#endif /* __ASM_KVM_BOOK3S_64_H__ */
......@@ -122,6 +122,7 @@
#define MMU_FTRS_POWER7 MMU_FTRS_POWER6
#define MMU_FTRS_POWER8 MMU_FTRS_POWER6
#define MMU_FTRS_POWER9 MMU_FTRS_POWER6
#define MMU_FTRS_POWER10 MMU_FTRS_POWER6
#define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
MMU_FTR_CI_LARGE_PAGE
#define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
......@@ -291,15 +292,6 @@ static inline bool early_radix_enabled(void)
}
#endif
#ifdef CONFIG_PPC_MEM_KEYS
extern u16 get_mm_addr_key(struct mm_struct *mm, unsigned long address);
#else
static inline u16 get_mm_addr_key(struct mm_struct *mm, unsigned long address)
{
return 0;
}
#endif /* CONFIG_PPC_MEM_KEYS */
#ifdef CONFIG_STRICT_KERNEL_RWX
static inline bool strict_kernel_rwx_enabled(void)
{
......
......@@ -185,11 +185,41 @@ static inline void mm_context_remove_copro(struct mm_struct *mm)
dec_mm_active_cpus(mm);
}
}
/*
* vas_windows counter shows number of open windows in the mm
* context. During context switch, use this counter to clear the
* foreign real address mapping (CP_ABORT) for the thread / process
* that intend to use COPY/PASTE. When a process closes all windows,
* disable CP_ABORT which is expensive to run.
*
* For user context, register a copro so that TLBIs are seen by the
* nest MMU. mm_context_add/remove_vas_window() are used only for user
* space windows.
*/
static inline void mm_context_add_vas_window(struct mm_struct *mm)
{
atomic_inc(&mm->context.vas_windows);
mm_context_add_copro(mm);
}
static inline void mm_context_remove_vas_window(struct mm_struct *mm)
{
int v;
mm_context_remove_copro(mm);
v = atomic_dec_if_positive(&mm->context.vas_windows);
/* Detect imbalance between add and remove */
WARN_ON(v < 0);
}
#else
static inline void inc_mm_active_cpus(struct mm_struct *mm) { }
static inline void dec_mm_active_cpus(struct mm_struct *mm) { }
static inline void mm_context_add_copro(struct mm_struct *mm) { }
static inline void mm_context_remove_copro(struct mm_struct *mm) { }
static inline void mm_context_add_vas_windows(struct mm_struct *mm) { }
static inline void mm_context_remove_vas_windows(struct mm_struct *mm) { }
#endif
......
......@@ -72,12 +72,9 @@ struct mod_arch_specific {
# ifdef MODULE
asm(".section .ftrace.tramp,\"ax\",@nobits; .align 3; .previous");
# endif /* MODULE */
#endif
int module_trampoline_target(struct module *mod, unsigned long trampoline,
unsigned long *target);
#ifdef CONFIG_DYNAMIC_FTRACE
int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs);
#else
static inline int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs)
......
......@@ -13,13 +13,13 @@ static inline pte_t *hugepd_page(hugepd_t hpd)
static inline unsigned int hugepd_shift(hugepd_t hpd)
{
return ((hpd_val(hpd) & _PMD_PAGE_MASK) >> 1) + 17;
return PAGE_SHIFT_8M;
}
static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
unsigned int pdshift)
{
unsigned long idx = (addr & ((1UL << pdshift) - 1)) >> PAGE_SHIFT;
unsigned long idx = (addr & (SZ_4M - 1)) >> PAGE_SHIFT;
return hugepd_page(hpd) + idx;
}
......@@ -32,8 +32,12 @@ static inline void flush_hugetlb_page(struct vm_area_struct *vma,
static inline void hugepd_populate(hugepd_t *hpdp, pte_t *new, unsigned int pshift)
{
*hpdp = __hugepd(__pa(new) | _PMD_USER | _PMD_PRESENT |
(pshift == PAGE_SHIFT_8M ? _PMD_PAGE_8M : _PMD_PAGE_512K));
*hpdp = __hugepd(__pa(new) | _PMD_USER | _PMD_PRESENT | _PMD_PAGE_8M);
}
static inline void hugepd_populate_kernel(hugepd_t *hpdp, pte_t *new, unsigned int pshift)
{
*hpdp = __hugepd(__pa(new) | _PMD_PRESENT | _PMD_PAGE_8M);
}
static inline int check_and_get_huge_psize(int shift)
......@@ -41,4 +45,24 @@ static inline int check_and_get_huge_psize(int shift)
return shift_to_mmu_psize(shift);
}
#define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
#define __HAVE_ARCH_HUGE_PTE_CLEAR
static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, unsigned long sz)
{
pte_update(mm, addr, ptep, ~0UL, 0, 1);
}
#define __HAVE_ARCH_HUGE_PTEP_SET_WRPROTECT
static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
unsigned long clr = ~pte_val(pte_wrprotect(__pte(~0)));
unsigned long set = pte_val(pte_wrprotect(__pte(0)));
pte_update(mm, addr, ptep, clr, set, 1);
}
#endif /* _ASM_POWERPC_NOHASH_32_HUGETLB_8XX_H */
......@@ -19,7 +19,6 @@
#define MI_RSV4I 0x08000000 /* Reserve 4 TLB entries */
#define MI_PPCS 0x02000000 /* Use MI_RPN prob/priv state */
#define MI_IDXMASK 0x00001f00 /* TLB index to be loaded */
#define MI_RESETVAL 0x00000000 /* Value of register at reset */
/* These are the Ks and Kp from the PowerPC books. For proper operation,
* Ks = 0, Kp = 1.
......@@ -37,16 +36,16 @@
* Therefore, we define 2 APG groups. lsb is _PMD_USER
* 0 => Kernel => 01 (all accesses performed according to page definition)
* 1 => User => 00 (all accesses performed as supervisor iaw page definition)
* 2-16 => NA => 11 (all accesses performed as user iaw page definition)
* 2-15 => Not Used
*/
#define MI_APG_INIT 0x4fffffff
#define MI_APG_INIT 0x40000000
/*
* 0 => Kernel => 01 (all accesses performed according to page definition)
* 1 => User => 10 (all accesses performed according to swaped page definition)
* 2-16 => NA => 11 (all accesses performed as user iaw page definition)
* 2-15 => Not Used
*/
#define MI_APG_KUEP 0x6fffffff
#define MI_APG_KUEP 0x60000000
/* The effective page number register. When read, contains the information
* about the last instruction TLB miss. When MI_RPN is written, bits in
......@@ -95,7 +94,6 @@
#define MD_TWAM 0x04000000 /* Use 4K page hardware assist */
#define MD_PPCS 0x02000000 /* Use MI_RPN prob/priv state */
#define MD_IDXMASK 0x00001f00 /* TLB index to be loaded */
#define MD_RESETVAL 0x04000000 /* Value of register at reset */
#define SPRN_M_CASID 793 /* Address space ID (context) to match */
#define MC_ASIDMASK 0x0000000f /* Bits used for ASID value */
......@@ -117,16 +115,16 @@
* Therefore, we define 2 APG groups. lsb is _PMD_USER
* 0 => Kernel => 01 (all accesses performed according to page definition)
* 1 => User => 00 (all accesses performed as supervisor iaw page definition)
* 2-16 => NA => 11 (all accesses performed as user iaw page definition)
* 2-15 => Not Used
*/
#define MD_APG_INIT 0x4fffffff
#define MD_APG_INIT 0x40000000
/*
* 0 => No user => 01 (all accesses performed according to page definition)
* 1 => User => 10 (all accesses performed according to swaped page definition)
* 2-16 => NA => 11 (all accesses performed as user iaw page definition)
* 2-15 => Not Used
*/
#define MD_APG_KUAP 0x6fffffff
#define MD_APG_KUAP 0x60000000
/* The effective page number register. When read, contains the information
* about the last instruction TLB miss. When MD_RPN is written, bits in
......@@ -178,12 +176,6 @@
*/
#define SPRN_M_TW 799
#ifdef CONFIG_PPC_MM_SLICES
#include <asm/nohash/32/slice.h>
#define SLICE_ARRAY_SIZE (1 << (32 - SLICE_LOW_SHIFT - 1))
#define LOW_SLICE_ARRAY_SZ SLICE_ARRAY_SIZE
#endif
#if defined(CONFIG_PPC_4K_PAGES)
#define mmu_virtual_psize MMU_PAGE_4K
#elif defined(CONFIG_PPC_16K_PAGES)
......@@ -201,71 +193,15 @@
#include <linux/mmdebug.h>
struct slice_mask {
u64 low_slices;
DECLARE_BITMAP(high_slices, 0);
};
void mmu_pin_tlb(unsigned long top, bool readonly);
typedef struct {
unsigned int id;
unsigned int active;
unsigned long vdso_base;
#ifdef CONFIG_PPC_MM_SLICES
u16 user_psize; /* page size index */
unsigned char low_slices_psize[SLICE_ARRAY_SIZE];
unsigned char high_slices_psize[0];
unsigned long slb_addr_limit;
struct slice_mask mask_base_psize; /* 4k or 16k */
struct slice_mask mask_512k;
struct slice_mask mask_8m;
#endif
void *pte_frag;
} mm_context_t;
#ifdef CONFIG_PPC_MM_SLICES
static inline u16 mm_ctx_user_psize(mm_context_t *ctx)
{
return ctx->user_psize;
}
static inline void mm_ctx_set_user_psize(mm_context_t *ctx, u16 user_psize)
{
ctx->user_psize = user_psize;
}
static inline unsigned char *mm_ctx_low_slices(mm_context_t *ctx)
{
return ctx->low_slices_psize;
}
static inline unsigned char *mm_ctx_high_slices(mm_context_t *ctx)
{
return ctx->high_slices_psize;
}
static inline unsigned long mm_ctx_slb_addr_limit(mm_context_t *ctx)
{
return ctx->slb_addr_limit;
}
static inline void mm_ctx_set_slb_addr_limit(mm_context_t *ctx, unsigned long limit)
{
ctx->slb_addr_limit = limit;
}
static inline struct slice_mask *slice_mask_for_size(mm_context_t *ctx, int psize)
{
if (psize == MMU_PAGE_512K)
return &ctx->mask_512k;
if (psize == MMU_PAGE_8M)
return &ctx->mask_8m;
BUG_ON(psize != mmu_virtual_psize);
return &ctx->mask_base_psize;
}
#endif /* CONFIG_PPC_MM_SLICE */
#define PHYS_IMMR_BASE (mfspr(SPRN_IMMR) & 0xfff80000)
#define VIRT_IMMR_BASE (__fix_to_virt(FIX_IMMR_BASE))
......@@ -304,13 +240,7 @@ static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize)
}
/* patch sites */
extern s32 patch__itlbmiss_linmem_top, patch__itlbmiss_linmem_top8;
extern s32 patch__dtlbmiss_linmem_top, patch__dtlbmiss_immr_jmp;
extern s32 patch__fixupdar_linmem_top;
extern s32 patch__dtlbmiss_romem_top, patch__dtlbmiss_romem_top8;
extern s32 patch__itlbmiss_exit_1, patch__itlbmiss_exit_2;
extern s32 patch__dtlbmiss_exit_1, patch__dtlbmiss_exit_2, patch__dtlbmiss_exit_3;
extern s32 patch__itlbmiss_exit_1, patch__dtlbmiss_exit_1;
extern s32 patch__itlbmiss_perf, patch__dtlbmiss_perf;
#endif /* !__ASSEMBLY__ */
......
......@@ -8,7 +8,6 @@
#include <linux/sched.h>
#include <linux/threads.h>
#include <asm/mmu.h> /* For sub-arch specific PPC_PIN_SIZE */
#include <asm/asm-405.h>
#ifdef CONFIG_44x
extern int icache_44x_need_flush;
......@@ -109,13 +108,13 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
*/
#define VMALLOC_OFFSET (0x1000000) /* 16M */
#ifdef PPC_PIN_SIZE
#define VMALLOC_START (((_ALIGN((long)high_memory, PPC_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
#define VMALLOC_START (((ALIGN((long)high_memory, PPC_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
#else
#define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
#endif
#ifdef CONFIG_KASAN_VMALLOC
#define VMALLOC_END _ALIGN_DOWN(ioremap_bot, PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
#define VMALLOC_END ALIGN_DOWN(ioremap_bot, PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
#else
#define VMALLOC_END ioremap_bot
#endif
......@@ -165,7 +164,7 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
#ifndef __ASSEMBLY__
#define pte_clear(mm, addr, ptep) \
do { pte_update(ptep, ~0, 0); } while (0)
do { pte_update(mm, addr, ptep, ~0, 0, 0); } while (0)
#ifndef pte_mkwrite
static inline pte_t pte_mkwrite(pte_t pte)
......@@ -205,6 +204,12 @@ static inline void pmd_clear(pmd_t *pmdp)
}
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
/* to find an entry in a page-table-directory */
#define pgd_index(address) ((address) >> PGDIR_SHIFT)
#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
/*
* PTE updates. This function is called whenever an existing
......@@ -220,66 +225,42 @@ static inline void pmd_clear(pmd_t *pmdp)
* that an executable user mapping was modified, which is needed
* to properly flush the virtually tagged instruction cache of
* those implementations.
*
* On the 8xx, the page tables are a bit special. For 16k pages, we have
* 4 identical entries. For 512k pages, we have 128 entries as if it was
* 4k pages, but they are flagged as 512k pages for the hardware.
* For other page sizes, we have a single entry in the table.
*/
#ifndef CONFIG_PTE_64BIT
static inline unsigned long pte_update(pte_t *p,
unsigned long clr,
unsigned long set)
#ifdef CONFIG_PPC_8xx
static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *p,
unsigned long clr, unsigned long set, int huge)
{
#ifdef PTE_ATOMIC_UPDATES
unsigned long old, tmp;
__asm__ __volatile__("\
1: lwarx %0,0,%3\n\
andc %1,%0,%4\n\
or %1,%1,%5\n"
PPC405_ERR77(0,%3)
" stwcx. %1,0,%3\n\
bne- 1b"
: "=&r" (old), "=&r" (tmp), "=m" (*p)
: "r" (p), "r" (clr), "r" (set), "m" (*p)
: "cc" );
#else /* PTE_ATOMIC_UPDATES */
unsigned long old = pte_val(*p);
unsigned long new = (old & ~clr) | set;
#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
p->pte = p->pte1 = p->pte2 = p->pte3 = new;
#else
*p = __pte(new);
#endif
#endif /* !PTE_ATOMIC_UPDATES */
pte_basic_t *entry = &p->pte;
pte_basic_t old = pte_val(*p);
pte_basic_t new = (old & ~(pte_basic_t)clr) | set;
int num, i;
pmd_t *pmd = pmd_offset(pud_offset(p4d_offset(pgd_offset(mm, addr), addr), addr), addr);
if (!huge)
num = PAGE_SIZE / SZ_4K;
else if ((pmd_val(*pmd) & _PMD_PAGE_MASK) != _PMD_PAGE_8M)
num = SZ_512K / SZ_4K;
else
num = 1;
for (i = 0; i < num; i++, entry++, new += SZ_4K)
*entry = new;
#ifdef CONFIG_44x
if ((old & _PAGE_USER) && (old & _PAGE_EXEC))
icache_44x_need_flush = 1;
#endif
return old;
}
#else /* CONFIG_PTE_64BIT */
static inline unsigned long long pte_update(pte_t *p,
unsigned long clr,
unsigned long set)
#else
static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *p,
unsigned long clr, unsigned long set, int huge)
{
#ifdef PTE_ATOMIC_UPDATES
unsigned long long old;
unsigned long tmp;
__asm__ __volatile__("\
1: lwarx %L0,0,%4\n\
lwzx %0,0,%3\n\
andc %1,%L0,%5\n\
or %1,%1,%6\n"
PPC405_ERR77(0,%3)
" stwcx. %1,0,%4\n\
bne- 1b"
: "=&r" (old), "=&r" (tmp), "=m" (*p)
: "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p)
: "cc" );
#else /* PTE_ATOMIC_UPDATES */
unsigned long long old = pte_val(*p);
*p = __pte((old & ~(unsigned long long)clr) | set);
#endif /* !PTE_ATOMIC_UPDATES */
pte_basic_t old = pte_val(*p);
pte_basic_t new = (old & ~(pte_basic_t)clr) | set;
*p = __pte(new);
#ifdef CONFIG_44x
if ((old & _PAGE_USER) && (old & _PAGE_EXEC))
......@@ -287,23 +268,24 @@ static inline unsigned long long pte_update(pte_t *p,
#endif
return old;
}
#endif /* CONFIG_PTE_64BIT */
#endif
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
static inline int __ptep_test_and_clear_young(unsigned int context, unsigned long addr, pte_t *ptep)
static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
unsigned long old;
old = pte_update(ptep, _PAGE_ACCESSED, 0);
old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0);
return (old & _PAGE_ACCESSED) != 0;
}
#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
__ptep_test_and_clear_young((__vma)->vm_mm->context.id, __addr, __ptep)
__ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep)
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep)
{
return __pte(pte_update(ptep, ~0, 0));
return __pte(pte_update(mm, addr, ptep, ~0, 0, 0));
}
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
......@@ -313,7 +295,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
unsigned long clr = ~pte_val(pte_wrprotect(__pte(~0)));
unsigned long set = pte_val(pte_wrprotect(__pte(0)));
pte_update(ptep, clr, set);
pte_update(mm, addr, ptep, clr, set, 0);
}
static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
......@@ -325,8 +307,9 @@ static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
pte_t pte_clr = pte_mkyoung(pte_mkdirty(pte_mkwrite(pte_mkexec(__pte(~0)))));
unsigned long set = pte_val(entry) & pte_val(pte_set);
unsigned long clr = ~pte_val(entry) & ~pte_val(pte_clr);
int huge = psize > mmu_virtual_psize ? 1 : 0;
pte_update(ptep, clr, set);
pte_update(vma->vm_mm, address, ptep, clr, set, huge);
flush_tlb_page(vma, address);
}
......@@ -358,13 +341,6 @@ static inline int pte_young(pte_t pte)
pfn_to_page((__pa(pmd_val(pmd)) >> PAGE_SHIFT))
#endif
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
/* to find an entry in a page-table-directory */
#define pgd_index(address) ((address) >> PGDIR_SHIFT)
#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
/* Find an entry in the third-level page table.. */
#define pte_index(address) \
(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
......
......@@ -44,9 +44,8 @@
#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */
#define _PAGE_USER 0x010 /* matches one of the zone permission bits */
#define _PAGE_SPECIAL 0x020 /* software: Special page */
#define _PAGE_RW 0x040 /* software: Writes permitted */
#define _PAGE_DIRTY 0x080 /* software: dirty page */
#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */
#define _PAGE_RW 0x100 /* hardware: WR, anded with dirty in exception */
#define _PAGE_EXEC 0x200 /* hardware: EX permission */
#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */
......@@ -58,8 +57,8 @@
#define _PAGE_KERNEL_RO 0
#define _PAGE_KERNEL_ROX _PAGE_EXEC
#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
#define _PAGE_KERNEL_RWX (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE | _PAGE_EXEC)
#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW)
#define _PAGE_KERNEL_RWX (_PAGE_DIRTY | _PAGE_RW | _PAGE_EXEC)
#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */
#define _PMD_PRESENT_MASK _PMD_PRESENT
......@@ -85,21 +84,5 @@
#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
#ifndef __ASSEMBLY__
static inline pte_t pte_wrprotect(pte_t pte)
{
return __pte(pte_val(pte) & ~(_PAGE_RW | _PAGE_HWWRITE));
}
#define pte_wrprotect pte_wrprotect
static inline pte_t pte_mkclean(pte_t pte)
{
return __pte(pte_val(pte) & ~(_PAGE_DIRTY | _PAGE_HWWRITE));
}
#define pte_mkclean pte_mkclean
#endif
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_NOHASH_32_PTE_40x_H */
......@@ -46,6 +46,8 @@
#define _PAGE_NA 0x0200 /* Supervisor NA, User no access */
#define _PAGE_RO 0x0600 /* Supervisor RO, User no access */
#define _PAGE_HUGE 0x0800 /* Copied to L1 PS bit 29 */
/* cache related flags non existing on 8xx */
#define _PAGE_COHERENT 0
#define _PAGE_WRITETHRU 0
......@@ -128,7 +130,7 @@ static inline pte_t pte_mkuser(pte_t pte)
static inline pte_t pte_mkhuge(pte_t pte)
{
return __pte(pte_val(pte) | _PAGE_SPS);
return __pte(pte_val(pte) | _PAGE_SPS | _PAGE_HUGE);
}
#define pte_mkhuge pte_mkhuge
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_POWERPC_NOHASH_32_SLICE_H
#define _ASM_POWERPC_NOHASH_32_SLICE_H
#ifdef CONFIG_PPC_MM_SLICES
#define SLICE_LOW_SHIFT 26 /* 64 slices */
#define SLICE_LOW_TOP (0x100000000ull)
#define SLICE_NUM_LOW (SLICE_LOW_TOP >> SLICE_LOW_SHIFT)
#define GET_LOW_SLICE_INDEX(addr) ((addr) >> SLICE_LOW_SHIFT)
#define SLICE_HIGH_SHIFT 0
#define SLICE_NUM_HIGH 0ul
#define GET_HIGH_SLICE_INDEX(addr) (addr & 0)
#define SLB_ADDR_LIMIT_DEFAULT DEFAULT_MAP_WINDOW
#endif /* CONFIG_PPC_MM_SLICES */
#endif /* _ASM_POWERPC_NOHASH_32_SLICE_H */
......@@ -211,22 +211,9 @@ static inline unsigned long pte_update(struct mm_struct *mm,
unsigned long set,
int huge)
{
#ifdef PTE_ATOMIC_UPDATES
unsigned long old, tmp;
__asm__ __volatile__(
"1: ldarx %0,0,%3 # pte_update\n\
andc %1,%0,%4 \n\
or %1,%1,%6\n\
stdcx. %1,0,%3 \n\
bne- 1b"
: "=&r" (old), "=&r" (tmp), "=m" (*ptep)
: "r" (ptep), "r" (clr), "m" (*ptep), "r" (set)
: "cc" );
#else
unsigned long old = pte_val(*ptep);
*ptep = __pte((old & ~clr) | set);
#endif
/* huge pages use the old page table lock */
if (!huge)
assert_pte_locked(mm, addr);
......@@ -310,21 +297,8 @@ static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long bits = pte_val(entry) &
(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
#ifdef PTE_ATOMIC_UPDATES
unsigned long old, tmp;
__asm__ __volatile__(
"1: ldarx %0,0,%4\n\
or %0,%3,%0\n\
stdcx. %0,0,%4\n\
bne- 1b"
:"=&r" (old), "=&r" (tmp), "=m" (*ptep)
:"r" (bits), "r" (ptep), "m" (*ptep)
:"cc");
#else
unsigned long old = pte_val(*ptep);
*ptep = __pte(old | bits);
#endif
flush_tlb_page(vma, address);
}
......
......@@ -130,12 +130,10 @@ static inline pte_t pte_exprotect(pte_t pte)
return __pte(pte_val(pte) & ~_PAGE_EXEC);
}
#ifndef pte_mkclean
static inline pte_t pte_mkclean(pte_t pte)
{
return __pte(pte_val(pte) & ~_PAGE_DIRTY);
}
#endif
static inline pte_t pte_mkold(pte_t pte)
{
......@@ -267,7 +265,7 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
static inline int hugepd_ok(hugepd_t hpd)
{
#ifdef CONFIG_PPC_8xx
return ((hpd_val(hpd) & 0x4) != 0);
return ((hpd_val(hpd) & _PMD_PAGE_MASK) == _PMD_PAGE_8M);
#else
/* We clear the top bit to indicate hugepd */
return (hpd_val(hpd) && (hpd_val(hpd) & PD_HUGE) == 0);
......
......@@ -29,6 +29,7 @@
#include <asm/hmi.h>
#include <asm/cpuidle.h>
#include <asm/atomic.h>
#include <asm/rtas-types.h>
#include <asm-generic/mmiowb_types.h>
......@@ -256,6 +257,7 @@ struct paca_struct {
u64 l1d_flush_size;
#endif
#ifdef CONFIG_PPC_PSERIES
struct rtas_args *rtas_args_reentrant;
u8 *mce_data_buf; /* buffer to hold per cpu rtas errlog */
#endif /* CONFIG_PPC_PSERIES */
......
......@@ -249,13 +249,6 @@ static inline bool pfn_valid(unsigned long pfn)
#include <asm/page_32.h>
#endif
/* align addr on a size boundary - adjust address up/down if needed */
#define _ALIGN_UP(addr, size) __ALIGN_KERNEL(addr, size)
#define _ALIGN_DOWN(addr, size) ((addr)&(~((typeof(addr))(size)-1)))
/* align addr on a size boundary - adjust address up if needed */
#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
/*
* Don't compare things with KERNELBASE or PAGE_OFFSET to test for
* "kernelness", use is_kernel_addr() - it should do what you want.
......
......@@ -107,6 +107,8 @@ unsigned long vmalloc_to_phys(void *vmalloc_addr);
void pgtable_cache_add(unsigned int shift);
pte_t *early_pte_alloc_kernel(pmd_t *pmdp, unsigned long va);
#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_PPC32)
void mark_initmem_nx(void);
#else
......
......@@ -158,6 +158,9 @@
/* VMX Vector Store Instructions */
#define OP_31_XOP_STVX 231
/* Prefixed Instructions */
#define OP_PREFIX 1
#define OP_31 31
#define OP_LWZ 32
#define OP_STFS 52
......
......@@ -180,14 +180,14 @@ struct thread_struct {
int fpexc_mode; /* floating-point exception mode */
unsigned int align_ctl; /* alignment handling control */
#ifdef CONFIG_HAVE_HW_BREAKPOINT
struct perf_event *ptrace_bps[HBP_NUM];
struct perf_event *ptrace_bps[HBP_NUM_MAX];
/*
* Helps identify source of single-step exception and subsequent
* hw-breakpoint enablement
*/
struct perf_event *last_hit_ubp;
struct perf_event *last_hit_ubp[HBP_NUM_MAX];
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */
struct arch_hw_breakpoint hw_brk[HBP_NUM_MAX]; /* hardware breakpoint info */
unsigned long trap_nr; /* last trap # on this thread */
u8 load_slb; /* Ages out SLB preload cache entries */
u8 load_fp;
......@@ -272,7 +272,6 @@ struct thread_struct {
unsigned mmcr0;
unsigned used_ebb;
unsigned int used_vas;
#endif
};
......@@ -301,14 +300,12 @@ struct thread_struct {
#else
#define INIT_THREAD { \
.ksp = INIT_SP, \
.regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \
.addr_limit = KERNEL_DS, \
.fpexc_mode = 0, \
.fscr = FSCR_TAR | FSCR_EBB \
}
#endif
#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.regs)
#define task_pt_regs(tsk) ((tsk)->thread.regs)
unsigned long get_wchan(struct task_struct *p);
......
......@@ -117,6 +117,7 @@ extern int of_read_drc_info_cell(struct property **prop,
#define OV1_PPC_2_07 0x01 /* set if we support PowerPC 2.07 */
#define OV1_PPC_3_00 0x80 /* set if we support PowerPC 3.00 */
#define OV1_PPC_3_1 0x40 /* set if we support PowerPC 3.1 */
/* Option vector 2: Open Firmware options supported */
#define OV2_REAL_MODE 0x20 /* set if we want OF in real mode */
......
......@@ -179,6 +179,22 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
#define current_pt_regs() \
((struct pt_regs *)((unsigned long)task_stack_page(current) + THREAD_SIZE) - 1)
#ifdef __powerpc64__
#ifdef CONFIG_PPC_BOOK3S
#define TRAP_FLAGS_MASK 0x10
#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
#define FULL_REGS(regs) true
#define SET_FULL_REGS(regs) do { } while (0)
#else
#define TRAP_FLAGS_MASK 0x11
#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
#define SET_FULL_REGS(regs) ((regs)->trap |= 1)
#endif
#define CHECK_FULL_REGS(regs) BUG_ON(!FULL_REGS(regs))
#define NV_REG_POISON 0xdeadbeefdeadbeefUL
#else
/*
* We use the least-significant bit of the trap field to indicate
* whether we have saved the full set of registers, or only a
......@@ -186,17 +202,13 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
* On 4xx we use the next bit to indicate whether the exception
* is a critical exception (1 means it is).
*/
#define TRAP_FLAGS_MASK 0x1F
#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
#ifndef __powerpc64__
#define SET_FULL_REGS(regs) ((regs)->trap |= 1)
#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0)
#define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0)
#define IS_DEBUG_EXC(regs) (((regs)->trap & 8) != 0)
#endif /* ! __powerpc64__ */
#define TRAP(regs) ((regs)->trap & ~0xF)
#ifdef __powerpc64__
#define NV_REG_POISON 0xdeadbeefdeadbeefUL
#define CHECK_FULL_REGS(regs) BUG_ON(regs->trap & 1)
#else
#define NV_REG_POISON 0xdeadbeef
#define CHECK_FULL_REGS(regs) \
do { \
......@@ -205,6 +217,26 @@ do { \
} while (0)
#endif /* __powerpc64__ */
static inline void set_trap(struct pt_regs *regs, unsigned long val)
{
regs->trap = (regs->trap & TRAP_FLAGS_MASK) | (val & ~TRAP_FLAGS_MASK);
}
static inline bool trap_is_syscall(struct pt_regs *regs)
{
return TRAP(regs) == 0xc00;
}
static inline bool trap_norestart(struct pt_regs *regs)
{
return regs->trap & 0x10;
}
static inline void set_trap_norestart(struct pt_regs *regs)
{
regs->trap |= 0x10;
}
#define arch_has_single_step() (1)
#ifndef CONFIG_BOOK3S_601
#define arch_has_block_step() (true)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -4,8 +4,6 @@
#ifdef CONFIG_PPC_BOOK3S_64
#include <asm/book3s/64/slice.h>
#elif defined(CONFIG_PPC_MMU_NOHASH_32)
#include <asm/nohash/32/slice.h>
#endif
#ifndef __ASSEMBLY__
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment