提交 c90fca95 编写于 作者: L Linus Torvalds

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

Pull powerpc updates from Michael Ellerman:
 "Notable changes:

   - Support for split PMD page table lock on 64-bit Book3S (Power8/9).

   - Add support for HAVE_RELIABLE_STACKTRACE, so we properly support
     live patching again.

   - Add support for patching barrier_nospec in copy_from_user() and
     syscall entry.

   - A couple of fixes for our data breakpoints on Book3S.

   - A series from Nick optimising TLB/mm handling with the Radix MMU.

   - Numerous small cleanups to squash sparse/gcc warnings from Mathieu
     Malaterre.

   - Several series optimising various parts of the 32-bit code from
     Christophe Leroy.

   - Removal of support for two old machines, "SBC834xE" and "C2K"
     ("GEFanuc,C2K"), which is why the diffstat has so many deletions.

  And many other small improvements & fixes.

  There's a few out-of-area changes. Some minor ftrace changes OK'ed by
  Steve, and a fix to our powernv cpuidle driver. Then there's a series
  touching mm, x86 and fs/proc/task_mmu.c, which cleans up some details
  around pkey support. It was ack'ed/reviewed by Ingo & Dave and has
  been in next for several weeks.

  Thanks to: Akshay Adiga, Alastair D'Silva, Alexey Kardashevskiy, Al
  Viro, Andrew Donnellan, Aneesh Kumar K.V, Anju T Sudhakar, Arnd
  Bergmann, Balbir Singh, Cédric Le Goater, Christophe Leroy, Christophe
  Lombard, Colin Ian King, Dave Hansen, Fabio Estevam, Finn Thain,
  Frederic Barrat, Gautham R. Shenoy, Haren Myneni, Hari Bathini, Ingo
  Molnar, Jonathan Neuschäfer, Josh Poimboeuf, Kamalesh Babulal,
  Madhavan Srinivasan, Mahesh Salgaonkar, Mark Greer, Mathieu Malaterre,
  Matthew Wilcox, Michael Neuling, Michal Suchanek, Naveen N. Rao,
  Nicholas Piggin, Nicolai Stange, Olof Johansson, Paul Gortmaker, Paul
  Mackerras, Peter Rosin, Pridhiviraj Paidipeddi, Ram Pai, Rashmica
  Gupta, Ravi Bangoria, Russell Currey, Sam Bobroff, Samuel
  Mendoza-Jonas, Segher Boessenkool, Shilpasri G Bhat, Simon Guo,
  Souptick Joarder, Stewart Smith, Thiago Jung Bauermann, Torsten Duwe,
  Vaibhav Jain, Wei Yongjun, Wolfram Sang, Yisheng Xie, YueHaibing"

* tag 'powerpc-4.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (251 commits)
  powerpc/64s/radix: Fix missing ptesync in flush_cache_vmap
  cpuidle: powernv: Fix promotion from snooze if next state disabled
  powerpc: fix build failure by disabling attribute-alias warning in pci_32
  ocxl: Fix missing unlock on error in afu_ioctl_enable_p9_wait()
  powerpc-opal: fix spelling mistake "Uniterrupted" -> "Uninterrupted"
  powerpc: fix spelling mistake: "Usupported" -> "Unsupported"
  powerpc/pkeys: Detach execute_only key on !PROT_EXEC
  powerpc/powernv: copy/paste - Mask SO bit in CR
  powerpc: Remove core support for Marvell mv64x60 hostbridges
  powerpc/boot: Remove core support for Marvell mv64x60 hostbridges
  powerpc/boot: Remove support for Marvell mv64x60 i2c controller
  powerpc/boot: Remove support for Marvell MPSC serial controller
  powerpc/embedded6xx: Remove C2K board support
  powerpc/lib: optimise PPC32 memcmp
  powerpc/lib: optimise 32 bits __clear_user()
  powerpc/time: inline arch_vtime_task_switch()
  powerpc/Makefile: set -mcpu=860 flag for the 8xx
  powerpc: Implement csum_ipv6_magic in assembly
  powerpc/32: Optimise __csum_partial()
  powerpc/lib: Adjust .balign inside string functions for PPC32
  ...
......@@ -69,7 +69,9 @@ Date: September 2014
Contact: linuxppc-dev@lists.ozlabs.org
Description: read/write
Set the mode for prefaulting in segments into the segment table
when performing the START_WORK ioctl. Possible values:
when performing the START_WORK ioctl. Only applicable when
running under hashed page table mmu.
Possible values:
none: No prefaulting (default)
work_element_descriptor: Treat the work element
descriptor as an effective address and
......
......@@ -157,6 +157,17 @@ OCXL_IOCTL_GET_METADATA:
Obtains configuration information from the card, such at the size of
MMIO areas, the AFU version, and the PASID for the current context.
OCXL_IOCTL_ENABLE_P9_WAIT:
Allows the AFU to wake a userspace thread executing 'wait'. Returns
information to userspace to allow it to configure the AFU. Note that
this is only available on POWER9.
OCXL_IOCTL_GET_FEATURES:
Reports on which CPU features that affect OpenCAPI are usable from
userspace.
mmap
----
......
Marvell Discovery mv64[345]6x System Controller chips
===========================================================
The Marvell mv64[345]60 series of system controller chips contain
many of the peripherals needed to implement a complete computer
system. In this section, we define device tree nodes to describe
the system controller chip itself and each of the peripherals
which it contains. Compatible string values for each node are
prefixed with the string "marvell,", for Marvell Technology Group Ltd.
1) The /system-controller node
This node is used to represent the system-controller and must be
present when the system uses a system controller chip. The top-level
system-controller node contains information that is global to all
devices within the system controller chip. The node name begins
with "system-controller" followed by the unit address, which is
the base address of the memory-mapped register set for the system
controller chip.
Required properties:
- ranges : Describes the translation of system controller addresses
for memory mapped registers.
- clock-frequency: Contains the main clock frequency for the system
controller chip.
- reg : This property defines the address and size of the
memory-mapped registers contained within the system controller
chip. The address specified in the "reg" property should match
the unit address of the system-controller node.
- #address-cells : Address representation for system controller
devices. This field represents the number of cells needed to
represent the address of the memory-mapped registers of devices
within the system controller chip.
- #size-cells : Size representation for the memory-mapped
registers within the system controller chip.
- #interrupt-cells : Defines the width of cells used to represent
interrupts.
Optional properties:
- model : The specific model of the system controller chip. Such
as, "mv64360", "mv64460", or "mv64560".
- compatible : A string identifying the compatibility identifiers
of the system controller chip.
The system-controller node contains child nodes for each system
controller device that the platform uses. Nodes should not be created
for devices which exist on the system controller chip but are not used
Example Marvell Discovery mv64360 system-controller node:
system-controller@f1000000 { /* Marvell Discovery mv64360 */
#address-cells = <1>;
#size-cells = <1>;
model = "mv64360"; /* Default */
compatible = "marvell,mv64360";
clock-frequency = <133333333>;
reg = <0xf1000000 0x10000>;
virtual-reg = <0xf1000000>;
ranges = <0x88000000 0x88000000 0x1000000 /* PCI 0 I/O Space */
0x80000000 0x80000000 0x8000000 /* PCI 0 MEM Space */
0xa0000000 0xa0000000 0x4000000 /* User FLASH */
0x00000000 0xf1000000 0x0010000 /* Bridge's regs */
0xf2000000 0xf2000000 0x0040000>;/* Integrated SRAM */
[ child node definitions... ]
}
2) Child nodes of /system-controller
a) Marvell Discovery MDIO bus
The MDIO is a bus to which the PHY devices are connected. For each
device that exists on this bus, a child node should be created. See
the definition of the PHY node below for an example of how to define
a PHY.
Required properties:
- #address-cells : Should be <1>
- #size-cells : Should be <0>
- compatible : Should be "marvell,mv64360-mdio"
Example:
mdio {
#address-cells = <1>;
#size-cells = <0>;
compatible = "marvell,mv64360-mdio";
ethernet-phy@0 {
......
};
};
b) Marvell Discovery ethernet controller
The Discover ethernet controller is described with two levels
of nodes. The first level describes an ethernet silicon block
and the second level describes up to 3 ethernet nodes within
that block. The reason for the multiple levels is that the
registers for the node are interleaved within a single set
of registers. The "ethernet-block" level describes the
shared register set, and the "ethernet" nodes describe ethernet
port-specific properties.
Ethernet block node
Required properties:
- #address-cells : <1>
- #size-cells : <0>
- compatible : "marvell,mv64360-eth-block"
- reg : Offset and length of the register set for this block
Optional properties:
- clocks : Phandle to the clock control device and gate bit
Example Discovery Ethernet block node:
ethernet-block@2000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "marvell,mv64360-eth-block";
reg = <0x2000 0x2000>;
ethernet@0 {
.......
};
};
Ethernet port node
Required properties:
- compatible : Should be "marvell,mv64360-eth".
- reg : Should be <0>, <1>, or <2>, according to which registers
within the silicon block the device uses.
- interrupts : <a> where a is the interrupt number for the port.
- interrupt-parent : the phandle for the interrupt controller
that services interrupts for this device.
- phy : the phandle for the PHY connected to this ethernet
controller.
- local-mac-address : 6 bytes, MAC address
Example Discovery Ethernet port node:
ethernet@0 {
compatible = "marvell,mv64360-eth";
reg = <0>;
interrupts = <32>;
interrupt-parent = <&PIC>;
phy = <&PHY0>;
local-mac-address = [ 00 00 00 00 00 00 ];
};
c) Marvell Discovery PHY nodes
Required properties:
- interrupts : <a> where a is the interrupt number for this phy.
- interrupt-parent : the phandle for the interrupt controller that
services interrupts for this device.
- reg : The ID number for the phy, usually a small integer
Example Discovery PHY node:
ethernet-phy@1 {
compatible = "broadcom,bcm5421";
interrupts = <76>; /* GPP 12 */
interrupt-parent = <&PIC>;
reg = <1>;
};
d) Marvell Discovery SDMA nodes
Represent DMA hardware associated with the MPSC (multiprotocol
serial controllers).
Required properties:
- compatible : "marvell,mv64360-sdma"
- reg : Offset and length of the register set for this device
- interrupts : <a> where a is the interrupt number for the DMA
device.
- interrupt-parent : the phandle for the interrupt controller
that services interrupts for this device.
Example Discovery SDMA node:
sdma@4000 {
compatible = "marvell,mv64360-sdma";
reg = <0x4000 0xc18>;
virtual-reg = <0xf1004000>;
interrupts = <36>;
interrupt-parent = <&PIC>;
};
e) Marvell Discovery BRG nodes
Represent baud rate generator hardware associated with the MPSC
(multiprotocol serial controllers).
Required properties:
- compatible : "marvell,mv64360-brg"
- reg : Offset and length of the register set for this device
- clock-src : A value from 0 to 15 which selects the clock
source for the baud rate generator. This value corresponds
to the CLKS value in the BRGx configuration register. See
the mv64x60 User's Manual.
- clock-frequence : The frequency (in Hz) of the baud rate
generator's input clock.
- current-speed : The current speed setting (presumably by
firmware) of the baud rate generator.
Example Discovery BRG node:
brg@b200 {
compatible = "marvell,mv64360-brg";
reg = <0xb200 0x8>;
clock-src = <8>;
clock-frequency = <133333333>;
current-speed = <9600>;
};
f) Marvell Discovery CUNIT nodes
Represent the Serial Communications Unit device hardware.
Required properties:
- reg : Offset and length of the register set for this device
Example Discovery CUNIT node:
cunit@f200 {
reg = <0xf200 0x200>;
};
g) Marvell Discovery MPSCROUTING nodes
Represent the Discovery's MPSC routing hardware
Required properties:
- reg : Offset and length of the register set for this device
Example Discovery CUNIT node:
mpscrouting@b500 {
reg = <0xb400 0xc>;
};
h) Marvell Discovery MPSCINTR nodes
Represent the Discovery's MPSC DMA interrupt hardware registers
(SDMA cause and mask registers).
Required properties:
- reg : Offset and length of the register set for this device
Example Discovery MPSCINTR node:
mpsintr@b800 {
reg = <0xb800 0x100>;
};
i) Marvell Discovery MPSC nodes
Represent the Discovery's MPSC (Multiprotocol Serial Controller)
serial port.
Required properties:
- compatible : "marvell,mv64360-mpsc"
- reg : Offset and length of the register set for this device
- sdma : the phandle for the SDMA node used by this port
- brg : the phandle for the BRG node used by this port
- cunit : the phandle for the CUNIT node used by this port
- mpscrouting : the phandle for the MPSCROUTING node used by this port
- mpscintr : the phandle for the MPSCINTR node used by this port
- cell-index : the hardware index of this cell in the MPSC core
- max_idle : value needed for MPSC CHR3 (Maximum Frame Length)
register
- interrupts : <a> where a is the interrupt number for the MPSC.
- interrupt-parent : the phandle for the interrupt controller
that services interrupts for this device.
Example Discovery MPSCINTR node:
mpsc@8000 {
compatible = "marvell,mv64360-mpsc";
reg = <0x8000 0x38>;
virtual-reg = <0xf1008000>;
sdma = <&SDMA0>;
brg = <&BRG0>;
cunit = <&CUNIT>;
mpscrouting = <&MPSCROUTING>;
mpscintr = <&MPSCINTR>;
cell-index = <0>;
max_idle = <40>;
interrupts = <40>;
interrupt-parent = <&PIC>;
};
j) Marvell Discovery Watch Dog Timer nodes
Represent the Discovery's watchdog timer hardware
Required properties:
- compatible : "marvell,mv64360-wdt"
- reg : Offset and length of the register set for this device
Example Discovery Watch Dog Timer node:
wdt@b410 {
compatible = "marvell,mv64360-wdt";
reg = <0xb410 0x8>;
};
k) Marvell Discovery I2C nodes
Represent the Discovery's I2C hardware
Required properties:
- device_type : "i2c"
- compatible : "marvell,mv64360-i2c"
- reg : Offset and length of the register set for this device
- interrupts : <a> where a is the interrupt number for the I2C.
- interrupt-parent : the phandle for the interrupt controller
that services interrupts for this device.
Example Discovery I2C node:
compatible = "marvell,mv64360-i2c";
reg = <0xc000 0x20>;
virtual-reg = <0xf100c000>;
interrupts = <37>;
interrupt-parent = <&PIC>;
};
l) Marvell Discovery PIC (Programmable Interrupt Controller) nodes
Represent the Discovery's PIC hardware
Required properties:
- #interrupt-cells : <1>
- #address-cells : <0>
- compatible : "marvell,mv64360-pic"
- reg : Offset and length of the register set for this device
- interrupt-controller
Example Discovery PIC node:
pic {
#interrupt-cells = <1>;
#address-cells = <0>;
compatible = "marvell,mv64360-pic";
reg = <0x0 0x88>;
interrupt-controller;
};
m) Marvell Discovery MPP (Multipurpose Pins) multiplexing nodes
Represent the Discovery's MPP hardware
Required properties:
- compatible : "marvell,mv64360-mpp"
- reg : Offset and length of the register set for this device
Example Discovery MPP node:
mpp@f000 {
compatible = "marvell,mv64360-mpp";
reg = <0xf000 0x10>;
};
n) Marvell Discovery GPP (General Purpose Pins) nodes
Represent the Discovery's GPP hardware
Required properties:
- compatible : "marvell,mv64360-gpp"
- reg : Offset and length of the register set for this device
Example Discovery GPP node:
gpp@f000 {
compatible = "marvell,mv64360-gpp";
reg = <0xf100 0x20>;
};
o) Marvell Discovery PCI host bridge node
Represents the Discovery's PCI host bridge device. The properties
for this node conform to Rev 2.1 of the PCI Bus Binding to IEEE
1275-1994. A typical value for the compatible property is
"marvell,mv64360-pci".
Example Discovery PCI host bridge node
pci@80000000 {
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
device_type = "pci";
compatible = "marvell,mv64360-pci";
reg = <0xcf8 0x8>;
ranges = <0x01000000 0x0 0x0
0x88000000 0x0 0x01000000
0x02000000 0x0 0x80000000
0x80000000 0x0 0x08000000>;
bus-range = <0 255>;
clock-frequency = <66000000>;
interrupt-parent = <&PIC>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x0a */
0x5000 0 0 1 &PIC 80
0x5000 0 0 2 &PIC 81
0x5000 0 0 3 &PIC 91
0x5000 0 0 4 &PIC 93
/* IDSEL 0x0b */
0x5800 0 0 1 &PIC 91
0x5800 0 0 2 &PIC 93
0x5800 0 0 3 &PIC 80
0x5800 0 0 4 &PIC 81
/* IDSEL 0x0c */
0x6000 0 0 1 &PIC 91
0x6000 0 0 2 &PIC 93
0x6000 0 0 3 &PIC 80
0x6000 0 0 4 &PIC 81
/* IDSEL 0x0d */
0x6800 0 0 1 &PIC 93
0x6800 0 0 2 &PIC 80
0x6800 0 0 3 &PIC 81
0x6800 0 0 4 &PIC 91
>;
};
p) Marvell Discovery CPU Error nodes
Represent the Discovery's CPU error handler device.
Required properties:
- compatible : "marvell,mv64360-cpu-error"
- reg : Offset and length of the register set for this device
- interrupts : the interrupt number for this device
- interrupt-parent : the phandle for the interrupt controller
that services interrupts for this device.
Example Discovery CPU Error node:
cpu-error@70 {
compatible = "marvell,mv64360-cpu-error";
reg = <0x70 0x10 0x128 0x28>;
interrupts = <3>;
interrupt-parent = <&PIC>;
};
q) Marvell Discovery SRAM Controller nodes
Represent the Discovery's SRAM controller device.
Required properties:
- compatible : "marvell,mv64360-sram-ctrl"
- reg : Offset and length of the register set for this device
- interrupts : the interrupt number for this device
- interrupt-parent : the phandle for the interrupt controller
that services interrupts for this device.
Example Discovery SRAM Controller node:
sram-ctrl@380 {
compatible = "marvell,mv64360-sram-ctrl";
reg = <0x380 0x80>;
interrupts = <13>;
interrupt-parent = <&PIC>;
};
r) Marvell Discovery PCI Error Handler nodes
Represent the Discovery's PCI error handler device.
Required properties:
- compatible : "marvell,mv64360-pci-error"
- reg : Offset and length of the register set for this device
- interrupts : the interrupt number for this device
- interrupt-parent : the phandle for the interrupt controller
that services interrupts for this device.
Example Discovery PCI Error Handler node:
pci-error@1d40 {
compatible = "marvell,mv64360-pci-error";
reg = <0x1d40 0x40 0xc28 0x4>;
interrupts = <12>;
interrupt-parent = <&PIC>;
};
s) Marvell Discovery Memory Controller nodes
Represent the Discovery's memory controller device.
Required properties:
- compatible : "marvell,mv64360-mem-ctrl"
- reg : Offset and length of the register set for this device
- interrupts : the interrupt number for this device
- interrupt-parent : the phandle for the interrupt controller
that services interrupts for this device.
Example Discovery Memory Controller node:
mem-ctrl@1400 {
compatible = "marvell,mv64360-mem-ctrl";
reg = <0x1400 0x60>;
interrupts = <17>;
interrupt-parent = <&PIC>;
};
......@@ -156,6 +156,7 @@ config PPC
select BUILDTIME_EXTABLE_SORT
select CLONE_BACKWARDS
select DCACHE_WORD_ACCESS if PPC64 && CPU_LITTLE_ENDIAN
select DYNAMIC_FTRACE if FUNCTION_TRACER
select EDAC_ATOMIC_SCRUB
select EDAC_SUPPORT
select GENERIC_ATOMIC64 if PPC32
......@@ -214,6 +215,7 @@ config PPC
select HAVE_PERF_USER_STACK_DUMP
select HAVE_RCU_TABLE_FREE if SMP
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_RELIABLE_STACKTRACE if PPC64 && CPU_LITTLE_ENDIAN
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_VIRT_CPU_ACCOUNTING
select HAVE_IRQ_TIME_ACCOUNTING
......@@ -228,6 +230,7 @@ config PPC
select OF_RESERVED_MEM
select OLD_SIGACTION if PPC32
select OLD_SIGSUSPEND
select RTC_LIB
select SPARSE_IRQ
select SYSCTL_EXCEPTION_TRACE
select VIRT_TO_BUS if !PPC64
......
......@@ -17,17 +17,18 @@ HAS_BIARCH := $(call cc-option-yn, -m32)
# Set default 32 bits cross compilers for vdso and boot wrapper
CROSS32_COMPILE ?=
CROSS32CC := $(CROSS32_COMPILE)gcc
CROSS32AR := $(CROSS32_COMPILE)ar
ifeq ($(HAS_BIARCH),y)
ifeq ($(CROSS32_COMPILE),)
CROSS32CC := $(CC) -m32
KBUILD_ARFLAGS += --target=elf32-powerpc
ifdef CONFIG_PPC32
# These options will be overridden by any -mcpu option that the CPU
# or platform code sets later on the command line, but they are needed
# to set a sane 32-bit cpu target for the 64-bit cross compiler which
# may default to the wrong ISA.
KBUILD_CFLAGS += -mcpu=powerpc
KBUILD_AFLAGS += -mcpu=powerpc
endif
endif
endif
export CROSS32CC CROSS32AR
ifeq ($(CROSS_COMPILE),)
KBUILD_DEFCONFIG := $(shell uname -m)_defconfig
......@@ -74,13 +75,15 @@ endif
endif
ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y)
override LD += -EL
KBUILD_CFLAGS += -mlittle-endian
LDFLAGS += -EL
LDEMULATION := lppc
GNUTARGET := powerpcle
MULTIPLEWORD := -mno-multiple
KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-save-toc-indirect)
else
override LD += -EB
KBUILD_CFLAGS += $(call cc-option,-mbig-endian)
LDFLAGS += -EB
LDEMULATION := ppc
GNUTARGET := powerpc
MULTIPLEWORD := -mmultiple
......@@ -93,19 +96,19 @@ aflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mabi=elfv1)
aflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -mabi=elfv2
endif
cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -mlittle-endian
cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mbig-endian)
ifneq ($(cc-name),clang)
cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -mno-strict-align
endif
cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mbig-endian)
cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -mlittle-endian
aflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mbig-endian)
aflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -mlittle-endian
ifeq ($(HAS_BIARCH),y)
override AS += -a$(BITS)
override LD += -m elf$(BITS)$(LDEMULATION)
override CC += -m$(BITS)
KBUILD_CFLAGS += -m$(BITS)
KBUILD_AFLAGS += -m$(BITS) -Wl,-a$(BITS)
LDFLAGS += -m elf$(BITS)$(LDEMULATION)
KBUILD_ARFLAGS += --target=elf$(BITS)-$(GNUTARGET)
endif
......@@ -178,6 +181,7 @@ CFLAGS-$(CONFIG_POWER6_CPU) += $(call cc-option,-mcpu=power6)
CFLAGS-$(CONFIG_POWER7_CPU) += $(call cc-option,-mcpu=power7)
CFLAGS-$(CONFIG_POWER8_CPU) += $(call cc-option,-mcpu=power8)
CFLAGS-$(CONFIG_POWER9_CPU) += $(call cc-option,-mcpu=power9)
CFLAGS-$(CONFIG_PPC_8xx) += $(call cc-option,-mcpu=860)
# Altivec option not allowed with e500mc64 in GCC.
ifeq ($(CONFIG_ALTIVEC),y)
......
......@@ -23,19 +23,23 @@ all: $(obj)/zImage
compress-$(CONFIG_KERNEL_GZIP) := CONFIG_KERNEL_GZIP
compress-$(CONFIG_KERNEL_XZ) := CONFIG_KERNEL_XZ
ifdef CROSS32_COMPILE
BOOTCC := $(CROSS32_COMPILE)gcc
BOOTAR := $(CROSS32_COMPILE)ar
else
BOOTCC := $(CC)
BOOTAR := $(AR)
endif
BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -Os -msoft-float -pipe \
-fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
-D$(compress-y)
BOOTCC := $(CC)
ifdef CONFIG_PPC64_BOOT_WRAPPER
BOOTCFLAGS += -m64
else
BOOTCFLAGS += -m32
ifdef CROSS32_COMPILE
BOOTCC := $(CROSS32_COMPILE)gcc
endif
endif
BOOTCFLAGS += -isystem $(shell $(BOOTCC) -print-file-name=include)
......@@ -49,6 +53,8 @@ endif
BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
BOOTARFLAGS := -cr$(KBUILD_ARFLAGS)
ifdef CONFIG_DEBUG_INFO
BOOTCFLAGS += -g
endif
......@@ -120,7 +126,7 @@ src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c
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) += mpsc.c mv64x60.c mv64x60_i2c.c ugecon.c fsl-soc.c
src-wlib-$(CONFIG_EMBEDDED6xx) += ugecon.c fsl-soc.c
src-wlib-$(CONFIG_XILINX_VIRTEX) += uartlite.c
src-wlib-$(CONFIG_CPM) += cpm-serial.c
......@@ -143,8 +149,8 @@ src-plat-$(CONFIG_PPC_82xx) += cuboot-pq2.c fixed-head.S ep8248e.c cuboot-824x.c
src-plat-$(CONFIG_PPC_83xx) += cuboot-83xx.c fixed-head.S redboot-83xx.c
src-plat-$(CONFIG_FSL_SOC_BOOKE) += cuboot-85xx.c cuboot-85xx-cpm2.c
src-plat-$(CONFIG_EMBEDDED6xx) += cuboot-pq2.c cuboot-mpc7448hpc2.c \
cuboot-c2k.c gamecube-head.S \
gamecube.c wii-head.S wii.c holly.c \
gamecube-head.S gamecube.c \
wii-head.S wii.c holly.c \
fixed-head.S mvme5100.c
src-plat-$(CONFIG_AMIGAONE) += cuboot-amigaone.c
src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c
......@@ -202,7 +208,7 @@ quiet_cmd_bootas = BOOTAS $@
cmd_bootas = $(BOOTCC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $<
quiet_cmd_bootar = BOOTAR $@
cmd_bootar = $(CROSS32AR) -cr$(KBUILD_ARFLAGS) $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@
cmd_bootar = $(BOOTAR) $(BOOTARFLAGS) $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@
$(obj-libfdt): $(obj)/%.o: $(srctree)/scripts/dtc/libfdt/%.c FORCE
$(call if_changed_dep,bootcc)
......@@ -339,7 +345,6 @@ image-$(CONFIG_MVME7100) += dtbImage.mvme7100
# Board ports in arch/powerpc/platform/embedded6xx/Kconfig
image-$(CONFIG_STORCENTER) += cuImage.storcenter
image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2
image-$(CONFIG_PPC_C2K) += cuImage.c2k
image-$(CONFIG_GAMECUBE) += dtbImage.gamecube
image-$(CONFIG_WII) += dtbImage.wii
image-$(CONFIG_MVME5100) += dtbImage.mvme5100
......
/*
* GEFanuc C2K platform code.
*
* Author: Remi Machet <rmachet@slac.stanford.edu>
*
* Originated from prpmc2800.c
*
* 2008 (c) Stanford University
* 2007 (c) MontaVista, Software, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
#include "types.h"
#include "stdio.h"
#include "io.h"
#include "ops.h"
#include "elf.h"
#include "mv64x60.h"
#include "cuboot.h"
#include "ppcboot.h"
static u8 *bridge_base;
static void c2k_bridge_setup(u32 mem_size)
{
u32 i, v[30], enables, acc_bits;
u32 pci_base_hi, pci_base_lo, size, buf[2];
unsigned long cpu_base;
int rc;
void *devp, *mv64x60_devp;
u8 *bridge_pbase, is_coherent;
struct mv64x60_cpu2pci_win *tbl;
int bus;
bridge_pbase = mv64x60_get_bridge_pbase();
is_coherent = mv64x60_is_coherent();
if (is_coherent)
acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_WB
| MV64x60_PCI_ACC_CNTL_SWAP_NONE
| MV64x60_PCI_ACC_CNTL_MBURST_32_BYTES
| MV64x60_PCI_ACC_CNTL_RDSIZE_32_BYTES;
else
acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_NONE
| MV64x60_PCI_ACC_CNTL_SWAP_NONE
| MV64x60_PCI_ACC_CNTL_MBURST_128_BYTES
| MV64x60_PCI_ACC_CNTL_RDSIZE_256_BYTES;
mv64x60_config_ctlr_windows(bridge_base, bridge_pbase, is_coherent);
mv64x60_devp = find_node_by_compatible(NULL, "marvell,mv64360");
if (mv64x60_devp == NULL)
fatal("Error: Missing marvell,mv64360 device tree node\n\r");
enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE));
enables |= 0x007ffe00; /* Disable all cpu->pci windows */
out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), enables);
/* Get the cpu -> pci i/o & mem mappings from the device tree */
devp = NULL;
for (bus = 0; ; bus++) {
char name[] = "pci ";
name[strlen(name)-1] = bus+'0';
devp = find_node_by_alias(name);
if (devp == NULL)
break;
if (bus >= 2)
fatal("Error: Only 2 PCI controllers are supported at" \
" this time.\n");
mv64x60_config_pci_windows(bridge_base, bridge_pbase, bus, 0,
mem_size, acc_bits);
rc = getprop(devp, "ranges", v, sizeof(v));
if (rc == 0)
fatal("Error: Can't find marvell,mv64360-pci ranges"
" property\n\r");
/* Get the cpu -> pci i/o & mem mappings from the device tree */
for (i = 0; i < rc; i += 6) {
switch (v[i] & 0xff000000) {
case 0x01000000: /* PCI I/O Space */
tbl = mv64x60_cpu2pci_io;
break;
case 0x02000000: /* PCI MEM Space */
tbl = mv64x60_cpu2pci_mem;
break;
default:
continue;
}
pci_base_hi = v[i+1];
pci_base_lo = v[i+2];
cpu_base = v[i+3];
size = v[i+5];
buf[0] = cpu_base;
buf[1] = size;
if (!dt_xlate_addr(devp, buf, sizeof(buf), &cpu_base))
fatal("Error: Can't translate PCI address " \
"0x%x\n\r", (u32)cpu_base);
mv64x60_config_cpu2pci_window(bridge_base, bus,
pci_base_hi, pci_base_lo, cpu_base, size, tbl);
}
enables &= ~(3<<(9+bus*5)); /* Enable cpu->pci<bus> i/o,
cpu->pci<bus> mem0 */
out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE),
enables);
};
}
static void c2k_fixups(void)
{
u32 mem_size;
mem_size = mv64x60_get_mem_size(bridge_base);
c2k_bridge_setup(mem_size); /* Do necessary bridge setup */
}
#define MV64x60_MPP_CNTL_0 0xf000
#define MV64x60_MPP_CNTL_2 0xf008
#define MV64x60_GPP_IO_CNTL 0xf100
#define MV64x60_GPP_LEVEL_CNTL 0xf110
#define MV64x60_GPP_VALUE_SET 0xf118
static void c2k_reset(void)
{
u32 temp;
udelay(5000000);
if (bridge_base != 0) {
temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0));
temp &= 0xFFFF0FFF;
out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0), temp);
temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL));
temp |= 0x00000004;
out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp);
temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
temp |= 0x00000004;
out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2));
temp &= 0xFFFF0FFF;
out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2), temp);
temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL));
temp |= 0x00080000;
out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp);
temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
temp |= 0x00080000;
out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
out_le32((u32 *)(bridge_base + MV64x60_GPP_VALUE_SET),
0x00080004);
}
for (;;);
}
static bd_t bd;
void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
CUBOOT_INIT();
fdt_init(_dtb_start);
bridge_base = mv64x60_get_bridge_base();
platform_ops.fixups = c2k_fixups;
platform_ops.exit = c2k_reset;
if (serial_console_init() < 0)
exit();
}
/* Device Tree Source for GEFanuc C2K
*
* Author: Remi Machet <rmachet@slac.stanford.edu>
*
* Originated from prpmc2800.dts
*
* 2008 (c) Stanford University
* 2007 (c) MontaVista, Software, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
model = "C2K";
compatible = "GEFanuc,C2K";
coherency-off;
aliases {
pci0 = &PCI0;
pci1 = &PCI1;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
device_type = "cpu";
compatible = "PowerPC,7447";
reg = <0>;
clock-frequency = <996000000>; /* 996 MHz */
bus-frequency = <166666667>; /* 166.6666 MHz */
timebase-frequency = <41666667>; /* 166.6666/4 MHz */
i-cache-line-size = <32>;
d-cache-line-size = <32>;
i-cache-size = <32768>;
d-cache-size = <32768>;
};
};
memory {
device_type = "memory";
reg = <0x00000000 0x40000000>; /* 1GB */
};
system-controller@d8000000 { /* Marvell Discovery */
#address-cells = <1>;
#size-cells = <1>;
model = "mv64460";
compatible = "marvell,mv64360";
clock-frequency = <166666667>; /* 166.66... MHz */
reg = <0xd8000000 0x00010000>;
virtual-reg = <0xd8000000>;
ranges = <0xd4000000 0xd4000000 0x01000000 /* PCI 0 I/O Space */
0x80000000 0x80000000 0x08000000 /* PCI 0 MEM Space */
0xd0000000 0xd0000000 0x01000000 /* PCI 1 I/O Space */
0xa0000000 0xa0000000 0x08000000 /* PCI 1 MEM Space */
0xd8100000 0xd8100000 0x00010000 /* FPGA */
0xd8110000 0xd8110000 0x00010000 /* FPGA USARTs */
0xf8000000 0xf8000000 0x08000000 /* User FLASH */
0x00000000 0xd8000000 0x00010000 /* Bridge's regs */
0xd8140000 0xd8140000 0x00040000>; /* Integrated SRAM */
mdio@2000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "marvell,mv64360-mdio";
reg = <0x2000 4>;
PHY0: ethernet-phy@0 {
interrupts = <76>; /* GPP 12 */
interrupt-parent = <&PIC>;
reg = <0>;
};
PHY1: ethernet-phy@1 {
interrupts = <76>; /* GPP 12 */
interrupt-parent = <&PIC>;
reg = <1>;
};
PHY2: ethernet-phy@2 {
interrupts = <76>; /* GPP 12 */
interrupt-parent = <&PIC>;
reg = <2>;
};
};
ethernet-group@2000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "marvell,mv64360-eth-group";
reg = <0x2000 0x2000>;
ethernet@0 {
device_type = "network";
compatible = "marvell,mv64360-eth";
reg = <0>;
interrupts = <32>;
interrupt-parent = <&PIC>;
phy = <&PHY0>;
local-mac-address = [ 00 00 00 00 00 00 ];
};
ethernet@1 {
device_type = "network";
compatible = "marvell,mv64360-eth";
reg = <1>;
interrupts = <33>;
interrupt-parent = <&PIC>;
phy = <&PHY1>;
local-mac-address = [ 00 00 00 00 00 00 ];
};
ethernet@2 {
device_type = "network";
compatible = "marvell,mv64360-eth";
reg = <2>;
interrupts = <34>;
interrupt-parent = <&PIC>;
phy = <&PHY2>;
local-mac-address = [ 00 00 00 00 00 00 ];
};
};
SDMA0: sdma@4000 {
compatible = "marvell,mv64360-sdma";
reg = <0x4000 0xc18>;
virtual-reg = <0xd8004000>;
interrupt-base = <0>;
interrupts = <36>;
interrupt-parent = <&PIC>;
};
SDMA1: sdma@6000 {
compatible = "marvell,mv64360-sdma";
reg = <0x6000 0xc18>;
virtual-reg = <0xd8006000>;
interrupt-base = <0>;
interrupts = <38>;
interrupt-parent = <&PIC>;
};
BRG0: brg@b200 {
compatible = "marvell,mv64360-brg";
reg = <0xb200 0x8>;
clock-src = <8>;
clock-frequency = <133333333>;
current-speed = <115200>;
};
BRG1: brg@b208 {
compatible = "marvell,mv64360-brg";
reg = <0xb208 0x8>;
clock-src = <8>;
clock-frequency = <133333333>;
current-speed = <115200>;
};
CUNIT: cunit@f200 {
reg = <0xf200 0x200>;
};
MPSCROUTING: mpscrouting@b400 {
reg = <0xb400 0xc>;
};
MPSCINTR: mpscintr@b800 {
reg = <0xb800 0x100>;
virtual-reg = <0xd800b800>;
};
MPSC0: mpsc@8000 {
compatible = "marvell,mv64360-mpsc";
reg = <0x8000 0x38>;
virtual-reg = <0xd8008000>;
sdma = <&SDMA0>;
brg = <&BRG0>;
cunit = <&CUNIT>;
mpscrouting = <&MPSCROUTING>;
mpscintr = <&MPSCINTR>;
cell-index = <0>;
interrupts = <40>;
interrupt-parent = <&PIC>;
};
MPSC1: mpsc@9000 {
compatible = "marvell,mv64360-mpsc";
reg = <0x9000 0x38>;
virtual-reg = <0xd8009000>;
sdma = <&SDMA1>;
brg = <&BRG1>;
cunit = <&CUNIT>;
mpscrouting = <&MPSCROUTING>;
mpscintr = <&MPSCINTR>;
cell-index = <1>;
interrupts = <42>;
interrupt-parent = <&PIC>;
};
wdt@b410 { /* watchdog timer */
compatible = "marvell,mv64360-wdt";
reg = <0xb410 0x8>;
};
i2c@c000 {
compatible = "marvell,mv64360-i2c";
reg = <0xc000 0x20>;
virtual-reg = <0xd800c000>;
interrupts = <37>;
interrupt-parent = <&PIC>;
};
PIC: pic {
#interrupt-cells = <1>;
#address-cells = <0>;
compatible = "marvell,mv64360-pic";
reg = <0x0000 0x88>;
interrupt-controller;
};
mpp@f000 {
compatible = "marvell,mv64360-mpp";
reg = <0xf000 0x10>;
};
gpp@f100 {
compatible = "marvell,mv64360-gpp";
reg = <0xf100 0x20>;
};
PCI0: pci@80000000 {
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
device_type = "pci";
compatible = "marvell,mv64360-pci";
reg = <0x0cf8 0x8>;
ranges = <0x01000000 0x0 0x00000000 0xd4000000 0x0 0x01000000
0x02000000 0x0 0x80000000 0x80000000 0x0 0x08000000>;
bus-range = <0 255>;
clock-frequency = <66000000>;
interrupt-pci-iack = <0x0c34>;
interrupt-parent = <&PIC>;
interrupt-map-mask = <0x0000 0x0 0x0 0x7>;
interrupt-map = <
/* Only one interrupt line for PMC0 slot (INTA) */
0x0000 0 0 1 &PIC 88
>;
};
PCI1: pci@a0000000 {
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
device_type = "pci";
compatible = "marvell,mv64360-pci";
reg = <0x0c78 0x8>;
ranges = <0x01000000 0x0 0x00000000 0xd0000000 0x0 0x01000000
0x02000000 0x0 0x80000000 0xa0000000 0x0 0x08000000>;
bus-range = <0 255>;
clock-frequency = <66000000>;
interrupt-pci-iack = <0x0cb4>;
interrupt-parent = <&PIC>;
interrupt-map-mask = <0xf800 0x00 0x00 0x7>;
interrupt-map = <
/* IDSEL 0x01: PMC1 ? */
0x0800 0 0 1 &PIC 88
/* IDSEL 0x02: cPCI bridge */
0x1000 0 0 1 &PIC 88
/* IDSEL 0x03: USB controller */
0x1800 0 0 1 &PIC 91
/* IDSEL 0x04: SATA controller */
0x2000 0 0 1 &PIC 95
>;
};
cpu-error@70 {
compatible = "marvell,mv64360-cpu-error";
reg = <0x0070 0x10 0x0128 0x28>;
interrupts = <3>;
interrupt-parent = <&PIC>;
};
sram-ctrl@380 {
compatible = "marvell,mv64360-sram-ctrl";
reg = <0x0380 0x80>;
interrupts = <13>;
interrupt-parent = <&PIC>;
};
pci-error@1d40 {
compatible = "marvell,mv64360-pci-error";
reg = <0x1d40 0x40 0x0c28 0x4>;
interrupts = <12>;
interrupt-parent = <&PIC>;
};
pci-error@1dc0 {
compatible = "marvell,mv64360-pci-error";
reg = <0x1dc0 0x40 0x0ca8 0x4>;
interrupts = <16>;
interrupt-parent = <&PIC>;
};
mem-ctrl@1400 {
compatible = "marvell,mv64360-mem-ctrl";
reg = <0x1400 0x60>;
interrupts = <17>;
interrupt-parent = <&PIC>;
};
/* Devices attached to the device controller */
devicebus@45c {
#address-cells = <2>;
#size-cells = <1>;
compatible = "marvell,mv64306-devctrl";
reg = <0x45C 0x88>;
interrupts = <1>;
interrupt-parent = <&PIC>;
ranges = <0 0 0xd8100000 0x10000
2 0 0xd8110000 0x10000
4 0 0xf8000000 0x8000000>;
fpga@0,0 {
compatible = "sbs,fpga-c2k";
reg = <0 0 0x10000>;
};
fpga_usart@2,0 {
compatible = "sbs,fpga_usart-c2k";
reg = <2 0 0x10000>;
};
nor_flash@4,0 {
compatible = "cfi-flash";
reg = <4 0 0x8000000>; /* 128MB */
bank-width = <4>;
device-width = <1>;
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "boot";
reg = <0x00000000 0x00080000>;
};
partition@40000 {
label = "kernel";
reg = <0x00080000 0x00400000>;
};
partition@440000 {
label = "initrd";
reg = <0x00480000 0x00B80000>;
};
partition@1000000 {
label = "rootfs";
reg = <0x01000000 0x06800000>;
};
partition@7800000 {
label = "recovery";
reg = <0x07800000 0x00800000>;
read-only;
};
};
};
};
chosen {
stdout-path = &MPSC0;
};
};
......@@ -269,7 +269,7 @@
i2c@118000 {
pca9547@77 {
compatible = "philips,pca9547";
compatible = "nxp,pca9547";
reg = <0x77>;
};
rtc@68 {
......
/*
* SBC8349E Device Tree Source
*
* Copyright 2007 Wind River Inc.
*
* Paul Gortmaker (see MAINTAINERS for contact information)
*
* -based largely on the Freescale MPC834x_MDS dts.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
/dts-v1/;
/ {
model = "SBC8349E";
compatible = "SBC834xE";
#address-cells = <1>;
#size-cells = <1>;
aliases {
ethernet0 = &enet0;
ethernet1 = &enet1;
serial0 = &serial0;
serial1 = &serial1;
pci0 = &pci0;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
PowerPC,8349@0 {
device_type = "cpu";
reg = <0x0>;
d-cache-line-size = <32>;
i-cache-line-size = <32>;
d-cache-size = <32768>;
i-cache-size = <32768>;
timebase-frequency = <0>; // from bootloader
bus-frequency = <0>; // from bootloader
clock-frequency = <0>; // from bootloader
};
};
memory {
device_type = "memory";
reg = <0x00000000 0x10000000>; // 256MB at 0
};
soc8349@e0000000 {
#address-cells = <1>;
#size-cells = <1>;
device_type = "soc";
ranges = <0x0 0xe0000000 0x00100000>;
reg = <0xe0000000 0x00000200>;
bus-frequency = <0>;
wdt@200 {
compatible = "mpc83xx_wdt";
reg = <0x200 0x100>;
};
i2c@3000 {
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
compatible = "fsl-i2c";
reg = <0x3000 0x100>;
interrupts = <14 0x8>;
interrupt-parent = <&ipic>;
dfsrr;
};
i2c@3100 {
#address-cells = <1>;
#size-cells = <0>;
cell-index = <1>;
compatible = "fsl-i2c";
reg = <0x3100 0x100>;
interrupts = <15 0x8>;
interrupt-parent = <&ipic>;
dfsrr;
};
spi@7000 {
cell-index = <0>;
compatible = "fsl,spi";
reg = <0x7000 0x1000>;
interrupts = <16 0x8>;
interrupt-parent = <&ipic>;
mode = "cpu";
};
dma@82a8 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,mpc8349-dma", "fsl,elo-dma";
reg = <0x82a8 4>;
ranges = <0 0x8100 0x1a8>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
cell-index = <0>;
dma-channel@0 {
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
reg = <0 0x80>;
cell-index = <0>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
};
dma-channel@80 {
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
reg = <0x80 0x80>;
cell-index = <1>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
};
dma-channel@100 {
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
reg = <0x100 0x80>;
cell-index = <2>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
};
dma-channel@180 {
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
reg = <0x180 0x28>;
cell-index = <3>;
interrupt-parent = <&ipic>;
interrupts = <71 8>;
};
};
/* phy type (ULPI or SERIAL) are only types supported for MPH */
/* port = 0 or 1 */
usb@22000 {
compatible = "fsl-usb2-mph";
reg = <0x22000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
interrupt-parent = <&ipic>;
interrupts = <39 0x8>;
phy_type = "ulpi";
port0;
};
enet0: ethernet@24000 {
#address-cells = <1>;
#size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <32 0x8 33 0x8 34 0x8>;
interrupt-parent = <&ipic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy0>;
linux,network-index = <0>;
mdio@520 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,gianfar-mdio";
reg = <0x520 0x20>;
phy0: ethernet-phy@19 {
interrupt-parent = <&ipic>;
interrupts = <20 0x8>;
reg = <0x19>;
};
phy1: ethernet-phy@1a {
interrupt-parent = <&ipic>;
interrupts = <21 0x8>;
reg = <0x1a>;
};
tbi0: tbi-phy@11 {
reg = <0x11>;
device_type = "tbi-phy";
};
};
};
enet1: ethernet@25000 {
#address-cells = <1>;
#size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 0x8 36 0x8 37 0x8>;
interrupt-parent = <&ipic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
linux,network-index = <1>;
mdio@520 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,gianfar-tbi";
reg = <0x520 0x20>;
tbi1: tbi-phy@11 {
reg = <0x11>;
device_type = "tbi-phy";
};
};
};
serial0: serial@4500 {
cell-index = <0>;
device_type = "serial";
compatible = "fsl,ns16550", "ns16550";
reg = <0x4500 0x100>;
clock-frequency = <0>;
interrupts = <9 0x8>;
interrupt-parent = <&ipic>;
};
serial1: serial@4600 {
cell-index = <1>;
device_type = "serial";
compatible = "fsl,ns16550", "ns16550";
reg = <0x4600 0x100>;
clock-frequency = <0>;
interrupts = <10 0x8>;
interrupt-parent = <&ipic>;
};
crypto@30000 {
compatible = "fsl,sec2.0";
reg = <0x30000 0x10000>;
interrupts = <11 0x8>;
interrupt-parent = <&ipic>;
fsl,num-channels = <4>;
fsl,channel-fifo-len = <24>;
fsl,exec-units-mask = <0x7e>;
fsl,descriptor-types-mask = <0x01010ebf>;
};
/* IPIC
* interrupts cell = <intr #, sense>
* sense values match linux IORESOURCE_IRQ_* defines:
* sense == 8: Level, low assertion
* sense == 2: Edge, high-to-low change
*/
ipic: pic@700 {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <2>;
reg = <0x700 0x100>;
device_type = "ipic";
};
};
localbus@e0005000 {
#address-cells = <2>;
#size-cells = <1>;
compatible = "fsl,mpc8349-localbus", "simple-bus";
reg = <0xe0005000 0x1000>;
interrupts = <77 0x8>;
interrupt-parent = <&ipic>;
ranges = <0x0 0x0 0xff800000 0x00800000 /* 8MB Flash */
0x1 0x0 0xf8000000 0x00002000 /* 8KB EEPROM */
0x2 0x0 0x10000000 0x04000000 /* 64MB SDRAM */
0x3 0x0 0x10000000 0x04000000>; /* 64MB SDRAM */
flash@0,0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "intel,28F640J3A", "cfi-flash";
reg = <0x0 0x0 0x800000>;
bank-width = <2>;
device-width = <1>;
partition@0 {
label = "u-boot";
reg = <0x00000000 0x00040000>;
read-only;
};
partition@40000 {
label = "user";
reg = <0x00040000 0x006c0000>;
};
partition@700000 {
label = "legacy u-boot";
reg = <0x00700000 0x00100000>;
read-only;
};
};
};
pci0: pci@e0008500 {
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x11 */
0x8800 0x0 0x0 0x1 &ipic 48 0x8
0x8800 0x0 0x0 0x2 &ipic 17 0x8
0x8800 0x0 0x0 0x3 &ipic 18 0x8
0x8800 0x0 0x0 0x4 &ipic 19 0x8>;
interrupt-parent = <&ipic>;
interrupts = <0x42 0x8>;
bus-range = <0 0>;
ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
clock-frequency = <66666666>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
reg = <0xe0008500 0x100 /* internal registers */
0xe0008300 0x8>; /* config space access registers */
compatible = "fsl,mpc8349-pci";
device_type = "pci";
};
};
......@@ -24,7 +24,7 @@ u32 mpc885_get_clock(u32 crystal)
{
u32 *immr;
u32 plprcr;
int mfi, mfn, mfd, pdf, div;
int mfi, mfn, mfd, pdf;
u32 ret;
immr = fsl_get_immr();
......@@ -43,7 +43,6 @@ u32 mpc885_get_clock(u32 crystal)
}
pdf = (plprcr >> 1) & 0xf;
div = (plprcr >> 20) & 3;
mfd = (plprcr >> 22) & 0x1f;
mfn = (plprcr >> 27) & 0x1f;
......
/*
* MPSC/UART driver for the Marvell mv64360, mv64460, ...
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
* 2007 (c) MontaVista Software, Inc. 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 MPSC_CHR_1 0x000c
#define MPSC_CHR_2 0x0010
#define MPSC_CHR_2_TA (1<<7)
#define MPSC_CHR_2_TCS (1<<9)
#define MPSC_CHR_2_RA (1<<23)
#define MPSC_CHR_2_CRD (1<<25)
#define MPSC_CHR_2_EH (1<<31)
#define MPSC_CHR_4 0x0018
#define MPSC_CHR_4_Z (1<<29)
#define MPSC_CHR_5 0x001c
#define MPSC_CHR_5_CTL1_INTR (1<<12)
#define MPSC_CHR_5_CTL1_VALID (1<<15)
#define MPSC_CHR_10 0x0030
#define MPSC_INTR_CAUSE 0x0000
#define MPSC_INTR_CAUSE_RCC (1<<6)
#define MPSC_INTR_MASK 0x0080
#define SDMA_SDCM 0x0008
#define SDMA_SDCM_AR (1<<15)
#define SDMA_SDCM_AT (1<<31)
static volatile char *mpsc_base;
static volatile char *mpscintr_base;
static u32 chr1, chr2;
static int mpsc_open(void)
{
chr1 = in_le32((u32 *)(mpsc_base + MPSC_CHR_1)) & 0x00ff0000;
chr2 = in_le32((u32 *)(mpsc_base + MPSC_CHR_2)) & ~(MPSC_CHR_2_TA
| MPSC_CHR_2_TCS | MPSC_CHR_2_RA | MPSC_CHR_2_CRD
| MPSC_CHR_2_EH);
out_le32((u32 *)(mpsc_base + MPSC_CHR_4), MPSC_CHR_4_Z);
out_le32((u32 *)(mpsc_base + MPSC_CHR_5),
MPSC_CHR_5_CTL1_INTR | MPSC_CHR_5_CTL1_VALID);
out_le32((u32 *)(mpsc_base + MPSC_CHR_2), chr2 | MPSC_CHR_2_EH);
return 0;
}
static void mpsc_putc(unsigned char c)
{
while (in_le32((u32 *)(mpsc_base + MPSC_CHR_2)) & MPSC_CHR_2_TCS);
out_le32((u32 *)(mpsc_base + MPSC_CHR_1), chr1 | c);
out_le32((u32 *)(mpsc_base + MPSC_CHR_2), chr2 | MPSC_CHR_2_TCS);
}
static unsigned char mpsc_getc(void)
{
u32 cause = 0;
unsigned char c;
while (!(cause & MPSC_INTR_CAUSE_RCC))
cause = in_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE));
c = in_8((u8 *)(mpsc_base + MPSC_CHR_10 + 2));
out_8((u8 *)(mpsc_base + MPSC_CHR_10 + 2), c);
out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE),
cause & ~MPSC_INTR_CAUSE_RCC);
return c;
}
static u8 mpsc_tstc(void)
{
return (u8)((in_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE))
& MPSC_INTR_CAUSE_RCC) != 0);
}
static void mpsc_stop_dma(volatile char *sdma_base)
{
out_le32((u32 *)(mpsc_base + MPSC_CHR_2),MPSC_CHR_2_TA | MPSC_CHR_2_RA);
out_le32((u32 *)(sdma_base + SDMA_SDCM), SDMA_SDCM_AR | SDMA_SDCM_AT);
while ((in_le32((u32 *)(sdma_base + SDMA_SDCM))
& (SDMA_SDCM_AR | SDMA_SDCM_AT)) != 0)
udelay(100);
}
static volatile char *mpsc_get_virtreg_of_phandle(void *devp, char *prop)
{
void *v;
int n;
n = getprop(devp, prop, &v, sizeof(v));
if (n != sizeof(v))
goto err_out;
devp = find_node_by_linuxphandle((u32)v);
if (devp == NULL)
goto err_out;
n = getprop(devp, "virtual-reg", &v, sizeof(v));
if (n == sizeof(v))
return v;
err_out:
return NULL;
}
int mpsc_console_init(void *devp, struct serial_console_data *scdp)
{
void *v;
int n, reg_set;
volatile char *sdma_base;
n = getprop(devp, "virtual-reg", &v, sizeof(v));
if (n != sizeof(v))
goto err_out;
mpsc_base = v;
sdma_base = mpsc_get_virtreg_of_phandle(devp, "sdma");
if (sdma_base == NULL)
goto err_out;
mpscintr_base = mpsc_get_virtreg_of_phandle(devp, "mpscintr");
if (mpscintr_base == NULL)
goto err_out;
n = getprop(devp, "cell-index", &v, sizeof(v));
if (n != sizeof(v))
goto err_out;
reg_set = (int)v;
mpscintr_base += (reg_set == 0) ? 0x4 : 0xc;
/* Make sure the mpsc ctlrs are shutdown */
out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), 0);
out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), 0);
out_le32((u32 *)(mpscintr_base + MPSC_INTR_MASK), 0);
out_le32((u32 *)(mpscintr_base + MPSC_INTR_MASK), 0);
mpsc_stop_dma(sdma_base);
scdp->open = mpsc_open;
scdp->putc = mpsc_putc;
scdp->getc = mpsc_getc;
scdp->tstc = mpsc_tstc;
scdp->close = NULL;
return 0;
err_out:
return -1;
}
/*
* Marvell hostbridge routines
*
* Author: Mark A. Greer <source@mvista.com>
*
* 2004, 2005, 2007 (c) MontaVista Software, Inc. 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 "elf.h"
#include "page.h"
#include "string.h"
#include "stdio.h"
#include "io.h"
#include "ops.h"
#include "mv64x60.h"
#define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
#define MV64x60_CPU2MEM_WINDOWS 4
#define MV64x60_CPU2MEM_0_BASE 0x0008
#define MV64x60_CPU2MEM_0_SIZE 0x0010
#define MV64x60_CPU2MEM_1_BASE 0x0208
#define MV64x60_CPU2MEM_1_SIZE 0x0210
#define MV64x60_CPU2MEM_2_BASE 0x0018
#define MV64x60_CPU2MEM_2_SIZE 0x0020
#define MV64x60_CPU2MEM_3_BASE 0x0218
#define MV64x60_CPU2MEM_3_SIZE 0x0220
#define MV64x60_ENET2MEM_BAR_ENABLE 0x2290
#define MV64x60_ENET2MEM_0_BASE 0x2200
#define MV64x60_ENET2MEM_0_SIZE 0x2204
#define MV64x60_ENET2MEM_1_BASE 0x2208
#define MV64x60_ENET2MEM_1_SIZE 0x220c
#define MV64x60_ENET2MEM_2_BASE 0x2210
#define MV64x60_ENET2MEM_2_SIZE 0x2214
#define MV64x60_ENET2MEM_3_BASE 0x2218
#define MV64x60_ENET2MEM_3_SIZE 0x221c
#define MV64x60_ENET2MEM_4_BASE 0x2220
#define MV64x60_ENET2MEM_4_SIZE 0x2224
#define MV64x60_ENET2MEM_5_BASE 0x2228
#define MV64x60_ENET2MEM_5_SIZE 0x222c
#define MV64x60_ENET2MEM_ACC_PROT_0 0x2294
#define MV64x60_ENET2MEM_ACC_PROT_1 0x2298
#define MV64x60_ENET2MEM_ACC_PROT_2 0x229c
#define MV64x60_MPSC2MEM_BAR_ENABLE 0xf250
#define MV64x60_MPSC2MEM_0_BASE 0xf200
#define MV64x60_MPSC2MEM_0_SIZE 0xf204
#define MV64x60_MPSC2MEM_1_BASE 0xf208
#define MV64x60_MPSC2MEM_1_SIZE 0xf20c
#define MV64x60_MPSC2MEM_2_BASE 0xf210
#define MV64x60_MPSC2MEM_2_SIZE 0xf214
#define MV64x60_MPSC2MEM_3_BASE 0xf218
#define MV64x60_MPSC2MEM_3_SIZE 0xf21c
#define MV64x60_MPSC_0_REMAP 0xf240
#define MV64x60_MPSC_1_REMAP 0xf244
#define MV64x60_MPSC2MEM_ACC_PROT_0 0xf254
#define MV64x60_MPSC2MEM_ACC_PROT_1 0xf258
#define MV64x60_MPSC2REGS_BASE 0xf25c
#define MV64x60_IDMA2MEM_BAR_ENABLE 0x0a80
#define MV64x60_IDMA2MEM_0_BASE 0x0a00
#define MV64x60_IDMA2MEM_0_SIZE 0x0a04
#define MV64x60_IDMA2MEM_1_BASE 0x0a08
#define MV64x60_IDMA2MEM_1_SIZE 0x0a0c
#define MV64x60_IDMA2MEM_2_BASE 0x0a10
#define MV64x60_IDMA2MEM_2_SIZE 0x0a14
#define MV64x60_IDMA2MEM_3_BASE 0x0a18
#define MV64x60_IDMA2MEM_3_SIZE 0x0a1c
#define MV64x60_IDMA2MEM_4_BASE 0x0a20
#define MV64x60_IDMA2MEM_4_SIZE 0x0a24
#define MV64x60_IDMA2MEM_5_BASE 0x0a28
#define MV64x60_IDMA2MEM_5_SIZE 0x0a2c
#define MV64x60_IDMA2MEM_6_BASE 0x0a30
#define MV64x60_IDMA2MEM_6_SIZE 0x0a34
#define MV64x60_IDMA2MEM_7_BASE 0x0a38
#define MV64x60_IDMA2MEM_7_SIZE 0x0a3c
#define MV64x60_IDMA2MEM_ACC_PROT_0 0x0a70
#define MV64x60_IDMA2MEM_ACC_PROT_1 0x0a74
#define MV64x60_IDMA2MEM_ACC_PROT_2 0x0a78
#define MV64x60_IDMA2MEM_ACC_PROT_3 0x0a7c
#define MV64x60_PCI_ACC_CNTL_WINDOWS 6
#define MV64x60_PCI0_PCI_DECODE_CNTL 0x0d3c
#define MV64x60_PCI1_PCI_DECODE_CNTL 0x0dbc
#define MV64x60_PCI0_BAR_ENABLE 0x0c3c
#define MV64x60_PCI02MEM_0_SIZE 0x0c08
#define MV64x60_PCI0_ACC_CNTL_0_BASE_LO 0x1e00
#define MV64x60_PCI0_ACC_CNTL_0_BASE_HI 0x1e04
#define MV64x60_PCI0_ACC_CNTL_0_SIZE 0x1e08
#define MV64x60_PCI0_ACC_CNTL_1_BASE_LO 0x1e10
#define MV64x60_PCI0_ACC_CNTL_1_BASE_HI 0x1e14
#define MV64x60_PCI0_ACC_CNTL_1_SIZE 0x1e18
#define MV64x60_PCI0_ACC_CNTL_2_BASE_LO 0x1e20
#define MV64x60_PCI0_ACC_CNTL_2_BASE_HI 0x1e24
#define MV64x60_PCI0_ACC_CNTL_2_SIZE 0x1e28
#define MV64x60_PCI0_ACC_CNTL_3_BASE_LO 0x1e30
#define MV64x60_PCI0_ACC_CNTL_3_BASE_HI 0x1e34
#define MV64x60_PCI0_ACC_CNTL_3_SIZE 0x1e38
#define MV64x60_PCI0_ACC_CNTL_4_BASE_LO 0x1e40
#define MV64x60_PCI0_ACC_CNTL_4_BASE_HI 0x1e44
#define MV64x60_PCI0_ACC_CNTL_4_SIZE 0x1e48
#define MV64x60_PCI0_ACC_CNTL_5_BASE_LO 0x1e50
#define MV64x60_PCI0_ACC_CNTL_5_BASE_HI 0x1e54
#define MV64x60_PCI0_ACC_CNTL_5_SIZE 0x1e58
#define MV64x60_PCI1_BAR_ENABLE 0x0cbc
#define MV64x60_PCI12MEM_0_SIZE 0x0c88
#define MV64x60_PCI1_ACC_CNTL_0_BASE_LO 0x1e80
#define MV64x60_PCI1_ACC_CNTL_0_BASE_HI 0x1e84
#define MV64x60_PCI1_ACC_CNTL_0_SIZE 0x1e88
#define MV64x60_PCI1_ACC_CNTL_1_BASE_LO 0x1e90
#define MV64x60_PCI1_ACC_CNTL_1_BASE_HI 0x1e94
#define MV64x60_PCI1_ACC_CNTL_1_SIZE 0x1e98
#define MV64x60_PCI1_ACC_CNTL_2_BASE_LO 0x1ea0
#define MV64x60_PCI1_ACC_CNTL_2_BASE_HI 0x1ea4
#define MV64x60_PCI1_ACC_CNTL_2_SIZE 0x1ea8
#define MV64x60_PCI1_ACC_CNTL_3_BASE_LO 0x1eb0
#define MV64x60_PCI1_ACC_CNTL_3_BASE_HI 0x1eb4
#define MV64x60_PCI1_ACC_CNTL_3_SIZE 0x1eb8
#define MV64x60_PCI1_ACC_CNTL_4_BASE_LO 0x1ec0
#define MV64x60_PCI1_ACC_CNTL_4_BASE_HI 0x1ec4
#define MV64x60_PCI1_ACC_CNTL_4_SIZE 0x1ec8
#define MV64x60_PCI1_ACC_CNTL_5_BASE_LO 0x1ed0
#define MV64x60_PCI1_ACC_CNTL_5_BASE_HI 0x1ed4
#define MV64x60_PCI1_ACC_CNTL_5_SIZE 0x1ed8
#define MV64x60_CPU2PCI_SWAP_NONE 0x01000000
#define MV64x60_CPU2PCI0_IO_BASE 0x0048
#define MV64x60_CPU2PCI0_IO_SIZE 0x0050
#define MV64x60_CPU2PCI0_IO_REMAP 0x00f0
#define MV64x60_CPU2PCI0_MEM_0_BASE 0x0058
#define MV64x60_CPU2PCI0_MEM_0_SIZE 0x0060
#define MV64x60_CPU2PCI0_MEM_0_REMAP_LO 0x00f8
#define MV64x60_CPU2PCI0_MEM_0_REMAP_HI 0x0320
#define MV64x60_CPU2PCI1_IO_BASE 0x0090
#define MV64x60_CPU2PCI1_IO_SIZE 0x0098
#define MV64x60_CPU2PCI1_IO_REMAP 0x0108
#define MV64x60_CPU2PCI1_MEM_0_BASE 0x00a0
#define MV64x60_CPU2PCI1_MEM_0_SIZE 0x00a8
#define MV64x60_CPU2PCI1_MEM_0_REMAP_LO 0x0110
#define MV64x60_CPU2PCI1_MEM_0_REMAP_HI 0x0340
struct mv64x60_mem_win {
u32 hi;
u32 lo;
u32 size;
};
struct mv64x60_pci_win {
u32 fcn;
u32 hi;
u32 lo;
u32 size;
};
/* PCI config access routines */
struct {
u32 addr;
u32 data;
} static mv64x60_pci_cfgio[2] = {
{ /* hose 0 */
.addr = 0xcf8,
.data = 0xcfc,
},
{ /* hose 1 */
.addr = 0xc78,
.data = 0xc7c,
}
};
u32 mv64x60_cfg_read(u8 *bridge_base, u8 hose, u8 bus, u8 devfn, u8 offset)
{
out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].addr),
(1 << 31) | (bus << 16) | (devfn << 8) | offset);
return in_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].data));
}
void mv64x60_cfg_write(u8 *bridge_base, u8 hose, u8 bus, u8 devfn, u8 offset,
u32 val)
{
out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].addr),
(1 << 31) | (bus << 16) | (devfn << 8) | offset);
out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].data), val);
}
/* I/O ctlr -> system memory setup */
static struct mv64x60_mem_win mv64x60_cpu2mem[MV64x60_CPU2MEM_WINDOWS] = {
{
.lo = MV64x60_CPU2MEM_0_BASE,
.size = MV64x60_CPU2MEM_0_SIZE,
},
{
.lo = MV64x60_CPU2MEM_1_BASE,
.size = MV64x60_CPU2MEM_1_SIZE,
},
{
.lo = MV64x60_CPU2MEM_2_BASE,
.size = MV64x60_CPU2MEM_2_SIZE,
},
{
.lo = MV64x60_CPU2MEM_3_BASE,
.size = MV64x60_CPU2MEM_3_SIZE,
},
};
static struct mv64x60_mem_win mv64x60_enet2mem[MV64x60_CPU2MEM_WINDOWS] = {
{
.lo = MV64x60_ENET2MEM_0_BASE,
.size = MV64x60_ENET2MEM_0_SIZE,
},
{
.lo = MV64x60_ENET2MEM_1_BASE,
.size = MV64x60_ENET2MEM_1_SIZE,
},
{
.lo = MV64x60_ENET2MEM_2_BASE,
.size = MV64x60_ENET2MEM_2_SIZE,
},
{
.lo = MV64x60_ENET2MEM_3_BASE,
.size = MV64x60_ENET2MEM_3_SIZE,
},
};
static struct mv64x60_mem_win mv64x60_mpsc2mem[MV64x60_CPU2MEM_WINDOWS] = {
{
.lo = MV64x60_MPSC2MEM_0_BASE,
.size = MV64x60_MPSC2MEM_0_SIZE,
},
{
.lo = MV64x60_MPSC2MEM_1_BASE,
.size = MV64x60_MPSC2MEM_1_SIZE,
},
{
.lo = MV64x60_MPSC2MEM_2_BASE,
.size = MV64x60_MPSC2MEM_2_SIZE,
},
{
.lo = MV64x60_MPSC2MEM_3_BASE,
.size = MV64x60_MPSC2MEM_3_SIZE,
},
};
static struct mv64x60_mem_win mv64x60_idma2mem[MV64x60_CPU2MEM_WINDOWS] = {
{
.lo = MV64x60_IDMA2MEM_0_BASE,
.size = MV64x60_IDMA2MEM_0_SIZE,
},
{
.lo = MV64x60_IDMA2MEM_1_BASE,
.size = MV64x60_IDMA2MEM_1_SIZE,
},
{
.lo = MV64x60_IDMA2MEM_2_BASE,
.size = MV64x60_IDMA2MEM_2_SIZE,
},
{
.lo = MV64x60_IDMA2MEM_3_BASE,
.size = MV64x60_IDMA2MEM_3_SIZE,
},
};
static u32 mv64x60_dram_selects[MV64x60_CPU2MEM_WINDOWS] = {0xe,0xd,0xb,0x7};
/*
* ENET, MPSC, and IDMA ctlrs on the MV64x60 have separate windows that
* must be set up so that the respective ctlr can access system memory.
* Configure them to be same as cpu->memory windows.
*/
void mv64x60_config_ctlr_windows(u8 *bridge_base, u8 *bridge_pbase,
u8 is_coherent)
{
u32 i, base, size, enables, prot = 0, snoop_bits = 0;
/* Disable ctlr->mem windows */
out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), 0x3f);
out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_BAR_ENABLE), 0xf);
out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), 0xff);
if (is_coherent)
snoop_bits = 0x2 << 12; /* Writeback */
enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE)) & 0xf;
for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
if (enables & (1 << i)) /* Set means disabled */
continue;
base = in_le32((u32 *)(bridge_base + mv64x60_cpu2mem[i].lo))
<< 16;
base |= snoop_bits | (mv64x60_dram_selects[i] << 8);
size = in_le32((u32 *)(bridge_base + mv64x60_cpu2mem[i].size))
<< 16;
prot |= (0x3 << (i << 1)); /* RW access */
out_le32((u32 *)(bridge_base + mv64x60_enet2mem[i].lo), base);
out_le32((u32 *)(bridge_base + mv64x60_enet2mem[i].size), size);
out_le32((u32 *)(bridge_base + mv64x60_mpsc2mem[i].lo), base);
out_le32((u32 *)(bridge_base + mv64x60_mpsc2mem[i].size), size);
out_le32((u32 *)(bridge_base + mv64x60_idma2mem[i].lo), base);
out_le32((u32 *)(bridge_base + mv64x60_idma2mem[i].size), size);
}
out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_0), prot);
out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_1), prot);
out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_2), prot);
out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_ACC_PROT_0), prot);
out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_ACC_PROT_1), prot);
out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_0), prot);
out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_1), prot);
out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_2), prot);
out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_3), prot);
/* Set mpsc->bridge's reg window to the bridge's internal registers. */
out_le32((u32 *)(bridge_base + MV64x60_MPSC2REGS_BASE),
(u32)bridge_pbase);
out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), enables);
out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_BAR_ENABLE), enables);
out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_BAR_ENABLE), enables);
}
/* PCI MEM -> system memory, et. al. setup */
static struct mv64x60_pci_win mv64x60_pci2mem[2] = {
{ /* hose 0 */
.fcn = 0,
.hi = 0x14,
.lo = 0x10,
.size = MV64x60_PCI02MEM_0_SIZE,
},
{ /* hose 1 */
.fcn = 0,
.hi = 0x94,
.lo = 0x90,
.size = MV64x60_PCI12MEM_0_SIZE,
},
};
static struct
mv64x60_mem_win mv64x60_pci_acc[2][MV64x60_PCI_ACC_CNTL_WINDOWS] = {
{ /* hose 0 */
{
.hi = MV64x60_PCI0_ACC_CNTL_0_BASE_HI,
.lo = MV64x60_PCI0_ACC_CNTL_0_BASE_LO,
.size = MV64x60_PCI0_ACC_CNTL_0_SIZE,
},
{
.hi = MV64x60_PCI0_ACC_CNTL_1_BASE_HI,
.lo = MV64x60_PCI0_ACC_CNTL_1_BASE_LO,
.size = MV64x60_PCI0_ACC_CNTL_1_SIZE,
},
{
.hi = MV64x60_PCI0_ACC_CNTL_2_BASE_HI,
.lo = MV64x60_PCI0_ACC_CNTL_2_BASE_LO,
.size = MV64x60_PCI0_ACC_CNTL_2_SIZE,
},
{
.hi = MV64x60_PCI0_ACC_CNTL_3_BASE_HI,
.lo = MV64x60_PCI0_ACC_CNTL_3_BASE_LO,
.size = MV64x60_PCI0_ACC_CNTL_3_SIZE,
},
},
{ /* hose 1 */
{
.hi = MV64x60_PCI1_ACC_CNTL_0_BASE_HI,
.lo = MV64x60_PCI1_ACC_CNTL_0_BASE_LO,
.size = MV64x60_PCI1_ACC_CNTL_0_SIZE,
},
{
.hi = MV64x60_PCI1_ACC_CNTL_1_BASE_HI,
.lo = MV64x60_PCI1_ACC_CNTL_1_BASE_LO,
.size = MV64x60_PCI1_ACC_CNTL_1_SIZE,
},
{
.hi = MV64x60_PCI1_ACC_CNTL_2_BASE_HI,
.lo = MV64x60_PCI1_ACC_CNTL_2_BASE_LO,
.size = MV64x60_PCI1_ACC_CNTL_2_SIZE,
},
{
.hi = MV64x60_PCI1_ACC_CNTL_3_BASE_HI,
.lo = MV64x60_PCI1_ACC_CNTL_3_BASE_LO,
.size = MV64x60_PCI1_ACC_CNTL_3_SIZE,
},
},
};
static struct mv64x60_mem_win mv64x60_pci2reg[2] = {
{
.hi = 0x24,
.lo = 0x20,
.size = 0,
},
{
.hi = 0xa4,
.lo = 0xa0,
.size = 0,
},
};
/* Only need to use 1 window (per hose) to get access to all of system memory */
void mv64x60_config_pci_windows(u8 *bridge_base, u8 *bridge_pbase, u8 hose,
u8 bus, u32 mem_size, u32 acc_bits)
{
u32 i, offset, bar_enable, enables;
/* Disable all windows but PCI MEM -> Bridge's regs window */
enables = ~(1 << 9);
bar_enable = hose ? MV64x60_PCI1_BAR_ENABLE : MV64x60_PCI0_BAR_ENABLE;
out_le32((u32 *)(bridge_base + bar_enable), enables);
for (i=0; i<MV64x60_PCI_ACC_CNTL_WINDOWS; i++)
out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][i].lo), 0);
/* If mem_size is 0, leave windows disabled */
if (mem_size == 0)
return;
/* Cause automatic updates of PCI remap regs */
offset = hose ?
MV64x60_PCI1_PCI_DECODE_CNTL : MV64x60_PCI0_PCI_DECODE_CNTL;
i = in_le32((u32 *)(bridge_base + offset));
out_le32((u32 *)(bridge_base + offset), i & ~0x1);
mem_size = (mem_size - 1) & 0xfffff000;
/* Map PCI MEM addr 0 -> System Mem addr 0 */
mv64x60_cfg_write(bridge_base, hose, bus,
PCI_DEVFN(0, mv64x60_pci2mem[hose].fcn),
mv64x60_pci2mem[hose].hi, 0);
mv64x60_cfg_write(bridge_base, hose, bus,
PCI_DEVFN(0, mv64x60_pci2mem[hose].fcn),
mv64x60_pci2mem[hose].lo, 0);
out_le32((u32 *)(bridge_base + mv64x60_pci2mem[hose].size),mem_size);
acc_bits |= MV64x60_PCI_ACC_CNTL_ENABLE;
out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].hi), 0);
out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].lo), acc_bits);
out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].size),mem_size);
/* Set PCI MEM->bridge's reg window to where they are in CPU mem map */
i = (u32)bridge_base;
i &= 0xffff0000;
i |= (0x2 << 1);
mv64x60_cfg_write(bridge_base, hose, bus, PCI_DEVFN(0,0),
mv64x60_pci2reg[hose].hi, 0);
mv64x60_cfg_write(bridge_base, hose, bus, PCI_DEVFN(0,0),
mv64x60_pci2reg[hose].lo, i);
enables &= ~0x1; /* Enable PCI MEM -> System Mem window 0 */
out_le32((u32 *)(bridge_base + bar_enable), enables);
}
/* CPU -> PCI I/O & MEM setup */
struct mv64x60_cpu2pci_win mv64x60_cpu2pci_io[2] = {
{ /* hose 0 */
.lo = MV64x60_CPU2PCI0_IO_BASE,
.size = MV64x60_CPU2PCI0_IO_SIZE,
.remap_hi = 0,
.remap_lo = MV64x60_CPU2PCI0_IO_REMAP,
},
{ /* hose 1 */
.lo = MV64x60_CPU2PCI1_IO_BASE,
.size = MV64x60_CPU2PCI1_IO_SIZE,
.remap_hi = 0,
.remap_lo = MV64x60_CPU2PCI1_IO_REMAP,
},
};
struct mv64x60_cpu2pci_win mv64x60_cpu2pci_mem[2] = {
{ /* hose 0 */
.lo = MV64x60_CPU2PCI0_MEM_0_BASE,
.size = MV64x60_CPU2PCI0_MEM_0_SIZE,
.remap_hi = MV64x60_CPU2PCI0_MEM_0_REMAP_HI,
.remap_lo = MV64x60_CPU2PCI0_MEM_0_REMAP_LO,
},
{ /* hose 1 */
.lo = MV64x60_CPU2PCI1_MEM_0_BASE,
.size = MV64x60_CPU2PCI1_MEM_0_SIZE,
.remap_hi = MV64x60_CPU2PCI1_MEM_0_REMAP_HI,
.remap_lo = MV64x60_CPU2PCI1_MEM_0_REMAP_LO,
},
};
/* Only need to set up 1 window to pci mem space */
void mv64x60_config_cpu2pci_window(u8 *bridge_base, u8 hose, u32 pci_base_hi,
u32 pci_base_lo, u32 cpu_base, u32 size,
struct mv64x60_cpu2pci_win *offset_tbl)
{
cpu_base >>= 16;
cpu_base |= MV64x60_CPU2PCI_SWAP_NONE;
out_le32((u32 *)(bridge_base + offset_tbl[hose].lo), cpu_base);
if (offset_tbl[hose].remap_hi != 0)
out_le32((u32 *)(bridge_base + offset_tbl[hose].remap_hi),
pci_base_hi);
out_le32((u32 *)(bridge_base + offset_tbl[hose].remap_lo),
pci_base_lo >> 16);
size = (size - 1) >> 16;
out_le32((u32 *)(bridge_base + offset_tbl[hose].size), size);
}
/* Read mem ctlr to get the amount of mem in system */
u32 mv64x60_get_mem_size(u8 *bridge_base)
{
u32 enables, i, v;
u32 mem = 0;
enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE)) & 0xf;
for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++)
if (!(enables & (1<<i))) {
v = in_le32((u32*)(bridge_base
+ mv64x60_cpu2mem[i].size));
v = ((v & 0xffff) + 1) << 16;
mem += v;
}
return mem;
}
/* Get physical address of bridge's registers */
u8 *mv64x60_get_bridge_pbase(void)
{
u32 v[2];
void *devp;
devp = find_node_by_compatible(NULL, "marvell,mv64360");
if (devp == NULL)
goto err_out;
if (getprop(devp, "reg", v, sizeof(v)) != sizeof(v))
goto err_out;
return (u8 *)v[0];
err_out:
return 0;
}
/* Get virtual address of bridge's registers */
u8 *mv64x60_get_bridge_base(void)
{
u32 v;
void *devp;
devp = find_node_by_compatible(NULL, "marvell,mv64360");
if (devp == NULL)
goto err_out;
if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v))
goto err_out;
return (u8 *)v;
err_out:
return 0;
}
u8 mv64x60_is_coherent(void)
{
u32 v;
void *devp;
devp = finddevice("/");
if (devp == NULL)
return 1; /* Assume coherency on */
if (getprop(devp, "coherency-off", &v, sizeof(v)) < 0)
return 1; /* Coherency on */
else
return 0;
}
/*
* Author: Mark A. Greer <source@mvista.com>
*
* 2007 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef _PPC_BOOT_MV64x60_H_
#define _PPC_BOOT_MV64x60_H_
#define MV64x60_CPU_BAR_ENABLE 0x0278
#define MV64x60_PCI_ACC_CNTL_ENABLE (1<<0)
#define MV64x60_PCI_ACC_CNTL_REQ64 (1<<1)
#define MV64x60_PCI_ACC_CNTL_SNOOP_NONE 0x00000000
#define MV64x60_PCI_ACC_CNTL_SNOOP_WT 0x00000004
#define MV64x60_PCI_ACC_CNTL_SNOOP_WB 0x00000008
#define MV64x60_PCI_ACC_CNTL_SNOOP_MASK 0x0000000c
#define MV64x60_PCI_ACC_CNTL_ACCPROT (1<<4)
#define MV64x60_PCI_ACC_CNTL_WRPROT (1<<5)
#define MV64x60_PCI_ACC_CNTL_SWAP_BYTE 0x00000000
#define MV64x60_PCI_ACC_CNTL_SWAP_NONE 0x00000040
#define MV64x60_PCI_ACC_CNTL_SWAP_BYTE_WORD 0x00000080
#define MV64x60_PCI_ACC_CNTL_SWAP_WORD 0x000000c0
#define MV64x60_PCI_ACC_CNTL_SWAP_MASK 0x000000c0
#define MV64x60_PCI_ACC_CNTL_MBURST_32_BYTES 0x00000000
#define MV64x60_PCI_ACC_CNTL_MBURST_64_BYTES 0x00000100
#define MV64x60_PCI_ACC_CNTL_MBURST_128_BYTES 0x00000200
#define MV64x60_PCI_ACC_CNTL_MBURST_MASK 0x00000300
#define MV64x60_PCI_ACC_CNTL_RDSIZE_32_BYTES 0x00000000
#define MV64x60_PCI_ACC_CNTL_RDSIZE_64_BYTES 0x00000400
#define MV64x60_PCI_ACC_CNTL_RDSIZE_128_BYTES 0x00000800
#define MV64x60_PCI_ACC_CNTL_RDSIZE_256_BYTES 0x00000c00
#define MV64x60_PCI_ACC_CNTL_RDSIZE_MASK 0x00000c00
struct mv64x60_cpu2pci_win {
u32 lo;
u32 size;
u32 remap_hi;
u32 remap_lo;
};
extern struct mv64x60_cpu2pci_win mv64x60_cpu2pci_io[2];
extern struct mv64x60_cpu2pci_win mv64x60_cpu2pci_mem[2];
u32 mv64x60_cfg_read(u8 *bridge_base, u8 hose, u8 bus, u8 devfn,
u8 offset);
void mv64x60_cfg_write(u8 *bridge_base, u8 hose, u8 bus, u8 devfn,
u8 offset, u32 val);
void mv64x60_config_ctlr_windows(u8 *bridge_base, u8 *bridge_pbase,
u8 is_coherent);
void mv64x60_config_pci_windows(u8 *bridge_base, u8 *bridge_pbase, u8 hose,
u8 bus, u32 mem_size, u32 acc_bits);
void mv64x60_config_cpu2pci_window(u8 *bridge_base, u8 hose, u32 pci_base_hi,
u32 pci_base_lo, u32 cpu_base, u32 size,
struct mv64x60_cpu2pci_win *offset_tbl);
u32 mv64x60_get_mem_size(u8 *bridge_base);
u8 *mv64x60_get_bridge_pbase(void);
u8 *mv64x60_get_bridge_base(void);
u8 mv64x60_is_coherent(void);
int mv64x60_i2c_open(void);
int mv64x60_i2c_read(u32 devaddr, u8 *buf, u32 offset, u32 offset_size,
u32 count);
void mv64x60_i2c_close(void);
#endif /* _PPC_BOOT_MV64x60_H_ */
/*
* Bootloader version of the i2c driver for the MV64x60.
*
* Author: Dale Farnsworth <dfarnsworth@mvista.com>
* Maintained by: Mark A. Greer <mgreer@mvista.com>
*
* 2003, 2007 (c) MontaVista, Software, Inc. 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 "elf.h"
#include "page.h"
#include "string.h"
#include "stdio.h"
#include "io.h"
#include "ops.h"
#include "mv64x60.h"
/* Register defines */
#define MV64x60_I2C_REG_SLAVE_ADDR 0x00
#define MV64x60_I2C_REG_DATA 0x04
#define MV64x60_I2C_REG_CONTROL 0x08
#define MV64x60_I2C_REG_STATUS 0x0c
#define MV64x60_I2C_REG_BAUD 0x0c
#define MV64x60_I2C_REG_EXT_SLAVE_ADDR 0x10
#define MV64x60_I2C_REG_SOFT_RESET 0x1c
#define MV64x60_I2C_CONTROL_ACK 0x04
#define MV64x60_I2C_CONTROL_IFLG 0x08
#define MV64x60_I2C_CONTROL_STOP 0x10
#define MV64x60_I2C_CONTROL_START 0x20
#define MV64x60_I2C_CONTROL_TWSIEN 0x40
#define MV64x60_I2C_CONTROL_INTEN 0x80
#define MV64x60_I2C_STATUS_BUS_ERR 0x00
#define MV64x60_I2C_STATUS_MAST_START 0x08
#define MV64x60_I2C_STATUS_MAST_REPEAT_START 0x10
#define MV64x60_I2C_STATUS_MAST_WR_ADDR_ACK 0x18
#define MV64x60_I2C_STATUS_MAST_WR_ADDR_NO_ACK 0x20
#define MV64x60_I2C_STATUS_MAST_WR_ACK 0x28
#define MV64x60_I2C_STATUS_MAST_WR_NO_ACK 0x30
#define MV64x60_I2C_STATUS_MAST_LOST_ARB 0x38
#define MV64x60_I2C_STATUS_MAST_RD_ADDR_ACK 0x40
#define MV64x60_I2C_STATUS_MAST_RD_ADDR_NO_ACK 0x48
#define MV64x60_I2C_STATUS_MAST_RD_DATA_ACK 0x50
#define MV64x60_I2C_STATUS_MAST_RD_DATA_NO_ACK 0x58
#define MV64x60_I2C_STATUS_MAST_WR_ADDR_2_ACK 0xd0
#define MV64x60_I2C_STATUS_MAST_WR_ADDR_2_NO_ACK 0xd8
#define MV64x60_I2C_STATUS_MAST_RD_ADDR_2_ACK 0xe0
#define MV64x60_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK 0xe8
#define MV64x60_I2C_STATUS_NO_STATUS 0xf8
static u8 *ctlr_base;
static int mv64x60_i2c_wait_for_status(int wanted)
{
int i;
int status;
for (i=0; i<1000; i++) {
udelay(10);
status = in_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_STATUS))
& 0xff;
if (status == wanted)
return status;
}
return -status;
}
static int mv64x60_i2c_control(int control, int status)
{
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control & 0xff);
return mv64x60_i2c_wait_for_status(status);
}
static int mv64x60_i2c_read_byte(int control, int status)
{
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control & 0xff);
if (mv64x60_i2c_wait_for_status(status) < 0)
return -1;
return in_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_DATA)) & 0xff;
}
static int mv64x60_i2c_write_byte(int data, int control, int status)
{
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_DATA), data & 0xff);
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control & 0xff);
return mv64x60_i2c_wait_for_status(status);
}
int mv64x60_i2c_read(u32 devaddr, u8 *buf, u32 offset, u32 offset_size,
u32 count)
{
int i;
int data;
int control;
int status;
if (ctlr_base == NULL)
return -1;
/* send reset */
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_SOFT_RESET), 0);
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_SLAVE_ADDR), 0);
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_EXT_SLAVE_ADDR), 0);
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_BAUD), (4 << 3) | 0x4);
if (mv64x60_i2c_control(MV64x60_I2C_CONTROL_TWSIEN,
MV64x60_I2C_STATUS_NO_STATUS) < 0)
return -1;
/* send start */
control = MV64x60_I2C_CONTROL_START | MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_MAST_START;
if (mv64x60_i2c_control(control, status) < 0)
return -1;
/* select device for writing */
data = devaddr & ~0x1;
control = MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_MAST_WR_ADDR_ACK;
if (mv64x60_i2c_write_byte(data, control, status) < 0)
return -1;
/* send offset of data */
control = MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_MAST_WR_ACK;
if (offset_size > 1) {
if (mv64x60_i2c_write_byte(offset >> 8, control, status) < 0)
return -1;
}
if (mv64x60_i2c_write_byte(offset, control, status) < 0)
return -1;
/* resend start */
control = MV64x60_I2C_CONTROL_START | MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_MAST_REPEAT_START;
if (mv64x60_i2c_control(control, status) < 0)
return -1;
/* select device for reading */
data = devaddr | 0x1;
control = MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_MAST_RD_ADDR_ACK;
if (mv64x60_i2c_write_byte(data, control, status) < 0)
return -1;
/* read all but last byte of data */
control = MV64x60_I2C_CONTROL_ACK | MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_MAST_RD_DATA_ACK;
for (i=1; i<count; i++) {
data = mv64x60_i2c_read_byte(control, status);
if (data < 0) {
printf("errors on iteration %d\n", i);
return -1;
}
*buf++ = data;
}
/* read last byte of data */
control = MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_MAST_RD_DATA_NO_ACK;
data = mv64x60_i2c_read_byte(control, status);
if (data < 0)
return -1;
*buf++ = data;
/* send stop */
control = MV64x60_I2C_CONTROL_STOP | MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_NO_STATUS;
if (mv64x60_i2c_control(control, status) < 0)
return -1;
return count;
}
int mv64x60_i2c_open(void)
{
u32 v;
void *devp;
devp = find_node_by_compatible(NULL, "marvell,mv64360-i2c");
if (devp == NULL)
goto err_out;
if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v))
goto err_out;
ctlr_base = (u8 *)v;
return 0;
err_out:
return -1;
}
void mv64x60_i2c_close(void)
{
ctlr_base = NULL;
}
......@@ -86,7 +86,6 @@ void start(void);
void fdt_init(void *blob);
int serial_console_init(void);
int ns16550_console_init(void *devp, struct serial_console_data *scdp);
int mpsc_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);
......
......@@ -120,10 +120,6 @@ int serial_console_init(void)
if (dt_is_compatible(devp, "ns16550") ||
dt_is_compatible(devp, "pnpPNP,501"))
rc = ns16550_console_init(devp, &serial_cd);
#ifdef CONFIG_EMBEDDED6xx
else if (dt_is_compatible(devp, "marvell,mv64360-mpsc"))
rc = mpsc_console_init(devp, &serial_cd);
#endif
#ifdef CONFIG_CPM
else if (dt_is_compatible(devp, "fsl,cpm1-scc-uart") ||
dt_is_compatible(devp, "fsl,cpm1-smc-uart") ||
......
CONFIG_SYSVIPC=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
# CONFIG_KALLSYMS is not set
CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_PPC_CHRP is not set
# CONFIG_PPC_PMAC is not set
CONFIG_PPC_83xx=y
CONFIG_SBC834x=y
CONFIG_GEN_RTC=y
CONFIG_PCI=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_XFRM_USER=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_SYN_COOKIES=y
# CONFIG_IPV6 is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=32768
CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_LOWLEVEL is not set
CONFIG_NETDEVICES=y
CONFIG_GIANFAR=y
CONFIG_BROADCOM_PHY=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE 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_PCI is not set
CONFIG_SERIAL_8250_NR_UARTS=2
CONFIG_SERIAL_8250_RUNTIME_UARTS=2
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MPC=y
CONFIG_WATCHDOG=y
# CONFIG_USB_HID is not set
CONFIG_USB=y
CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_FSL=y
CONFIG_USB_STORAGE=y
CONFIG_EXT2_FS=y
CONFIG_EXT4_FS=y
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_HW is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_AUDIT=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
CONFIG_KPROBES=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_OSF_PARTITION=y
CONFIG_MAC_PARTITION=y
CONFIG_BSD_DISKLABEL=y
CONFIG_MINIX_SUBPARTITION=y
CONFIG_SOLARIS_X86_PARTITION=y
CONFIG_UNIXWARE_DISKLABEL=y
CONFIG_SGI_PARTITION=y
CONFIG_SUN_PARTITION=y
# CONFIG_PPC_CHRP is not set
# CONFIG_PPC_PMAC is not set
CONFIG_EMBEDDED6xx=y
CONFIG_PPC_C2K=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_ONDEMAND=m
CONFIG_GEN_RTC=y
CONFIG_HIGHMEM=y
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_BINFMT_MISC=y
CONFIG_PM=y
CONFIG_PCI_MSI=y
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_SHPC=m
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_XFRM_USER=y
CONFIG_NET_KEY=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_NET_IPIP=m
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_SYN_COOKIES=y
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_ECN=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_MATCH_FRAG=m
CONFIG_IP6_NF_MATCH_OPTS=m
CONFIG_IP6_NF_MATCH_HL=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_MATCH_RT=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_RAW=m
CONFIG_BRIDGE_NF_EBTABLES=m
CONFIG_BRIDGE_EBT_BROUTE=m
CONFIG_BRIDGE_EBT_T_FILTER=m
CONFIG_BRIDGE_EBT_T_NAT=m
CONFIG_BRIDGE_EBT_802_3=m
CONFIG_BRIDGE_EBT_AMONG=m
CONFIG_BRIDGE_EBT_ARP=m
CONFIG_BRIDGE_EBT_IP=m
CONFIG_BRIDGE_EBT_LIMIT=m
CONFIG_BRIDGE_EBT_MARK=m
CONFIG_BRIDGE_EBT_PKTTYPE=m
CONFIG_BRIDGE_EBT_STP=m
CONFIG_BRIDGE_EBT_VLAN=m
CONFIG_BRIDGE_EBT_ARPREPLY=m
CONFIG_BRIDGE_EBT_DNAT=m
CONFIG_BRIDGE_EBT_MARK_T=m
CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_LOG=m
CONFIG_IP_SCTP=m
CONFIG_ATM=m
CONFIG_ATM_CLIP=m
CONFIG_ATM_LANE=m
CONFIG_ATM_BR2684=m
CONFIG_BRIDGE=m
CONFIG_VLAN_8021Q=m
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CBQ=m
CONFIG_NET_SCH_HTB=m
CONFIG_NET_SCH_HFSC=m
CONFIG_NET_SCH_ATM=m
CONFIG_NET_SCH_PRIO=m
CONFIG_NET_SCH_RED=m
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_SCH_TEQL=m
CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_GRED=m
CONFIG_NET_SCH_DSMARK=m
CONFIG_NET_SCH_NETEM=m
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
CONFIG_CLS_U32_PERF=y
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
CONFIG_NET_CLS_IND=y
CONFIG_BT=m
CONFIG_BT_RFCOMM=m
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=m
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_HIDP=m
CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_H4=y
CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBFUSB=m
CONFIG_BT_HCIVHCI=m
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_MTD=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=16384
CONFIG_SCSI=m
CONFIG_BLK_DEV_SD=m
CONFIG_CHR_DEV_ST=m
CONFIG_CHR_DEV_OSST=m
CONFIG_BLK_DEV_SR=m
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=m
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_ISCSI_ATTRS=m
CONFIG_BLK_DEV_3W_XXXX_RAID=m
CONFIG_SCSI_3W_9XXX=m
CONFIG_SCSI_ACARD=m
CONFIG_SCSI_AACRAID=m
CONFIG_SCSI_AIC7XXX=m
CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
CONFIG_AIC7XXX_RESET_DELAY_MS=15000
# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
CONFIG_SCSI_AIC79XX=m
CONFIG_AIC79XX_CMDS_PER_DEVICE=4
CONFIG_AIC79XX_RESET_DELAY_MS=15000
# CONFIG_AIC79XX_DEBUG_ENABLE is not set
# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
CONFIG_SCSI_ARCMSR=m
CONFIG_MEGARAID_NEWGEN=y
CONFIG_MEGARAID_MM=m
CONFIG_MEGARAID_MAILBOX=m
CONFIG_MEGARAID_SAS=m
CONFIG_SCSI_GDTH=m
CONFIG_SCSI_IPS=m
CONFIG_SCSI_INITIO=m
CONFIG_SCSI_SYM53C8XX_2=m
CONFIG_SCSI_QLOGIC_1280=m
CONFIG_NETDEVICES=y
CONFIG_BONDING=m
CONFIG_DUMMY=m
CONFIG_NETCONSOLE=m
CONFIG_TUN=m
# CONFIG_ATM_DRIVERS is not set
CONFIG_MV643XX_ETH=y
CONFIG_VITESSE_PHY=y
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=m
# CONFIG_SERIO is not set
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_NONSTANDARD=y
CONFIG_SERIAL_MPSC=y
CONFIG_SERIAL_MPSC_CONSOLE=y
CONFIG_NVRAM=m
CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=8192
CONFIG_I2C=m
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_MV64XXX=m
CONFIG_HWMON=m
CONFIG_SENSORS_ADM1021=m
CONFIG_SENSORS_ADM1025=m
CONFIG_SENSORS_ADM1026=m
CONFIG_SENSORS_ADM1031=m
CONFIG_SENSORS_DS1621=m
CONFIG_SENSORS_GL518SM=m
CONFIG_SENSORS_MAX1619=m
CONFIG_SENSORS_LM75=m
CONFIG_SENSORS_LM77=m
CONFIG_SENSORS_LM78=m
CONFIG_SENSORS_LM80=m
CONFIG_SENSORS_LM83=m
CONFIG_SENSORS_LM85=m
CONFIG_SENSORS_LM87=m
CONFIG_SENSORS_LM90=m
CONFIG_SENSORS_PCF8591=m
CONFIG_SENSORS_VIA686A=m
CONFIG_SENSORS_W83781D=m
CONFIG_SENSORS_W83L785TS=m
CONFIG_WATCHDOG=y
CONFIG_SOFT_WATCHDOG=m
CONFIG_PCIPCWATCHDOG=m
CONFIG_WDTPCI=m
CONFIG_USBPCWATCHDOG=m
# CONFIG_VGA_CONSOLE is not set
CONFIG_USB=m
CONFIG_USB_MON=m
CONFIG_USB_EHCI_HCD=m
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_OHCI_HCD=m
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
CONFIG_USB_UHCI_HCD=m
CONFIG_USB_ACM=m
CONFIG_USB_PRINTER=m
CONFIG_USB_STORAGE=m
CONFIG_USB_STORAGE_DATAFAB=m
CONFIG_USB_STORAGE_FREECOM=m
CONFIG_USB_STORAGE_ISD200=m
CONFIG_USB_STORAGE_SDDR09=m
CONFIG_USB_STORAGE_SDDR55=m
CONFIG_USB_STORAGE_JUMPSHOT=m
CONFIG_USB_MDC800=m
CONFIG_USB_MICROTEK=m
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_BELKIN=m
CONFIG_USB_SERIAL_WHITEHEAT=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
CONFIG_USB_SERIAL_VISOR=m
CONFIG_USB_SERIAL_IPAQ=m
CONFIG_USB_SERIAL_IR=m
CONFIG_USB_SERIAL_EDGEPORT=m
CONFIG_USB_SERIAL_EDGEPORT_TI=m
CONFIG_USB_SERIAL_KEYSPAN_PDA=m
CONFIG_USB_SERIAL_KEYSPAN=m
CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
CONFIG_USB_SERIAL_PL2303=m
CONFIG_USB_SERIAL_SAFE=m
CONFIG_USB_SERIAL_SAFE_PADDED=y
CONFIG_USB_SERIAL_CYBERJACK=m
CONFIG_USB_SERIAL_XIRCOM=m
CONFIG_USB_SERIAL_OMNINET=m
CONFIG_USB_EMI62=m
CONFIG_USB_RIO500=m
CONFIG_USB_LEGOTOWER=m
CONFIG_USB_LCD=m
CONFIG_USB_LED=m
CONFIG_USB_TEST=m
CONFIG_USB_ATM=m
CONFIG_USB_SPEEDTOUCH=m
CONFIG_INFINIBAND=m
CONFIG_INFINIBAND_USER_MAD=m
CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_INFINIBAND_MTHCA=m
CONFIG_INFINIBAND_IPOIB=m
CONFIG_INFINIBAND_IPOIB_CM=y
CONFIG_INFINIBAND_SRP=m
CONFIG_DMADEVICES=y
CONFIG_EXT4_FS=m
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_QUOTA=y
CONFIG_QFMT_V2=y
CONFIG_AUTOFS4_FS=m
CONFIG_UDF_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_HFS_FS=m
CONFIG_HFSPLUS_FS=m
CONFIG_JFFS2_FS=y
CONFIG_CRAMFS=m
CONFIG_VXFS_FS=m
CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_CIFS=m
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="utf8"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
CONFIG_NLS_CODEPAGE_850=m
CONFIG_NLS_CODEPAGE_852=m
CONFIG_NLS_CODEPAGE_855=m
CONFIG_NLS_CODEPAGE_857=m
CONFIG_NLS_CODEPAGE_860=m
CONFIG_NLS_CODEPAGE_861=m
CONFIG_NLS_CODEPAGE_862=m
CONFIG_NLS_CODEPAGE_863=m
CONFIG_NLS_CODEPAGE_864=m
CONFIG_NLS_CODEPAGE_865=m
CONFIG_NLS_CODEPAGE_866=m
CONFIG_NLS_CODEPAGE_869=m
CONFIG_NLS_CODEPAGE_936=m
CONFIG_NLS_CODEPAGE_950=m
CONFIG_NLS_CODEPAGE_932=m
CONFIG_NLS_CODEPAGE_949=m
CONFIG_NLS_CODEPAGE_874=m
CONFIG_NLS_ISO8859_8=m
CONFIG_NLS_CODEPAGE_1250=m
CONFIG_NLS_CODEPAGE_1251=m
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_ISO8859_2=m
CONFIG_NLS_ISO8859_3=m
CONFIG_NLS_ISO8859_4=m
CONFIG_NLS_ISO8859_5=m
CONFIG_NLS_ISO8859_6=m
CONFIG_NLS_ISO8859_7=m
CONFIG_NLS_ISO8859_9=m
CONFIG_NLS_ISO8859_13=m
CONFIG_NLS_ISO8859_14=m
CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_CRC_CCITT=m
CONFIG_CRC_T10DIF=m
CONFIG_DEBUG_INFO=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_HIGHMEM=y
CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_BOOTX_TEXT=y
CONFIG_PPC_EARLY_DEBUG=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
......@@ -38,7 +38,9 @@ CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_SCOM_DEBUGFS=y
CONFIG_OPAL_PRD=y
CONFIG_PPC_MEMTRACE=y
# CONFIG_PPC_PSERIES is not set
# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
......@@ -54,7 +56,10 @@ CONFIG_NUMA=y
CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_KSM=y
CONFIG_MEMORY_FAILURE=y
CONFIG_HWPOISON_INJECT=m
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
CONFIG_PPC_64K_PAGES=y
CONFIG_PPC_SUBPAGE_PROT=y
CONFIG_SCHED_SMT=y
......@@ -72,7 +77,13 @@ CONFIG_SYN_COOKIES=y
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
# CONFIG_IPV6 is not set
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
CONFIG_INET6_XFRM_MODE_TRANSPORT=m
CONFIG_INET6_XFRM_MODE_TUNNEL=m
CONFIG_INET6_XFRM_MODE_BEET=m
CONFIG_IPV6_SIT=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_ADVANCED is not set
CONFIG_BRIDGE=m
......@@ -81,33 +92,28 @@ CONFIG_NET_SCHED=y
CONFIG_NET_CLS_BPF=m
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_BPF=m
CONFIG_DNS_RESOLVER=y
CONFIG_BPF_JIT=y
# CONFIG_WIRELESS is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_MTD=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_POWERNV_FLASH=y
CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
CONFIG_BLK_DEV_FD=m
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM=m
CONFIG_BLK_DEV_RAM_SIZE=65536
CONFIG_VIRTIO_BLK=m
CONFIG_BLK_DEV_NVME=y
CONFIG_IDE=y
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_GENERIC=y
CONFIG_BLK_DEV_AMD74XX=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR=m
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=y
CONFIG_CHR_DEV_SG=m
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_FC_ATTRS=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_FC_ATTRS=m
CONFIG_SCSI_SRP_ATTRS=y
CONFIG_SCSI_CXGB3_ISCSI=m
CONFIG_SCSI_CXGB4_ISCSI=m
......@@ -121,7 +127,6 @@ CONFIG_SCSI_IPR=y
CONFIG_SCSI_QLA_FC=m
CONFIG_SCSI_QLA_ISCSI=m
CONFIG_SCSI_LPFC=m
CONFIG_SCSI_VIRTIO=m
CONFIG_SCSI_DH=y
CONFIG_SCSI_DH_RDAC=m
CONFIG_SCSI_DH_ALUA=m
......@@ -152,16 +157,16 @@ CONFIG_DUMMY=m
CONFIG_MACVLAN=m
CONFIG_MACVTAP=m
CONFIG_VXLAN=m
CONFIG_NETCONSOLE=y
CONFIG_NETCONSOLE=m
CONFIG_TUN=m
CONFIG_VETH=m
CONFIG_VIRTIO_NET=m
CONFIG_VORTEX=m
CONFIG_ACENIC=m
CONFIG_ACENIC_OMIT_TIGON_I=y
CONFIG_PCNET32=m
CONFIG_TIGON3=y
CONFIG_BNX2X=m
# CONFIG_CAVIUM_PTP is not set
CONFIG_CHELSIO_T1=m
CONFIG_BE2NET=m
CONFIG_S2IO=m
......@@ -172,46 +177,62 @@ CONFIG_IXGB=m
CONFIG_IXGBE=m
CONFIG_I40E=m
CONFIG_MLX4_EN=m
CONFIG_MLX5_CORE=m
CONFIG_MLX5_FPGA=y
CONFIG_MLX5_CORE_EN=y
CONFIG_MLX5_CORE_IPOIB=y
CONFIG_MYRI10GE=m
CONFIG_QLGE=m
CONFIG_NETXEN_NIC=m
CONFIG_PPP=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_DEFLATE=m
CONFIG_PPPOE=m
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_USB_NET_DRIVERS=m
# CONFIG_WLAN is not set
CONFIG_INPUT_EVDEV=m
CONFIG_INPUT_MISC=y
# CONFIG_SERIO_SERPORT is not set
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_PCI=m
CONFIG_SERIAL_JSM=m
CONFIG_VIRTIO_CONSOLE=m
CONFIG_IPMI_HANDLER=y
CONFIG_IPMI_DEVICE_INTERFACE=y
CONFIG_IPMI_POWERNV=y
CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=1024
# CONFIG_DEVPORT is not set
CONFIG_I2C_CHARDEV=y
# CONFIG_PTP_1588_CLOCK is not set
CONFIG_DRM=y
CONFIG_DRM_AST=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_OF=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX=m
CONFIG_FB_MATROX_MILLENIUM=y
CONFIG_FB_MATROX_MYSTIQUE=y
CONFIG_FB_MATROX_G=y
CONFIG_FB_RADEON=y
CONFIG_FB_IBM_GXT4500=y
CONFIG_FB_RADEON=m
CONFIG_FB_IBM_GXT4500=m
CONFIG_LCD_PLATFORM=m
CONFIG_BACKLIGHT_GENERIC=m
# CONFIG_VGA_CONSOLE is not set
CONFIG_LOGO=y
CONFIG_HID_GYRATION=y
CONFIG_HID_PANTHERLORD=y
CONFIG_HID_PETALYNX=y
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SUNPLUS=y
CONFIG_HID_A4TECH=m
CONFIG_HID_APPLE=m
CONFIG_HID_BELKIN=m
CONFIG_HID_CHERRY=m
CONFIG_HID_CHICONY=m
CONFIG_HID_CYPRESS=m
CONFIG_HID_EZKEY=m
CONFIG_HID_GYRATION=m
CONFIG_HID_ITE=m
CONFIG_HID_KENSINGTON=m
CONFIG_HID_LOGITECH=m
CONFIG_HID_MICROSOFT=m
CONFIG_HID_MONTEREY=m
CONFIG_HID_PANTHERLORD=m
CONFIG_HID_PETALYNX=m
CONFIG_HID_SAMSUNG=m
CONFIG_HID_SUNPLUS=m
CONFIG_USB_HID=m
CONFIG_USB_HIDDEV=y
CONFIG_USB=y
CONFIG_USB_MON=m
......@@ -219,6 +240,7 @@ CONFIG_USB_XHCI_HCD=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_HCD_PPC_OF is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PCI=m
CONFIG_USB_STORAGE=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=m
......@@ -236,8 +258,9 @@ CONFIG_INFINIBAND_SRP=m
CONFIG_INFINIBAND_ISER=m
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_GENERIC=y
CONFIG_VIRTIO_PCI=m
CONFIG_VIRTIO_BALLOON=m
# CONFIG_VIRTIO_MENU is not set
CONFIG_LIBNVDIMM=y
# CONFIG_ND_BLK is not set
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
......@@ -253,12 +276,13 @@ CONFIG_XFS_POSIX_ACL=y
CONFIG_BTRFS_FS=m
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_NILFS2_FS=m
CONFIG_FANOTIFY=y
CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=m
CONFIG_OVERLAY_FS=m
CONFIG_ISO9660_FS=y
CONFIG_UDF_FS=m
CONFIG_MSDOS_FS=y
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
......@@ -270,9 +294,9 @@ CONFIG_SQUASHFS_XATTR=y
CONFIG_SQUASHFS_LZO=y
CONFIG_SQUASHFS_XZ=y
CONFIG_PSTORE=y
CONFIG_NFS_FS=y
CONFIG_NFS_FS=m
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFS_V4=m
CONFIG_NFSD=m
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
......@@ -291,9 +315,7 @@ CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_HARDLOCKUP_DETECTOR=y
CONFIG_LATENCYTOP=y
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_FUNCTION_GRAPH_TRACER=y
CONFIG_SCHED_TRACER=y
CONFIG_FTRACE_SYSCALLS=y
CONFIG_BLK_DEV_IO_TRACE=y
......@@ -303,10 +325,10 @@ CONFIG_FTR_FIXUP_SELFTEST=y
CONFIG_MSI_BITMAP_SELFTEST=y
CONFIG_XMON=y
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_CCM=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_CRC32C_VPMSUM=m
CONFIG_CRYPTO_CRCT10DIF_VPMSUM=m
CONFIG_CRYPTO_MD5_PPC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA1_PPC=m
......
......@@ -49,7 +49,9 @@ CONFIG_BLK_DEV_RAM_COUNT=2
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_NETDEVICES=y
# CONFIG_ETHERNET is not set
CONFIG_B43=y
CONFIG_B43_BUSES_SSB=y
CONFIG_B43_SDIO=y
# CONFIG_B43_PHY_LP is not set
CONFIG_B43_DEBUG=y
......@@ -57,6 +59,7 @@ CONFIG_INPUT_FF_MEMLESS=m
CONFIG_INPUT_JOYDEV=y
CONFIG_INPUT_EVDEV=y
# CONFIG_KEYBOARD_ATKBD is not set
CONFIG_KEYBOARD_GPIO=y
# CONFIG_MOUSE_PS2 is not set
CONFIG_INPUT_JOYSTICK=y
CONFIG_INPUT_MISC=y
......@@ -71,6 +74,9 @@ CONFIG_I2C_CHARDEV=y
CONFIG_I2C_GPIO=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_HLWD=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_GPIO=y
# CONFIG_HWMON is not set
CONFIG_SSB_DEBUG=y
CONFIG_FB=y
......@@ -88,6 +94,14 @@ CONFIG_HID_APPLE=m
CONFIG_HID_WACOM=m
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_OF_HLWD=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_PANIC=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_GENERIC=y
CONFIG_EXT2_FS=y
......
......@@ -36,8 +36,7 @@ void kexec_copy_flush(struct kimage *image);
/* pseries hcall tracing */
extern struct static_key hcall_tracepoint_key;
void __trace_hcall_entry(unsigned long opcode, unsigned long *args);
void __trace_hcall_exit(long opcode, unsigned long retval,
unsigned long *retbuf);
void __trace_hcall_exit(long opcode, long retval, unsigned long *retbuf);
/* OPAL tracing */
#ifdef HAVE_JUMP_LABEL
extern struct static_key opal_tracepoint_key;
......@@ -81,18 +80,12 @@ void machine_check_exception(struct pt_regs *regs);
void emulation_assist_interrupt(struct pt_regs *regs);
/* signals, syscalls and interrupts */
#ifdef CONFIG_PPC64
int sys_swapcontext(struct ucontext __user *old_ctx,
struct ucontext __user *new_ctx,
long ctx_size, long r6, long r7, long r8, struct pt_regs *regs);
#else
long sys_swapcontext(struct ucontext __user *old_ctx,
struct ucontext __user *new_ctx,
int ctx_size, int r6, int r7, int r8, struct pt_regs *regs);
int sys_debug_setcontext(struct ucontext __user *ctx,
int ndbg, struct sig_dbg_op __user *dbg,
int r6, int r7, int r8,
struct pt_regs *regs);
long ctx_size);
#ifdef CONFIG_PPC32
long sys_debug_setcontext(struct ucontext __user *ctx,
int ndbg, struct sig_dbg_op __user *dbg);
int
ppc_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp);
unsigned long __init early_init(unsigned long dt_ptr);
......@@ -141,4 +134,7 @@ unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip);
void pnv_power9_force_smt4_catch(void);
void pnv_power9_force_smt4_release(void);
void tm_enable(void);
void tm_disable(void);
void tm_abort(uint8_t cause);
#endif /* _ASM_POWERPC_ASM_PROTOTYPES_H */
......@@ -76,6 +76,21 @@ do { \
___p1; \
})
#ifdef CONFIG_PPC_BOOK3S_64
/*
* Prevent execution of subsequent instructions until preceding branches have
* been fully resolved and are no longer executing speculatively.
*/
#define barrier_nospec_asm NOSPEC_BARRIER_FIXUP_SECTION; nop
// This also acts as a compiler barrier due to the memory clobber.
#define barrier_nospec() asm (stringify_in_c(barrier_nospec_asm) ::: "memory")
#else /* !CONFIG_PPC_BOOK3S_64 */
#define barrier_nospec_asm
#define barrier_nospec()
#endif
#include <asm-generic/barrier.h>
#endif /* _ASM_POWERPC_BARRIER_H */
......@@ -99,6 +99,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
static inline void pgtable_free(void *table, unsigned index_size)
{
if (!index_size) {
pgtable_page_dtor(virt_to_page(table));
free_page((unsigned long)table);
} else {
BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE);
......
......@@ -235,15 +235,18 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
}
static inline void __ptep_set_access_flags(struct mm_struct *mm,
static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
pte_t *ptep, pte_t entry,
unsigned long address)
unsigned long address,
int psize)
{
unsigned long set = pte_val(entry) &
(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
unsigned long clr = ~pte_val(entry) & _PAGE_RO;
pte_update(ptep, clr, set);
flush_tlb_page(vma, address);
}
#define __HAVE_ARCH_PTE_SAME
......
......@@ -38,8 +38,12 @@
#define H_PAGE_4K_PFN 0x0
#define H_PAGE_THP_HUGE 0x0
#define H_PAGE_COMBO 0x0
#define H_PTE_FRAG_NR 0
#define H_PTE_FRAG_SIZE_SHIFT 0
/* 8 bytes per each pte entry */
#define H_PTE_FRAG_SIZE_SHIFT (H_PTE_INDEX_SIZE + 3)
#define H_PTE_FRAG_NR (PAGE_SIZE >> H_PTE_FRAG_SIZE_SHIFT)
#define H_PMD_FRAG_SIZE_SHIFT (H_PMD_INDEX_SIZE + 3)
#define H_PMD_FRAG_NR (PAGE_SIZE >> H_PMD_FRAG_SIZE_SHIFT)
/* memory key bits, only 8 keys supported */
#define H_PTE_PKEY_BIT0 0
......
......@@ -46,6 +46,13 @@
#define H_PTE_FRAG_SIZE_SHIFT (H_PTE_INDEX_SIZE + 3 + 1)
#define H_PTE_FRAG_NR (PAGE_SIZE >> H_PTE_FRAG_SIZE_SHIFT)
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLB_PAGE)
#define H_PMD_FRAG_SIZE_SHIFT (H_PMD_INDEX_SIZE + 3 + 1)
#else
#define H_PMD_FRAG_SIZE_SHIFT (H_PMD_INDEX_SIZE + 3)
#endif
#define H_PMD_FRAG_NR (PAGE_SIZE >> H_PMD_FRAG_SIZE_SHIFT)
#ifndef __ASSEMBLY__
#include <asm/errno.h>
......
......@@ -23,16 +23,6 @@
H_PUD_INDEX_SIZE + H_PGD_INDEX_SIZE + PAGE_SHIFT)
#define H_PGTABLE_RANGE (ASM_CONST(1) << H_PGTABLE_EADDR_SIZE)
#if (defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLB_PAGE)) && \
defined(CONFIG_PPC_64K_PAGES)
/*
* only with hash 64k we need to use the second half of pmd page table
* to store pointer to deposited pgtable_t
*/
#define H_PMD_CACHE_INDEX (H_PMD_INDEX_SIZE + 1)
#else
#define H_PMD_CACHE_INDEX H_PMD_INDEX_SIZE
#endif
/*
* We store the slot details in the second half of page table.
* Increase the pud level table so that hugetlb ptes can be stored
......
......@@ -134,10 +134,11 @@ typedef struct {
#ifdef CONFIG_PPC_SUBPAGE_PROT
struct subpage_prot_table spt;
#endif /* CONFIG_PPC_SUBPAGE_PROT */
#ifdef CONFIG_PPC_64K_PAGES
/* for 4K PTE fragment support */
/*
* pagetable fragment support
*/
void *pte_frag;
#endif
void *pmd_frag;
#ifdef CONFIG_SPAPR_TCE_IOMMU
struct list_head iommu_group_mem_list;
#endif
......
......@@ -42,7 +42,9 @@ extern struct kmem_cache *pgtable_cache[];
})
extern pte_t *pte_fragment_alloc(struct mm_struct *, unsigned long, int);
extern pmd_t *pmd_fragment_alloc(struct mm_struct *, unsigned long);
extern void pte_fragment_free(unsigned long *, int);
extern void pmd_fragment_free(unsigned long *);
extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift);
#ifdef CONFIG_SMP
extern void __tlb_remove_table(void *_table);
......@@ -88,8 +90,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
* need to do this for 4k.
*/
#if defined(CONFIG_HUGETLB_PAGE) && defined(CONFIG_PPC_64K_PAGES) && \
((H_PGD_INDEX_SIZE == H_PUD_CACHE_INDEX) || \
(H_PGD_INDEX_SIZE == H_PMD_CACHE_INDEX))
(H_PGD_INDEX_SIZE == H_PUD_CACHE_INDEX)
memset(pgd, 0, PGD_TABLE_SIZE);
#endif
return pgd;
......@@ -124,36 +125,35 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
}
static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
unsigned long address)
unsigned long address)
{
/*
* By now all the pud entries should be none entries. So go
* ahead and flush the page walk cache
*/
flush_tlb_pgtable(tlb, address);
pgtable_free_tlb(tlb, pud, PUD_CACHE_INDEX);
pgtable_free_tlb(tlb, pud, PUD_INDEX);
}
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{
return kmem_cache_alloc(PGT_CACHE(PMD_CACHE_INDEX),
pgtable_gfp_flags(mm, GFP_KERNEL));
return pmd_fragment_alloc(mm, addr);
}
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
{
kmem_cache_free(PGT_CACHE(PMD_CACHE_INDEX), pmd);
pmd_fragment_free((unsigned long *)pmd);
}
static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
unsigned long address)
unsigned long address)
{
/*
* By now all the pud entries should be none entries. So go
* ahead and flush the page walk cache
*/
flush_tlb_pgtable(tlb, address);
return pgtable_free_tlb(tlb, pmd, PMD_CACHE_INDEX);
return pgtable_free_tlb(tlb, pmd, PMD_INDEX);
}
static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
......@@ -173,31 +173,6 @@ static inline pgtable_t pmd_pgtable(pmd_t pmd)
return (pgtable_t)pmd_page_vaddr(pmd);
}
#ifdef CONFIG_PPC_4K_PAGES
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long address)
{
return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
}
static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
unsigned long address)
{
struct page *page;
pte_t *pte;
pte = (pte_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO | __GFP_ACCOUNT);
if (!pte)
return NULL;
page = virt_to_page(pte);
if (!pgtable_page_ctor(page)) {
__free_page(page);
return NULL;
}
return pte;
}
#else /* if CONFIG_PPC_64K_PAGES */
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long address)
{
......@@ -209,7 +184,6 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
{
return (pgtable_t)pte_fragment_alloc(mm, address, 0);
}
#endif
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
{
......@@ -229,7 +203,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
* ahead and flush the page walk cache
*/
flush_tlb_pgtable(tlb, address);
pgtable_free_tlb(tlb, table, 0);
pgtable_free_tlb(tlb, table, PTE_INDEX);
}
#define check_pgt_cache() do { } while (0)
......
......@@ -212,13 +212,13 @@ extern unsigned long __pte_index_size;
extern unsigned long __pmd_index_size;
extern unsigned long __pud_index_size;
extern unsigned long __pgd_index_size;
extern unsigned long __pmd_cache_index;
extern unsigned long __pud_cache_index;
#define PTE_INDEX_SIZE __pte_index_size
#define PMD_INDEX_SIZE __pmd_index_size
#define PUD_INDEX_SIZE __pud_index_size
#define PGD_INDEX_SIZE __pgd_index_size
#define PMD_CACHE_INDEX __pmd_cache_index
/* pmd table use page table fragments */
#define PMD_CACHE_INDEX 0
#define PUD_CACHE_INDEX __pud_cache_index
/*
* Because of use of pte fragments and THP, size of page table
......@@ -246,6 +246,12 @@ extern unsigned long __pte_frag_size_shift;
#define PTE_FRAG_SIZE_SHIFT __pte_frag_size_shift
#define PTE_FRAG_SIZE (1UL << PTE_FRAG_SIZE_SHIFT)
extern unsigned long __pmd_frag_nr;
#define PMD_FRAG_NR __pmd_frag_nr
extern unsigned long __pmd_frag_size_shift;
#define PMD_FRAG_SIZE_SHIFT __pmd_frag_size_shift
#define PMD_FRAG_SIZE (1UL << PMD_FRAG_SIZE_SHIFT)
#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
#define PTRS_PER_PUD (1 << PUD_INDEX_SIZE)
......@@ -273,6 +279,16 @@ extern unsigned long __pte_frag_size_shift;
/* Bits to mask out from a PGD to get to the PUD page */
#define PGD_MASKED_BITS 0xc0000000000000ffUL
/*
* Used as an indicator for rcu callback functions
*/
enum pgtable_index {
PTE_INDEX = 0,
PMD_INDEX,
PUD_INDEX,
PGD_INDEX,
};
extern unsigned long __vmalloc_start;
extern unsigned long __vmalloc_end;
#define VMALLOC_START __vmalloc_start
......@@ -751,12 +767,14 @@ static inline bool check_pte_access(unsigned long access, unsigned long ptev)
* Generic functions with hash/radix callbacks
*/
static inline void __ptep_set_access_flags(struct mm_struct *mm,
static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
pte_t *ptep, pte_t entry,
unsigned long address)
unsigned long address,
int psize)
{
if (radix_enabled())
return radix__ptep_set_access_flags(mm, ptep, entry, address);
return radix__ptep_set_access_flags(vma, ptep, entry,
address, psize);
return hash__ptep_set_access_flags(ptep, entry);
}
......
......@@ -15,4 +15,7 @@
#define RADIX_PTE_FRAG_SIZE_SHIFT (RADIX_PTE_INDEX_SIZE + 3)
#define RADIX_PTE_FRAG_NR (PAGE_SIZE >> RADIX_PTE_FRAG_SIZE_SHIFT)
#define RADIX_PMD_FRAG_SIZE_SHIFT (RADIX_PMD_INDEX_SIZE + 3)
#define RADIX_PMD_FRAG_NR (PAGE_SIZE >> RADIX_PMD_FRAG_SIZE_SHIFT)
#endif /* _ASM_POWERPC_PGTABLE_RADIX_4K_H */
......@@ -16,4 +16,8 @@
*/
#define RADIX_PTE_FRAG_SIZE_SHIFT (RADIX_PTE_INDEX_SIZE + 3)
#define RADIX_PTE_FRAG_NR (PAGE_SIZE >> RADIX_PTE_FRAG_SIZE_SHIFT)
#define RADIX_PMD_FRAG_SIZE_SHIFT (RADIX_PMD_INDEX_SIZE + 3)
#define RADIX_PMD_FRAG_NR (PAGE_SIZE >> RADIX_PMD_FRAG_SIZE_SHIFT)
#endif /* _ASM_POWERPC_PGTABLE_RADIX_64K_H */
......@@ -124,23 +124,28 @@ extern void radix__mark_rodata_ro(void);
extern void radix__mark_initmem_nx(void);
#endif
extern void radix__ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep,
pte_t entry, unsigned long address,
int psize);
static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned long clr,
unsigned long set)
{
pte_t pte;
unsigned long old_pte, new_pte;
do {
pte = READ_ONCE(*ptep);
old_pte = pte_val(pte);
new_pte = (old_pte | set) & ~clr;
} while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
return old_pte;
__be64 old_be, tmp_be;
__asm__ __volatile__(
"1: ldarx %0,0,%3 # pte_update\n"
" andc %1,%0,%5 \n"
" or %1,%1,%4 \n"
" stdcx. %1,0,%3 \n"
" bne- 1b"
: "=&r" (old_be), "=&r" (tmp_be), "=m" (*ptep)
: "r" (ptep), "r" (cpu_to_be64(set)), "r" (cpu_to_be64(clr))
: "cc" );
return be64_to_cpu(old_be);
}
static inline unsigned long radix__pte_update(struct mm_struct *mm,
unsigned long addr,
pte_t *ptep, unsigned long clr,
......@@ -176,48 +181,14 @@ static inline pte_t radix__ptep_get_and_clear_full(struct mm_struct *mm,
unsigned long old_pte;
if (full) {
/*
* If we are trying to clear the pte, we can skip
* the DD1 pte update sequence and batch the tlb flush. The
* tlb flush batching is done by mmu gather code. We
* still keep the cmp_xchg update to make sure we get
* correct R/C bit which might be updated via Nest MMU.
*/
old_pte = __radix_pte_update(ptep, ~0ul, 0);
old_pte = pte_val(*ptep);
*ptep = __pte(0);
} else
old_pte = radix__pte_update(mm, addr, ptep, ~0ul, 0, 0);
return __pte(old_pte);
}
/*
* Set the dirty and/or accessed bits atomically in a linux PTE, this
* function doesn't need to invalidate tlb.
*/
static inline void radix__ptep_set_access_flags(struct mm_struct *mm,
pte_t *ptep, pte_t entry,
unsigned long address)
{
unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED |
_PAGE_RW | _PAGE_EXEC);
if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
unsigned long old_pte, new_pte;
old_pte = __radix_pte_update(ptep, ~0, 0);
/*
* new value of pte
*/
new_pte = old_pte | set;
radix__flush_tlb_pte_p9_dd1(old_pte, mm, address);
__radix_pte_update(ptep, 0, new_pte);
} else
__radix_pte_update(ptep, 0, set);
asm volatile("ptesync" : : : "memory");
}
static inline int radix__pte_same(pte_t pte_a, pte_t pte_b)
{
return ((pte_raw(pte_a) ^ pte_raw(pte_b)) == 0);
......@@ -232,7 +203,24 @@ static inline void radix__set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte, int percpu)
{
*ptep = pte;
asm volatile("ptesync" : : : "memory");
/*
* The architecture suggests a ptesync after setting the pte, which
* orders the store that updates the pte with subsequent page table
* walk accesses which may load the pte. Without this it may be
* possible for a subsequent access to result in spurious fault.
*
* This is not necessary for correctness, because a spurious fault
* is tolerated by the page fault handler, and this store will
* eventually be seen. In testing, there was no noticable increase
* in user faults on POWER9. Avoiding ptesync here is a significant
* win for things like fork. If a future microarchitecture benefits
* from ptesync, it should probably go into update_mmu_cache, rather
* than set_pte_at (which is used to set ptes unrelated to faults).
*
* Spurious faults to vmalloc region are not tolerated, so there is
* a ptesync in flush_cache_vmap.
*/
}
static inline int radix__pmd_bad(pmd_t pmd)
......
......@@ -51,4 +51,11 @@ extern void radix__flush_tlb_all(void);
extern void radix__flush_tlb_pte_p9_dd1(unsigned long old_pte, struct mm_struct *mm,
unsigned long address);
extern void radix__flush_tlb_lpid_page(unsigned int lpid,
unsigned long addr,
unsigned long page_size);
extern void radix__flush_pwc_lpid(unsigned int lpid);
extern void radix__local_flush_tlb_lpid(unsigned int lpid);
extern void radix__local_flush_tlb_lpid_guest(unsigned int lpid);
#endif
......@@ -4,7 +4,7 @@
#define MMU_NO_CONTEXT ~0UL
#include <linux/mm_types.h>
#include <asm/book3s/64/tlbflush-hash.h>
#include <asm/book3s/64/tlbflush-radix.h>
......@@ -137,6 +137,16 @@ static inline void flush_all_mm(struct mm_struct *mm)
#define flush_tlb_page(vma, addr) local_flush_tlb_page(vma, addr)
#define flush_all_mm(mm) local_flush_all_mm(mm)
#endif /* CONFIG_SMP */
#define flush_tlb_fix_spurious_fault flush_tlb_fix_spurious_fault
static inline void flush_tlb_fix_spurious_fault(struct vm_area_struct *vma,
unsigned long address)
{
/* See ptep_set_access_flags comment */
if (atomic_read(&vma->vm_mm->context.copros) > 0)
flush_tlb_page(vma, address);
}
/*
* flush the page walk cache for the address
*/
......
......@@ -9,11 +9,14 @@
#if defined(CONFIG_PPC_8xx) || defined(CONFIG_403GCX)
#define L1_CACHE_SHIFT 4
#define MAX_COPY_PREFETCH 1
#define IFETCH_ALIGN_SHIFT 2
#elif defined(CONFIG_PPC_E500MC)
#define L1_CACHE_SHIFT 6
#define MAX_COPY_PREFETCH 4
#define IFETCH_ALIGN_SHIFT 3
#elif defined(CONFIG_PPC32)
#define MAX_COPY_PREFETCH 4
#define IFETCH_ALIGN_SHIFT 3 /* 603 fetches 2 insn at a time */
#if defined(CONFIG_PPC_47x)
#define L1_CACHE_SHIFT 7
#else
......
......@@ -23,9 +23,21 @@
#define flush_cache_range(vma, start, end) do { } while (0)
#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
#define flush_icache_page(vma, page) do { } while (0)
#define flush_cache_vmap(start, end) do { } while (0)
#define flush_cache_vunmap(start, end) do { } while (0)
#ifdef CONFIG_PPC_BOOK3S_64
/*
* Book3s has no ptesync after setting a pte, so without this ptesync it's
* possible for a kernel virtual mapping access to return a spurious fault
* if it's accessed right after the pte is set. The page fault handler does
* not expect this type of fault. flush_cache_vmap is not exactly the right
* place to put this, but it seems to work well enough.
*/
#define flush_cache_vmap(start, end) do { asm volatile("ptesync" ::: "memory"); } while (0)
#else
#define flush_cache_vmap(start, end) do { } while (0)
#endif
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
extern void flush_dcache_page(struct page *page);
#define flush_dcache_mmap_lock(mapping) do { } while (0)
......
......@@ -12,6 +12,8 @@
#ifdef CONFIG_GENERIC_CSUM
#include <asm-generic/checksum.h>
#else
#include <linux/bitops.h>
#include <linux/in6.h>
/*
* Computes the checksum of a memory block at src, length len,
* and adds in "sum" (32-bit), while copying the block to dst.
......@@ -55,11 +57,7 @@ static inline __sum16 csum_fold(__wsum sum)
static inline u32 from64to32(u64 x)
{
/* add up 32-bit and 32-bit for 32+c bit */
x = (x & 0xffffffff) + (x >> 32);
/* add up carry.. */
x = (x & 0xffffffff) + (x >> 32);
return (u32)x;
return (x + ror64(x, 32)) >> 32;
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
......@@ -112,7 +110,7 @@ static inline __wsum csum_add(__wsum csum, __wsum addend)
#ifdef __powerpc64__
res += (__force u64)addend;
return (__force __wsum) from64to32(res);
return (__force __wsum)((u32)res + (res >> 32));
#else
asm("addc %0,%0,%1;"
"addze %0,%0;"
......@@ -214,6 +212,11 @@ static inline __sum16 ip_compute_csum(const void *buff, int len)
return csum_fold(csum_partial(buff, len, 0));
}
#define _HAVE_ARCH_IPV6_CSUM
__sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, __u8 proto, __wsum sum);
#endif
#endif /* __KERNEL__ */
#endif
......@@ -215,6 +215,7 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTR_P9_TM_HV_ASSIST LONG_ASM_CONST(0x0000100000000000)
#define CPU_FTR_P9_TM_XER_SO_BUG LONG_ASM_CONST(0x0000200000000000)
#define CPU_FTR_P9_TLBIE_BUG LONG_ASM_CONST(0x0000400000000000)
#define CPU_FTR_P9_TIDR LONG_ASM_CONST(0x0000800000000000)
#ifndef __ASSEMBLY__
......@@ -462,7 +463,7 @@ static inline void cpu_feature_keys_init(void) { }
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_P9_TLBIE_BUG)
CPU_FTR_P9_TLBIE_BUG | CPU_FTR_P9_TIDR)
#define CPU_FTRS_POWER9_DD1 ((CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1) & \
(~CPU_FTR_SAO))
#define CPU_FTRS_POWER9_DD2_0 CPU_FTRS_POWER9
......
......@@ -47,9 +47,23 @@ static inline unsigned long cputime_to_usecs(const cputime_t ct)
* has to be populated in the new task
*/
#ifdef CONFIG_PPC64
#define get_accounting(tsk) (&get_paca()->accounting)
static inline void arch_vtime_task_switch(struct task_struct *tsk) { }
#else
void arch_vtime_task_switch(struct task_struct *tsk);
#define get_accounting(tsk) (&task_thread_info(tsk)->accounting)
/*
* Called from the context switch with interrupts disabled, to charge all
* accumulated times to the current process, and to prepare accounting on
* the next process.
*/
static inline void arch_vtime_task_switch(struct task_struct *prev)
{
struct cpu_accounting_data *acct = get_accounting(current);
struct cpu_accounting_data *acct0 = get_accounting(prev);
acct->starttime = acct0->starttime;
acct->startspurr = acct0->startspurr;
}
#endif
#endif /* __KERNEL__ */
......
......@@ -106,6 +106,9 @@ struct eeh_pe {
#define eeh_pe_for_each_dev(pe, edev, tmp) \
list_for_each_entry_safe(edev, tmp, &pe->edevs, list)
#define eeh_for_each_pe(root, pe) \
for (pe = root; pe; pe = eeh_pe_next(pe, root))
static inline bool eeh_pe_passed(struct eeh_pe *pe)
{
return pe ? !!atomic_read(&pe->pass_dev_cnt) : false;
......@@ -262,19 +265,21 @@ static inline bool eeh_state_active(int state)
== (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE);
}
typedef void *(*eeh_traverse_func)(void *data, void *flag);
typedef void *(*eeh_edev_traverse_func)(struct eeh_dev *edev, void *flag);
typedef void *(*eeh_pe_traverse_func)(struct eeh_pe *pe, void *flag);
void eeh_set_pe_aux_size(int size);
int eeh_phb_pe_create(struct pci_controller *phb);
struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb);
struct eeh_pe *eeh_pe_next(struct eeh_pe *pe, struct eeh_pe *root);
struct eeh_pe *eeh_pe_get(struct pci_controller *phb,
int pe_no, int config_addr);
int eeh_add_to_parent_pe(struct eeh_dev *edev);
int eeh_rmv_from_parent_pe(struct eeh_dev *edev);
void eeh_pe_update_time_stamp(struct eeh_pe *pe);
void *eeh_pe_traverse(struct eeh_pe *root,
eeh_traverse_func fn, void *flag);
eeh_pe_traverse_func fn, void *flag);
void *eeh_pe_dev_traverse(struct eeh_pe *root,
eeh_traverse_func fn, void *flag);
eeh_edev_traverse_func fn, void *flag);
void eeh_pe_restore_bars(struct eeh_pe *pe);
const char *eeh_pe_loc_get(struct eeh_pe *pe);
struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe);
......
......@@ -211,6 +211,14 @@ label##3: \
FTR_ENTRY_OFFSET 951b-952b; \
.popsection;
#define NOSPEC_BARRIER_FIXUP_SECTION \
953: \
.pushsection __barrier_nospec_fixup,"a"; \
.align 2; \
954: \
FTR_ENTRY_OFFSET 953b-954b; \
.popsection;
#ifndef __ASSEMBLY__
#include <linux/types.h>
......@@ -219,6 +227,7 @@ extern long stf_barrier_fallback;
extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup;
extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup;
extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup;
void apply_feature_fixups(void);
void setup_feature_keys(void);
......
......@@ -48,9 +48,6 @@
#else /* !__ASSEMBLY__ */
extern void _mcount(void);
#ifdef CONFIG_DYNAMIC_FTRACE
# define FTRACE_ADDR ((unsigned long)ftrace_caller)
# define FTRACE_REGS_ADDR FTRACE_ADDR
static inline unsigned long ftrace_call_adjust(unsigned long addr)
{
/* reloction of mcount call site is the same as the address */
......@@ -60,15 +57,15 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
struct dyn_arch_ftrace {
struct module *mod;
};
#endif /* CONFIG_DYNAMIC_FTRACE */
#endif /* __ASSEMBLY__ */
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
#define ARCH_SUPPORTS_FTRACE_OPS 1
#endif
#endif
#endif /* CONFIG_FUNCTION_TRACER */
#if defined(CONFIG_FTRACE_SYSCALLS) && !defined(__ASSEMBLY__)
#ifndef __ASSEMBLY__
#ifdef CONFIG_FTRACE_SYSCALLS
/*
* Some syscall entry functions on powerpc start with "ppc_" (fork and clone,
* for instance) or ppc32_/ppc64_. We should also match the sys_ variant with
......@@ -94,7 +91,25 @@ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name
(!strncmp(sym, "ppc32_", 6) && !strcmp(sym + 6, name + 4)) ||
(!strncmp(sym, "ppc64_", 6) && !strcmp(sym + 6, name + 4));
}
#endif
#endif /* CONFIG_FTRACE_SYSCALLS && !__ASSEMBLY__ */
#endif /* PPC64_ELF_ABI_v1 */
#endif /* CONFIG_FTRACE_SYSCALLS */
#ifdef CONFIG_PPC64
#include <asm/paca.h>
static inline void this_cpu_disable_ftrace(void)
{
get_paca()->ftrace_enabled = 0;
}
static inline void this_cpu_enable_ftrace(void)
{
get_paca()->ftrace_enabled = 1;
}
#else /* CONFIG_PPC64 */
static inline void this_cpu_disable_ftrace(void) { }
static inline void this_cpu_enable_ftrace(void) { }
#endif /* CONFIG_PPC64 */
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_POWERPC_FTRACE */
......@@ -8,6 +8,7 @@
typedef struct {
unsigned int __softirq_pending;
unsigned int timer_irqs_event;
unsigned int broadcast_irqs_event;
unsigned int timer_irqs_others;
unsigned int pmu_irqs;
unsigned int mce_exceptions;
......
......@@ -166,22 +166,9 @@ static inline pte_t huge_pte_wrprotect(pte_t pte)
return pte_wrprotect(pte);
}
static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t pte, int dirty)
{
#ifdef HUGETLB_NEED_PRELOAD
/*
* The "return 1" forces a call of update_mmu_cache, which will write a
* TLB entry. Without this, platforms that don't do a write of the TLB
* entry in the TLB miss handler asm will fault ad infinitum.
*/
ptep_set_access_flags(vma, addr, ptep, pte, dirty);
return 1;
#else
return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
#endif
}
extern int huge_ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t pte, int dirty);
static inline pte_t huge_ptep_get(pte_t *ptep)
{
......@@ -202,7 +189,7 @@ static inline void flush_hugetlb_page(struct vm_area_struct *vma,
static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
unsigned pdshift)
{
return 0;
return NULL;
}
#endif /* CONFIG_HUGETLB_PAGE */
......
......@@ -55,6 +55,7 @@ extern void replay_system_reset(void);
extern void __replay_interrupt(unsigned int vector);
extern void timer_interrupt(struct pt_regs *);
extern void timer_broadcast_interrupt(void);
extern void performance_monitor_exception(struct pt_regs *regs);
extern void WatchdogException(struct pt_regs *regs);
extern void unknown_exception(struct pt_regs *regs);
......@@ -228,8 +229,8 @@ static inline bool arch_irqs_disabled(void)
#define __hard_irq_enable() asm volatile("wrteei 1" : : : "memory")
#define __hard_irq_disable() asm volatile("wrteei 0" : : : "memory")
#else
#define __hard_irq_enable() __mtmsrd(local_paca->kernel_msr | MSR_EE, 1)
#define __hard_irq_disable() __mtmsrd(local_paca->kernel_msr, 1)
#define __hard_irq_enable() __mtmsrd(MSR_EE|MSR_RI, 1)
#define __hard_irq_disable() __mtmsrd(MSR_RI, 1)
#endif
#define hard_irq_disable() do { \
......@@ -237,8 +238,12 @@ static inline bool arch_irqs_disabled(void)
__hard_irq_disable(); \
flags = irq_soft_mask_set_return(IRQS_ALL_DISABLED); \
local_paca->irq_happened |= PACA_IRQ_HARD_DIS; \
if (!arch_irqs_disabled_flags(flags)) \
if (!arch_irqs_disabled_flags(flags)) { \
asm ("stdx %%r1, 0, %1 ;" \
: "=m" (local_paca->saved_r1) \
: "b" (&local_paca->saved_r1)); \
trace_hardirqs_off(); \
} \
} while(0)
static inline bool lazy_irq_pending(void)
......
......@@ -128,4 +128,5 @@ extern int init_imc_pmu(struct device_node *parent,
struct imc_pmu *pmu_ptr, int pmu_id);
extern void thread_imc_disable(void);
extern int get_max_nest_dev(void);
extern void unregister_thread_imc(void);
#endif /* __ASM_POWERPC_IMC_PMU_H */
......@@ -367,6 +367,11 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
*(volatile unsigned long __force *)PCI_FIX_ADDR(addr) = v;
}
static inline void __raw_writeq_be(unsigned long v, volatile void __iomem *addr)
{
__raw_writeq((__force unsigned long)cpu_to_be64(v), addr);
}
/*
* Real mode versions of the above. Those instructions are only supposed
* to be used in hypervisor real mode as per the architecture spec.
......@@ -395,6 +400,11 @@ static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
: : "r" (val), "r" (paddr) : "memory");
}
static inline void __raw_rm_writeq_be(u64 val, volatile void __iomem *paddr)
{
__raw_rm_writeq((__force u64)cpu_to_be64(val), paddr);
}
static inline u8 __raw_rm_readb(volatile void __iomem *paddr)
{
u8 ret;
......
......@@ -83,7 +83,7 @@ struct machdep_calls {
int (*set_rtc_time)(struct rtc_time *);
void (*get_rtc_time)(struct rtc_time *);
unsigned long (*get_boot_time)(void);
time64_t (*get_boot_time)(void);
unsigned char (*rtc_read_val)(int addr);
void (*rtc_write_val)(int addr, unsigned char val);
......
......@@ -230,10 +230,6 @@ typedef struct {
unsigned int id;
unsigned int active;
unsigned long vdso_base;
#ifdef CONFIG_PPC_64K_PAGES
/* for 4K PTE fragment support */
void *pte_frag;
#endif
} mm_context_t;
/* Page size definitions, common between 32 and 64-bit
......@@ -275,8 +271,6 @@ static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize)
*/
#if defined(CONFIG_PPC_4K_PAGES)
#define mmu_virtual_psize MMU_PAGE_4K
#elif defined(CONFIG_PPC_64K_PAGES)
#define mmu_virtual_psize MMU_PAGE_64K
#else
#error Unsupported page size
#endif
......
......@@ -250,11 +250,6 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,
#define thread_pkey_regs_restore(new_thread, old_thread)
#define thread_pkey_regs_init(thread)
static inline int vma_pkey(struct vm_area_struct *vma)
{
return 0;
}
static inline u64 pte_to_hpte_pkey_bits(u64 pteflags)
{
return 0x0UL;
......
......@@ -50,10 +50,6 @@ struct mod_arch_specific {
unsigned int stubs_section; /* Index of stubs section in module */
unsigned int toc_section; /* What section is the TOC? */
bool toc_fixed; /* Have we fixed up .TOC.? */
#ifdef CONFIG_DYNAMIC_FTRACE
unsigned long toc;
unsigned long tramp;
#endif
/* For module function descriptor dereference */
unsigned long start_opd;
......@@ -62,10 +58,14 @@ struct mod_arch_specific {
/* Indices of PLT sections within module. */
unsigned int core_plt_section;
unsigned int init_plt_section;
#endif /* powerpc64 */
#ifdef CONFIG_DYNAMIC_FTRACE
unsigned long tramp;
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
unsigned long tramp_regs;
#endif
#endif
#endif /* powerpc64 */
/* List of BUG addresses, source line numbers and filenames */
struct list_head bug_list;
......
......@@ -350,14 +350,14 @@ extern struct mpc52xx_suspend mpc52xx_suspend;
extern int __init mpc52xx_pm_init(void);
extern int mpc52xx_set_wakeup_gpio(u8 pin, u8 level);
#ifdef CONFIG_PPC_LITE5200
extern int __init lite5200_pm_init(void);
/* lite5200 calls mpc5200 suspend functions, so here they are */
extern int mpc52xx_pm_prepare(void);
extern int mpc52xx_pm_enter(suspend_state_t);
extern void mpc52xx_pm_finish(void);
extern char saved_sram[0x4000]; /* reuse buffer from mpc52xx suspend */
#ifdef CONFIG_PPC_LITE5200
int __init lite5200_pm_init(void);
#endif
#endif /* CONFIG_PM */
......
......@@ -8,4 +8,10 @@ extern void arch_touch_nmi_watchdog(void);
static inline void arch_touch_nmi_watchdog(void) {}
#endif
#if defined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_STACKTRACE)
extern void arch_trigger_cpumask_backtrace(const cpumask_t *mask,
bool exclude_self);
#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
#endif
#endif /* _ASM_NMI_H */
......@@ -100,6 +100,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
static inline void pgtable_free(void *table, unsigned index_size)
{
if (!index_size) {
pgtable_page_dtor(virt_to_page(table));
free_page((unsigned long)table);
} else {
BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE);
......
......@@ -133,7 +133,7 @@ extern int icache_44x_need_flush;
#ifndef __ASSEMBLY__
#define pte_clear(mm, addr, ptep) \
do { pte_update(ptep, ~_PAGE_HASHPTE, 0); } while (0)
do { pte_update(ptep, ~0, 0); } while (0)
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD)
......@@ -145,21 +145,6 @@ static inline void pmd_clear(pmd_t *pmdp)
/*
* When flushing the tlb entry for a page, we also need to flush the hash
* table entry. flush_hash_pages is assembler (for speed) in hashtable.S.
*/
extern int flush_hash_pages(unsigned context, unsigned long va,
unsigned long pmdval, int count);
/* Add an HPTE to the hash table */
extern void add_hash_page(unsigned context, unsigned long va,
unsigned long pmdval);
/* Flush an entry from the TLB/hash table */
extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep,
unsigned long address);
/*
* PTE updates. This function is called whenever an existing
* valid PTE is updated. This does -not- include set_pte_at()
......@@ -246,12 +231,6 @@ static inline int __ptep_test_and_clear_young(unsigned int context, unsigned lon
{
unsigned long old;
old = pte_update(ptep, _PAGE_ACCESSED, 0);
#if _PAGE_HASHPTE != 0
if (old & _PAGE_HASHPTE) {
unsigned long ptephys = __pa(ptep) & PAGE_MASK;
flush_hash_pages(context, addr, ptephys, 1);
}
#endif
return (old & _PAGE_ACCESSED) != 0;
}
#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
......@@ -261,7 +240,7 @@ static inline int __ptep_test_and_clear_young(unsigned int context, unsigned lon
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(ptep, ~0, 0));
}
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
......@@ -277,19 +256,27 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
}
static inline void __ptep_set_access_flags(struct mm_struct *mm,
static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
pte_t *ptep, pte_t entry,
unsigned long address)
unsigned long address,
int psize)
{
unsigned long set = pte_val(entry) &
(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
unsigned long clr = ~pte_val(entry) & (_PAGE_RO | _PAGE_NA);
pte_update(ptep, clr, set);
flush_tlb_page(vma, address);
}
static inline int pte_young(pte_t pte)
{
return pte_val(pte) & _PAGE_ACCESSED;
}
#define __HAVE_ARCH_PTE_SAME
#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)
#define pte_same(A,B) ((pte_val(A) ^ pte_val(B)) == 0)
/*
* Note that on Book E processors, the pmd contains the kernel virtual
......@@ -330,7 +317,7 @@ static inline void __ptep_set_access_flags(struct mm_struct *mm,
/*
* Encode and decode a swap entry.
* Note that the bits we use in a PTE for representing a swap entry
* must not include the _PAGE_PRESENT bit or the _PAGE_HASHPTE bit (if used).
* must not include the _PAGE_PRESENT bit.
* -- paulus
*/
#define __swp_type(entry) ((entry).val & 0x1f)
......
......@@ -52,12 +52,9 @@
#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */
#define _PMD_BAD 0x802
#define _PMD_SIZE 0x0e0 /* size field, != 0 for large-page PMD entry */
#define _PMD_SIZE_4M 0x0c0
#define _PMD_SIZE_16M 0x0e0
#define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4))
/* Until my rework is finished, 40x still needs atomic PTE updates */
#define PTE_ATOMIC_UPDATES 1
......
......@@ -52,8 +52,6 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
kmem_cache_free(PGT_CACHE(PGD_INDEX_SIZE), pgd);
}
#ifndef CONFIG_PPC_64K_PAGES
#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, (unsigned long)PUD)
static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
......@@ -86,6 +84,18 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
#define pmd_pgtable(pmd) pmd_page(pmd)
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{
return kmem_cache_alloc(PGT_CACHE(PMD_CACHE_INDEX),
pgtable_gfp_flags(mm, GFP_KERNEL));
}
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
{
kmem_cache_free(PGT_CACHE(PMD_CACHE_INDEX), pmd);
}
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long address)
{
......@@ -120,84 +130,47 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
__free_page(ptepage);
}
extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift);
#ifdef CONFIG_SMP
extern void __tlb_remove_table(void *_table);
#endif
static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
unsigned long address)
static inline void pgtable_free(void *table, int shift)
{
tlb_flush_pgtable(tlb, address);
pgtable_free_tlb(tlb, page_address(table), 0);
if (!shift) {
pgtable_page_dtor(virt_to_page(table));
free_page((unsigned long)table);
} else {
BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE);
kmem_cache_free(PGT_CACHE(shift), table);
}
}
#else /* if CONFIG_PPC_64K_PAGES */
extern pte_t *pte_fragment_alloc(struct mm_struct *, unsigned long, int);
extern void pte_fragment_free(unsigned long *, int);
extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift);
#ifdef CONFIG_SMP
extern void __tlb_remove_table(void *_table);
#endif
#define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd)
static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
pte_t *pte)
static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift)
{
pmd_set(pmd, (unsigned long)pte);
}
unsigned long pgf = (unsigned long)table;
static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
pgtable_t pte_page)
{
pmd_set(pmd, (unsigned long)pte_page);
BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE);
pgf |= shift;
tlb_remove_table(tlb, (void *)pgf);
}
static inline pgtable_t pmd_pgtable(pmd_t pmd)
static inline void __tlb_remove_table(void *_table)
{
return (pgtable_t)(pmd_val(pmd) & ~PMD_MASKED_BITS);
}
void *table = (void *)((unsigned long)_table & ~MAX_PGTABLE_INDEX_SIZE);
unsigned shift = (unsigned long)_table & MAX_PGTABLE_INDEX_SIZE;
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long address)
{
return (pte_t *)pte_fragment_alloc(mm, address, 1);
pgtable_free(table, shift);
}
static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
unsigned long address)
{
return (pgtable_t)pte_fragment_alloc(mm, address, 0);
}
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
{
pte_fragment_free((unsigned long *)pte, 1);
}
static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
#else
static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift)
{
pte_fragment_free((unsigned long *)ptepage, 0);
pgtable_free(table, shift);
}
#endif
static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
unsigned long address)
{
tlb_flush_pgtable(tlb, address);
pgtable_free_tlb(tlb, table, 0);
}
#endif /* CONFIG_PPC_64K_PAGES */
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{
return kmem_cache_alloc(PGT_CACHE(PMD_CACHE_INDEX),
pgtable_gfp_flags(mm, GFP_KERNEL));
}
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
{
kmem_cache_free(PGT_CACHE(PMD_CACHE_INDEX), pmd);
pgtable_free_tlb(tlb, page_address(table), 0);
}
#define __pmd_free_tlb(tlb, pmd, addr) \
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_POWERPC_NOHASH_64_PGTABLE_64K_H
#define _ASM_POWERPC_NOHASH_64_PGTABLE_64K_H
#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopud.h>
#define PTE_INDEX_SIZE 8
#define PMD_INDEX_SIZE 10
#define PUD_INDEX_SIZE 0
#define PGD_INDEX_SIZE 12
/*
* we support 32 fragments per PTE page of 64K size
*/
#define PTE_FRAG_NR 32
/*
* We use a 2K PTE page fragment and another 2K for storing
* real_pte_t hash index
*/
#define PTE_FRAG_SIZE_SHIFT 11
#define PTE_FRAG_SIZE (1UL << PTE_FRAG_SIZE_SHIFT)
#ifndef __ASSEMBLY__
#define PTE_TABLE_SIZE PTE_FRAG_SIZE
#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
#define PUD_TABLE_SIZE (0)
#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
#endif /* __ASSEMBLY__ */
#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
/* PMD_SHIFT determines what a second-level page table entry can map */
#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE)
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))
/* PGDIR_SHIFT determines what a third-level page table entry can map */
#define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE)
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/*
* Bits to mask out from a PMD to get to the PTE page
* PMDs point to PTE table fragments which are PTE_FRAG_SIZE aligned.
*/
#define PMD_MASKED_BITS (PTE_FRAG_SIZE - 1)
/* Bits to mask out from a PGD/PUD to get to the PMD page */
#define PUD_MASKED_BITS 0x1ff
#define pgd_pte(pgd) (pud_pte(((pud_t){ pgd })))
#define pte_pgd(pte) ((pgd_t)pte_pud(pte))
#endif /* _ASM_POWERPC_NOHASH_64_PGTABLE_64K_H */
......@@ -6,13 +6,13 @@
* the ppc64 hashed page table.
*/
#ifdef CONFIG_PPC_64K_PAGES
#include <asm/nohash/64/pgtable-64k.h>
#else
#include <asm/nohash/64/pgtable-4k.h>
#endif
#include <asm/barrier.h>
#ifdef CONFIG_PPC_64K_PAGES
#error "Page size not supported"
#endif
#define FIRST_USER_ADDRESS 0UL
/*
......@@ -173,8 +173,6 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val)
/* to find an entry in a kernel page-table-directory */
/* This now only contains the vmalloc pages */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, unsigned long pte, int huge);
/* Atomic PTE updates */
static inline unsigned long pte_update(struct mm_struct *mm,
......@@ -188,14 +186,12 @@ static inline unsigned long pte_update(struct mm_struct *mm,
__asm__ __volatile__(
"1: ldarx %0,0,%3 # pte_update\n\
andi. %1,%0,%6\n\
bne- 1b \n\
andc %1,%0,%4 \n\
or %1,%1,%7\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), "i" (_PAGE_BUSY), "r" (set)
: "r" (ptep), "r" (clr), "m" (*ptep), "r" (set)
: "cc" );
#else
unsigned long old = pte_val(*ptep);
......@@ -205,20 +201,20 @@ static inline unsigned long pte_update(struct mm_struct *mm,
if (!huge)
assert_pte_locked(mm, addr);
#ifdef CONFIG_PPC_BOOK3S_64
if (old & _PAGE_HASHPTE)
hpte_need_flush(mm, addr, ptep, old, huge);
#endif
return old;
}
static inline int pte_young(pte_t pte)
{
return pte_val(pte) & _PAGE_ACCESSED;
}
static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
unsigned long old;
if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
if (pte_young(*ptep))
return 0;
old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0);
return (old & _PAGE_ACCESSED) != 0;
......@@ -285,9 +281,10 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
/* Set the dirty and/or accessed bits atomically in a linux PTE, this
* function doesn't need to flush the hash entry
*/
static inline void __ptep_set_access_flags(struct mm_struct *mm,
static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
pte_t *ptep, pte_t entry,
unsigned long address)
unsigned long address,
int psize)
{
unsigned long bits = pte_val(entry) &
(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
......@@ -297,22 +294,22 @@ static inline void __ptep_set_access_flags(struct mm_struct *mm,
__asm__ __volatile__(
"1: ldarx %0,0,%4\n\
andi. %1,%0,%6\n\
bne- 1b \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), "i" (_PAGE_BUSY)
:"r" (bits), "r" (ptep), "m" (*ptep)
:"cc");
#else
unsigned long old = pte_val(*ptep);
*ptep = __pte(old | bits);
#endif
flush_tlb_page(vma, address);
}
#define __HAVE_ARCH_PTE_SAME
#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
#define pte_same(A,B) ((pte_val(A) ^ pte_val(B)) == 0)
#define pte_ERROR(e) \
pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
......@@ -324,11 +321,6 @@ static inline void __ptep_set_access_flags(struct mm_struct *mm,
/* Encode and de-code a swap entry */
#define MAX_SWAPFILES_CHECK() do { \
BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS); \
/* \
* Don't have overlapping bits with _PAGE_HPTEFLAGS \
* We filter HPTEFLAGS on set_pte. \
*/ \
BUILD_BUG_ON(_PAGE_HPTEFLAGS & (0x1f << _PAGE_BIT_SWAP_TYPE)); \
} while (0)
/*
* on pte we don't need handle RADIX_TREE_EXCEPTIONAL_SHIFT;
......
......@@ -17,7 +17,6 @@ static inline int pte_write(pte_t pte)
}
static inline int pte_read(pte_t pte) { return 1; }
static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; }
static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
......@@ -148,70 +147,33 @@ extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte, int percpu)
{
#if defined(CONFIG_PPC_STD_MMU_32) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT)
/* First case is 32-bit Hash MMU in SMP mode with 32-bit PTEs. We use the
* helper pte_update() which does an atomic update. We need to do that
* because a concurrent invalidation can clear _PAGE_HASHPTE. If it's a
* per-CPU PTE such as a kmap_atomic, we do a simple update preserving
* the hash bits instead (ie, same as the non-SMP case)
*/
if (percpu)
*ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
| (pte_val(pte) & ~_PAGE_HASHPTE));
else
pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte));
#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT)
/* Second case is 32-bit with 64-bit PTE. In this case, we
* can just store as long as we do the two halves in the right order
* with a barrier in between. This is possible because we take care,
* in the hash code, to pre-invalidate if the PTE was already hashed,
* which synchronizes us with any concurrent invalidation.
* In the percpu case, we also fallback to the simple update preserving
* the hash bits
* with a barrier in between.
* In the percpu case, we also fallback to the simple update
*/
if (percpu) {
*ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
| (pte_val(pte) & ~_PAGE_HASHPTE));
if (IS_ENABLED(CONFIG_PPC32) && IS_ENABLED(CONFIG_PTE_64BIT) && !percpu) {
__asm__ __volatile__("\
stw%U0%X0 %2,%0\n\
eieio\n\
stw%U0%X0 %L2,%1"
: "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
: "r" (pte) : "memory");
return;
}
#if _PAGE_HASHPTE != 0
if (pte_val(*ptep) & _PAGE_HASHPTE)
flush_hash_entry(mm, ptep, addr);
#endif
__asm__ __volatile__("\
stw%U0%X0 %2,%0\n\
eieio\n\
stw%U0%X0 %L2,%1"
: "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
: "r" (pte) : "memory");
#elif defined(CONFIG_PPC_STD_MMU_32)
/* Third case is 32-bit hash table in UP mode, we need to preserve
* the _PAGE_HASHPTE bit since we may not have invalidated the previous
* translation in the hash yet (done in a subsequent flush_tlb_xxx())
* and see we need to keep track that this PTE needs invalidating
*/
*ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
| (pte_val(pte) & ~_PAGE_HASHPTE));
#else
/* Anything else just stores the PTE normally. That covers all 64-bit
* cases, and 32-bit non-hash with 32-bit PTEs.
*/
*ptep = pte;
#ifdef CONFIG_PPC_BOOK3E_64
/*
* With hardware tablewalk, a sync is needed to ensure that
* subsequent accesses see the PTE we just wrote. Unlike userspace
* mappings, we can't tolerate spurious faults, so make sure
* the new PTE will be seen the first time.
*/
if (is_kernel_addr(addr))
if (IS_ENABLED(CONFIG_PPC_BOOK3E_64) && is_kernel_addr(addr))
mb();
#endif
#endif
}
......
......@@ -57,14 +57,8 @@
#define _PAGE_USER (_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be read */
#define _PAGE_PRIVILEGED (_PAGE_BAP_SR)
#define _PAGE_HASHPTE 0
#define _PAGE_BUSY 0
#define _PAGE_SPECIAL _PAGE_SW0
/* Flags to be preserved on PTE modifications */
#define _PAGE_HPTEFLAGS _PAGE_BUSY
/* Base page size */
#ifdef CONFIG_PPC_64K_PAGES
#define _PAGE_PSIZE _PAGE_PSIZE_64K
......
......@@ -201,13 +201,21 @@
#define OPAL_SET_POWER_SHIFT_RATIO 155
#define OPAL_SENSOR_GROUP_CLEAR 156
#define OPAL_PCI_SET_P2P 157
#define OPAL_QUIESCE 158
#define OPAL_NPU_SPA_SETUP 159
#define OPAL_NPU_SPA_CLEAR_CACHE 160
#define OPAL_NPU_TL_SET 161
#define OPAL_SENSOR_READ_U64 162
#define OPAL_PCI_GET_PBCQ_TUNNEL_BAR 164
#define OPAL_PCI_SET_PBCQ_TUNNEL_BAR 165
#define OPAL_LAST 165
#define QUIESCE_HOLD 1 /* Spin all calls at entry */
#define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */
#define QUIESCE_LOCK_BREAK 3 /* Set to ignore locks. */
#define QUIESCE_RESUME 4 /* Un-quiesce */
#define QUIESCE_RESUME_FAST_REBOOT 5 /* Un-quiesce, fast reboot */
/* Device tree flags */
/*
......
......@@ -201,6 +201,7 @@ int64_t opal_get_param(uint64_t token, uint32_t param_id, uint64_t buffer,
int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer,
uint64_t length);
int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data);
int64_t opal_sensor_read_u64(u32 sensor_hndl, int token, __be64 *sensor_data);
int64_t opal_handle_hmi(void);
int64_t opal_register_dump_region(uint32_t id, uint64_t start, uint64_t end);
int64_t opal_unregister_dump_region(uint32_t id);
......@@ -293,6 +294,7 @@ int opal_set_power_shift_ratio(u32 handle, int token, u32 psr);
int opal_sensor_group_clear(u32 group_hndl, int token);
s64 opal_signal_system_reset(s32 cpu);
s64 opal_quiesce(u64 shutdown_type, s32 cpu);
/* Internal functions */
extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
......@@ -323,9 +325,10 @@ extern int opal_async_wait_response(uint64_t token, struct opal_msg *msg);
extern int opal_async_wait_response_interruptible(uint64_t token,
struct opal_msg *msg);
extern int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data);
extern int opal_get_sensor_data_u64(u32 sensor_hndl, u64 *sensor_data);
struct rtc_time;
extern unsigned long opal_get_boot_time(void);
extern time64_t opal_get_boot_time(void);
extern void opal_nvram_init(void);
extern void opal_flash_update_init(void);
extern void opal_flash_update_print_message(void);
......
......@@ -161,7 +161,7 @@ struct paca_struct {
struct task_struct *__current; /* Pointer to current */
u64 kstack; /* Saved Kernel stack addr */
u64 stab_rr; /* stab/slb round-robin counter */
u64 saved_r1; /* r1 save for RTAS calls or PM */
u64 saved_r1; /* r1 save for RTAS calls or PM or EE=0 */
u64 saved_msr; /* MSR saved here by enter_rtas */
u16 trap_save; /* Used when bad stack is encountered */
u8 irq_soft_mask; /* mask for irq soft masking */
......@@ -222,6 +222,7 @@ struct paca_struct {
u8 hmi_event_available; /* HMI event is available */
u8 hmi_p9_special_emu; /* HMI P9 special emulation */
#endif
u8 ftrace_enabled; /* Hard disable ftrace */
/* Stuff for accurate time accounting */
struct cpu_accounting_data accounting;
......
......@@ -39,6 +39,7 @@
#ifndef __ASSEMBLY__
#ifdef CONFIG_HUGETLB_PAGE
extern bool hugetlb_disabled;
extern unsigned int HPAGE_SHIFT;
#else
#define HPAGE_SHIFT PAGE_SHIFT
......
......@@ -8,6 +8,7 @@
#include <asm/processor.h> /* For TASK_SIZE */
#include <asm/mmu.h>
#include <asm/page.h>
#include <asm/tlbflush.h>
struct mm_struct;
......
......@@ -15,19 +15,6 @@ DECLARE_STATIC_KEY_TRUE(pkey_disabled);
extern int pkeys_total; /* total pkeys as per device tree */
extern u32 initial_allocation_mask; /* bits set for reserved keys */
/*
* Define these here temporarily so we're not dependent on patching linux/mm.h.
* Once it's updated we can drop these.
*/
#ifndef VM_PKEY_BIT0
# define VM_PKEY_SHIFT VM_HIGH_ARCH_BIT_0
# define VM_PKEY_BIT0 VM_HIGH_ARCH_0
# define VM_PKEY_BIT1 VM_HIGH_ARCH_1
# define VM_PKEY_BIT2 VM_HIGH_ARCH_2
# define VM_PKEY_BIT3 VM_HIGH_ARCH_3
# define VM_PKEY_BIT4 VM_HIGH_ARCH_4
#endif
#define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | \
VM_PKEY_BIT3 | VM_PKEY_BIT4)
......
......@@ -39,10 +39,10 @@ static inline long extended_cede_processor(unsigned long latency_hint)
set_cede_latency_hint(latency_hint);
rc = cede_processor();
#ifdef CONFIG_TRACE_IRQFLAGS
/* Ensure that H_CEDE returns with IRQs on */
if (WARN_ON(!(mfmsr() & MSR_EE)))
__hard_irq_enable();
#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
/* Ensure that H_CEDE returns with IRQs on */
if (WARN_ON(!(mfmsr() & MSR_EE)))
__hard_irq_enable();
#endif
set_cede_latency_hint(old_latency_hint);
......
......@@ -245,6 +245,7 @@ extern void pmf_put_function(struct pmf_function *func);
extern int pmf_call_one(struct pmf_function *func, struct pmf_args *args);
int pmac_pfunc_base_install(void);
/* Suspend/resume code called by via-pmu directly for now */
extern void pmac_pfunc_base_suspend(void);
......
......@@ -28,7 +28,7 @@ extern int pnv_ocxl_map_xsl_regs(struct pci_dev *dev, void __iomem **dsisr,
extern int pnv_ocxl_spa_setup(struct pci_dev *dev, void *spa_mem, int PE_mask,
void **platform_data);
extern void pnv_ocxl_spa_release(void *platform_data);
extern int pnv_ocxl_spa_remove_pe(void *platform_data, int pe_handle);
extern int pnv_ocxl_spa_remove_pe_from_cache(void *platform_data, int pe_handle);
extern int pnv_ocxl_alloc_xive_irq(u32 *irq, u64 *trigger_addr);
extern void pnv_ocxl_free_xive_irq(u32 irq);
......
......@@ -162,6 +162,7 @@
/* VMX Vector Store Instructions */
#define OP_31_XOP_STVX 231
#define OP_31 31
#define OP_LWZ 32
#define OP_STFS 52
#define OP_STFSU 53
......
......@@ -80,10 +80,8 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
#else
#define SAVE_GPR(n, base) stw n,GPR0+4*(n)(base)
#define REST_GPR(n, base) lwz n,GPR0+4*(n)(base)
#define SAVE_NVGPRS(base) SAVE_GPR(13, base); SAVE_8GPRS(14, base); \
SAVE_10GPRS(22, base)
#define REST_NVGPRS(base) REST_GPR(13, base); REST_8GPRS(14, base); \
REST_10GPRS(22, base)
#define SAVE_NVGPRS(base) stmw 13, GPR0+4*13(base)
#define REST_NVGPRS(base) lmw 13, GPR0+4*13(base)
#endif
#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base)
......
......@@ -249,7 +249,7 @@ struct thread_struct {
unsigned long ksp_vsid;
#endif
struct pt_regs *regs; /* Pointer to saved register state */
mm_segment_t fs; /* for get_fs() validation */
mm_segment_t addr_limit; /* for get_fs() validation */
#ifdef CONFIG_BOOKE
/* BookE base exception scratch space; align on cacheline */
unsigned long normsave[8] ____cacheline_aligned;
......@@ -264,10 +264,6 @@ struct thread_struct {
struct thread_fp_state *fp_save_area;
int fpexc_mode; /* floating-point exception mode */
unsigned int align_ctl; /* alignment handling control */
#ifdef CONFIG_PPC64
unsigned long start_tb; /* Start purr when proc switched in */
unsigned long accum_tb; /* Total accumulated purr for process */
#endif
#ifdef CONFIG_HAVE_HW_BREAKPOINT
struct perf_event *ptrace_bps[HBP_NUM];
/*
......@@ -383,7 +379,7 @@ struct thread_struct {
#define INIT_THREAD { \
.ksp = INIT_SP, \
.ksp_limit = INIT_SP_LIMIT, \
.fs = KERNEL_DS, \
.addr_limit = KERNEL_DS, \
.pgdir = swapper_pg_dir, \
.fpexc_mode = MSR_FE0 | MSR_FE1, \
SPEFSCR_INIT \
......@@ -392,7 +388,7 @@ struct thread_struct {
#define INIT_THREAD { \
.ksp = INIT_SP, \
.regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \
.fs = KERNEL_DS, \
.addr_limit = KERNEL_DS, \
.fpexc_mode = 0, \
.ppr = INIT_PPR, \
.fscr = FSCR_TAR | FSCR_EBB \
......
......@@ -60,10 +60,6 @@
#ifndef _PMD_PRESENT_MASK
#define _PMD_PRESENT_MASK _PMD_PRESENT
#endif
#ifndef _PMD_SIZE
#define _PMD_SIZE 0
#define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE()
#endif
#ifndef _PMD_USER
#define _PMD_USER 0
#endif
......@@ -88,11 +84,7 @@
#define _PTE_NONE_MASK _PAGE_HPTEFLAGS
#endif
/* Make sure we get a link error if PMD_PAGE_SIZE is ever called on a
* kernel without large page PMD support
*/
#ifndef __ASSEMBLY__
extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
/*
* Don't just check for any non zero bits in __PAGE_USER, since for book3e
......
此差异已折叠。
......@@ -83,6 +83,9 @@ extern int rh_get_stats(rh_info_t * info, int what, int max_stats,
/* Simple dump of remote heap info */
extern void rh_dump(rh_info_t * info);
/* Simple dump of remote info block */
void rh_dump_blk(rh_info_t *info, rh_block_t *blk);
/* Set owner of taken block */
extern int rh_set_owner(rh_info_t * info, unsigned long start, const char *owner);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册