Commit fac515db authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt

Merge remote-tracking branch 'scott/next' into next

Freescale updates from Scott:

<<
Highlights include 32-bit booke relocatable support, e6500 hardware
tablewalk support, various e500 SPE fixes, some new/revived boards, and
e6500 deeper idle and altivec powerdown modes.
>>
parents 3ac8ff1c d064f30e
* Solomon SSD1289 Framebuffer Driver
Required properties:
- compatible: Should be "solomon,ssd1289fb". The only supported bus for
now is lbc.
- reg: Should contain address of the controller on the LBC bus. The detail
was described in Documentation/devicetree/bindings/powerpc/fsl/lbc.txt
Examples:
display@2,0 {
compatible = "solomon,ssd1289fb";
reg = <0x2 0x0000 0x0004>;
};
...@@ -402,8 +402,7 @@ config KEXEC ...@@ -402,8 +402,7 @@ config KEXEC
config CRASH_DUMP config CRASH_DUMP
bool "Build a kdump crash kernel" bool "Build a kdump crash kernel"
depends on PPC64 || 6xx || FSL_BOOKE || (44x && !SMP) depends on PPC64 || 6xx || FSL_BOOKE || (44x && !SMP)
select RELOCATABLE if PPC64 || 44x select RELOCATABLE if PPC64 || 44x || FSL_BOOKE
select DYNAMIC_MEMSTART if FSL_BOOKE
help help
Build a kernel suitable for use as a kdump capture kernel. Build a kernel suitable for use as a kdump capture kernel.
The same kernel binary can be used as production kernel and dump The same kernel binary can be used as production kernel and dump
...@@ -884,7 +883,7 @@ config DYNAMIC_MEMSTART ...@@ -884,7 +883,7 @@ config DYNAMIC_MEMSTART
config RELOCATABLE config RELOCATABLE
bool "Build a relocatable kernel" bool "Build a relocatable kernel"
depends on ADVANCED_OPTIONS && FLATMEM && 44x depends on ADVANCED_OPTIONS && FLATMEM && (44x || FSL_BOOKE)
select NONSTATIC_KERNEL select NONSTATIC_KERNEL
help help
This builds a kernel image that is capable of running at the This builds a kernel image that is capable of running at the
......
...@@ -71,9 +71,9 @@ src-wlib-y := string.S crt0.S crtsavres.S stdio.c main.c \ ...@@ -71,9 +71,9 @@ src-wlib-y := string.S crt0.S crtsavres.S stdio.c main.c \
uartlite.c mpc52xx-psc.c uartlite.c mpc52xx-psc.c
src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c
src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c
src-wlib-$(CONFIG_8xx) += mpc8xx.c planetcore.c src-wlib-$(CONFIG_8xx) += mpc8xx.c planetcore.c fsl-soc.c
src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c
src-wlib-$(CONFIG_EMBEDDED6xx) += mv64x60.c mv64x60_i2c.c ugecon.c src-wlib-$(CONFIG_EMBEDDED6xx) += mv64x60.c mv64x60_i2c.c ugecon.c fsl-soc.c
src-plat-y := of.c epapr.c src-plat-y := of.c epapr.c
src-plat-$(CONFIG_40x) += fixed-head.S ep405.c cuboot-hotfoot.c \ src-plat-$(CONFIG_40x) += fixed-head.S ep405.c cuboot-hotfoot.c \
...@@ -95,7 +95,7 @@ src-plat-$(CONFIG_FSL_SOC_BOOKE) += cuboot-85xx.c cuboot-85xx-cpm2.c ...@@ -95,7 +95,7 @@ src-plat-$(CONFIG_FSL_SOC_BOOKE) += cuboot-85xx.c cuboot-85xx-cpm2.c
src-plat-$(CONFIG_EMBEDDED6xx) += cuboot-pq2.c cuboot-mpc7448hpc2.c \ src-plat-$(CONFIG_EMBEDDED6xx) += cuboot-pq2.c cuboot-mpc7448hpc2.c \
cuboot-c2k.c gamecube-head.S \ cuboot-c2k.c gamecube-head.S \
gamecube.c wii-head.S wii.c holly.c \ gamecube.c wii-head.S wii.c holly.c \
prpmc2800.c prpmc2800.c fixed-head.S mvme5100.c
src-plat-$(CONFIG_AMIGAONE) += cuboot-amigaone.c src-plat-$(CONFIG_AMIGAONE) += cuboot-amigaone.c
src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c
src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c
...@@ -286,6 +286,7 @@ image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2 ...@@ -286,6 +286,7 @@ image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2
image-$(CONFIG_PPC_C2K) += cuImage.c2k image-$(CONFIG_PPC_C2K) += cuImage.c2k
image-$(CONFIG_GAMECUBE) += dtbImage.gamecube image-$(CONFIG_GAMECUBE) += dtbImage.gamecube
image-$(CONFIG_WII) += dtbImage.wii image-$(CONFIG_WII) += dtbImage.wii
image-$(CONFIG_MVME5100) += dtbImage.mvme5100
# Board port in arch/powerpc/platform/amigaone/Kconfig # Board port in arch/powerpc/platform/amigaone/Kconfig
image-$(CONFIG_AMIGAONE) += cuImage.amigaone image-$(CONFIG_AMIGAONE) += cuImage.amigaone
......
/*
* QorIQ Elo3 DMA device tree stub [ controller @ offset 0x102300 ]
*
* Copyright 2013 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
dma2: dma@102300 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,elo3-dma";
reg = <0x102300 0x4>,
<0x102600 0x4>;
ranges = <0x0 0x102100 0x500>;
dma-channel@0 {
compatible = "fsl,eloplus-dma-channel";
reg = <0x0 0x80>;
interrupts = <464 2 0 0>;
};
dma-channel@80 {
compatible = "fsl,eloplus-dma-channel";
reg = <0x80 0x80>;
interrupts = <465 2 0 0>;
};
dma-channel@100 {
compatible = "fsl,eloplus-dma-channel";
reg = <0x100 0x80>;
interrupts = <466 2 0 0>;
};
dma-channel@180 {
compatible = "fsl,eloplus-dma-channel";
reg = <0x180 0x80>;
interrupts = <467 2 0 0>;
};
dma-channel@300 {
compatible = "fsl,eloplus-dma-channel";
reg = <0x300 0x80>;
interrupts = <468 2 0 0>;
};
dma-channel@380 {
compatible = "fsl,eloplus-dma-channel";
reg = <0x380 0x80>;
interrupts = <469 2 0 0>;
};
dma-channel@400 {
compatible = "fsl,eloplus-dma-channel";
reg = <0x400 0x80>;
interrupts = <470 2 0 0>;
};
dma-channel@480 {
compatible = "fsl,eloplus-dma-channel";
reg = <0x480 0x80>;
interrupts = <471 2 0 0>;
};
};
...@@ -36,7 +36,8 @@ &lbc { ...@@ -36,7 +36,8 @@ &lbc {
#address-cells = <2>; #address-cells = <2>;
#size-cells = <1>; #size-cells = <1>;
compatible = "fsl,p1020-elbc", "fsl,elbc", "simple-bus"; compatible = "fsl,p1020-elbc", "fsl,elbc", "simple-bus";
interrupts = <19 2 0 0>; interrupts = <19 2 0 0>,
<16 2 0 0>;
}; };
/* controller at 0x9000 */ /* controller at 0x9000 */
......
...@@ -36,7 +36,8 @@ &lbc { ...@@ -36,7 +36,8 @@ &lbc {
#address-cells = <2>; #address-cells = <2>;
#size-cells = <1>; #size-cells = <1>;
compatible = "fsl,p1021-elbc", "fsl,elbc", "simple-bus"; compatible = "fsl,p1021-elbc", "fsl,elbc", "simple-bus";
interrupts = <19 2 0 0>; interrupts = <19 2 0 0>,
<16 2 0 0>;
}; };
/* controller at 0x9000 */ /* controller at 0x9000 */
......
...@@ -40,7 +40,8 @@ &lbc { ...@@ -40,7 +40,8 @@ &lbc {
* pin muxing when the DIU is enabled. * pin muxing when the DIU is enabled.
*/ */
compatible = "fsl,p1022-elbc", "fsl,elbc"; compatible = "fsl,p1022-elbc", "fsl,elbc";
interrupts = <19 2 0 0>; interrupts = <19 2 0 0>,
<16 2 0 0>;
}; };
/* controller at 0x9000 */ /* controller at 0x9000 */
......
...@@ -36,7 +36,8 @@ &lbc { ...@@ -36,7 +36,8 @@ &lbc {
#address-cells = <2>; #address-cells = <2>;
#size-cells = <1>; #size-cells = <1>;
compatible = "fsl,p1023-elbc", "fsl,elbc", "simple-bus"; compatible = "fsl,p1023-elbc", "fsl,elbc", "simple-bus";
interrupts = <19 2 0 0>; interrupts = <19 2 0 0>,
<16 2 0 0>;
}; };
/* controller at 0xa000 */ /* controller at 0xa000 */
......
/*
* Device Tree Source for Motorola/Emerson MVME5100.
*
* Copyright 2013 CSC Australia Pty. Ltd.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without
* any warranty of any kind, whether express or implied.
*/
/dts-v1/;
/ {
model = "MVME5100";
compatible = "MVME5100";
#address-cells = <1>;
#size-cells = <1>;
aliases {
serial0 = &serial0;
pci0 = &pci0;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
PowerPC,7410 {
device_type = "cpu";
reg = <0x0>;
/* Following required by dtc but not used */
d-cache-line-size = <32>;
i-cache-line-size = <32>;
i-cache-size = <32768>;
d-cache-size = <32768>;
timebase-frequency = <25000000>;
clock-frequency = <500000000>;
bus-frequency = <100000000>;
};
};
memory {
device_type = "memory";
reg = <0x0 0x20000000>;
};
hawk@fef80000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "hawk-bridge", "simple-bus";
ranges = <0x0 0xfef80000 0x10000>;
reg = <0xfef80000 0x10000>;
serial0: serial@8000 {
device_type = "serial";
compatible = "ns16550";
reg = <0x8000 0x80>;
reg-shift = <4>;
clock-frequency = <1843200>;
current-speed = <9600>;
interrupts = <1 1>; // IRQ1 Level Active Low.
interrupt-parent = <&mpic>;
};
serial1: serial@8200 {
device_type = "serial";
compatible = "ns16550";
reg = <0x8200 0x80>;
reg-shift = <4>;
clock-frequency = <1843200>;
current-speed = <9600>;
interrupts = <1 1>; // IRQ1 Level Active Low.
interrupt-parent = <&mpic>;
};
mpic: interrupt-controller@f3f80000 {
#interrupt-cells = <2>;
#address-cells = <0>;
device_type = "open-pic";
compatible = "chrp,open-pic";
interrupt-controller;
reg = <0xf3f80000 0x40000>;
};
};
pci0: pci@feff0000 {
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
device_type = "pci";
compatible = "hawk-pci";
reg = <0xfec00000 0x400000>;
8259-interrupt-acknowledge = <0xfeff0030>;
ranges = <0x1000000 0x0 0x0 0xfe000000 0x0 0x800000
0x2000000 0x0 0x80000000 0x80000000 0x0 0x74000000>;
bus-range = <0 255>;
clock-frequency = <33333333>;
interrupt-parent = <&mpic>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/*
* This definition (IDSEL 11) duplicates the
* interrupts definition in the i8259
* interrupt controller below.
*
* Do not change the interrupt sense/polarity from
* 0x2 to anything else, doing so will cause endless
* "spurious" i8259 interrupts to be fielded.
*/
// IDSEL 11 - iPMC712 PCI/ISA Bridge
0x5800 0x0 0x0 0x1 &mpic 0x0 0x2
0x5800 0x0 0x0 0x2 &mpic 0x0 0x2
0x5800 0x0 0x0 0x3 &mpic 0x0 0x2
0x5800 0x0 0x0 0x4 &mpic 0x0 0x2
/* IDSEL 12 - Not Used */
/* IDSEL 13 - Universe VME Bridge */
0x6800 0x0 0x0 0x1 &mpic 0x5 0x1
0x6800 0x0 0x0 0x2 &mpic 0x6 0x1
0x6800 0x0 0x0 0x3 &mpic 0x7 0x1
0x6800 0x0 0x0 0x4 &mpic 0x8 0x1
/* IDSEL 14 - ENET 1 */
0x7000 0x0 0x0 0x1 &mpic 0x2 0x1
/* IDSEL 15 - Not Used */
/* IDSEL 16 - PMC Slot 1 */
0x8000 0x0 0x0 0x1 &mpic 0x9 0x1
0x8000 0x0 0x0 0x2 &mpic 0xa 0x1
0x8000 0x0 0x0 0x3 &mpic 0xb 0x1
0x8000 0x0 0x0 0x4 &mpic 0xc 0x1
/* IDSEL 17 - PMC Slot 2 */
0x8800 0x0 0x0 0x1 &mpic 0xc 0x1
0x8800 0x0 0x0 0x2 &mpic 0x9 0x1
0x8800 0x0 0x0 0x3 &mpic 0xa 0x1
0x8800 0x0 0x0 0x4 &mpic 0xb 0x1
/* IDSEL 18 - Not Used */
/* IDSEL 19 - ENET 2 */
0x9800 0x0 0x0 0x1 &mpic 0xd 0x1
/* IDSEL 20 - PMCSPAN (PCI-X) */
0xa000 0x0 0x0 0x1 &mpic 0x9 0x1
0xa000 0x0 0x0 0x2 &mpic 0xa 0x1
0xa000 0x0 0x0 0x3 &mpic 0xb 0x1
0xa000 0x0 0x0 0x4 &mpic 0xc 0x1
>;
isa {
#address-cells = <2>;
#size-cells = <1>;
#interrupt-cells = <2>;
device_type = "isa";
compatible = "isa";
ranges = <0x00000001 0 0x01000000 0 0x00000000 0x00001000>;
interrupt-parent = <&i8259>;
i8259: interrupt-controller@20 {
#interrupt-cells = <2>;
#address-cells = <0>;
interrupts = <0 2>;
device_type = "interrupt-controller";
compatible = "chrp,iic";
interrupt-controller;
reg = <1 0x00000020 0x00000002
1 0x000000a0 0x00000002
1 0x000004d0 0x00000002>;
interrupt-parent = <&mpic>;
};
};
};
chosen {
linux,stdout-path = &serial0;
};
};
...@@ -15,52 +15,9 @@ / { ...@@ -15,52 +15,9 @@ / {
model = "fsl,P1010RDB"; model = "fsl,P1010RDB";
compatible = "fsl,P1010RDB"; compatible = "fsl,P1010RDB";
memory { /include/ "p1010rdb_32b.dtsi"
device_type = "memory";
};
board_ifc: ifc: ifc@ffe1e000 {
/* NOR, NAND Flashes and CPLD on board */
ranges = <0x0 0x0 0x0 0xee000000 0x02000000
0x1 0x0 0x0 0xff800000 0x00010000
0x3 0x0 0x0 0xffb00000 0x00000020>;
reg = <0x0 0xffe1e000 0 0x2000>;
};
board_soc: soc: soc@ffe00000 {
ranges = <0x0 0x0 0xffe00000 0x100000>;
};
pci0: pcie@ffe09000 {
reg = <0 0xffe09000 0 0x1000>;
ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
pcie@0 {
ranges = <0x2000000 0x0 0xa0000000
0x2000000 0x0 0xa0000000
0x0 0x20000000
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
};
};
pci1: pcie@ffe0a000 {
reg = <0 0xffe0a000 0 0x1000>;
ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
pcie@0 {
ranges = <0x2000000 0x0 0x80000000
0x2000000 0x0 0x80000000
0x0 0x20000000
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
};
};
}; };
/include/ "p1010rdb.dtsi" /include/ "p1010rdb.dtsi"
/include/ "p1010rdb-pa.dtsi"
/include/ "fsl/p1010si-post.dtsi" /include/ "fsl/p1010si-post.dtsi"
/*
* P1010 RDB Device Tree Source stub (no addresses or top-level ranges)
*
* Copyright 2013 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
&ifc_nand {
partition@0 {
/* This location must not be altered */
/* 1MB for u-boot Bootloader Image */
reg = <0x0 0x00100000>;
label = "NAND U-Boot Image";
read-only;
};
partition@100000 {
/* 1MB for DTB Image */
reg = <0x00100000 0x00100000>;
label = "NAND DTB Image";
};
partition@200000 {
/* 4MB for Linux Kernel Image */
reg = <0x00200000 0x00400000>;
label = "NAND Linux Kernel Image";
};
partition@600000 {
/* 4MB for Compressed Root file System Image */
reg = <0x00600000 0x00400000>;
label = "NAND Compressed RFS Image";
};
partition@a00000 {
/* 15MB for JFFS2 based Root file System */
reg = <0x00a00000 0x00f00000>;
label = "NAND JFFS2 Root File System";
};
partition@1900000 {
/* 7MB for User Area */
reg = <0x01900000 0x00700000>;
label = "NAND User area";
};
};
&phy0 {
interrupts = <1 1 0 0>;
};
&phy1 {
interrupts = <2 1 0 0>;
};
&phy2 {
interrupts = <4 1 0 0>;
};
...@@ -38,52 +38,9 @@ / { ...@@ -38,52 +38,9 @@ / {
model = "fsl,P1010RDB"; model = "fsl,P1010RDB";
compatible = "fsl,P1010RDB"; compatible = "fsl,P1010RDB";
memory { /include/ "p1010rdb_36b.dtsi"
device_type = "memory";
};
board_ifc: ifc: ifc@fffe1e000 {
/* NOR, NAND Flashes and CPLD on board */
ranges = <0x0 0x0 0xf 0xee000000 0x02000000
0x1 0x0 0xf 0xff800000 0x00010000
0x3 0x0 0xf 0xffb00000 0x00000020>;
reg = <0xf 0xffe1e000 0 0x2000>;
};
board_soc: soc: soc@fffe00000 {
ranges = <0x0 0xf 0xffe00000 0x100000>;
};
pci0: pcie@fffe09000 {
reg = <0xf 0xffe09000 0 0x1000>;
ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
pcie@0 {
ranges = <0x2000000 0x0 0xc0000000
0x2000000 0x0 0xc0000000
0x0 0x20000000
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
};
};
pci1: pcie@fffe0a000 {
reg = <0xf 0xffe0a000 0 0x1000>;
ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
pcie@0 {
ranges = <0x2000000 0x0 0xc0000000
0x2000000 0x0 0xc0000000
0x0 0x20000000
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
};
};
}; };
/include/ "p1010rdb.dtsi" /include/ "p1010rdb.dtsi"
/include/ "p1010rdb-pa.dtsi"
/include/ "fsl/p1010si-post.dtsi" /include/ "fsl/p1010si-post.dtsi"
/*
* P1010 RDB Device Tree Source
*
* Copyright 2011 Freescale Semiconductor Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
/include/ "fsl/p1010si-pre.dtsi"
/ {
model = "fsl,P1010RDB-PB";
compatible = "fsl,P1010RDB-PB";
/include/ "p1010rdb_32b.dtsi"
};
/include/ "p1010rdb.dtsi"
&phy0 {
interrupts = <0 1 0 0>;
};
&phy1 {
interrupts = <2 1 0 0>;
};
&phy2 {
interrupts = <1 1 0 0>;
};
/include/ "fsl/p1010si-post.dtsi"
/*
* P1010 RDB Device Tree Source (36-bit address map)
*
* Copyright 2011 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/include/ "fsl/p1010si-pre.dtsi"
/ {
model = "fsl,P1010RDB-PB";
compatible = "fsl,P1010RDB-PB";
/include/ "p1010rdb_36b.dtsi"
};
/include/ "p1010rdb.dtsi"
&phy0 {
interrupts = <0 1 0 0>;
};
&phy1 {
interrupts = <2 1 0 0>;
};
&phy2 {
interrupts = <1 1 0 0>;
};
/include/ "fsl/p1010si-post.dtsi"
...@@ -69,49 +69,11 @@ partition@1f00000 { ...@@ -69,49 +69,11 @@ partition@1f00000 {
}; };
}; };
nand@1,0 { ifc_nand: nand@1,0 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
compatible = "fsl,ifc-nand"; compatible = "fsl,ifc-nand";
reg = <0x1 0x0 0x10000>; reg = <0x1 0x0 0x10000>;
partition@0 {
/* This location must not be altered */
/* 1MB for u-boot Bootloader Image */
reg = <0x0 0x00100000>;
label = "NAND U-Boot Image";
read-only;
};
partition@100000 {
/* 1MB for DTB Image */
reg = <0x00100000 0x00100000>;
label = "NAND DTB Image";
};
partition@200000 {
/* 4MB for Linux Kernel Image */
reg = <0x00200000 0x00400000>;
label = "NAND Linux Kernel Image";
};
partition@600000 {
/* 4MB for Compressed Root file System Image */
reg = <0x00600000 0x00400000>;
label = "NAND Compressed RFS Image";
};
partition@a00000 {
/* 15MB for JFFS2 based Root file System */
reg = <0x00a00000 0x00f00000>;
label = "NAND JFFS2 Root File System";
};
partition@1900000 {
/* 7MB for User Area */
reg = <0x01900000 0x00700000>;
label = "NAND User area";
};
}; };
cpld@3,0 { cpld@3,0 {
...@@ -193,17 +155,14 @@ usb@22000 { ...@@ -193,17 +155,14 @@ usb@22000 {
mdio@24000 { mdio@24000 {
phy0: ethernet-phy@0 { phy0: ethernet-phy@0 {
interrupts = <3 1 0 0>;
reg = <0x1>; reg = <0x1>;
}; };
phy1: ethernet-phy@1 { phy1: ethernet-phy@1 {
interrupts = <2 1 0 0>;
reg = <0x0>; reg = <0x0>;
}; };
phy2: ethernet-phy@2 { phy2: ethernet-phy@2 {
interrupts = <2 1 0 0>;
reg = <0x2>; reg = <0x2>;
}; };
......
/*
* P1010 RDB Device Tree Source stub (no addresses or top-level ranges)
*
* Copyright 2013 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
memory {
device_type = "memory";
};
board_ifc: ifc: ifc@ffe1e000 {
/* NOR, NAND Flashes and CPLD on board */
ranges = <0x0 0x0 0x0 0xee000000 0x02000000
0x1 0x0 0x0 0xff800000 0x00010000
0x3 0x0 0x0 0xffb00000 0x00000020>;
reg = <0x0 0xffe1e000 0 0x2000>;
};
board_soc: soc: soc@ffe00000 {
ranges = <0x0 0x0 0xffe00000 0x100000>;
};
pci0: pcie@ffe09000 {
reg = <0 0xffe09000 0 0x1000>;
ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
pcie@0 {
ranges = <0x2000000 0x0 0xa0000000
0x2000000 0x0 0xa0000000
0x0 0x20000000
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
};
};
pci1: pcie@ffe0a000 {
reg = <0 0xffe0a000 0 0x1000>;
ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
pcie@0 {
ranges = <0x2000000 0x0 0x80000000
0x2000000 0x0 0x80000000
0x0 0x20000000
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
};
};
/*
* P1010 RDB Device Tree Source stub (no addresses or top-level ranges)
*
* Copyright 2013 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
memory {
device_type = "memory";
};
board_ifc: ifc: ifc@fffe1e000 {
/* NOR, NAND Flashes and CPLD on board */
ranges = <0x0 0x0 0xf 0xee000000 0x02000000
0x1 0x0 0xf 0xff800000 0x00010000
0x3 0x0 0xf 0xffb00000 0x00000020>;
reg = <0xf 0xffe1e000 0 0x2000>;
};
board_soc: soc: soc@fffe00000 {
ranges = <0x0 0xf 0xffe00000 0x100000>;
};
pci0: pcie@fffe09000 {
reg = <0xf 0xffe09000 0 0x1000>;
ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
pcie@0 {
ranges = <0x2000000 0x0 0xc0000000
0x2000000 0x0 0xc0000000
0x0 0x20000000
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
};
};
pci1: pcie@fffe0a000 {
reg = <0xf 0xffe0a000 0 0x1000>;
ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
pcie@0 {
ranges = <0x2000000 0x0 0xc0000000
0x2000000 0x0 0xc0000000
0x0 0x20000000
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
};
};
...@@ -146,8 +146,9 @@ wm8776:codec@1a { ...@@ -146,8 +146,9 @@ wm8776:codec@1a {
*/ */
}; };
rtc@68 { rtc@68 {
compatible = "dallas,ds1339"; compatible = "dallas,ds3232";
reg = <0x68>; reg = <0x68>;
interrupts = <0x1 0x1 0 0>;
}; };
adt7461@4c { adt7461@4c {
compatible = "adi,adt7461"; compatible = "adi,adt7461";
......
/*
* P1025 TWR Device Tree Source (32-bit address map)
*
* Copyright 2013 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/include/ "fsl/p1021si-pre.dtsi"
/ {
model = "fsl,P1025";
compatible = "fsl,TWR-P1025";
memory {
device_type = "memory";
};
lbc: localbus@ffe05000 {
reg = <0 0xffe05000 0 0x1000>;
/* NOR Flash and SSD1289 */
ranges = <0x0 0x0 0x0 0xec000000 0x04000000
0x2 0x0 0x0 0xe0000000 0x00020000>;
};
soc: soc@ffe00000 {
ranges = <0x0 0x0 0xffe00000 0x100000>;
};
pci0: pcie@ffe09000 {
ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
reg = <0 0xffe09000 0 0x1000>;
pcie@0 {
ranges = <0x2000000 0x0 0xa0000000
0x2000000 0x0 0xa0000000
0x0 0x20000000
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
};
};
pci1: pcie@ffe0a000 {
reg = <0 0xffe0a000 0 0x1000>;
ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
pcie@0 {
ranges = <0x2000000 0x0 0x80000000
0x2000000 0x0 0x80000000
0x0 0x20000000
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
};
};
qe: qe@ffe80000 {
ranges = <0x0 0x0 0xffe80000 0x40000>;
reg = <0 0xffe80000 0 0x480>;
brg-frequency = <0>;
bus-frequency = <0>;
};
};
/include/ "p1025twr.dtsi"
/include/ "fsl/p1021si-post.dtsi"
/*
* P1025 TWR Device Tree Source stub (no addresses or top-level ranges)
*
* Copyright 2013 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Freescale Semiconductor nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* ALTERNATIVELY, this software may be distributed under the terms of the
* GNU General Public License ("GPL") as published by the Free Software
* Foundation, either version 2 of that License or (at your option) any
* later version.
*
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/{
aliases {
ethernet3 = &enet3;
ethernet4 = &enet4;
};
};
&lbc {
nor@0,0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "cfi-flash";
reg = <0x0 0x0 0x4000000>;
bank-width = <2>;
device-width = <1>;
partition@0 {
/* This location must not be altered */
/* 256KB for Vitesse 7385 Switch firmware */
reg = <0x0 0x00040000>;
label = "NOR Vitesse-7385 Firmware";
read-only;
};
partition@40000 {
/* 256KB for DTB Image */
reg = <0x00040000 0x00040000>;
label = "NOR DTB Image";
};
partition@80000 {
/* 5.5 MB for Linux Kernel Image */
reg = <0x00080000 0x00580000>;
label = "NOR Linux Kernel Image";
};
partition@400000 {
/* 56.75MB for Root file System */
reg = <0x00600000 0x038c0000>;
label = "NOR Root File System";
};
partition@ec0000 {
/* This location must not be altered */
/* 256KB for QE ucode firmware*/
reg = <0x03ec0000 0x00040000>;
label = "NOR QE microcode firmware";
read-only;
};
partition@f00000 {
/* This location must not be altered */
/* 512KB for u-boot Bootloader Image */
/* 512KB for u-boot Environment Variables */
reg = <0x03f00000 0x00100000>;
label = "NOR U-Boot Image";
read-only;
};
};
/* CS2 for Display */
display@2,0 {
compatible = "solomon,ssd1289fb";
reg = <0x2 0x0000 0x0004>;
};
};
&soc {
usb@22000 {
phy_type = "ulpi";
};
mdio@24000 {
phy0: ethernet-phy@2 {
interrupt-parent = <&mpic>;
interrupts = <1 1 0 0>;
reg = <0x2>;
};
phy1: ethernet-phy@1 {
interrupt-parent = <&mpic>;
interrupts = <2 1 0 0>;
reg = <0x1>;
};
tbi0: tbi-phy@11 {
reg = <0x11>;
device_type = "tbi-phy";
};
};
mdio@25000 {
tbi1: tbi-phy@11 {
reg = <0x11>;
device_type = "tbi-phy";
};
};
mdio@26000 {
tbi2: tbi-phy@11 {
reg = <0x11>;
device_type = "tbi-phy";
};
};
enet0: ethernet@b0000 {
phy-handle = <&phy0>;
phy-connection-type = "rgmii-id";
};
enet1: ethernet@b1000 {
status = "disabled";
};
enet2: ethernet@b2000 {
phy-handle = <&phy1>;
phy-connection-type = "rgmii-id";
};
par_io@e0100 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0xe0100 0x60>;
ranges = <0x0 0xe0100 0x60>;
device_type = "par_io";
num-ports = <3>;
pio1: ucc_pin@01 {
pio-map = <
/* port pin dir open_drain assignment has_irq */
0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
0x0 0x17 0x2 0x0 0x2 0x0 /* CLK12 */
0x0 0x18 0x2 0x0 0x1 0x0 /* CLK9 */
0x0 0x7 0x1 0x0 0x2 0x0 /* ENET1_TXD0_SER1_TXD0 */
0x0 0x9 0x1 0x0 0x2 0x0 /* ENET1_TXD1_SER1_TXD1 */
0x0 0xb 0x1 0x0 0x2 0x0 /* ENET1_TXD2_SER1_TXD2 */
0x0 0xc 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */
0x0 0x6 0x2 0x0 0x2 0x0 /* ENET1_RXD0_SER1_RXD0 */
0x0 0xa 0x2 0x0 0x2 0x0 /* ENET1_RXD1_SER1_RXD1 */
0x0 0xe 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */
0x0 0xf 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */
0x0 0x5 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */
0x0 0xd 0x1 0x0 0x2 0x0 /* ENET1_TX_ER */
0x0 0x4 0x2 0x0 0x2 0x0 /* ENET1_RX_DV_SER1_CTS_B */
0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RX_ER_SER1_CD_B */
0x0 0x11 0x2 0x0 0x2 0x0 /* ENET1_CRS */
0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */
};
pio2: ucc_pin@02 {
pio-map = <
/* port pin dir open_drain assignment has_irq */
0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
0x1 0xb 0x2 0x0 0x1 0x0 /* CLK13 */
0x1 0x7 0x1 0x0 0x2 0x0 /* ENET5_TXD0_SER5_TXD0 */
0x1 0xa 0x1 0x0 0x2 0x0 /* ENET5_TXD1_SER5_TXD1 */
0x1 0x6 0x2 0x0 0x2 0x0 /* ENET5_RXD0_SER5_RXD0 */
0x1 0x9 0x2 0x0 0x2 0x0 /* ENET5_RXD1_SER5_RXD1 */
0x1 0x5 0x1 0x0 0x2 0x0 /* ENET5_TX_EN_SER5_RTS_B */
0x1 0x4 0x2 0x0 0x2 0x0 /* ENET5_RX_DV_SER5_CTS_B */
0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */
};
pio3: ucc_pin@03 {
pio-map = <
/* port pin dir open_drain assignment has_irq */
0x0 0x16 0x2 0x0 0x2 0x0 /* SER7_CD_B*/
0x0 0x12 0x2 0x0 0x2 0x0 /* SER7_CTS_B*/
0x0 0x13 0x1 0x0 0x2 0x0 /* SER7_RTS_B*/
0x0 0x14 0x2 0x0 0x2 0x0 /* SER7_RXD0*/
0x0 0x15 0x1 0x0 0x2 0x0>; /* SER7_TXD0*/
};
pio4: ucc_pin@04 {
pio-map = <
/* port pin dir open_drain assignment has_irq */
0x1 0x0 0x2 0x0 0x2 0x0 /* SER3_CD_B*/
0x0 0x1c 0x2 0x0 0x2 0x0 /* SER3_CTS_B*/
0x0 0x1d 0x1 0x0 0x2 0x0 /* SER3_RTS_B*/
0x0 0x1e 0x2 0x0 0x2 0x0 /* SER3_RXD0*/
0x0 0x1f 0x1 0x0 0x2 0x0>; /* SER3_TXD0*/
};
};
};
&qe {
enet3: ucc@2000 {
device_type = "network";
compatible = "ucc_geth";
rx-clock-name = "clk12";
tx-clock-name = "clk9";
pio-handle = <&pio1>;
phy-handle = <&qe_phy0>;
phy-connection-type = "mii";
};
mdio@2120 {
qe_phy0: ethernet-phy@18 {
interrupt-parent = <&mpic>;
interrupts = <4 1 0 0>;
reg = <0x18>;
device_type = "ethernet-phy";
};
qe_phy1: ethernet-phy@19 {
interrupt-parent = <&mpic>;
interrupts = <5 1 0 0>;
reg = <0x19>;
device_type = "ethernet-phy";
};
tbi-phy@11 {
reg = <0x11>;
device_type = "tbi-phy";
};
};
enet4: ucc@2400 {
device_type = "network";
compatible = "ucc_geth";
rx-clock-name = "none";
tx-clock-name = "clk13";
pio-handle = <&pio2>;
phy-handle = <&qe_phy1>;
phy-connection-type = "rmii";
};
serial2: ucc@2600 {
device_type = "serial";
compatible = "ucc_uart";
port-number = <0>;
rx-clock-name = "brg6";
tx-clock-name = "brg6";
pio-handle = <&pio3>;
};
serial3: ucc@2200 {
device_type = "serial";
compatible = "ucc_uart";
port-number = <1>;
rx-clock-name = "brg2";
tx-clock-name = "brg2";
pio-handle = <&pio4>;
};
};
/*
* Motorola/Emerson MVME5100 with PPCBug firmware.
*
* Author: Stephen Chivers <schivers@csc.com>
*
* Copyright 2013 CSC Australia Pty. Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*/
#include "types.h"
#include "ops.h"
#include "io.h"
BSS_STACK(4096);
void platform_init(unsigned long r3, unsigned long r4, unsigned long r5)
{
u32 heapsize;
heapsize = 0x8000000 - (u32)_end; /* 128M */
simple_alloc_init(_end, heapsize, 32, 64);
fdt_init(_dtb_start);
serial_console_init();
}
...@@ -265,6 +265,10 @@ epapr) ...@@ -265,6 +265,10 @@ epapr)
link_address='0x20000000' link_address='0x20000000'
pie=-pie pie=-pie
;; ;;
mvme5100)
platformo="$object/fixed-head.o $object/mvme5100.o"
binary=y
;;
esac esac
vmz="$tmpdir/`basename \"$kernel\"`.$ext" vmz="$tmpdir/`basename \"$kernel\"`.$ext"
......
CONFIG_PPC_85xx=y
CONFIG_SMP=y
CONFIG_NR_CPUS=2
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_AUDIT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_RCU_FANOUT=32
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
CONFIG_MAC_PARTITION=y
CONFIG_PHYSICAL_START=0x00000000
CONFIG_P1023_RDB=y
CONFIG_P1023_RDS=y
CONFIG_QUICC_ENGINE=y
CONFIG_QE_GPIO=y
CONFIG_CPM2=y
CONFIG_HIGHMEM=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=m
CONFIG_MATH_EMULATION=y
CONFIG_SWIOTLB=y
CONFIG_PCI=y
CONFIG_PCIEPORTBUS=y
# CONFIG_PCIEAER is not set
# CONFIG_PCIEASPM is not set
CONFIG_PCI_MSI=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_XFRM_USER=y
CONFIG_NET_KEY=y
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_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_NET_IPIP=y
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_ARPD=y
CONFIG_INET_ESP=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_IPV6=y
CONFIG_IP_SCTP=m
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_FSL_ELBC=y
CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=131072
CONFIG_EEPROM_AT24=y
CONFIG_EEPROM_LEGACY=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y
CONFIG_CHR_DEV_SG=y
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_LOGGING=y
CONFIG_ATA=y
CONFIG_SATA_FSL=y
CONFIG_SATA_SIL24=y
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
CONFIG_FS_ENET=y
CONFIG_FSL_PQ_MDIO=y
CONFIG_E1000E=y
CONFIG_PHYLIB=y
CONFIG_AT803X_PHY=y
CONFIG_MARVELL_PHY=y
CONFIG_DAVICOM_PHY=y
CONFIG_CICADA_PHY=y
CONFIG_VITESSE_PHY=y
CONFIG_FIXED_PHY=y
CONFIG_INPUT_FF_MEMLESS=m
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=2
CONFIG_SERIAL_8250_RUNTIME_UARTS=2
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_RSA=y
CONFIG_HW_RANDOM=y
CONFIG_NVRAM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_CPM=m
CONFIG_I2C_MPC=y
CONFIG_GPIO_MPC8XXX=y
# CONFIG_HWMON is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
# CONFIG_SND_SUPPORT_OLD_API is not set
CONFIG_USB=y
CONFIG_USB_DEVICEFS=y
CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_FSL=y
CONFIG_USB_STORAGE=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_DS1307=y
CONFIG_RTC_DRV_CMOS=y
CONFIG_DMADEVICES=y
CONFIG_FSL_DMA=y
# CONFIG_NET_DMA is not set
CONFIG_STAGING=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=y
CONFIG_NTFS_FS=y
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_ADFS_FS=m
CONFIG_AFFS_FS=m
CONFIG_HFS_FS=m
CONFIG_HFSPLUS_FS=m
CONFIG_BEFS_FS=m
CONFIG_BFS_FS=m
CONFIG_EFS_FS=m
CONFIG_CRAMFS=y
CONFIG_VXFS_FS=m
CONFIG_HPFS_FS=m
CONFIG_QNX4FS_FS=m
CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
CONFIG_NFS_FS=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
CONFIG_CRC_T10DIF=y
CONFIG_FRAME_WARN=8092
CONFIG_DEBUG_FS=y
CONFIG_DETECT_HUNG_TASK=y
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_DEBUG_INFO=y
CONFIG_STRICT_DEVMEM=y
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_DEV_FSL_CAAM=y
...@@ -70,3 +70,4 @@ CONFIG_DEBUG_KERNEL=y ...@@ -70,3 +70,4 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_CRC32_SLICEBY4=y
...@@ -72,3 +72,4 @@ CONFIG_DEBUG_KERNEL=y ...@@ -72,3 +72,4 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_CRC32_SLICEBY4=y
...@@ -31,6 +31,7 @@ CONFIG_C293_PCIE=y ...@@ -31,6 +31,7 @@ CONFIG_C293_PCIE=y
CONFIG_P1010_RDB=y CONFIG_P1010_RDB=y
CONFIG_P1022_DS=y CONFIG_P1022_DS=y
CONFIG_P1022_RDK=y CONFIG_P1022_RDK=y
CONFIG_P1023_RDB=y
CONFIG_P1023_RDS=y CONFIG_P1023_RDS=y
CONFIG_SOCRATES=y CONFIG_SOCRATES=y
CONFIG_KSI8560=y CONFIG_KSI8560=y
...@@ -113,6 +114,7 @@ CONFIG_BLK_DEV_LOOP=y ...@@ -113,6 +114,7 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=131072 CONFIG_BLK_DEV_RAM_SIZE=131072
CONFIG_EEPROM_AT24=y
CONFIG_EEPROM_LEGACY=y CONFIG_EEPROM_LEGACY=y
CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y CONFIG_CHR_DEV_ST=y
...@@ -211,6 +213,7 @@ CONFIG_EDAC=y ...@@ -211,6 +213,7 @@ CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y CONFIG_EDAC_MM_EDAC=y
CONFIG_RTC_CLASS=y CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_CMOS=y CONFIG_RTC_DRV_CMOS=y
CONFIG_RTC_DRV_DS1307=y
CONFIG_DMADEVICES=y CONFIG_DMADEVICES=y
CONFIG_FSL_DMA=y CONFIG_FSL_DMA=y
# CONFIG_NET_DMA is not set # CONFIG_NET_DMA is not set
......
...@@ -34,6 +34,7 @@ CONFIG_C293_PCIE=y ...@@ -34,6 +34,7 @@ CONFIG_C293_PCIE=y
CONFIG_P1010_RDB=y CONFIG_P1010_RDB=y
CONFIG_P1022_DS=y CONFIG_P1022_DS=y
CONFIG_P1022_RDK=y CONFIG_P1022_RDK=y
CONFIG_P1023_RDB=y
CONFIG_P1023_RDS=y CONFIG_P1023_RDS=y
CONFIG_SOCRATES=y CONFIG_SOCRATES=y
CONFIG_KSI8560=y CONFIG_KSI8560=y
...@@ -116,6 +117,7 @@ CONFIG_BLK_DEV_LOOP=y ...@@ -116,6 +117,7 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=131072 CONFIG_BLK_DEV_RAM_SIZE=131072
CONFIG_EEPROM_AT24=y
CONFIG_EEPROM_LEGACY=y CONFIG_EEPROM_LEGACY=y
CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y CONFIG_CHR_DEV_ST=y
...@@ -212,6 +214,7 @@ CONFIG_EDAC=y ...@@ -212,6 +214,7 @@ CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y CONFIG_EDAC_MM_EDAC=y
CONFIG_RTC_CLASS=y CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_CMOS=y CONFIG_RTC_DRV_CMOS=y
CONFIG_RTC_DRV_DS1307=y
CONFIG_DMADEVICES=y CONFIG_DMADEVICES=y
CONFIG_FSL_DMA=y CONFIG_FSL_DMA=y
# CONFIG_NET_DMA is not set # CONFIG_NET_DMA is not set
......
...@@ -55,3 +55,4 @@ CONFIG_PARTITION_ADVANCED=y ...@@ -55,3 +55,4 @@ CONFIG_PARTITION_ADVANCED=y
CONFIG_CRC_CCITT=y CONFIG_CRC_CCITT=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRC32_SLICEBY4=y
...@@ -78,3 +78,4 @@ CONFIG_DEBUG_KERNEL=y ...@@ -78,3 +78,4 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_CRC32_SLICEBY4=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
# CONFIG_PID_NS is not set
# CONFIG_NET_NS is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
# CONFIG_COMPAT_BRK is not set
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_EMBEDDED6xx=y
CONFIG_MVME5100=y
CONFIG_KVM_GUEST=y
CONFIG_HZ_100=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_COMPACTION is not set
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="console=ttyS0,9600 ip=dhcp root=/dev/nfs"
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_INET_LRO is not set
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
CONFIG_NF_CONNTRACK=m
CONFIG_NF_CT_PROTO_SCTP=m
CONFIG_NF_CONNTRACK_AMANDA=m
CONFIG_NF_CONNTRACK_FTP=m
CONFIG_NF_CONNTRACK_H323=m
CONFIG_NF_CONNTRACK_IRC=m
CONFIG_NF_CONNTRACK_NETBIOS_NS=m
CONFIG_NF_CONNTRACK_PPTP=m
CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NETFILTER_XT_MATCH_MAC=m
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
CONFIG_NETFILTER_XT_MATCH_STATE=m
CONFIG_NF_CONNTRACK_IPV4=m
CONFIG_IP_NF_IPTABLES=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_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_LAPB=m
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=2
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_EEPROM_LEGACY=m
CONFIG_NETDEVICES=y
CONFIG_TUN=m
# CONFIG_NET_VENDOR_3COM is not set
CONFIG_E100=y
# CONFIG_WLAN is not set
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=10
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_HW_RANDOM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MPC=y
# CONFIG_HWMON is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
# CONFIG_VGA_CONSOLE is not set
# CONFIG_HID is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_VME_BUS=m
CONFIG_VME_CA91CX42=m
CONFIG_EXT2_FS=m
CONFIG_EXT3_FS=m
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_XFS_FS=m
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
CONFIG_CIFS=m
CONFIG_NLS=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_932=m
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_UTF8=m
CONFIG_CRC_CCITT=m
CONFIG_CRC_T10DIF=y
CONFIG_XZ_DEC=y
CONFIG_XZ_DEC_X86=y
CONFIG_XZ_DEC_IA64=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_ARMTHUMB=y
CONFIG_XZ_DEC_SPARC=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=20
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_DEFLATE=m
# CONFIG_CRYPTO_ANSI_CPRNG is not set
...@@ -84,3 +84,4 @@ CONFIG_DEBUG_KERNEL=y ...@@ -84,3 +84,4 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_CRC32_SLICEBY4=y
...@@ -285,7 +285,7 @@ struct fsl_lbc_ctrl { ...@@ -285,7 +285,7 @@ struct fsl_lbc_ctrl {
/* device info */ /* device info */
struct device *dev; struct device *dev;
struct fsl_lbc_regs __iomem *regs; struct fsl_lbc_regs __iomem *regs;
int irq; int irq[2];
wait_queue_head_t irq_wait; wait_queue_head_t irq_wait;
spinlock_t lock; spinlock_t lock;
void *nand; void *nand;
......
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
#define BOOKE_INTERRUPT_GUEST_DBELL_CRIT 39 #define BOOKE_INTERRUPT_GUEST_DBELL_CRIT 39
#define BOOKE_INTERRUPT_HV_SYSCALL 40 #define BOOKE_INTERRUPT_HV_SYSCALL 40
#define BOOKE_INTERRUPT_HV_PRIV 41 #define BOOKE_INTERRUPT_HV_PRIV 41
#define BOOKE_INTERRUPT_LRAT_ERROR 42
/* book3s */ /* book3s */
......
...@@ -286,8 +286,21 @@ static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize) ...@@ -286,8 +286,21 @@ static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize)
extern int mmu_linear_psize; extern int mmu_linear_psize;
extern int mmu_vmemmap_psize; extern int mmu_vmemmap_psize;
struct tlb_core_data {
/* For software way selection, as on Freescale TLB1 */
u8 esel_next, esel_max, esel_first;
/* Per-core spinlock for e6500 TLB handlers (no tlbsrx.) */
u8 lock;
};
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
extern unsigned long linear_map_top; extern unsigned long linear_map_top;
extern int book3e_htw_mode;
#define PPC_HTW_NONE 0
#define PPC_HTW_IBM 1
#define PPC_HTW_E6500 2
/* /*
* 64-bit booke platforms don't load the tlb in the tlb miss handler code. * 64-bit booke platforms don't load the tlb in the tlb miss handler code.
......
...@@ -180,16 +180,17 @@ static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr) ...@@ -180,16 +180,17 @@ static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
#define MMU_PAGE_64K_AP 3 /* "Admixed pages" (hash64 only) */ #define MMU_PAGE_64K_AP 3 /* "Admixed pages" (hash64 only) */
#define MMU_PAGE_256K 4 #define MMU_PAGE_256K 4
#define MMU_PAGE_1M 5 #define MMU_PAGE_1M 5
#define MMU_PAGE_4M 6 #define MMU_PAGE_2M 6
#define MMU_PAGE_8M 7 #define MMU_PAGE_4M 7
#define MMU_PAGE_16M 8 #define MMU_PAGE_8M 8
#define MMU_PAGE_64M 9 #define MMU_PAGE_16M 9
#define MMU_PAGE_256M 10 #define MMU_PAGE_64M 10
#define MMU_PAGE_1G 11 #define MMU_PAGE_256M 11
#define MMU_PAGE_16G 12 #define MMU_PAGE_1G 12
#define MMU_PAGE_64G 13 #define MMU_PAGE_16G 13
#define MMU_PAGE_64G 14
#define MMU_PAGE_COUNT 14
#define MMU_PAGE_COUNT 15
#if defined(CONFIG_PPC_STD_MMU_64) #if defined(CONFIG_PPC_STD_MMU_64)
/* 64-bit classic hash table MMU */ /* 64-bit classic hash table MMU */
......
...@@ -112,6 +112,10 @@ struct paca_struct { ...@@ -112,6 +112,10 @@ struct paca_struct {
/* Keep pgd in the same cacheline as the start of extlb */ /* Keep pgd in the same cacheline as the start of extlb */
pgd_t *pgd __attribute__((aligned(0x80))); /* Current PGD */ pgd_t *pgd __attribute__((aligned(0x80))); /* Current PGD */
pgd_t *kernel_pgd; /* Kernel PGD */ pgd_t *kernel_pgd; /* Kernel PGD */
/* Shared by all threads of a core -- points to tcd of first thread */
struct tlb_core_data *tcd_ptr;
/* We can have up to 3 levels of reentrancy in the TLB miss handler */ /* We can have up to 3 levels of reentrancy in the TLB miss handler */
u64 extlb[3][EX_TLB_SIZE / sizeof(u64)]; u64 extlb[3][EX_TLB_SIZE / sizeof(u64)];
u64 exmc[8]; /* used for machine checks */ u64 exmc[8]; /* used for machine checks */
...@@ -122,6 +126,8 @@ struct paca_struct { ...@@ -122,6 +126,8 @@ struct paca_struct {
void *mc_kstack; void *mc_kstack;
void *crit_kstack; void *crit_kstack;
void *dbg_kstack; void *dbg_kstack;
struct tlb_core_data tcd;
#endif /* CONFIG_PPC_BOOK3E */ #endif /* CONFIG_PPC_BOOK3E */
mm_context_t context; mm_context_t context;
......
...@@ -294,6 +294,11 @@ GLUE(.,name): ...@@ -294,6 +294,11 @@ GLUE(.,name):
* you want to access various offsets within it). On ppc32 this is * you want to access various offsets within it). On ppc32 this is
* identical to LOAD_REG_IMMEDIATE. * identical to LOAD_REG_IMMEDIATE.
* *
* LOAD_REG_ADDR_PIC(rn, name)
* Loads the address of label 'name' into register 'run'. Use this when
* the kernel doesn't run at the linked or relocated address. Please
* note that this macro will clobber the lr register.
*
* LOAD_REG_ADDRBASE(rn, name) * LOAD_REG_ADDRBASE(rn, name)
* ADDROFF(name) * ADDROFF(name)
* LOAD_REG_ADDRBASE loads part of the address of label 'name' into * LOAD_REG_ADDRBASE loads part of the address of label 'name' into
...@@ -304,6 +309,14 @@ GLUE(.,name): ...@@ -304,6 +309,14 @@ GLUE(.,name):
* LOAD_REG_ADDRBASE(rX, name) * LOAD_REG_ADDRBASE(rX, name)
* ld rY,ADDROFF(name)(rX) * ld rY,ADDROFF(name)(rX)
*/ */
/* Be careful, this will clobber the lr register. */
#define LOAD_REG_ADDR_PIC(reg, name) \
bl 0f; \
0: mflr reg; \
addis reg,reg,(name - 0b)@ha; \
addi reg,reg,(name - 0b)@l;
#ifdef __powerpc64__ #ifdef __powerpc64__
#define LOAD_REG_IMMEDIATE(reg,expr) \ #define LOAD_REG_IMMEDIATE(reg,expr) \
lis reg,(expr)@highest; \ lis reg,(expr)@highest; \
......
...@@ -256,6 +256,8 @@ struct thread_struct { ...@@ -256,6 +256,8 @@ struct thread_struct {
unsigned long evr[32]; /* upper 32-bits of SPE regs */ unsigned long evr[32]; /* upper 32-bits of SPE regs */
u64 acc; /* Accumulator */ u64 acc; /* Accumulator */
unsigned long spefscr; /* SPE & eFP status */ unsigned long spefscr; /* SPE & eFP status */
unsigned long spefscr_last; /* SPEFSCR value on last prctl
call or trap return */
int used_spe; /* set if process has used spe */ int used_spe; /* set if process has used spe */
#endif /* CONFIG_SPE */ #endif /* CONFIG_SPE */
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
...@@ -317,7 +319,9 @@ struct thread_struct { ...@@ -317,7 +319,9 @@ struct thread_struct {
(_ALIGN_UP(sizeof(init_thread_info), 16) + (unsigned long) &init_stack) (_ALIGN_UP(sizeof(init_thread_info), 16) + (unsigned long) &init_stack)
#ifdef CONFIG_SPE #ifdef CONFIG_SPE
#define SPEFSCR_INIT .spefscr = SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE | SPEFSCR_FOVFE, #define SPEFSCR_INIT \
.spefscr = SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE | SPEFSCR_FOVFE, \
.spefscr_last = SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE | SPEFSCR_FOVFE,
#else #else
#define SPEFSCR_INIT #define SPEFSCR_INIT
#endif #endif
......
...@@ -1075,6 +1075,8 @@ ...@@ -1075,6 +1075,8 @@
#define PVR_8560 0x80200000 #define PVR_8560 0x80200000
#define PVR_VER_E500V1 0x8020 #define PVR_VER_E500V1 0x8020
#define PVR_VER_E500V2 0x8021 #define PVR_VER_E500V2 0x8021
#define PVR_VER_E6500 0x8040
/* /*
* For the 8xx processors, all of them report the same PVR family for * For the 8xx processors, all of them report the same PVR family for
* the PowerPC core. The various versions of these processors must be * the PowerPC core. The various versions of these processors must be
......
...@@ -101,6 +101,7 @@ ...@@ -101,6 +101,7 @@
#define SPRN_IVOR39 0x1B1 /* Interrupt Vector Offset Register 39 */ #define SPRN_IVOR39 0x1B1 /* Interrupt Vector Offset Register 39 */
#define SPRN_IVOR40 0x1B2 /* Interrupt Vector Offset Register 40 */ #define SPRN_IVOR40 0x1B2 /* Interrupt Vector Offset Register 40 */
#define SPRN_IVOR41 0x1B3 /* Interrupt Vector Offset Register 41 */ #define SPRN_IVOR41 0x1B3 /* Interrupt Vector Offset Register 41 */
#define SPRN_IVOR42 0x1B4 /* Interrupt Vector Offset Register 42 */
#define SPRN_GIVOR2 0x1B8 /* Guest IVOR2 */ #define SPRN_GIVOR2 0x1B8 /* Guest IVOR2 */
#define SPRN_GIVOR3 0x1B9 /* Guest IVOR3 */ #define SPRN_GIVOR3 0x1B9 /* Guest IVOR3 */
#define SPRN_GIVOR4 0x1BA /* Guest IVOR4 */ #define SPRN_GIVOR4 0x1BA /* Guest IVOR4 */
...@@ -170,6 +171,7 @@ ...@@ -170,6 +171,7 @@
#define SPRN_L2CSR1 0x3FA /* L2 Data Cache Control and Status Register 1 */ #define SPRN_L2CSR1 0x3FA /* L2 Data Cache Control and Status Register 1 */
#define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */ #define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */
#define SPRN_ICCR 0x3FB /* Instruction Cache Cacheability Register */ #define SPRN_ICCR 0x3FB /* Instruction Cache Cacheability Register */
#define SPRN_PWRMGTCR0 0x3FB /* Power management control register 0 */
#define SPRN_SVR 0x3FF /* System Version Register */ #define SPRN_SVR 0x3FF /* System Version Register */
/* /*
...@@ -216,6 +218,14 @@ ...@@ -216,6 +218,14 @@
#define CCR1_DPC 0x00000100 /* Disable L1 I-Cache/D-Cache parity checking */ #define CCR1_DPC 0x00000100 /* Disable L1 I-Cache/D-Cache parity checking */
#define CCR1_TCS 0x00000080 /* Timer Clock Select */ #define CCR1_TCS 0x00000080 /* Timer Clock Select */
/* Bit definitions for PWRMGTCR0. */
#define PWRMGTCR0_PW20_WAIT (1 << 14) /* PW20 state enable bit */
#define PWRMGTCR0_PW20_ENT_SHIFT 8
#define PWRMGTCR0_PW20_ENT 0x3F00
#define PWRMGTCR0_AV_IDLE_PD_EN (1 << 22) /* Altivec idle enable */
#define PWRMGTCR0_AV_IDLE_CNT_SHIFT 16
#define PWRMGTCR0_AV_IDLE_CNT 0x3F0000
/* Bit definitions for the MCSR. */ /* Bit definitions for the MCSR. */
#define MCSR_MCS 0x80000000 /* Machine Check Summary */ #define MCSR_MCS 0x80000000 /* Machine Check Summary */
#define MCSR_IB 0x40000000 /* Instruction PLB Error */ #define MCSR_IB 0x40000000 /* Instruction PLB Error */
......
...@@ -203,6 +203,15 @@ int main(void) ...@@ -203,6 +203,15 @@ int main(void)
DEFINE(PACA_MC_STACK, offsetof(struct paca_struct, mc_kstack)); DEFINE(PACA_MC_STACK, offsetof(struct paca_struct, mc_kstack));
DEFINE(PACA_CRIT_STACK, offsetof(struct paca_struct, crit_kstack)); DEFINE(PACA_CRIT_STACK, offsetof(struct paca_struct, crit_kstack));
DEFINE(PACA_DBG_STACK, offsetof(struct paca_struct, dbg_kstack)); DEFINE(PACA_DBG_STACK, offsetof(struct paca_struct, dbg_kstack));
DEFINE(PACA_TCD_PTR, offsetof(struct paca_struct, tcd_ptr));
DEFINE(TCD_ESEL_NEXT,
offsetof(struct tlb_core_data, esel_next));
DEFINE(TCD_ESEL_MAX,
offsetof(struct tlb_core_data, esel_max));
DEFINE(TCD_ESEL_FIRST,
offsetof(struct tlb_core_data, esel_first));
DEFINE(TCD_LOCK, offsetof(struct tlb_core_data, lock));
#endif /* CONFIG_PPC_BOOK3E */ #endif /* CONFIG_PPC_BOOK3E */
#ifdef CONFIG_PPC_STD_MMU_64 #ifdef CONFIG_PPC_STD_MMU_64
......
...@@ -53,11 +53,57 @@ _GLOBAL(__e500_dcache_setup) ...@@ -53,11 +53,57 @@ _GLOBAL(__e500_dcache_setup)
isync isync
blr blr
/*
* FIXME - we haven't yet done testing to determine a reasonable default
* value for PW20_WAIT_IDLE_BIT.
*/
#define PW20_WAIT_IDLE_BIT 50 /* 1ms, TB frequency is 41.66MHZ */
_GLOBAL(setup_pw20_idle)
mfspr r3, SPRN_PWRMGTCR0
/* Set PW20_WAIT bit, enable pw20 state*/
ori r3, r3, PWRMGTCR0_PW20_WAIT
li r11, PW20_WAIT_IDLE_BIT
/* Set Automatic PW20 Core Idle Count */
rlwimi r3, r11, PWRMGTCR0_PW20_ENT_SHIFT, PWRMGTCR0_PW20_ENT
mtspr SPRN_PWRMGTCR0, r3
blr
/*
* FIXME - we haven't yet done testing to determine a reasonable default
* value for AV_WAIT_IDLE_BIT.
*/
#define AV_WAIT_IDLE_BIT 50 /* 1ms, TB frequency is 41.66MHZ */
_GLOBAL(setup_altivec_idle)
mfspr r3, SPRN_PWRMGTCR0
/* Enable Altivec Idle */
oris r3, r3, PWRMGTCR0_AV_IDLE_PD_EN@h
li r11, AV_WAIT_IDLE_BIT
/* Set Automatic AltiVec Idle Count */
rlwimi r3, r11, PWRMGTCR0_AV_IDLE_CNT_SHIFT, PWRMGTCR0_AV_IDLE_CNT
mtspr SPRN_PWRMGTCR0, r3
blr
_GLOBAL(__setup_cpu_e6500) _GLOBAL(__setup_cpu_e6500)
mflr r6 mflr r6
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
bl .setup_altivec_ivors bl .setup_altivec_ivors
/* Touch IVOR42 only if the CPU supports E.HV category */
mfspr r10,SPRN_MMUCFG
rlwinm. r10,r10,0,MMUCFG_LPIDSIZE
beq 1f
bl .setup_lrat_ivor
1:
#endif #endif
bl setup_pw20_idle
bl setup_altivec_idle
bl __setup_cpu_e5500 bl __setup_cpu_e5500
mtlr r6 mtlr r6
blr blr
...@@ -119,6 +165,14 @@ _GLOBAL(__setup_cpu_e5500) ...@@ -119,6 +165,14 @@ _GLOBAL(__setup_cpu_e5500)
_GLOBAL(__restore_cpu_e6500) _GLOBAL(__restore_cpu_e6500)
mflr r5 mflr r5
bl .setup_altivec_ivors bl .setup_altivec_ivors
/* Touch IVOR42 only if the CPU supports E.HV category */
mfspr r10,SPRN_MMUCFG
rlwinm. r10,r10,0,MMUCFG_LPIDSIZE
beq 1f
bl .setup_lrat_ivor
1:
bl .setup_pw20_idle
bl .setup_altivec_idle
bl __restore_cpu_e5500 bl __restore_cpu_e5500
mtlr r5 mtlr r5
blr blr
......
...@@ -308,6 +308,7 @@ interrupt_base_book3e: /* fake trap */ ...@@ -308,6 +308,7 @@ interrupt_base_book3e: /* fake trap */
EXCEPTION_STUB(0x2e0, guest_doorbell_crit) EXCEPTION_STUB(0x2e0, guest_doorbell_crit)
EXCEPTION_STUB(0x300, hypercall) EXCEPTION_STUB(0x300, hypercall)
EXCEPTION_STUB(0x320, ehpriv) EXCEPTION_STUB(0x320, ehpriv)
EXCEPTION_STUB(0x340, lrat_error)
.globl interrupt_end_book3e .globl interrupt_end_book3e
interrupt_end_book3e: interrupt_end_book3e:
...@@ -677,6 +678,17 @@ kernel_dbg_exc: ...@@ -677,6 +678,17 @@ kernel_dbg_exc:
bl .unknown_exception bl .unknown_exception
b .ret_from_except b .ret_from_except
/* LRAT Error interrupt */
START_EXCEPTION(lrat_error);
NORMAL_EXCEPTION_PROLOG(0x340, BOOKE_INTERRUPT_LRAT_ERROR,
PROLOG_ADDITION_NONE)
EXCEPTION_COMMON(0x340, PACA_EXGEN, INTS_KEEP)
addi r3,r1,STACK_FRAME_OVERHEAD
bl .save_nvgprs
INTS_RESTORE_HARD
bl .unknown_exception
b .ret_from_except
/* /*
* An interrupt came in while soft-disabled; We mark paca->irq_happened * An interrupt came in while soft-disabled; We mark paca->irq_happened
* accordingly and if the interrupt is level sensitive, we hard disable * accordingly and if the interrupt is level sensitive, we hard disable
...@@ -859,6 +871,7 @@ BAD_STACK_TRAMPOLINE(0x2e0) ...@@ -859,6 +871,7 @@ BAD_STACK_TRAMPOLINE(0x2e0)
BAD_STACK_TRAMPOLINE(0x300) BAD_STACK_TRAMPOLINE(0x300)
BAD_STACK_TRAMPOLINE(0x310) BAD_STACK_TRAMPOLINE(0x310)
BAD_STACK_TRAMPOLINE(0x320) BAD_STACK_TRAMPOLINE(0x320)
BAD_STACK_TRAMPOLINE(0x340)
BAD_STACK_TRAMPOLINE(0x400) BAD_STACK_TRAMPOLINE(0x400)
BAD_STACK_TRAMPOLINE(0x500) BAD_STACK_TRAMPOLINE(0x500)
BAD_STACK_TRAMPOLINE(0x600) BAD_STACK_TRAMPOLINE(0x600)
...@@ -1055,12 +1068,9 @@ skpinv: addi r6,r6,1 /* Increment */ ...@@ -1055,12 +1068,9 @@ skpinv: addi r6,r6,1 /* Increment */
mtspr SPRN_MAS0,r3 mtspr SPRN_MAS0,r3
tlbre tlbre
mfspr r6,SPRN_MAS1 mfspr r6,SPRN_MAS1
rlwinm r6,r6,0,2,0 /* clear IPROT */ rlwinm r6,r6,0,2,31 /* clear IPROT and VALID */
mtspr SPRN_MAS1,r6 mtspr SPRN_MAS1,r6
tlbwe tlbwe
/* Invalidate TLB1 */
PPC_TLBILX_ALL(0,R0)
sync sync
isync isync
...@@ -1114,12 +1124,9 @@ skpinv: addi r6,r6,1 /* Increment */ ...@@ -1114,12 +1124,9 @@ skpinv: addi r6,r6,1 /* Increment */
mtspr SPRN_MAS0,r4 mtspr SPRN_MAS0,r4
tlbre tlbre
mfspr r5,SPRN_MAS1 mfspr r5,SPRN_MAS1
rlwinm r5,r5,0,2,0 /* clear IPROT */ rlwinm r5,r5,0,2,31 /* clear IPROT and VALID */
mtspr SPRN_MAS1,r5 mtspr SPRN_MAS1,r5
tlbwe tlbwe
/* Invalidate TLB1 */
PPC_TLBILX_ALL(0,R0)
sync sync
isync isync
...@@ -1414,3 +1421,7 @@ _GLOBAL(setup_ehv_ivors) ...@@ -1414,3 +1421,7 @@ _GLOBAL(setup_ehv_ivors)
SET_IVOR(38, 0x2c0) /* Guest Processor Doorbell */ SET_IVOR(38, 0x2c0) /* Guest Processor Doorbell */
SET_IVOR(39, 0x2e0) /* Guest Processor Doorbell Crit/MC */ SET_IVOR(39, 0x2e0) /* Guest Processor Doorbell Crit/MC */
blr blr
_GLOBAL(setup_lrat_ivor)
SET_IVOR(42, 0x340) /* LRAT Error */
blr
...@@ -176,6 +176,8 @@ skpinv: addi r6,r6,1 /* Increment */ ...@@ -176,6 +176,8 @@ skpinv: addi r6,r6,1 /* Increment */
/* 7. Jump to KERNELBASE mapping */ /* 7. Jump to KERNELBASE mapping */
lis r6,(KERNELBASE & ~0xfff)@h lis r6,(KERNELBASE & ~0xfff)@h
ori r6,r6,(KERNELBASE & ~0xfff)@l ori r6,r6,(KERNELBASE & ~0xfff)@l
rlwinm r7,r25,0,0x03ffffff
add r6,r7,r6
#elif defined(ENTRY_MAPPING_KEXEC_SETUP) #elif defined(ENTRY_MAPPING_KEXEC_SETUP)
/* /*
......
...@@ -65,29 +65,78 @@ _ENTRY(_start); ...@@ -65,29 +65,78 @@ _ENTRY(_start);
nop nop
/* Translate device tree address to physical, save in r30/r31 */ /* Translate device tree address to physical, save in r30/r31 */
mfmsr r16 bl get_phys_addr
mfspr r17,SPRN_PID mr r30,r3
rlwinm r17,r17,16,0x3fff0000 /* turn PID into MAS6[SPID] */ mr r31,r4
rlwimi r17,r16,28,0x00000001 /* turn MSR[DS] into MAS6[SAS] */
mtspr SPRN_MAS6,r17
tlbsx 0,r3 /* must succeed */
mfspr r16,SPRN_MAS1
mfspr r20,SPRN_MAS3
rlwinm r17,r16,25,0x1f /* r17 = log2(page size) */
li r18,1024
slw r18,r18,r17 /* r18 = page size */
addi r18,r18,-1
and r19,r3,r18 /* r19 = page offset */
andc r31,r20,r18 /* r31 = page base */
or r31,r31,r19 /* r31 = devtree phys addr */
mfspr r30,SPRN_MAS7
li r25,0 /* phys kernel start (low) */ li r25,0 /* phys kernel start (low) */
li r24,0 /* CPU number */ li r24,0 /* CPU number */
li r23,0 /* phys kernel start (high) */ li r23,0 /* phys kernel start (high) */
#ifdef CONFIG_RELOCATABLE
LOAD_REG_ADDR_PIC(r3, _stext) /* Get our current runtime base */
/* Translate _stext address to physical, save in r23/r25 */
bl get_phys_addr
mr r23,r3
mr r25,r4
bl 0f
0: mflr r8
addis r3,r8,(is_second_reloc - 0b)@ha
lwz r19,(is_second_reloc - 0b)@l(r3)
/* Check if this is the second relocation. */
cmpwi r19,1
bne 1f
/*
* For the second relocation, we already get the real memstart_addr
* from device tree. So we will map PAGE_OFFSET to memstart_addr,
* then the virtual address of start kernel should be:
* PAGE_OFFSET + (kernstart_addr - memstart_addr)
* Since the offset between kernstart_addr and memstart_addr should
* never be beyond 1G, so we can just use the lower 32bit of them
* for the calculation.
*/
lis r3,PAGE_OFFSET@h
addis r4,r8,(kernstart_addr - 0b)@ha
addi r4,r4,(kernstart_addr - 0b)@l
lwz r5,4(r4)
addis r6,r8,(memstart_addr - 0b)@ha
addi r6,r6,(memstart_addr - 0b)@l
lwz r7,4(r6)
subf r5,r7,r5
add r3,r3,r5
b 2f
1:
/*
* We have the runtime (virutal) address of our base.
* We calculate our shift of offset from a 64M page.
* We could map the 64M page we belong to at PAGE_OFFSET and
* get going from there.
*/
lis r4,KERNELBASE@h
ori r4,r4,KERNELBASE@l
rlwinm r6,r25,0,0x3ffffff /* r6 = PHYS_START % 64M */
rlwinm r5,r4,0,0x3ffffff /* r5 = KERNELBASE % 64M */
subf r3,r5,r6 /* r3 = r6 - r5 */
add r3,r4,r3 /* Required Virtual Address */
2: bl relocate
/*
* For the second relocation, we already set the right tlb entries
* for the kernel space, so skip the code in fsl_booke_entry_mapping.S
*/
cmpwi r19,1
beq set_ivor
#endif
/* We try to not make any assumptions about how the boot loader /* We try to not make any assumptions about how the boot loader
* setup or used the TLBs. We invalidate all mappings from the * setup or used the TLBs. We invalidate all mappings from the
* boot loader and load a single entry in TLB1[0] to map the * boot loader and load a single entry in TLB1[0] to map the
...@@ -113,6 +162,7 @@ _ENTRY(__early_start) ...@@ -113,6 +162,7 @@ _ENTRY(__early_start)
#include "fsl_booke_entry_mapping.S" #include "fsl_booke_entry_mapping.S"
#undef ENTRY_MAPPING_BOOT_SETUP #undef ENTRY_MAPPING_BOOT_SETUP
set_ivor:
/* Establish the interrupt vector offsets */ /* Establish the interrupt vector offsets */
SET_IVOR(0, CriticalInput); SET_IVOR(0, CriticalInput);
SET_IVOR(1, MachineCheck); SET_IVOR(1, MachineCheck);
...@@ -166,8 +216,7 @@ _ENTRY(__early_start) ...@@ -166,8 +216,7 @@ _ENTRY(__early_start)
/* Check to see if we're the second processor, and jump /* Check to see if we're the second processor, and jump
* to the secondary_start code if so * to the secondary_start code if so
*/ */
lis r24, boot_cpuid@h LOAD_REG_ADDR_PIC(r24, boot_cpuid)
ori r24, r24, boot_cpuid@l
lwz r24, 0(r24) lwz r24, 0(r24)
cmpwi r24, -1 cmpwi r24, -1
mfspr r24,SPRN_PIR mfspr r24,SPRN_PIR
...@@ -197,6 +246,18 @@ _ENTRY(__early_start) ...@@ -197,6 +246,18 @@ _ENTRY(__early_start)
bl early_init bl early_init
#ifdef CONFIG_RELOCATABLE
mr r3,r30
mr r4,r31
#ifdef CONFIG_PHYS_64BIT
mr r5,r23
mr r6,r25
#else
mr r5,r25
#endif
bl relocate_init
#endif
#ifdef CONFIG_DYNAMIC_MEMSTART #ifdef CONFIG_DYNAMIC_MEMSTART
lis r3,kernstart_addr@ha lis r3,kernstart_addr@ha
la r3,kernstart_addr@l(r3) la r3,kernstart_addr@l(r3)
...@@ -855,6 +916,33 @@ KernelSPE: ...@@ -855,6 +916,33 @@ KernelSPE:
#endif /* CONFIG_SPE */ #endif /* CONFIG_SPE */
/*
* Translate the effec addr in r3 to phys addr. The phys addr will be put
* into r3(higher 32bit) and r4(lower 32bit)
*/
get_phys_addr:
mfmsr r8
mfspr r9,SPRN_PID
rlwinm r9,r9,16,0x3fff0000 /* turn PID into MAS6[SPID] */
rlwimi r9,r8,28,0x00000001 /* turn MSR[DS] into MAS6[SAS] */
mtspr SPRN_MAS6,r9
tlbsx 0,r3 /* must succeed */
mfspr r8,SPRN_MAS1
mfspr r12,SPRN_MAS3
rlwinm r9,r8,25,0x1f /* r9 = log2(page size) */
li r10,1024
slw r10,r10,r9 /* r10 = page size */
addi r10,r10,-1
and r11,r3,r10 /* r11 = page offset */
andc r4,r12,r10 /* r4 = page base */
or r4,r4,r11 /* r4 = devtree phys addr */
#ifdef CONFIG_PHYS_64BIT
mfspr r3,SPRN_MAS7
#endif
blr
/* /*
* Global functions * Global functions
*/ */
...@@ -1057,24 +1145,36 @@ _GLOBAL(__flush_disable_L1) ...@@ -1057,24 +1145,36 @@ _GLOBAL(__flush_disable_L1)
/* When we get here, r24 needs to hold the CPU # */ /* When we get here, r24 needs to hold the CPU # */
.globl __secondary_start .globl __secondary_start
__secondary_start: __secondary_start:
lis r3,__secondary_hold_acknowledge@h LOAD_REG_ADDR_PIC(r3, tlbcam_index)
ori r3,r3,__secondary_hold_acknowledge@l lwz r3,0(r3)
stw r24,0(r3)
li r3,0
mr r4,r24 /* Why? */
bl call_setup_cpu
lis r3,tlbcam_index@ha
lwz r3,tlbcam_index@l(r3)
mtctr r3 mtctr r3
li r26,0 /* r26 safe? */ li r26,0 /* r26 safe? */
bl switch_to_as1
mr r27,r3 /* tlb entry */
/* Load each CAM entry */ /* Load each CAM entry */
1: mr r3,r26 1: mr r3,r26
bl loadcam_entry bl loadcam_entry
addi r26,r26,1 addi r26,r26,1
bdnz 1b bdnz 1b
mr r3,r27 /* tlb entry */
LOAD_REG_ADDR_PIC(r4, memstart_addr)
lwz r4,0(r4)
mr r5,r25 /* phys kernel start */
rlwinm r5,r5,0,~0x3ffffff /* aligned 64M */
subf r4,r5,r4 /* memstart_addr - phys kernel start */
li r5,0 /* no device tree */
li r6,0 /* not boot cpu */
bl restore_to_as0
lis r3,__secondary_hold_acknowledge@h
ori r3,r3,__secondary_hold_acknowledge@l
stw r24,0(r3)
li r3,0
mr r4,r24 /* Why? */
bl call_setup_cpu
/* get current_thread_info and current */ /* get current_thread_info and current */
lis r1,secondary_ti@ha lis r1,secondary_ti@ha
...@@ -1110,6 +1210,112 @@ __secondary_hold_acknowledge: ...@@ -1110,6 +1210,112 @@ __secondary_hold_acknowledge:
.long -1 .long -1
#endif #endif
/*
* Create a tlb entry with the same effective and physical address as
* the tlb entry used by the current running code. But set the TS to 1.
* Then switch to the address space 1. It will return with the r3 set to
* the ESEL of the new created tlb.
*/
_GLOBAL(switch_to_as1)
mflr r5
/* Find a entry not used */
mfspr r3,SPRN_TLB1CFG
andi. r3,r3,0xfff
mfspr r4,SPRN_PID
rlwinm r4,r4,16,0x3fff0000 /* turn PID into MAS6[SPID] */
mtspr SPRN_MAS6,r4
1: lis r4,0x1000 /* Set MAS0(TLBSEL) = 1 */
addi r3,r3,-1
rlwimi r4,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
mtspr SPRN_MAS0,r4
tlbre
mfspr r4,SPRN_MAS1
andis. r4,r4,MAS1_VALID@h
bne 1b
/* Get the tlb entry used by the current running code */
bl 0f
0: mflr r4
tlbsx 0,r4
mfspr r4,SPRN_MAS1
ori r4,r4,MAS1_TS /* Set the TS = 1 */
mtspr SPRN_MAS1,r4
mfspr r4,SPRN_MAS0
rlwinm r4,r4,0,~MAS0_ESEL_MASK
rlwimi r4,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
mtspr SPRN_MAS0,r4
tlbwe
isync
sync
mfmsr r4
ori r4,r4,MSR_IS | MSR_DS
mtspr SPRN_SRR0,r5
mtspr SPRN_SRR1,r4
sync
rfi
/*
* Restore to the address space 0 and also invalidate the tlb entry created
* by switch_to_as1.
* r3 - the tlb entry which should be invalidated
* r4 - __pa(PAGE_OFFSET in AS1) - __pa(PAGE_OFFSET in AS0)
* r5 - device tree virtual address. If r4 is 0, r5 is ignored.
* r6 - boot cpu
*/
_GLOBAL(restore_to_as0)
mflr r0
bl 0f
0: mflr r9
addi r9,r9,1f - 0b
/*
* We may map the PAGE_OFFSET in AS0 to a different physical address,
* so we need calculate the right jump and device tree address based
* on the offset passed by r4.
*/
add r9,r9,r4
add r5,r5,r4
add r0,r0,r4
2: mfmsr r7
li r8,(MSR_IS | MSR_DS)
andc r7,r7,r8
mtspr SPRN_SRR0,r9
mtspr SPRN_SRR1,r7
sync
rfi
/* Invalidate the temporary tlb entry for AS1 */
1: lis r9,0x1000 /* Set MAS0(TLBSEL) = 1 */
rlwimi r9,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
mtspr SPRN_MAS0,r9
tlbre
mfspr r9,SPRN_MAS1
rlwinm r9,r9,0,2,31 /* Clear MAS1 Valid and IPPROT */
mtspr SPRN_MAS1,r9
tlbwe
isync
cmpwi r4,0
cmpwi cr1,r6,0
cror eq,4*cr1+eq,eq
bne 3f /* offset != 0 && is_boot_cpu */
mtlr r0
blr
/*
* The PAGE_OFFSET will map to a different physical address,
* jump to _start to do another relocation again.
*/
3: mr r3,r5
bl _start
/* /*
* We put a few things here that have to be page-aligned. This stuff * We put a few things here that have to be page-aligned. This stuff
* goes at the beginning of the data segment, which is page-aligned. * goes at the beginning of the data segment, which is page-aligned.
......
...@@ -160,6 +160,11 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) ...@@ -160,6 +160,11 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
#ifdef CONFIG_PPC_STD_MMU_64 #ifdef CONFIG_PPC_STD_MMU_64
new_paca->slb_shadow_ptr = init_slb_shadow(cpu); new_paca->slb_shadow_ptr = init_slb_shadow(cpu);
#endif /* CONFIG_PPC_STD_MMU_64 */ #endif /* CONFIG_PPC_STD_MMU_64 */
#ifdef CONFIG_PPC_BOOK3E
/* For now -- if we have threads this will be adjusted later */
new_paca->tcd_ptr = &new_paca->tcd;
#endif
} }
/* Put the paca pointer into r13 and SPRG_PACA */ /* Put the paca pointer into r13 and SPRG_PACA */
......
...@@ -1296,6 +1296,19 @@ int set_fpexc_mode(struct task_struct *tsk, unsigned int val) ...@@ -1296,6 +1296,19 @@ int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
if (val & PR_FP_EXC_SW_ENABLE) { if (val & PR_FP_EXC_SW_ENABLE) {
#ifdef CONFIG_SPE #ifdef CONFIG_SPE
if (cpu_has_feature(CPU_FTR_SPE)) { if (cpu_has_feature(CPU_FTR_SPE)) {
/*
* When the sticky exception bits are set
* directly by userspace, it must call prctl
* with PR_GET_FPEXC (with PR_FP_EXC_SW_ENABLE
* in the existing prctl settings) or
* PR_SET_FPEXC (with PR_FP_EXC_SW_ENABLE in
* the bits being set). <fenv.h> functions
* saving and restoring the whole
* floating-point environment need to do so
* anyway to restore the prctl settings from
* the saved environment.
*/
tsk->thread.spefscr_last = mfspr(SPRN_SPEFSCR);
tsk->thread.fpexc_mode = val & tsk->thread.fpexc_mode = val &
(PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT); (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
return 0; return 0;
...@@ -1327,9 +1340,22 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr) ...@@ -1327,9 +1340,22 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE) if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
#ifdef CONFIG_SPE #ifdef CONFIG_SPE
if (cpu_has_feature(CPU_FTR_SPE)) if (cpu_has_feature(CPU_FTR_SPE)) {
/*
* When the sticky exception bits are set
* directly by userspace, it must call prctl
* with PR_GET_FPEXC (with PR_FP_EXC_SW_ENABLE
* in the existing prctl settings) or
* PR_SET_FPEXC (with PR_FP_EXC_SW_ENABLE in
* the bits being set). <fenv.h> functions
* saving and restoring the whole
* floating-point environment need to do so
* anyway to restore the prctl settings from
* the saved environment.
*/
tsk->thread.spefscr_last = mfspr(SPRN_SPEFSCR);
val = tsk->thread.fpexc_mode; val = tsk->thread.fpexc_mode;
else } else
return -EINVAL; return -EINVAL;
#else #else
return -EINVAL; return -EINVAL;
......
...@@ -523,6 +523,20 @@ static int __init early_init_dt_scan_memory_ppc(unsigned long node, ...@@ -523,6 +523,20 @@ static int __init early_init_dt_scan_memory_ppc(unsigned long node,
return early_init_dt_scan_memory(node, uname, depth, data); return early_init_dt_scan_memory(node, uname, depth, data);
} }
/*
* For a relocatable kernel, we need to get the memstart_addr first,
* then use it to calculate the virtual kernel start address. This has
* to happen at a very early stage (before machine_init). In this case,
* we just want to get the memstart_address and would not like to mess the
* memblock at this stage. So introduce a variable to skip the memblock_add()
* for this reason.
*/
#ifdef CONFIG_RELOCATABLE
static int add_mem_to_memblock = 1;
#else
#define add_mem_to_memblock 1
#endif
void __init early_init_dt_add_memory_arch(u64 base, u64 size) void __init early_init_dt_add_memory_arch(u64 base, u64 size)
{ {
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
...@@ -543,6 +557,7 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) ...@@ -543,6 +557,7 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
} }
/* Add the chunk to the MEMBLOCK list */ /* Add the chunk to the MEMBLOCK list */
if (add_mem_to_memblock)
memblock_add(base, size); memblock_add(base, size);
} }
...@@ -740,6 +755,30 @@ void __init early_init_devtree(void *params) ...@@ -740,6 +755,30 @@ void __init early_init_devtree(void *params)
DBG(" <- early_init_devtree()\n"); DBG(" <- early_init_devtree()\n");
} }
#ifdef CONFIG_RELOCATABLE
/*
* This function run before early_init_devtree, so we have to init
* initial_boot_params.
*/
void __init early_get_first_memblock_info(void *params, phys_addr_t *size)
{
/* Setup flat device-tree pointer */
initial_boot_params = params;
/*
* Scan the memory nodes and set add_mem_to_memblock to 0 to avoid
* mess the memblock.
*/
add_mem_to_memblock = 0;
of_scan_flat_dt(early_init_dt_scan_root, NULL);
of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL);
add_mem_to_memblock = 1;
if (size)
*size = first_memblock_size;
}
#endif
/******* /*******
* *
* New implementation of the OF "find" APIs, return a refcounted * New implementation of the OF "find" APIs, return a refcounted
......
...@@ -97,6 +97,36 @@ int dcache_bsize; ...@@ -97,6 +97,36 @@ int dcache_bsize;
int icache_bsize; int icache_bsize;
int ucache_bsize; int ucache_bsize;
#if defined(CONFIG_PPC_BOOK3E) && defined(CONFIG_SMP)
static void setup_tlb_core_data(void)
{
int cpu;
for_each_possible_cpu(cpu) {
int first = cpu_first_thread_sibling(cpu);
paca[cpu].tcd_ptr = &paca[first].tcd;
/*
* If we have threads, we need either tlbsrx.
* or e6500 tablewalk mode, or else TLB handlers
* will be racy and could produce duplicate entries.
*/
if (smt_enabled_at_boot >= 2 &&
!mmu_has_feature(MMU_FTR_USE_TLBRSRV) &&
book3e_htw_mode != PPC_HTW_E6500) {
/* Should we panic instead? */
WARN_ONCE("%s: unsupported MMU configuration -- expect problems\n",
__func__);
}
}
}
#else
static void setup_tlb_core_data(void)
{
}
#endif
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static char *smt_enabled_cmdline; static char *smt_enabled_cmdline;
...@@ -445,6 +475,7 @@ void __init setup_system(void) ...@@ -445,6 +475,7 @@ void __init setup_system(void)
smp_setup_cpu_maps(); smp_setup_cpu_maps();
check_smt_enabled(); check_smt_enabled();
setup_tlb_core_data();
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* Release secondary cpus out of their spinloops at 0x60 now that /* Release secondary cpus out of their spinloops at 0x60 now that
......
...@@ -74,21 +74,21 @@ _GLOBAL(swsusp_arch_suspend) ...@@ -74,21 +74,21 @@ _GLOBAL(swsusp_arch_suspend)
bne 1b bne 1b
/* Save SPRGs */ /* Save SPRGs */
mfsprg r4,0 mfspr r4,SPRN_SPRG0
stw r4,SL_SPRG0(r11) stw r4,SL_SPRG0(r11)
mfsprg r4,1 mfspr r4,SPRN_SPRG1
stw r4,SL_SPRG1(r11) stw r4,SL_SPRG1(r11)
mfsprg r4,2 mfspr r4,SPRN_SPRG2
stw r4,SL_SPRG2(r11) stw r4,SL_SPRG2(r11)
mfsprg r4,3 mfspr r4,SPRN_SPRG3
stw r4,SL_SPRG3(r11) stw r4,SL_SPRG3(r11)
mfsprg r4,4 mfspr r4,SPRN_SPRG4
stw r4,SL_SPRG4(r11) stw r4,SL_SPRG4(r11)
mfsprg r4,5 mfspr r4,SPRN_SPRG5
stw r4,SL_SPRG5(r11) stw r4,SL_SPRG5(r11)
mfsprg r4,6 mfspr r4,SPRN_SPRG6
stw r4,SL_SPRG6(r11) stw r4,SL_SPRG6(r11)
mfsprg r4,7 mfspr r4,SPRN_SPRG7
stw r4,SL_SPRG7(r11) stw r4,SL_SPRG7(r11)
/* Call the low level suspend stuff (we should probably have made /* Call the low level suspend stuff (we should probably have made
...@@ -150,21 +150,21 @@ _GLOBAL(swsusp_arch_resume) ...@@ -150,21 +150,21 @@ _GLOBAL(swsusp_arch_resume)
bl _tlbil_all bl _tlbil_all
lwz r4,SL_SPRG0(r11) lwz r4,SL_SPRG0(r11)
mtsprg 0,r4 mtspr SPRN_SPRG0,r4
lwz r4,SL_SPRG1(r11) lwz r4,SL_SPRG1(r11)
mtsprg 1,r4 mtspr SPRN_SPRG1,r4
lwz r4,SL_SPRG2(r11) lwz r4,SL_SPRG2(r11)
mtsprg 2,r4 mtspr SPRN_SPRG2,r4
lwz r4,SL_SPRG3(r11) lwz r4,SL_SPRG3(r11)
mtsprg 3,r4 mtspr SPRN_SPRG3,r4
lwz r4,SL_SPRG4(r11) lwz r4,SL_SPRG4(r11)
mtsprg 4,r4 mtspr SPRN_SPRG4,r4
lwz r4,SL_SPRG5(r11) lwz r4,SL_SPRG5(r11)
mtsprg 5,r4 mtspr SPRN_SPRG5,r4
lwz r4,SL_SPRG6(r11) lwz r4,SL_SPRG6(r11)
mtsprg 6,r4 mtspr SPRN_SPRG6,r4
lwz r4,SL_SPRG7(r11) lwz r4,SL_SPRG7(r11)
mtsprg 7,r4 mtspr SPRN_SPRG7,r4
/* restore the MSR */ /* restore the MSR */
lwz r3,SL_MSR(r11) lwz r3,SL_MSR(r11)
......
...@@ -86,6 +86,304 @@ __setup("smt-snooze-delay=", setup_smt_snooze_delay); ...@@ -86,6 +86,304 @@ __setup("smt-snooze-delay=", setup_smt_snooze_delay);
#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC64 */
#ifdef CONFIG_PPC_FSL_BOOK3E
#define MAX_BIT 63
static u64 pw20_wt;
static u64 altivec_idle_wt;
static unsigned int get_idle_ticks_bit(u64 ns)
{
u64 cycle;
if (ns >= 10000)
cycle = div_u64(ns + 500, 1000) * tb_ticks_per_usec;
else
cycle = div_u64(ns * tb_ticks_per_usec, 1000);
if (!cycle)
return 0;
return ilog2(cycle);
}
static void do_show_pwrmgtcr0(void *val)
{
u32 *value = val;
*value = mfspr(SPRN_PWRMGTCR0);
}
static ssize_t show_pw20_state(struct device *dev,
struct device_attribute *attr, char *buf)
{
u32 value;
unsigned int cpu = dev->id;
smp_call_function_single(cpu, do_show_pwrmgtcr0, &value, 1);
value &= PWRMGTCR0_PW20_WAIT;
return sprintf(buf, "%u\n", value ? 1 : 0);
}
static void do_store_pw20_state(void *val)
{
u32 *value = val;
u32 pw20_state;
pw20_state = mfspr(SPRN_PWRMGTCR0);
if (*value)
pw20_state |= PWRMGTCR0_PW20_WAIT;
else
pw20_state &= ~PWRMGTCR0_PW20_WAIT;
mtspr(SPRN_PWRMGTCR0, pw20_state);
}
static ssize_t store_pw20_state(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
u32 value;
unsigned int cpu = dev->id;
if (kstrtou32(buf, 0, &value))
return -EINVAL;
if (value > 1)
return -EINVAL;
smp_call_function_single(cpu, do_store_pw20_state, &value, 1);
return count;
}
static ssize_t show_pw20_wait_time(struct device *dev,
struct device_attribute *attr, char *buf)
{
u32 value;
u64 tb_cycle = 1;
u64 time;
unsigned int cpu = dev->id;
if (!pw20_wt) {
smp_call_function_single(cpu, do_show_pwrmgtcr0, &value, 1);
value = (value & PWRMGTCR0_PW20_ENT) >>
PWRMGTCR0_PW20_ENT_SHIFT;
tb_cycle = (tb_cycle << (MAX_BIT - value + 1));
/* convert ms to ns */
if (tb_ticks_per_usec > 1000) {
time = div_u64(tb_cycle, tb_ticks_per_usec / 1000);
} else {
u32 rem_us;
time = div_u64_rem(tb_cycle, tb_ticks_per_usec,
&rem_us);
time = time * 1000 + rem_us * 1000 / tb_ticks_per_usec;
}
} else {
time = pw20_wt;
}
return sprintf(buf, "%llu\n", time > 0 ? time : 0);
}
static void set_pw20_wait_entry_bit(void *val)
{
u32 *value = val;
u32 pw20_idle;
pw20_idle = mfspr(SPRN_PWRMGTCR0);
/* Set Automatic PW20 Core Idle Count */
/* clear count */
pw20_idle &= ~PWRMGTCR0_PW20_ENT;
/* set count */
pw20_idle |= ((MAX_BIT - *value) << PWRMGTCR0_PW20_ENT_SHIFT);
mtspr(SPRN_PWRMGTCR0, pw20_idle);
}
static ssize_t store_pw20_wait_time(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
u32 entry_bit;
u64 value;
unsigned int cpu = dev->id;
if (kstrtou64(buf, 0, &value))
return -EINVAL;
if (!value)
return -EINVAL;
entry_bit = get_idle_ticks_bit(value);
if (entry_bit > MAX_BIT)
return -EINVAL;
pw20_wt = value;
smp_call_function_single(cpu, set_pw20_wait_entry_bit,
&entry_bit, 1);
return count;
}
static ssize_t show_altivec_idle(struct device *dev,
struct device_attribute *attr, char *buf)
{
u32 value;
unsigned int cpu = dev->id;
smp_call_function_single(cpu, do_show_pwrmgtcr0, &value, 1);
value &= PWRMGTCR0_AV_IDLE_PD_EN;
return sprintf(buf, "%u\n", value ? 1 : 0);
}
static void do_store_altivec_idle(void *val)
{
u32 *value = val;
u32 altivec_idle;
altivec_idle = mfspr(SPRN_PWRMGTCR0);
if (*value)
altivec_idle |= PWRMGTCR0_AV_IDLE_PD_EN;
else
altivec_idle &= ~PWRMGTCR0_AV_IDLE_PD_EN;
mtspr(SPRN_PWRMGTCR0, altivec_idle);
}
static ssize_t store_altivec_idle(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
u32 value;
unsigned int cpu = dev->id;
if (kstrtou32(buf, 0, &value))
return -EINVAL;
if (value > 1)
return -EINVAL;
smp_call_function_single(cpu, do_store_altivec_idle, &value, 1);
return count;
}
static ssize_t show_altivec_idle_wait_time(struct device *dev,
struct device_attribute *attr, char *buf)
{
u32 value;
u64 tb_cycle = 1;
u64 time;
unsigned int cpu = dev->id;
if (!altivec_idle_wt) {
smp_call_function_single(cpu, do_show_pwrmgtcr0, &value, 1);
value = (value & PWRMGTCR0_AV_IDLE_CNT) >>
PWRMGTCR0_AV_IDLE_CNT_SHIFT;
tb_cycle = (tb_cycle << (MAX_BIT - value + 1));
/* convert ms to ns */
if (tb_ticks_per_usec > 1000) {
time = div_u64(tb_cycle, tb_ticks_per_usec / 1000);
} else {
u32 rem_us;
time = div_u64_rem(tb_cycle, tb_ticks_per_usec,
&rem_us);
time = time * 1000 + rem_us * 1000 / tb_ticks_per_usec;
}
} else {
time = altivec_idle_wt;
}
return sprintf(buf, "%llu\n", time > 0 ? time : 0);
}
static void set_altivec_idle_wait_entry_bit(void *val)
{
u32 *value = val;
u32 altivec_idle;
altivec_idle = mfspr(SPRN_PWRMGTCR0);
/* Set Automatic AltiVec Idle Count */
/* clear count */
altivec_idle &= ~PWRMGTCR0_AV_IDLE_CNT;
/* set count */
altivec_idle |= ((MAX_BIT - *value) << PWRMGTCR0_AV_IDLE_CNT_SHIFT);
mtspr(SPRN_PWRMGTCR0, altivec_idle);
}
static ssize_t store_altivec_idle_wait_time(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
u32 entry_bit;
u64 value;
unsigned int cpu = dev->id;
if (kstrtou64(buf, 0, &value))
return -EINVAL;
if (!value)
return -EINVAL;
entry_bit = get_idle_ticks_bit(value);
if (entry_bit > MAX_BIT)
return -EINVAL;
altivec_idle_wt = value;
smp_call_function_single(cpu, set_altivec_idle_wait_entry_bit,
&entry_bit, 1);
return count;
}
/*
* Enable/Disable interface:
* 0, disable. 1, enable.
*/
static DEVICE_ATTR(pw20_state, 0600, show_pw20_state, store_pw20_state);
static DEVICE_ATTR(altivec_idle, 0600, show_altivec_idle, store_altivec_idle);
/*
* Set wait time interface:(Nanosecond)
* Example: Base on TBfreq is 41MHZ.
* 1~48(ns): TB[63]
* 49~97(ns): TB[62]
* 98~195(ns): TB[61]
* 196~390(ns): TB[60]
* 391~780(ns): TB[59]
* 781~1560(ns): TB[58]
* ...
*/
static DEVICE_ATTR(pw20_wait_time, 0600,
show_pw20_wait_time,
store_pw20_wait_time);
static DEVICE_ATTR(altivec_idle_wait_time, 0600,
show_altivec_idle_wait_time,
store_altivec_idle_wait_time);
#endif
/* /*
* Enabling PMCs will slow partition context switch times so we only do * Enabling PMCs will slow partition context switch times so we only do
* it the first time we write to the PMCs. * it the first time we write to the PMCs.
...@@ -425,6 +723,15 @@ static void register_cpu_online(unsigned int cpu) ...@@ -425,6 +723,15 @@ static void register_cpu_online(unsigned int cpu)
device_create_file(s, &dev_attr_pir); device_create_file(s, &dev_attr_pir);
#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC64 */
#ifdef CONFIG_PPC_FSL_BOOK3E
if (PVR_VER(cur_cpu_spec->pvr_value) == PVR_VER_E6500) {
device_create_file(s, &dev_attr_pw20_state);
device_create_file(s, &dev_attr_pw20_wait_time);
device_create_file(s, &dev_attr_altivec_idle);
device_create_file(s, &dev_attr_altivec_idle_wait_time);
}
#endif
cacheinfo_cpu_online(cpu); cacheinfo_cpu_online(cpu);
} }
...@@ -497,6 +804,15 @@ static void unregister_cpu_online(unsigned int cpu) ...@@ -497,6 +804,15 @@ static void unregister_cpu_online(unsigned int cpu)
device_remove_file(s, &dev_attr_pir); device_remove_file(s, &dev_attr_pir);
#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC64 */
#ifdef CONFIG_PPC_FSL_BOOK3E
if (PVR_VER(cur_cpu_spec->pvr_value) == PVR_VER_E6500) {
device_remove_file(s, &dev_attr_pw20_state);
device_remove_file(s, &dev_attr_pw20_wait_time);
device_remove_file(s, &dev_attr_altivec_idle);
device_remove_file(s, &dev_attr_altivec_idle_wait_time);
}
#endif
cacheinfo_cpu_offline(cpu); cacheinfo_cpu_offline(cpu);
} }
......
...@@ -319,6 +319,8 @@ kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(DBG), \ ...@@ -319,6 +319,8 @@ kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(DBG), \
SPRN_DSRR0, SPRN_DSRR1, 0 SPRN_DSRR0, SPRN_DSRR1, 0
kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(CRIT), \ kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(CRIT), \
SPRN_CSRR0, SPRN_CSRR1, 0 SPRN_CSRR0, SPRN_CSRR1, 0
kvm_handler BOOKE_INTERRUPT_LRAT_ERROR, EX_PARAMS(GEN), \
SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR)
#else #else
/* /*
* For input register values, see arch/powerpc/include/asm/kvm_booke_hv_asm.h * For input register values, see arch/powerpc/include/asm/kvm_booke_hv_asm.h
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
*/ */
#include <linux/types.h> #include <linux/types.h>
#include <linux/prctl.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/reg.h> #include <asm/reg.h>
...@@ -275,21 +276,13 @@ int do_spe_mathemu(struct pt_regs *regs) ...@@ -275,21 +276,13 @@ int do_spe_mathemu(struct pt_regs *regs)
case EFSCTSF: case EFSCTSF:
case EFSCTUF: case EFSCTUF:
if (!((vb.wp[1] >> 23) == 0xff && ((vb.wp[1] & 0x7fffff) > 0))) { if (SB_c == FP_CLS_NAN) {
/* NaN */ vc.wp[1] = 0;
if (((vb.wp[1] >> 23) & 0xff) == 0) { FP_SET_EXCEPTION(FP_EX_INVALID);
/* denorm */ } else {
vc.wp[1] = 0x0; SB_e += (func == EFSCTSF ? 31 : 32);
} else if ((vb.wp[1] >> 31) == 0) { FP_TO_INT_ROUND_S(vc.wp[1], SB, 32,
/* positive normal */ (func == EFSCTSF));
vc.wp[1] = (func == EFSCTSF) ?
0x7fffffff : 0xffffffff;
} else { /* negative normal */
vc.wp[1] = (func == EFSCTSF) ?
0x80000000 : 0x0;
}
} else { /* rB is NaN */
vc.wp[1] = 0x0;
} }
goto update_regs; goto update_regs;
...@@ -306,16 +299,25 @@ int do_spe_mathemu(struct pt_regs *regs) ...@@ -306,16 +299,25 @@ int do_spe_mathemu(struct pt_regs *regs)
} }
case EFSCTSI: case EFSCTSI:
case EFSCTSIZ:
case EFSCTUI: case EFSCTUI:
case EFSCTUIZ: if (SB_c == FP_CLS_NAN) {
if (func & 0x4) { vc.wp[1] = 0;
_FP_ROUND(1, SB); FP_SET_EXCEPTION(FP_EX_INVALID);
} else { } else {
_FP_ROUND_ZERO(1, SB); FP_TO_INT_ROUND_S(vc.wp[1], SB, 32,
((func & 0x3) != 0));
} }
goto update_regs;
case EFSCTSIZ:
case EFSCTUIZ:
if (SB_c == FP_CLS_NAN) {
vc.wp[1] = 0;
FP_SET_EXCEPTION(FP_EX_INVALID);
} else {
FP_TO_INT_S(vc.wp[1], SB, 32, FP_TO_INT_S(vc.wp[1], SB, 32,
(((func & 0x3) != 0) || SB_s)); ((func & 0x3) != 0));
}
goto update_regs; goto update_regs;
default: default:
...@@ -404,22 +406,13 @@ int do_spe_mathemu(struct pt_regs *regs) ...@@ -404,22 +406,13 @@ int do_spe_mathemu(struct pt_regs *regs)
case EFDCTSF: case EFDCTSF:
case EFDCTUF: case EFDCTUF:
if (!((vb.wp[0] >> 20) == 0x7ff && if (DB_c == FP_CLS_NAN) {
((vb.wp[0] & 0xfffff) > 0 || (vb.wp[1] > 0)))) { vc.wp[1] = 0;
/* not a NaN */ FP_SET_EXCEPTION(FP_EX_INVALID);
if (((vb.wp[0] >> 20) & 0x7ff) == 0) { } else {
/* denorm */ DB_e += (func == EFDCTSF ? 31 : 32);
vc.wp[1] = 0x0; FP_TO_INT_ROUND_D(vc.wp[1], DB, 32,
} else if ((vb.wp[0] >> 31) == 0) { (func == EFDCTSF));
/* positive normal */
vc.wp[1] = (func == EFDCTSF) ?
0x7fffffff : 0xffffffff;
} else { /* negative normal */
vc.wp[1] = (func == EFDCTSF) ?
0x80000000 : 0x0;
}
} else { /* NaN */
vc.wp[1] = 0x0;
} }
goto update_regs; goto update_regs;
...@@ -437,21 +430,35 @@ int do_spe_mathemu(struct pt_regs *regs) ...@@ -437,21 +430,35 @@ int do_spe_mathemu(struct pt_regs *regs)
case EFDCTUIDZ: case EFDCTUIDZ:
case EFDCTSIDZ: case EFDCTSIDZ:
_FP_ROUND_ZERO(2, DB); if (DB_c == FP_CLS_NAN) {
FP_TO_INT_D(vc.dp[0], DB, 64, ((func & 0x1) == 0)); vc.dp[0] = 0;
FP_SET_EXCEPTION(FP_EX_INVALID);
} else {
FP_TO_INT_D(vc.dp[0], DB, 64,
((func & 0x1) == 0));
}
goto update_regs; goto update_regs;
case EFDCTUI: case EFDCTUI:
case EFDCTSI: case EFDCTSI:
if (DB_c == FP_CLS_NAN) {
vc.wp[1] = 0;
FP_SET_EXCEPTION(FP_EX_INVALID);
} else {
FP_TO_INT_ROUND_D(vc.wp[1], DB, 32,
((func & 0x3) != 0));
}
goto update_regs;
case EFDCTUIZ: case EFDCTUIZ:
case EFDCTSIZ: case EFDCTSIZ:
if (func & 0x4) { if (DB_c == FP_CLS_NAN) {
_FP_ROUND(2, DB); vc.wp[1] = 0;
FP_SET_EXCEPTION(FP_EX_INVALID);
} else { } else {
_FP_ROUND_ZERO(2, DB);
}
FP_TO_INT_D(vc.wp[1], DB, 32, FP_TO_INT_D(vc.wp[1], DB, 32,
(((func & 0x3) != 0) || DB_s)); ((func & 0x3) != 0));
}
goto update_regs; goto update_regs;
default: default:
...@@ -556,37 +563,60 @@ int do_spe_mathemu(struct pt_regs *regs) ...@@ -556,37 +563,60 @@ int do_spe_mathemu(struct pt_regs *regs)
cmp = -1; cmp = -1;
goto cmp_vs; goto cmp_vs;
case EVFSCTSF:
__asm__ __volatile__ ("mtspr 512, %4\n"
"efsctsf %0, %2\n"
"efsctsf %1, %3\n"
: "=r" (vc.wp[0]), "=r" (vc.wp[1])
: "r" (vb.wp[0]), "r" (vb.wp[1]), "r" (0));
goto update_regs;
case EVFSCTUF: case EVFSCTUF:
__asm__ __volatile__ ("mtspr 512, %4\n" case EVFSCTSF:
"efsctuf %0, %2\n" if (SB0_c == FP_CLS_NAN) {
"efsctuf %1, %3\n" vc.wp[0] = 0;
: "=r" (vc.wp[0]), "=r" (vc.wp[1]) FP_SET_EXCEPTION(FP_EX_INVALID);
: "r" (vb.wp[0]), "r" (vb.wp[1]), "r" (0)); } else {
SB0_e += (func == EVFSCTSF ? 31 : 32);
FP_TO_INT_ROUND_S(vc.wp[0], SB0, 32,
(func == EVFSCTSF));
}
if (SB1_c == FP_CLS_NAN) {
vc.wp[1] = 0;
FP_SET_EXCEPTION(FP_EX_INVALID);
} else {
SB1_e += (func == EVFSCTSF ? 31 : 32);
FP_TO_INT_ROUND_S(vc.wp[1], SB1, 32,
(func == EVFSCTSF));
}
goto update_regs; goto update_regs;
case EVFSCTUI: case EVFSCTUI:
case EVFSCTSI: case EVFSCTSI:
if (SB0_c == FP_CLS_NAN) {
vc.wp[0] = 0;
FP_SET_EXCEPTION(FP_EX_INVALID);
} else {
FP_TO_INT_ROUND_S(vc.wp[0], SB0, 32,
((func & 0x3) != 0));
}
if (SB1_c == FP_CLS_NAN) {
vc.wp[1] = 0;
FP_SET_EXCEPTION(FP_EX_INVALID);
} else {
FP_TO_INT_ROUND_S(vc.wp[1], SB1, 32,
((func & 0x3) != 0));
}
goto update_regs;
case EVFSCTUIZ: case EVFSCTUIZ:
case EVFSCTSIZ: case EVFSCTSIZ:
if (func & 0x4) { if (SB0_c == FP_CLS_NAN) {
_FP_ROUND(1, SB0); vc.wp[0] = 0;
_FP_ROUND(1, SB1); FP_SET_EXCEPTION(FP_EX_INVALID);
} else { } else {
_FP_ROUND_ZERO(1, SB0);
_FP_ROUND_ZERO(1, SB1);
}
FP_TO_INT_S(vc.wp[0], SB0, 32, FP_TO_INT_S(vc.wp[0], SB0, 32,
(((func & 0x3) != 0) || SB0_s)); ((func & 0x3) != 0));
}
if (SB1_c == FP_CLS_NAN) {
vc.wp[1] = 0;
FP_SET_EXCEPTION(FP_EX_INVALID);
} else {
FP_TO_INT_S(vc.wp[1], SB1, 32, FP_TO_INT_S(vc.wp[1], SB1, 32,
(((func & 0x3) != 0) || SB1_s)); ((func & 0x3) != 0));
}
goto update_regs; goto update_regs;
default: default:
...@@ -630,9 +660,27 @@ int do_spe_mathemu(struct pt_regs *regs) ...@@ -630,9 +660,27 @@ int do_spe_mathemu(struct pt_regs *regs)
regs->ccr |= (IR << ((7 - ((speinsn >> 23) & 0x7)) << 2)); regs->ccr |= (IR << ((7 - ((speinsn >> 23) & 0x7)) << 2));
update_regs: update_regs:
__FPU_FPSCR &= ~FP_EX_MASK; /*
* If the "invalid" exception sticky bit was set by the
* processor for non-finite input, but was not set before the
* instruction being emulated, clear it. Likewise for the
* "underflow" bit, which may have been set by the processor
* for exact underflow, not just inexact underflow when the
* flag should be set for IEEE 754 semantics. Other sticky
* exceptions will only be set by the processor when they are
* correct according to IEEE 754 semantics, and we must not
* clear sticky bits that were already set before the emulated
* instruction as they represent the user-visible sticky
* exception status. "inexact" traps to kernel are not
* required for IEEE semantics and are not enabled by default,
* so the "inexact" sticky bit may have been set by a previous
* instruction without the kernel being aware of it.
*/
__FPU_FPSCR
&= ~(FP_EX_INVALID | FP_EX_UNDERFLOW) | current->thread.spefscr_last;
__FPU_FPSCR |= (FP_CUR_EXCEPTIONS & FP_EX_MASK); __FPU_FPSCR |= (FP_CUR_EXCEPTIONS & FP_EX_MASK);
mtspr(SPRN_SPEFSCR, __FPU_FPSCR); mtspr(SPRN_SPEFSCR, __FPU_FPSCR);
current->thread.spefscr_last = __FPU_FPSCR;
current->thread.evr[fc] = vc.wp[0]; current->thread.evr[fc] = vc.wp[0];
regs->gpr[fc] = vc.wp[1]; regs->gpr[fc] = vc.wp[1];
...@@ -644,6 +692,23 @@ int do_spe_mathemu(struct pt_regs *regs) ...@@ -644,6 +692,23 @@ int do_spe_mathemu(struct pt_regs *regs)
pr_debug("va: %08x %08x\n", va.wp[0], va.wp[1]); pr_debug("va: %08x %08x\n", va.wp[0], va.wp[1]);
pr_debug("vb: %08x %08x\n", vb.wp[0], vb.wp[1]); pr_debug("vb: %08x %08x\n", vb.wp[0], vb.wp[1]);
if (current->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE) {
if ((FP_CUR_EXCEPTIONS & FP_EX_DIVZERO)
&& (current->thread.fpexc_mode & PR_FP_EXC_DIV))
return 1;
if ((FP_CUR_EXCEPTIONS & FP_EX_OVERFLOW)
&& (current->thread.fpexc_mode & PR_FP_EXC_OVF))
return 1;
if ((FP_CUR_EXCEPTIONS & FP_EX_UNDERFLOW)
&& (current->thread.fpexc_mode & PR_FP_EXC_UND))
return 1;
if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT)
&& (current->thread.fpexc_mode & PR_FP_EXC_RES))
return 1;
if ((FP_CUR_EXCEPTIONS & FP_EX_INVALID)
&& (current->thread.fpexc_mode & PR_FP_EXC_INV))
return 1;
}
return 0; return 0;
illegal: illegal:
...@@ -662,21 +727,28 @@ int speround_handler(struct pt_regs *regs) ...@@ -662,21 +727,28 @@ int speround_handler(struct pt_regs *regs)
{ {
union dw_union fgpr; union dw_union fgpr;
int s_lo, s_hi; int s_lo, s_hi;
unsigned long speinsn, type, fc; int lo_inexact, hi_inexact;
int fp_result;
unsigned long speinsn, type, fb, fc, fptype, func;
if (get_user(speinsn, (unsigned int __user *) regs->nip)) if (get_user(speinsn, (unsigned int __user *) regs->nip))
return -EFAULT; return -EFAULT;
if ((speinsn >> 26) != 4) if ((speinsn >> 26) != 4)
return -EINVAL; /* not an spe instruction */ return -EINVAL; /* not an spe instruction */
type = insn_type(speinsn & 0x7ff); func = speinsn & 0x7ff;
type = insn_type(func);
if (type == XCR) return -ENOSYS; if (type == XCR) return -ENOSYS;
__FPU_FPSCR = mfspr(SPRN_SPEFSCR); __FPU_FPSCR = mfspr(SPRN_SPEFSCR);
pr_debug("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR); pr_debug("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR);
fptype = (speinsn >> 5) & 0x7;
/* No need to round if the result is exact */ /* No need to round if the result is exact */
if (!(__FPU_FPSCR & FP_EX_INEXACT)) lo_inexact = __FPU_FPSCR & (SPEFSCR_FG | SPEFSCR_FX);
hi_inexact = __FPU_FPSCR & (SPEFSCR_FGH | SPEFSCR_FXH);
if (!(lo_inexact || (hi_inexact && fptype == VCT)))
return 0; return 0;
fc = (speinsn >> 21) & 0x1f; fc = (speinsn >> 21) & 0x1f;
...@@ -685,9 +757,68 @@ int speround_handler(struct pt_regs *regs) ...@@ -685,9 +757,68 @@ int speround_handler(struct pt_regs *regs)
fgpr.wp[0] = current->thread.evr[fc]; fgpr.wp[0] = current->thread.evr[fc];
fgpr.wp[1] = regs->gpr[fc]; fgpr.wp[1] = regs->gpr[fc];
fb = (speinsn >> 11) & 0x1f;
switch (func) {
case EFSCTUIZ:
case EFSCTSIZ:
case EVFSCTUIZ:
case EVFSCTSIZ:
case EFDCTUIDZ:
case EFDCTSIDZ:
case EFDCTUIZ:
case EFDCTSIZ:
/*
* These instructions always round to zero,
* independent of the rounding mode.
*/
return 0;
case EFSCTUI:
case EFSCTUF:
case EVFSCTUI:
case EVFSCTUF:
case EFDCTUI:
case EFDCTUF:
fp_result = 0;
s_lo = 0;
s_hi = 0;
break;
case EFSCTSI:
case EFSCTSF:
fp_result = 0;
/* Recover the sign of a zero result if possible. */
if (fgpr.wp[1] == 0)
s_lo = regs->gpr[fb] & SIGN_BIT_S;
break;
case EVFSCTSI:
case EVFSCTSF:
fp_result = 0;
/* Recover the sign of a zero result if possible. */
if (fgpr.wp[1] == 0)
s_lo = regs->gpr[fb] & SIGN_BIT_S;
if (fgpr.wp[0] == 0)
s_hi = current->thread.evr[fb] & SIGN_BIT_S;
break;
case EFDCTSI:
case EFDCTSF:
fp_result = 0;
s_hi = s_lo;
/* Recover the sign of a zero result if possible. */
if (fgpr.wp[1] == 0)
s_hi = current->thread.evr[fb] & SIGN_BIT_S;
break;
default:
fp_result = 1;
break;
}
pr_debug("round fgpr: %08x %08x\n", fgpr.wp[0], fgpr.wp[1]); pr_debug("round fgpr: %08x %08x\n", fgpr.wp[0], fgpr.wp[1]);
switch ((speinsn >> 5) & 0x7) { switch (fptype) {
/* Since SPE instructions on E500 core can handle round to nearest /* Since SPE instructions on E500 core can handle round to nearest
* and round toward zero with IEEE-754 complied, we just need * and round toward zero with IEEE-754 complied, we just need
* to handle round toward +Inf and round toward -Inf by software. * to handle round toward +Inf and round toward -Inf by software.
...@@ -696,25 +827,52 @@ int speround_handler(struct pt_regs *regs) ...@@ -696,25 +827,52 @@ int speround_handler(struct pt_regs *regs)
if ((FP_ROUNDMODE) == FP_RND_PINF) { if ((FP_ROUNDMODE) == FP_RND_PINF) {
if (!s_lo) fgpr.wp[1]++; /* Z > 0, choose Z1 */ if (!s_lo) fgpr.wp[1]++; /* Z > 0, choose Z1 */
} else { /* round to -Inf */ } else { /* round to -Inf */
if (s_lo) fgpr.wp[1]++; /* Z < 0, choose Z2 */ if (s_lo) {
if (fp_result)
fgpr.wp[1]++; /* Z < 0, choose Z2 */
else
fgpr.wp[1]--; /* Z < 0, choose Z2 */
}
} }
break; break;
case DPFP: case DPFP:
if (FP_ROUNDMODE == FP_RND_PINF) { if (FP_ROUNDMODE == FP_RND_PINF) {
if (!s_hi) fgpr.dp[0]++; /* Z > 0, choose Z1 */ if (!s_hi) {
if (fp_result)
fgpr.dp[0]++; /* Z > 0, choose Z1 */
else
fgpr.wp[1]++; /* Z > 0, choose Z1 */
}
} else { /* round to -Inf */ } else { /* round to -Inf */
if (s_hi) fgpr.dp[0]++; /* Z < 0, choose Z2 */ if (s_hi) {
if (fp_result)
fgpr.dp[0]++; /* Z < 0, choose Z2 */
else
fgpr.wp[1]--; /* Z < 0, choose Z2 */
}
} }
break; break;
case VCT: case VCT:
if (FP_ROUNDMODE == FP_RND_PINF) { if (FP_ROUNDMODE == FP_RND_PINF) {
if (!s_lo) fgpr.wp[1]++; /* Z_low > 0, choose Z1 */ if (lo_inexact && !s_lo)
if (!s_hi) fgpr.wp[0]++; /* Z_high word > 0, choose Z1 */ fgpr.wp[1]++; /* Z_low > 0, choose Z1 */
if (hi_inexact && !s_hi)
fgpr.wp[0]++; /* Z_high word > 0, choose Z1 */
} else { /* round to -Inf */ } else { /* round to -Inf */
if (s_lo) fgpr.wp[1]++; /* Z_low < 0, choose Z2 */ if (lo_inexact && s_lo) {
if (s_hi) fgpr.wp[0]++; /* Z_high < 0, choose Z2 */ if (fp_result)
fgpr.wp[1]++; /* Z_low < 0, choose Z2 */
else
fgpr.wp[1]--; /* Z_low < 0, choose Z2 */
}
if (hi_inexact && s_hi) {
if (fp_result)
fgpr.wp[0]++; /* Z_high < 0, choose Z2 */
else
fgpr.wp[0]--; /* Z_high < 0, choose Z2 */
}
} }
break; break;
...@@ -727,6 +885,8 @@ int speround_handler(struct pt_regs *regs) ...@@ -727,6 +885,8 @@ int speround_handler(struct pt_regs *regs)
pr_debug(" to fgpr: %08x %08x\n", fgpr.wp[0], fgpr.wp[1]); pr_debug(" to fgpr: %08x %08x\n", fgpr.wp[0], fgpr.wp[1]);
if (current->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
return (current->thread.fpexc_mode & PR_FP_EXC_RES) ? 1 : 0;
return 0; return 0;
} }
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/paca.h>
#include "mmu_decl.h" #include "mmu_decl.h"
...@@ -171,11 +172,10 @@ unsigned long calc_cam_sz(unsigned long ram, unsigned long virt, ...@@ -171,11 +172,10 @@ unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
return 1UL << camsize; return 1UL << camsize;
} }
unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx) static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
unsigned long ram, int max_cam_idx)
{ {
int i; int i;
unsigned long virt = PAGE_OFFSET;
phys_addr_t phys = memstart_addr;
unsigned long amount_mapped = 0; unsigned long amount_mapped = 0;
/* Calculate CAM values */ /* Calculate CAM values */
...@@ -192,9 +192,23 @@ unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx) ...@@ -192,9 +192,23 @@ unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
} }
tlbcam_index = i; tlbcam_index = i;
#ifdef CONFIG_PPC64
get_paca()->tcd.esel_next = i;
get_paca()->tcd.esel_max = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY;
get_paca()->tcd.esel_first = i;
#endif
return amount_mapped; return amount_mapped;
} }
unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
{
unsigned long virt = PAGE_OFFSET;
phys_addr_t phys = memstart_addr;
return map_mem_in_cams_addr(phys, virt, ram, max_cam_idx);
}
#ifdef CONFIG_PPC32 #ifdef CONFIG_PPC32
#if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS) #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS)
...@@ -222,7 +236,9 @@ void __init adjust_total_lowmem(void) ...@@ -222,7 +236,9 @@ void __init adjust_total_lowmem(void)
/* adjust lowmem size to __max_low_memory */ /* adjust lowmem size to __max_low_memory */
ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem); ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem);
i = switch_to_as1();
__max_low_memory = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM); __max_low_memory = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM);
restore_to_as0(i, 0, 0, 1);
pr_info("Memory CAM mapping: "); pr_info("Memory CAM mapping: ");
for (i = 0; i < tlbcam_index - 1; i++) for (i = 0; i < tlbcam_index - 1; i++)
...@@ -241,4 +257,62 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base, ...@@ -241,4 +257,62 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
/* 64M mapped initially according to head_fsl_booke.S */ /* 64M mapped initially according to head_fsl_booke.S */
memblock_set_current_limit(min_t(u64, limit, 0x04000000)); memblock_set_current_limit(min_t(u64, limit, 0x04000000));
} }
#ifdef CONFIG_RELOCATABLE
int __initdata is_second_reloc;
notrace void __init relocate_init(u64 dt_ptr, phys_addr_t start)
{
unsigned long base = KERNELBASE;
kernstart_addr = start;
if (is_second_reloc) {
virt_phys_offset = PAGE_OFFSET - memstart_addr;
return;
}
/*
* Relocatable kernel support based on processing of dynamic
* relocation entries. Before we get the real memstart_addr,
* We will compute the virt_phys_offset like this:
* virt_phys_offset = stext.run - kernstart_addr
*
* stext.run = (KERNELBASE & ~0x3ffffff) +
* (kernstart_addr & 0x3ffffff)
* When we relocate, we have :
*
* (kernstart_addr & 0x3ffffff) = (stext.run & 0x3ffffff)
*
* hence:
* virt_phys_offset = (KERNELBASE & ~0x3ffffff) -
* (kernstart_addr & ~0x3ffffff)
*
*/
start &= ~0x3ffffff;
base &= ~0x3ffffff;
virt_phys_offset = base - start;
early_get_first_memblock_info(__va(dt_ptr), NULL);
/*
* We now get the memstart_addr, then we should check if this
* address is the same as what the PAGE_OFFSET map to now. If
* not we have to change the map of PAGE_OFFSET to memstart_addr
* and do a second relocation.
*/
if (start != memstart_addr) {
int n;
long offset = start - memstart_addr;
is_second_reloc = 1;
n = switch_to_as1();
/* map a 64M area for the second relocation */
if (memstart_addr > start)
map_mem_in_cams(0x4000000, CONFIG_LOWMEM_CAM_NUM);
else
map_mem_in_cams_addr(start, PAGE_OFFSET + offset,
0x4000000, CONFIG_LOWMEM_CAM_NUM);
restore_to_as0(n, offset, __va(dt_ptr), 1);
/* We should never reach here */
panic("Relocation error");
}
}
#endif
#endif #endif
...@@ -8,6 +8,44 @@ ...@@ -8,6 +8,44 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/hugetlb.h> #include <linux/hugetlb.h>
#ifdef CONFIG_PPC_FSL_BOOK3E
#ifdef CONFIG_PPC64
static inline int tlb1_next(void)
{
struct paca_struct *paca = get_paca();
struct tlb_core_data *tcd;
int this, next;
tcd = paca->tcd_ptr;
this = tcd->esel_next;
next = this + 1;
if (next >= tcd->esel_max)
next = tcd->esel_first;
tcd->esel_next = next;
return this;
}
#else
static inline int tlb1_next(void)
{
int index, ncams;
ncams = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY;
index = __get_cpu_var(next_tlbcam_idx);
/* Just round-robin the entries and wrap when we hit the end */
if (unlikely(index == ncams - 1))
__get_cpu_var(next_tlbcam_idx) = tlbcam_index;
else
__get_cpu_var(next_tlbcam_idx)++;
return index;
}
#endif /* !PPC64 */
#endif /* FSL */
static inline int mmu_get_tsize(int psize) static inline int mmu_get_tsize(int psize)
{ {
return mmu_psize_defs[psize].enc; return mmu_psize_defs[psize].enc;
...@@ -47,7 +85,7 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea, ...@@ -47,7 +85,7 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
struct mm_struct *mm; struct mm_struct *mm;
#ifdef CONFIG_PPC_FSL_BOOK3E #ifdef CONFIG_PPC_FSL_BOOK3E
int index, ncams; int index;
#endif #endif
if (unlikely(is_kernel_addr(ea))) if (unlikely(is_kernel_addr(ea)))
...@@ -77,18 +115,11 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea, ...@@ -77,18 +115,11 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
} }
#ifdef CONFIG_PPC_FSL_BOOK3E #ifdef CONFIG_PPC_FSL_BOOK3E
ncams = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY;
/* We have to use the CAM(TLB1) on FSL parts for hugepages */ /* We have to use the CAM(TLB1) on FSL parts for hugepages */
index = __get_cpu_var(next_tlbcam_idx); index = tlb1_next();
mtspr(SPRN_MAS0, MAS0_ESEL(index) | MAS0_TLBSEL(1)); mtspr(SPRN_MAS0, MAS0_ESEL(index) | MAS0_TLBSEL(1));
/* Just round-robin the entries and wrap when we hit the end */
if (unlikely(index == ncams - 1))
__get_cpu_var(next_tlbcam_idx) = tlbcam_index;
else
__get_cpu_var(next_tlbcam_idx)++;
#endif #endif
mas1 = MAS1_VALID | MAS1_TID(mm->context.id) | MAS1_TSIZE(tsize); mas1 = MAS1_VALID | MAS1_TID(mm->context.id) | MAS1_TSIZE(tsize);
mas2 = ea & ~((1UL << shift) - 1); mas2 = ea & ~((1UL << shift) - 1);
mas2 |= (pte_val(pte) >> PTE_WIMGE_SHIFT) & MAS2_WIMGE_MASK; mas2 |= (pte_val(pte) >> PTE_WIMGE_SHIFT) & MAS2_WIMGE_MASK;
...@@ -103,6 +134,7 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea, ...@@ -103,6 +134,7 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
if (mmu_has_feature(MMU_FTR_USE_PAIRED_MAS)) { if (mmu_has_feature(MMU_FTR_USE_PAIRED_MAS)) {
mtspr(SPRN_MAS7_MAS3, mas7_3); mtspr(SPRN_MAS7_MAS3, mas7_3);
} else { } else {
if (mmu_has_feature(MMU_FTR_BIG_PHYS))
mtspr(SPRN_MAS7, upper_32_bits(mas7_3)); mtspr(SPRN_MAS7, upper_32_bits(mas7_3));
mtspr(SPRN_MAS3, lower_32_bits(mas7_3)); mtspr(SPRN_MAS3, lower_32_bits(mas7_3));
} }
......
...@@ -307,6 +307,12 @@ static void __init register_page_bootmem_info(void) ...@@ -307,6 +307,12 @@ static void __init register_page_bootmem_info(void)
void __init mem_init(void) void __init mem_init(void)
{ {
/*
* book3s is limited to 16 page sizes due to encoding this in
* a 4-bit field for slices.
*/
BUILD_BUG_ON(MMU_PAGE_COUNT > 16);
#ifdef CONFIG_SWIOTLB #ifdef CONFIG_SWIOTLB
swiotlb_init(0); swiotlb_init(0);
#endif #endif
......
...@@ -148,6 +148,8 @@ extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt, ...@@ -148,6 +148,8 @@ extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
extern void MMU_init_hw(void); extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(unsigned long top); extern unsigned long mmu_mapin_ram(unsigned long top);
extern void adjust_total_lowmem(void); extern void adjust_total_lowmem(void);
extern int switch_to_as1(void);
extern void restore_to_as0(int esel, int offset, void *dt_ptr, int bootcpu);
#endif #endif
extern void loadcam_entry(unsigned int index); extern void loadcam_entry(unsigned int index);
......
...@@ -299,6 +299,7 @@ int map_page(unsigned long va, phys_addr_t pa, int flags) ...@@ -299,6 +299,7 @@ int map_page(unsigned long va, phys_addr_t pa, int flags)
set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT,
__pgprot(flags))); __pgprot(flags)));
} }
smp_wmb();
return err; return err;
} }
......
...@@ -152,6 +152,18 @@ int map_kernel_page(unsigned long ea, unsigned long pa, int flags) ...@@ -152,6 +152,18 @@ int map_kernel_page(unsigned long ea, unsigned long pa, int flags)
} }
#endif /* !CONFIG_PPC_MMU_NOHASH */ #endif /* !CONFIG_PPC_MMU_NOHASH */
} }
#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.
*/
mb();
#else
smp_wmb();
#endif
return 0; return 0;
} }
......
...@@ -136,7 +136,7 @@ BEGIN_MMU_FTR_SECTION ...@@ -136,7 +136,7 @@ BEGIN_MMU_FTR_SECTION
*/ */
PPC_TLBSRX_DOT(0,R16) PPC_TLBSRX_DOT(0,R16)
ldx r14,r14,r15 /* grab pgd entry */ ldx r14,r14,r15 /* grab pgd entry */
beq normal_tlb_miss_done /* tlb exists already, bail */ beq tlb_miss_done_bolted /* tlb exists already, bail */
MMU_FTR_SECTION_ELSE MMU_FTR_SECTION_ELSE
ldx r14,r14,r15 /* grab pgd entry */ ldx r14,r14,r15 /* grab pgd entry */
ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBRSRV) ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBRSRV)
...@@ -192,6 +192,7 @@ ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBRSRV) ...@@ -192,6 +192,7 @@ ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBRSRV)
mtspr SPRN_MAS7_MAS3,r15 mtspr SPRN_MAS7_MAS3,r15
tlbwe tlbwe
tlb_miss_done_bolted:
TLB_MISS_STATS_X(MMSTAT_TLB_MISS_NORM_OK) TLB_MISS_STATS_X(MMSTAT_TLB_MISS_NORM_OK)
tlb_epilog_bolted tlb_epilog_bolted
rfi rfi
...@@ -239,6 +240,177 @@ itlb_miss_fault_bolted: ...@@ -239,6 +240,177 @@ itlb_miss_fault_bolted:
beq tlb_miss_common_bolted beq tlb_miss_common_bolted
b itlb_miss_kernel_bolted b itlb_miss_kernel_bolted
/*
* TLB miss handling for e6500 and derivatives, using hardware tablewalk.
*
* Linear mapping is bolted: no virtual page table or nested TLB misses
* Indirect entries in TLB1, hardware loads resulting direct entries
* into TLB0
* No HES or NV hint on TLB1, so we need to do software round-robin
* No tlbsrx. so we need a spinlock, and we have to deal
* with MAS-damage caused by tlbsx
* 4K pages only
*/
START_EXCEPTION(instruction_tlb_miss_e6500)
tlb_prolog_bolted BOOKE_INTERRUPT_ITLB_MISS SPRN_SRR0
ld r11,PACA_TCD_PTR(r13)
srdi. r15,r16,60 /* get region */
ori r16,r16,1
TLB_MISS_STATS_SAVE_INFO_BOLTED
bne tlb_miss_kernel_e6500 /* user/kernel test */
b tlb_miss_common_e6500
START_EXCEPTION(data_tlb_miss_e6500)
tlb_prolog_bolted BOOKE_INTERRUPT_DTLB_MISS SPRN_DEAR
ld r11,PACA_TCD_PTR(r13)
srdi. r15,r16,60 /* get region */
rldicr r16,r16,0,62
TLB_MISS_STATS_SAVE_INFO_BOLTED
bne tlb_miss_kernel_e6500 /* user vs kernel check */
/*
* This is the guts of the TLB miss handler for e6500 and derivatives.
* We are entered with:
*
* r16 = page of faulting address (low bit 0 if data, 1 if instruction)
* r15 = crap (free to use)
* r14 = page table base
* r13 = PACA
* r11 = tlb_per_core ptr
* r10 = crap (free to use)
*/
tlb_miss_common_e6500:
/*
* Search if we already have an indirect entry for that virtual
* address, and if we do, bail out.
*
* MAS6:IND should be already set based on MAS4
*/
addi r10,r11,TCD_LOCK
1: lbarx r15,0,r10
cmpdi r15,0
bne 2f
li r15,1
stbcx. r15,0,r10
bne 1b
.subsection 1
2: lbz r15,0(r10)
cmpdi r15,0
bne 2b
b 1b
.previous
mfspr r15,SPRN_MAS2
tlbsx 0,r16
mfspr r10,SPRN_MAS1
andis. r10,r10,MAS1_VALID@h
bne tlb_miss_done_e6500
/* Undo MAS-damage from the tlbsx */
mfspr r10,SPRN_MAS1
oris r10,r10,MAS1_VALID@h
mtspr SPRN_MAS1,r10
mtspr SPRN_MAS2,r15
/* Now, we need to walk the page tables. First check if we are in
* range.
*/
rldicl. r10,r16,64-PGTABLE_EADDR_SIZE,PGTABLE_EADDR_SIZE+4
bne- tlb_miss_fault_e6500
rldicl r15,r16,64-PGDIR_SHIFT+3,64-PGD_INDEX_SIZE-3
cmpldi cr0,r14,0
clrrdi r15,r15,3
beq- tlb_miss_fault_e6500 /* No PGDIR, bail */
ldx r14,r14,r15 /* grab pgd entry */
rldicl r15,r16,64-PUD_SHIFT+3,64-PUD_INDEX_SIZE-3
clrrdi r15,r15,3
cmpdi cr0,r14,0
bge tlb_miss_fault_e6500 /* Bad pgd entry or hugepage; bail */
ldx r14,r14,r15 /* grab pud entry */
rldicl r15,r16,64-PMD_SHIFT+3,64-PMD_INDEX_SIZE-3
clrrdi r15,r15,3
cmpdi cr0,r14,0
bge tlb_miss_fault_e6500
ldx r14,r14,r15 /* Grab pmd entry */
mfspr r10,SPRN_MAS0
cmpdi cr0,r14,0
bge tlb_miss_fault_e6500
/* Now we build the MAS for a 2M indirect page:
*
* MAS 0 : ESEL needs to be filled by software round-robin
* MAS 1 : Fully set up
* - PID already updated by caller if necessary
* - TSIZE for now is base ind page size always
* - TID already cleared if necessary
* MAS 2 : Default not 2M-aligned, need to be redone
* MAS 3+7 : Needs to be done
*/
ori r14,r14,(BOOK3E_PAGESZ_4K << MAS3_SPSIZE_SHIFT)
mtspr SPRN_MAS7_MAS3,r14
clrrdi r15,r16,21 /* make EA 2M-aligned */
mtspr SPRN_MAS2,r15
lbz r15,TCD_ESEL_NEXT(r11)
lbz r16,TCD_ESEL_MAX(r11)
lbz r14,TCD_ESEL_FIRST(r11)
rlwimi r10,r15,16,0x00ff0000 /* insert esel_next into MAS0 */
addi r15,r15,1 /* increment esel_next */
mtspr SPRN_MAS0,r10
cmpw r15,r16
iseleq r15,r14,r15 /* if next == last use first */
stb r15,TCD_ESEL_NEXT(r11)
tlbwe
tlb_miss_done_e6500:
.macro tlb_unlock_e6500
li r15,0
isync
stb r15,TCD_LOCK(r11)
.endm
tlb_unlock_e6500
TLB_MISS_STATS_X(MMSTAT_TLB_MISS_NORM_OK)
tlb_epilog_bolted
rfi
tlb_miss_kernel_e6500:
mfspr r10,SPRN_MAS1
ld r14,PACA_KERNELPGD(r13)
cmpldi cr0,r15,8 /* Check for vmalloc region */
rlwinm r10,r10,0,16,1 /* Clear TID */
mtspr SPRN_MAS1,r10
beq+ tlb_miss_common_e6500
tlb_miss_fault_e6500:
tlb_unlock_e6500
/* We need to check if it was an instruction miss */
andi. r16,r16,1
bne itlb_miss_fault_e6500
dtlb_miss_fault_e6500:
TLB_MISS_STATS_D(MMSTAT_TLB_MISS_NORM_FAULT)
tlb_epilog_bolted
b exc_data_storage_book3e
itlb_miss_fault_e6500:
TLB_MISS_STATS_I(MMSTAT_TLB_MISS_NORM_FAULT)
tlb_epilog_bolted
b exc_instruction_storage_book3e
/********************************************************************** /**********************************************************************
* * * *
* TLB miss handling for Book3E with TLB reservation and HES support * * TLB miss handling for Book3E with TLB reservation and HES support *
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <asm/tlb.h> #include <asm/tlb.h>
#include <asm/code-patching.h> #include <asm/code-patching.h>
#include <asm/hugetlb.h> #include <asm/hugetlb.h>
#include <asm/paca.h>
#include "mmu_decl.h" #include "mmu_decl.h"
...@@ -58,6 +59,10 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { ...@@ -58,6 +59,10 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = {
.shift = 12, .shift = 12,
.enc = BOOK3E_PAGESZ_4K, .enc = BOOK3E_PAGESZ_4K,
}, },
[MMU_PAGE_2M] = {
.shift = 21,
.enc = BOOK3E_PAGESZ_2M,
},
[MMU_PAGE_4M] = { [MMU_PAGE_4M] = {
.shift = 22, .shift = 22,
.enc = BOOK3E_PAGESZ_4M, .enc = BOOK3E_PAGESZ_4M,
...@@ -136,7 +141,7 @@ static inline int mmu_get_tsize(int psize) ...@@ -136,7 +141,7 @@ static inline int mmu_get_tsize(int psize)
int mmu_linear_psize; /* Page size used for the linear mapping */ int mmu_linear_psize; /* Page size used for the linear mapping */
int mmu_pte_psize; /* Page size used for PTE pages */ int mmu_pte_psize; /* Page size used for PTE pages */
int mmu_vmemmap_psize; /* Page size used for the virtual mem map */ int mmu_vmemmap_psize; /* Page size used for the virtual mem map */
int book3e_htw_enabled; /* Is HW tablewalk enabled ? */ int book3e_htw_mode; /* HW tablewalk? Value is PPC_HTW_* */
unsigned long linear_map_top; /* Top of linear mapping */ unsigned long linear_map_top; /* Top of linear mapping */
#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC64 */
...@@ -377,7 +382,7 @@ void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address) ...@@ -377,7 +382,7 @@ void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address)
{ {
int tsize = mmu_psize_defs[mmu_pte_psize].enc; int tsize = mmu_psize_defs[mmu_pte_psize].enc;
if (book3e_htw_enabled) { if (book3e_htw_mode != PPC_HTW_NONE) {
unsigned long start = address & PMD_MASK; unsigned long start = address & PMD_MASK;
unsigned long end = address + PMD_SIZE; unsigned long end = address + PMD_SIZE;
unsigned long size = 1UL << mmu_psize_defs[mmu_pte_psize].shift; unsigned long size = 1UL << mmu_psize_defs[mmu_pte_psize].shift;
...@@ -430,7 +435,7 @@ static void setup_page_sizes(void) ...@@ -430,7 +435,7 @@ static void setup_page_sizes(void)
def = &mmu_psize_defs[psize]; def = &mmu_psize_defs[psize];
shift = def->shift; shift = def->shift;
if (shift == 0) if (shift == 0 || shift & 1)
continue; continue;
/* adjust to be in terms of 4^shift Kb */ /* adjust to be in terms of 4^shift Kb */
...@@ -440,21 +445,40 @@ static void setup_page_sizes(void) ...@@ -440,21 +445,40 @@ static void setup_page_sizes(void)
def->flags |= MMU_PAGE_SIZE_DIRECT; def->flags |= MMU_PAGE_SIZE_DIRECT;
} }
goto no_indirect; goto out;
} }
if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2) { if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2) {
u32 tlb1ps = mfspr(SPRN_TLB1PS); u32 tlb1cfg, tlb1ps;
tlb0cfg = mfspr(SPRN_TLB0CFG);
tlb1cfg = mfspr(SPRN_TLB1CFG);
tlb1ps = mfspr(SPRN_TLB1PS);
eptcfg = mfspr(SPRN_EPTCFG);
if ((tlb1cfg & TLBnCFG_IND) && (tlb0cfg & TLBnCFG_PT))
book3e_htw_mode = PPC_HTW_E6500;
/*
* We expect 4K subpage size and unrestricted indirect size.
* The lack of a restriction on indirect size is a Freescale
* extension, indicated by PSn = 0 but SPSn != 0.
*/
if (eptcfg != 2)
book3e_htw_mode = PPC_HTW_NONE;
for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
struct mmu_psize_def *def = &mmu_psize_defs[psize]; struct mmu_psize_def *def = &mmu_psize_defs[psize];
if (tlb1ps & (1U << (def->shift - 10))) { if (tlb1ps & (1U << (def->shift - 10))) {
def->flags |= MMU_PAGE_SIZE_DIRECT; def->flags |= MMU_PAGE_SIZE_DIRECT;
if (book3e_htw_mode && psize == MMU_PAGE_2M)
def->flags |= MMU_PAGE_SIZE_INDIRECT;
} }
} }
goto no_indirect; goto out;
} }
#endif #endif
...@@ -471,8 +495,11 @@ static void setup_page_sizes(void) ...@@ -471,8 +495,11 @@ static void setup_page_sizes(void)
} }
/* Indirect page sizes supported ? */ /* Indirect page sizes supported ? */
if ((tlb0cfg & TLBnCFG_IND) == 0) if ((tlb0cfg & TLBnCFG_IND) == 0 ||
goto no_indirect; (tlb0cfg & TLBnCFG_PT) == 0)
goto out;
book3e_htw_mode = PPC_HTW_IBM;
/* Now, we only deal with one IND page size for each /* Now, we only deal with one IND page size for each
* direct size. Hopefully all implementations today are * direct size. Hopefully all implementations today are
...@@ -497,8 +524,8 @@ static void setup_page_sizes(void) ...@@ -497,8 +524,8 @@ static void setup_page_sizes(void)
def->ind = ps + 10; def->ind = ps + 10;
} }
} }
no_indirect:
out:
/* Cleanup array and print summary */ /* Cleanup array and print summary */
pr_info("MMU: Supported page sizes\n"); pr_info("MMU: Supported page sizes\n");
for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
...@@ -520,23 +547,23 @@ static void setup_page_sizes(void) ...@@ -520,23 +547,23 @@ static void setup_page_sizes(void)
static void setup_mmu_htw(void) static void setup_mmu_htw(void)
{ {
/* Check if HW tablewalk is present, and if yes, enable it by: /*
* * If we want to use HW tablewalk, enable it by patching the TLB miss
* - patching the TLB miss handlers to branch to the * handlers to branch to the one dedicated to it.
* one dedicates to it
*
* - setting the global book3e_htw_enabled
*/ */
unsigned int tlb0cfg = mfspr(SPRN_TLB0CFG);
if ((tlb0cfg & TLBnCFG_IND) && switch (book3e_htw_mode) {
(tlb0cfg & TLBnCFG_PT)) { case PPC_HTW_IBM:
patch_exception(0x1c0, exc_data_tlb_miss_htw_book3e); patch_exception(0x1c0, exc_data_tlb_miss_htw_book3e);
patch_exception(0x1e0, exc_instruction_tlb_miss_htw_book3e); patch_exception(0x1e0, exc_instruction_tlb_miss_htw_book3e);
book3e_htw_enabled = 1; break;
case PPC_HTW_E6500:
patch_exception(0x1c0, exc_data_tlb_miss_e6500_book3e);
patch_exception(0x1e0, exc_instruction_tlb_miss_e6500_book3e);
break;
} }
pr_info("MMU: Book3E HW tablewalk %s\n", pr_info("MMU: Book3E HW tablewalk %s\n",
book3e_htw_enabled ? "enabled" : "not supported"); book3e_htw_mode != PPC_HTW_NONE ? "enabled" : "not supported");
} }
/* /*
...@@ -576,8 +603,16 @@ static void __early_init_mmu(int boot_cpu) ...@@ -576,8 +603,16 @@ static void __early_init_mmu(int boot_cpu)
/* Set MAS4 based on page table setting */ /* Set MAS4 based on page table setting */
mas4 = 0x4 << MAS4_WIMGED_SHIFT; mas4 = 0x4 << MAS4_WIMGED_SHIFT;
if (book3e_htw_enabled) { switch (book3e_htw_mode) {
mas4 |= mas4 | MAS4_INDD; case PPC_HTW_E6500:
mas4 |= MAS4_INDD;
mas4 |= BOOK3E_PAGESZ_2M << MAS4_TSIZED_SHIFT;
mas4 |= MAS4_TLBSELD(1);
mmu_pte_psize = MMU_PAGE_2M;
break;
case PPC_HTW_IBM:
mas4 |= MAS4_INDD;
#ifdef CONFIG_PPC_64K_PAGES #ifdef CONFIG_PPC_64K_PAGES
mas4 |= BOOK3E_PAGESZ_256M << MAS4_TSIZED_SHIFT; mas4 |= BOOK3E_PAGESZ_256M << MAS4_TSIZED_SHIFT;
mmu_pte_psize = MMU_PAGE_256M; mmu_pte_psize = MMU_PAGE_256M;
...@@ -585,13 +620,16 @@ static void __early_init_mmu(int boot_cpu) ...@@ -585,13 +620,16 @@ static void __early_init_mmu(int boot_cpu)
mas4 |= BOOK3E_PAGESZ_1M << MAS4_TSIZED_SHIFT; mas4 |= BOOK3E_PAGESZ_1M << MAS4_TSIZED_SHIFT;
mmu_pte_psize = MMU_PAGE_1M; mmu_pte_psize = MMU_PAGE_1M;
#endif #endif
} else { break;
case PPC_HTW_NONE:
#ifdef CONFIG_PPC_64K_PAGES #ifdef CONFIG_PPC_64K_PAGES
mas4 |= BOOK3E_PAGESZ_64K << MAS4_TSIZED_SHIFT; mas4 |= BOOK3E_PAGESZ_64K << MAS4_TSIZED_SHIFT;
#else #else
mas4 |= BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT; mas4 |= BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT;
#endif #endif
mmu_pte_psize = mmu_virtual_psize; mmu_pte_psize = mmu_virtual_psize;
break;
} }
mtspr(SPRN_MAS4, mas4); mtspr(SPRN_MAS4, mas4);
...@@ -611,8 +649,11 @@ static void __early_init_mmu(int boot_cpu) ...@@ -611,8 +649,11 @@ static void __early_init_mmu(int boot_cpu)
/* limit memory so we dont have linear faults */ /* limit memory so we dont have linear faults */
memblock_enforce_memory_limit(linear_map_top); memblock_enforce_memory_limit(linear_map_top);
if (book3e_htw_mode == PPC_HTW_NONE) {
patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e); patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e);
patch_exception(0x1e0, exc_instruction_tlb_miss_bolted_book3e); patch_exception(0x1e0,
exc_instruction_tlb_miss_bolted_book3e);
}
} }
#endif #endif
......
...@@ -402,7 +402,9 @@ _GLOBAL(set_context) ...@@ -402,7 +402,9 @@ _GLOBAL(set_context)
* Load TLBCAM[index] entry in to the L2 CAM MMU * Load TLBCAM[index] entry in to the L2 CAM MMU
*/ */
_GLOBAL(loadcam_entry) _GLOBAL(loadcam_entry)
LOAD_REG_ADDR(r4, TLBCAM) mflr r5
LOAD_REG_ADDR_PIC(r4, TLBCAM)
mtlr r5
mulli r5,r3,TLBCAM_SIZE mulli r5,r3,TLBCAM_SIZE
add r3,r5,r4 add r3,r5,r4
lwz r4,TLBCAM_MAS0(r3) lwz r4,TLBCAM_MAS0(r3)
......
...@@ -123,6 +123,12 @@ config P1023_RDS ...@@ -123,6 +123,12 @@ config P1023_RDS
help help
This option enables support for the P1023 RDS and RDB boards This option enables support for the P1023 RDS and RDB boards
config TWR_P102x
bool "Freescale TWR-P102x"
select DEFAULT_UIMAGE
help
This option enables support for the TWR-P1025 board.
config SOCRATES config SOCRATES
bool "Socrates" bool "Socrates"
select DEFAULT_UIMAGE select DEFAULT_UIMAGE
......
...@@ -18,6 +18,7 @@ obj-$(CONFIG_P1010_RDB) += p1010rdb.o ...@@ -18,6 +18,7 @@ obj-$(CONFIG_P1010_RDB) += p1010rdb.o
obj-$(CONFIG_P1022_DS) += p1022_ds.o obj-$(CONFIG_P1022_DS) += p1022_ds.o
obj-$(CONFIG_P1022_RDK) += p1022_rdk.o obj-$(CONFIG_P1022_RDK) += p1022_rdk.o
obj-$(CONFIG_P1023_RDS) += p1023_rds.o obj-$(CONFIG_P1023_RDS) += p1023_rds.o
obj-$(CONFIG_TWR_P102x) += twr_p102x.o
obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
obj-$(CONFIG_STX_GP3) += stx_gp3.o obj-$(CONFIG_STX_GP3) += stx_gp3.o
obj-$(CONFIG_TQM85xx) += tqm85xx.o obj-$(CONFIG_TQM85xx) += tqm85xx.o
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <asm/qe.h>
#include <sysdev/cpm2_pic.h> #include <sysdev/cpm2_pic.h>
#include "mpc85xx.h" #include "mpc85xx.h"
...@@ -82,3 +83,40 @@ void __init mpc85xx_cpm2_pic_init(void) ...@@ -82,3 +83,40 @@ void __init mpc85xx_cpm2_pic_init(void)
irq_set_chained_handler(irq, cpm2_cascade); irq_set_chained_handler(irq, cpm2_cascade);
} }
#endif #endif
#ifdef CONFIG_QUICC_ENGINE
void __init mpc85xx_qe_init(void)
{
struct device_node *np;
np = of_find_compatible_node(NULL, NULL, "fsl,qe");
if (!np) {
np = of_find_node_by_name(NULL, "qe");
if (!np) {
pr_err("%s: Could not find Quicc Engine node\n",
__func__);
return;
}
}
if (!of_device_is_available(np)) {
of_node_put(np);
return;
}
qe_reset();
of_node_put(np);
np = of_find_node_by_name(NULL, "par_io");
if (np) {
struct device_node *ucc;
par_io_init(np);
of_node_put(np);
for_each_node_by_name(ucc, "ucc")
par_io_of_config(ucc);
}
}
#endif
...@@ -8,4 +8,10 @@ extern void mpc85xx_cpm2_pic_init(void); ...@@ -8,4 +8,10 @@ extern void mpc85xx_cpm2_pic_init(void);
static inline void __init mpc85xx_cpm2_pic_init(void) {} static inline void __init mpc85xx_cpm2_pic_init(void) {}
#endif /* CONFIG_CPM2 */ #endif /* CONFIG_CPM2 */
#ifdef CONFIG_QUICC_ENGINE
extern void mpc85xx_qe_init(void);
#else
static inline void __init mpc85xx_qe_init(void) {}
#endif
#endif #endif
/* /*
* Copyright (C) 2006-2010, 2012 Freescale Semiconductor, Inc. * Copyright (C) 2006-2010, 2012-2013 Freescale Semiconductor, Inc.
* All rights reserved. * All rights reserved.
* *
* Author: Andy Fleming <afleming@freescale.com> * Author: Andy Fleming <afleming@freescale.com>
...@@ -238,32 +238,7 @@ static void __init mpc85xx_mds_qe_init(void) ...@@ -238,32 +238,7 @@ static void __init mpc85xx_mds_qe_init(void)
{ {
struct device_node *np; struct device_node *np;
np = of_find_compatible_node(NULL, NULL, "fsl,qe"); mpc85xx_qe_init();
if (!np) {
np = of_find_node_by_name(NULL, "qe");
if (!np)
return;
}
if (!of_device_is_available(np)) {
of_node_put(np);
return;
}
qe_reset();
of_node_put(np);
np = of_find_node_by_name(NULL, "par_io");
if (np) {
struct device_node *ucc;
par_io_init(np);
of_node_put(np);
for_each_node_by_name(ucc, "ucc")
par_io_of_config(ucc);
}
mpc85xx_mds_reset_ucc_phys(); mpc85xx_mds_reset_ucc_phys();
if (machine_is(p1021_mds)) { if (machine_is(p1021_mds)) {
......
/* /*
* MPC85xx RDB Board Setup * MPC85xx RDB Board Setup
* *
* Copyright 2009,2012 Freescale Semiconductor Inc. * Copyright 2009,2012-2013 Freescale Semiconductor Inc.
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License as published by the
...@@ -98,26 +98,7 @@ static void __init mpc85xx_rdb_setup_arch(void) ...@@ -98,26 +98,7 @@ static void __init mpc85xx_rdb_setup_arch(void)
fsl_pci_assign_primary(); fsl_pci_assign_primary();
#ifdef CONFIG_QUICC_ENGINE #ifdef CONFIG_QUICC_ENGINE
np = of_find_compatible_node(NULL, NULL, "fsl,qe"); mpc85xx_qe_init();
if (!np) {
pr_err("%s: Could not find Quicc Engine node\n", __func__);
goto qe_fail;
}
qe_reset();
of_node_put(np);
np = of_find_node_by_name(NULL, "par_io");
if (np) {
struct device_node *ucc;
par_io_init(np);
of_node_put(np);
for_each_node_by_name(ucc, "ucc")
par_io_of_config(ucc);
}
#if defined(CONFIG_UCC_GETH) || defined(CONFIG_SERIAL_QE) #if defined(CONFIG_UCC_GETH) || defined(CONFIG_SERIAL_QE)
if (machine_is(p1025_rdb)) { if (machine_is(p1025_rdb)) {
...@@ -148,8 +129,6 @@ static void __init mpc85xx_rdb_setup_arch(void) ...@@ -148,8 +129,6 @@ static void __init mpc85xx_rdb_setup_arch(void)
} }
#endif #endif
qe_fail:
#endif /* CONFIG_QUICC_ENGINE */ #endif /* CONFIG_QUICC_ENGINE */
printk(KERN_INFO "MPC85xx RDB board from Freescale Semiconductor\n"); printk(KERN_INFO "MPC85xx RDB board from Freescale Semiconductor\n");
......
...@@ -389,15 +389,18 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image) ...@@ -389,15 +389,18 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image)
} }
#endif /* CONFIG_KEXEC */ #endif /* CONFIG_KEXEC */
static void smp_85xx_setup_cpu(int cpu_nr) static void smp_85xx_basic_setup(int cpu_nr)
{ {
if (smp_85xx_ops.probe == smp_mpic_probe)
mpic_setup_this_cpu();
if (cpu_has_feature(CPU_FTR_DBELL)) if (cpu_has_feature(CPU_FTR_DBELL))
doorbell_setup_this_cpu(); doorbell_setup_this_cpu();
} }
static void smp_85xx_setup_cpu(int cpu_nr)
{
mpic_setup_this_cpu();
smp_85xx_basic_setup(cpu_nr);
}
static const struct of_device_id mpc85xx_smp_guts_ids[] = { static const struct of_device_id mpc85xx_smp_guts_ids[] = {
{ .compatible = "fsl,mpc8572-guts", }, { .compatible = "fsl,mpc8572-guts", },
{ .compatible = "fsl,p1020-guts", }, { .compatible = "fsl,p1020-guts", },
...@@ -412,13 +415,14 @@ void __init mpc85xx_smp_init(void) ...@@ -412,13 +415,14 @@ void __init mpc85xx_smp_init(void)
{ {
struct device_node *np; struct device_node *np;
smp_85xx_ops.setup_cpu = smp_85xx_setup_cpu;
np = of_find_node_by_type(NULL, "open-pic"); np = of_find_node_by_type(NULL, "open-pic");
if (np) { if (np) {
smp_85xx_ops.probe = smp_mpic_probe; smp_85xx_ops.probe = smp_mpic_probe;
smp_85xx_ops.setup_cpu = smp_85xx_setup_cpu;
smp_85xx_ops.message_pass = smp_mpic_message_pass; smp_85xx_ops.message_pass = smp_mpic_message_pass;
} } else
smp_85xx_ops.setup_cpu = smp_85xx_basic_setup;
if (cpu_has_feature(CPU_FTR_DBELL)) { if (cpu_has_feature(CPU_FTR_DBELL)) {
/* /*
...@@ -427,6 +431,7 @@ void __init mpc85xx_smp_init(void) ...@@ -427,6 +431,7 @@ void __init mpc85xx_smp_init(void)
*/ */
smp_85xx_ops.message_pass = NULL; smp_85xx_ops.message_pass = NULL;
smp_85xx_ops.cause_ipi = doorbell_cause_ipi; smp_85xx_ops.cause_ipi = doorbell_cause_ipi;
smp_85xx_ops.probe = NULL;
} }
np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids);
......
/*
* Copyright 2010-2011, 2013 Freescale Semiconductor, Inc.
*
* Author: Michael Johnston <michael.johnston@freescale.com>
*
* Description:
* TWR-P102x Board Setup
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/of_platform.h>
#include <asm/pci-bridge.h>
#include <asm/udbg.h>
#include <asm/mpic.h>
#include <asm/qe.h>
#include <asm/qe_ic.h>
#include <asm/fsl_guts.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
#include "smp.h"
#include "mpc85xx.h"
static void __init twr_p1025_pic_init(void)
{
struct mpic *mpic;
#ifdef CONFIG_QUICC_ENGINE
struct device_node *np;
#endif
mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
MPIC_SINGLE_DEST_CPU,
0, 256, " OpenPIC ");
BUG_ON(mpic == NULL);
mpic_init(mpic);
#ifdef CONFIG_QUICC_ENGINE
np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
if (np) {
qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
qe_ic_cascade_high_mpic);
of_node_put(np);
} else
pr_err("Could not find qe-ic node\n");
#endif
}
/* ************************************************************************
*
* Setup the architecture
*
*/
static void __init twr_p1025_setup_arch(void)
{
#ifdef CONFIG_QUICC_ENGINE
struct device_node *np;
#endif
if (ppc_md.progress)
ppc_md.progress("twr_p1025_setup_arch()", 0);
mpc85xx_smp_init();
fsl_pci_assign_primary();
#ifdef CONFIG_QUICC_ENGINE
mpc85xx_qe_init();
#if defined(CONFIG_UCC_GETH) || defined(CONFIG_SERIAL_QE)
if (machine_is(twr_p1025)) {
struct ccsr_guts __iomem *guts;
np = of_find_compatible_node(NULL, NULL, "fsl,p1021-guts");
if (np) {
guts = of_iomap(np, 0);
if (!guts)
pr_err("twr_p1025: could not map global utilities register\n");
else {
/* P1025 has pins muxed for QE and other functions. To
* enable QE UEC mode, we need to set bit QE0 for UCC1
* in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9
* and QE12 for QE MII management signals in PMUXCR
* register.
* Set QE mux bits in PMUXCR */
setbits32(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
MPC85xx_PMUXCR_QE(3) |
MPC85xx_PMUXCR_QE(9) |
MPC85xx_PMUXCR_QE(12));
iounmap(guts);
#if defined(CONFIG_SERIAL_QE)
/* On P1025TWR board, the UCC7 acted as UART port.
* However, The UCC7's CTS pin is low level in default,
* it will impact the transmission in full duplex
* communication. So disable the Flow control pin PA18.
* The UCC7 UART just can use RXD and TXD pins.
*/
par_io_config_pin(0, 18, 0, 0, 0, 0);
#endif
/* Drive PB29 to CPLD low - CPLD will then change
* muxing from LBC to QE */
par_io_config_pin(1, 29, 1, 0, 0, 0);
par_io_data_set(1, 29, 0);
}
of_node_put(np);
}
}
#endif
#endif /* CONFIG_QUICC_ENGINE */
pr_info("TWR-P1025 board from Freescale Semiconductor\n");
}
machine_arch_initcall(twr_p1025, mpc85xx_common_publish_devices);
static int __init twr_p1025_probe(void)
{
unsigned long root = of_get_flat_dt_root();
return of_flat_dt_is_compatible(root, "fsl,TWR-P1025");
}
define_machine(twr_p1025) {
.name = "TWR-P1025",
.probe = twr_p1025_probe,
.setup_arch = twr_p1025_setup_arch,
.init_IRQ = twr_p1025_pic_init,
#ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
#endif
.get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
...@@ -67,6 +67,18 @@ config PPC_C2K ...@@ -67,6 +67,18 @@ config PPC_C2K
This option enables support for the GE Fanuc C2K board (formerly This option enables support for the GE Fanuc C2K board (formerly
an SBS board). an SBS board).
config MVME5100
bool "Motorola/Emerson MVME5100"
depends on EMBEDDED6xx
select MPIC
select PCI
select PPC_INDIRECT_PCI
select PPC_I8259
select PPC_NATIVE
help
This option enables support for the Motorola (now Emerson) MVME5100
board.
config TSI108_BRIDGE config TSI108_BRIDGE
bool bool
select PCI select PCI
...@@ -113,4 +125,3 @@ config WII ...@@ -113,4 +125,3 @@ config WII
help help
Select WII if configuring for the Nintendo Wii. Select WII if configuring for the Nintendo Wii.
More information at: <http://gc-linux.sourceforge.net/> More information at: <http://gc-linux.sourceforge.net/>
...@@ -11,3 +11,4 @@ obj-$(CONFIG_USBGECKO_UDBG) += usbgecko_udbg.o ...@@ -11,3 +11,4 @@ obj-$(CONFIG_USBGECKO_UDBG) += usbgecko_udbg.o
obj-$(CONFIG_GAMECUBE_COMMON) += flipper-pic.o obj-$(CONFIG_GAMECUBE_COMMON) += flipper-pic.o
obj-$(CONFIG_GAMECUBE) += gamecube.o obj-$(CONFIG_GAMECUBE) += gamecube.o
obj-$(CONFIG_WII) += wii.o hlwd-pic.o obj-$(CONFIG_WII) += wii.o hlwd-pic.o
obj-$(CONFIG_MVME5100) += mvme5100.o
/*
* Board setup routines for the Motorola/Emerson MVME5100.
*
* Copyright 2013 CSC Australia Pty. Ltd.
*
* Based on earlier code by:
*
* Matt Porter, MontaVista Software Inc.
* Copyright 2001 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 as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* Author: Stephen Chivers <schivers@csc.com>
*
*/
#include <linux/of_platform.h>
#include <asm/i8259.h>
#include <asm/pci-bridge.h>
#include <asm/mpic.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>
#define HAWK_MPIC_SIZE 0x00040000U
#define MVME5100_PCI_MEM_OFFSET 0x00000000
/* Board register addresses. */
#define BOARD_STATUS_REG 0xfef88080
#define BOARD_MODFAIL_REG 0xfef88090
#define BOARD_MODRST_REG 0xfef880a0
#define BOARD_TBEN_REG 0xfef880c0
#define BOARD_SW_READ_REG 0xfef880e0
#define BOARD_GEO_ADDR_REG 0xfef880e8
#define BOARD_EXT_FEATURE1_REG 0xfef880f0
#define BOARD_EXT_FEATURE2_REG 0xfef88100
static phys_addr_t pci_membase;
static u_char *restart;
static void mvme5100_8259_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq = i8259_irq();
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
chip->irq_eoi(&desc->irq_data);
}
static void __init mvme5100_pic_init(void)
{
struct mpic *mpic;
struct device_node *np;
struct device_node *cp = NULL;
unsigned int cirq;
unsigned long intack = 0;
const u32 *prop = NULL;
np = of_find_node_by_type(NULL, "open-pic");
if (!np) {
pr_err("Could not find open-pic node\n");
return;
}
mpic = mpic_alloc(np, pci_membase, 0, 16, 256, " OpenPIC ");
BUG_ON(mpic == NULL);
of_node_put(np);
mpic_assign_isu(mpic, 0, pci_membase + 0x10000);
mpic_init(mpic);
cp = of_find_compatible_node(NULL, NULL, "chrp,iic");
if (cp == NULL) {
pr_warn("mvme5100_pic_init: couldn't find i8259\n");
return;
}
cirq = irq_of_parse_and_map(cp, 0);
if (cirq == NO_IRQ) {
pr_warn("mvme5100_pic_init: no cascade interrupt?\n");
return;
}
np = of_find_compatible_node(NULL, "pci", "mpc10x-pci");
if (np) {
prop = of_get_property(np, "8259-interrupt-acknowledge", NULL);
if (prop)
intack = prop[0];
of_node_put(np);
}
if (intack)
pr_debug("mvme5100_pic_init: PCI 8259 intack at 0x%016lx\n",
intack);
i8259_init(cp, intack);
of_node_put(cp);
irq_set_chained_handler(cirq, mvme5100_8259_cascade);
}
static int __init mvme5100_add_bridge(struct device_node *dev)
{
const int *bus_range;
int len;
struct pci_controller *hose;
unsigned short devid;
pr_info("Adding PCI host bridge %s\n", dev->full_name);
bus_range = of_get_property(dev, "bus-range", &len);
hose = pcibios_alloc_controller(dev);
if (hose == NULL)
return -ENOMEM;
hose->first_busno = bus_range ? bus_range[0] : 0;
hose->last_busno = bus_range ? bus_range[1] : 0xff;
setup_indirect_pci(hose, 0xfe000cf8, 0xfe000cfc, 0);
pci_process_bridge_OF_ranges(hose, dev, 1);
early_read_config_word(hose, 0, 0, PCI_DEVICE_ID, &devid);
if (devid != PCI_DEVICE_ID_MOTOROLA_HAWK) {
pr_err("HAWK PHB not present?\n");
return 0;
}
early_read_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase);
if (pci_membase == 0) {
pr_err("HAWK PHB mibar not correctly set?\n");
return 0;
}
pr_info("mvme5100_pic_init: pci_membase: %x\n", pci_membase);
return 0;
}
static struct of_device_id mvme5100_of_bus_ids[] __initdata = {
{ .compatible = "hawk-bridge", },
{},
};
/*
* Setup the architecture
*/
static void __init mvme5100_setup_arch(void)
{
struct device_node *np;
if (ppc_md.progress)
ppc_md.progress("mvme5100_setup_arch()", 0);
for_each_compatible_node(np, "pci", "hawk-pci")
mvme5100_add_bridge(np);
restart = ioremap(BOARD_MODRST_REG, 4);
}
static void mvme5100_show_cpuinfo(struct seq_file *m)
{
seq_puts(m, "Vendor\t\t: Motorola/Emerson\n");
seq_puts(m, "Machine\t\t: MVME5100\n");
}
static void mvme5100_restart(char *cmd)
{
local_irq_disable();
mtmsr(mfmsr() | MSR_IP);
out_8((u_char *) restart, 0x01);
while (1)
;
}
/*
* Called very early, device-tree isn't unflattened
*/
static int __init mvme5100_probe(void)
{
unsigned long root = of_get_flat_dt_root();
return of_flat_dt_is_compatible(root, "MVME5100");
}
static int __init probe_of_platform_devices(void)
{
of_platform_bus_probe(NULL, mvme5100_of_bus_ids, NULL);
return 0;
}
machine_device_initcall(mvme5100, probe_of_platform_devices);
define_machine(mvme5100) {
.name = "MVME5100",
.probe = mvme5100_probe,
.setup_arch = mvme5100_setup_arch,
.init_IRQ = mvme5100_pic_init,
.show_cpuinfo = mvme5100_show_cpuinfo,
.get_irq = mpic_get_irq,
.restart = mvme5100_restart,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
...@@ -214,10 +214,14 @@ static irqreturn_t fsl_lbc_ctrl_irq(int irqno, void *data) ...@@ -214,10 +214,14 @@ static irqreturn_t fsl_lbc_ctrl_irq(int irqno, void *data)
struct fsl_lbc_ctrl *ctrl = data; struct fsl_lbc_ctrl *ctrl = data;
struct fsl_lbc_regs __iomem *lbc = ctrl->regs; struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
u32 status; u32 status;
unsigned long flags;
spin_lock_irqsave(&fsl_lbc_lock, flags);
status = in_be32(&lbc->ltesr); status = in_be32(&lbc->ltesr);
if (!status) if (!status) {
spin_unlock_irqrestore(&fsl_lbc_lock, flags);
return IRQ_NONE; return IRQ_NONE;
}
out_be32(&lbc->ltesr, LTESR_CLEAR); out_be32(&lbc->ltesr, LTESR_CLEAR);
out_be32(&lbc->lteatr, 0); out_be32(&lbc->lteatr, 0);
...@@ -260,6 +264,7 @@ static irqreturn_t fsl_lbc_ctrl_irq(int irqno, void *data) ...@@ -260,6 +264,7 @@ static irqreturn_t fsl_lbc_ctrl_irq(int irqno, void *data)
if (status & ~LTESR_MASK) if (status & ~LTESR_MASK)
dev_err(ctrl->dev, "Unknown error: " dev_err(ctrl->dev, "Unknown error: "
"LTESR 0x%08X\n", status); "LTESR 0x%08X\n", status);
spin_unlock_irqrestore(&fsl_lbc_lock, flags);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -298,8 +303,8 @@ static int fsl_lbc_ctrl_probe(struct platform_device *dev) ...@@ -298,8 +303,8 @@ static int fsl_lbc_ctrl_probe(struct platform_device *dev)
goto err; goto err;
} }
fsl_lbc_ctrl_dev->irq = irq_of_parse_and_map(dev->dev.of_node, 0); fsl_lbc_ctrl_dev->irq[0] = irq_of_parse_and_map(dev->dev.of_node, 0);
if (fsl_lbc_ctrl_dev->irq == NO_IRQ) { if (!fsl_lbc_ctrl_dev->irq[0]) {
dev_err(&dev->dev, "failed to get irq resource\n"); dev_err(&dev->dev, "failed to get irq resource\n");
ret = -ENODEV; ret = -ENODEV;
goto err; goto err;
...@@ -311,20 +316,34 @@ static int fsl_lbc_ctrl_probe(struct platform_device *dev) ...@@ -311,20 +316,34 @@ static int fsl_lbc_ctrl_probe(struct platform_device *dev)
if (ret < 0) if (ret < 0)
goto err; goto err;
ret = request_irq(fsl_lbc_ctrl_dev->irq, fsl_lbc_ctrl_irq, 0, ret = request_irq(fsl_lbc_ctrl_dev->irq[0], fsl_lbc_ctrl_irq, 0,
"fsl-lbc", fsl_lbc_ctrl_dev); "fsl-lbc", fsl_lbc_ctrl_dev);
if (ret != 0) { if (ret != 0) {
dev_err(&dev->dev, "failed to install irq (%d)\n", dev_err(&dev->dev, "failed to install irq (%d)\n",
fsl_lbc_ctrl_dev->irq); fsl_lbc_ctrl_dev->irq[0]);
ret = fsl_lbc_ctrl_dev->irq; ret = fsl_lbc_ctrl_dev->irq[0];
goto err; goto err;
} }
fsl_lbc_ctrl_dev->irq[1] = irq_of_parse_and_map(dev->dev.of_node, 1);
if (fsl_lbc_ctrl_dev->irq[1]) {
ret = request_irq(fsl_lbc_ctrl_dev->irq[1], fsl_lbc_ctrl_irq,
IRQF_SHARED, "fsl-lbc-err", fsl_lbc_ctrl_dev);
if (ret) {
dev_err(&dev->dev, "failed to install irq (%d)\n",
fsl_lbc_ctrl_dev->irq[1]);
ret = fsl_lbc_ctrl_dev->irq[1];
goto err1;
}
}
/* Enable interrupts for any detected events */ /* Enable interrupts for any detected events */
out_be32(&fsl_lbc_ctrl_dev->regs->lteir, LTEIR_ENABLE); out_be32(&fsl_lbc_ctrl_dev->regs->lteir, LTEIR_ENABLE);
return 0; return 0;
err1:
free_irq(fsl_lbc_ctrl_dev->irq[0], fsl_lbc_ctrl_dev);
err: err:
iounmap(fsl_lbc_ctrl_dev->regs); iounmap(fsl_lbc_ctrl_dev->regs);
kfree(fsl_lbc_ctrl_dev); kfree(fsl_lbc_ctrl_dev);
......
...@@ -454,7 +454,7 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus) ...@@ -454,7 +454,7 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)
} }
} }
int __init fsl_add_bridge(struct platform_device *pdev, int is_primary) int fsl_add_bridge(struct platform_device *pdev, int is_primary)
{ {
int len; int len;
struct pci_controller *hose; struct pci_controller *hose;
...@@ -1035,6 +1035,7 @@ static const struct of_device_id pci_ids[] = { ...@@ -1035,6 +1035,7 @@ static const struct of_device_id pci_ids[] = {
{ .compatible = "fsl,mpc8548-pcie", }, { .compatible = "fsl,mpc8548-pcie", },
{ .compatible = "fsl,mpc8610-pci", }, { .compatible = "fsl,mpc8610-pci", },
{ .compatible = "fsl,mpc8641-pcie", }, { .compatible = "fsl,mpc8641-pcie", },
{ .compatible = "fsl,qoriq-pcie", },
{ .compatible = "fsl,qoriq-pcie-v2.1", }, { .compatible = "fsl,qoriq-pcie-v2.1", },
{ .compatible = "fsl,qoriq-pcie-v2.2", }, { .compatible = "fsl,qoriq-pcie-v2.2", },
{ .compatible = "fsl,qoriq-pcie-v2.3", }, { .compatible = "fsl,qoriq-pcie-v2.3", },
......
...@@ -152,9 +152,7 @@ static struct pci_ops indirect_pci_ops = ...@@ -152,9 +152,7 @@ static struct pci_ops indirect_pci_ops =
.write = indirect_write_config, .write = indirect_write_config,
}; };
void __init void setup_indirect_pci(struct pci_controller *hose, resource_size_t cfg_addr,
setup_indirect_pci(struct pci_controller* hose,
resource_size_t cfg_addr,
resource_size_t cfg_data, u32 flags) resource_size_t cfg_data, u32 flags)
{ {
resource_size_t base = cfg_addr & PAGE_MASK; resource_size_t base = cfg_addr & PAGE_MASK;
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#define MPIC_TIMER_TCR_ROVR_OFFSET 24 #define MPIC_TIMER_TCR_ROVR_OFFSET 24
#define TIMER_STOP 0x80000000 #define TIMER_STOP 0x80000000
#define GTCCR_TOG 0x80000000
#define TIMERS_PER_GROUP 4 #define TIMERS_PER_GROUP 4
#define MAX_TICKS (~0U >> 1) #define MAX_TICKS (~0U >> 1)
#define MAX_TICKS_CASCADE (~0U) #define MAX_TICKS_CASCADE (~0U)
...@@ -96,6 +97,9 @@ static void convert_ticks_to_time(struct timer_group_priv *priv, ...@@ -96,6 +97,9 @@ static void convert_ticks_to_time(struct timer_group_priv *priv,
time->tv_sec = (__kernel_time_t)div_u64(ticks, priv->timerfreq); time->tv_sec = (__kernel_time_t)div_u64(ticks, priv->timerfreq);
tmp_sec = (u64)time->tv_sec * (u64)priv->timerfreq; tmp_sec = (u64)time->tv_sec * (u64)priv->timerfreq;
time->tv_usec = 0;
if (tmp_sec <= ticks)
time->tv_usec = (__kernel_suseconds_t) time->tv_usec = (__kernel_suseconds_t)
div_u64((ticks - tmp_sec) * 1000000, priv->timerfreq); div_u64((ticks - tmp_sec) * 1000000, priv->timerfreq);
...@@ -327,11 +331,13 @@ void mpic_get_remain_time(struct mpic_timer *handle, struct timeval *time) ...@@ -327,11 +331,13 @@ void mpic_get_remain_time(struct mpic_timer *handle, struct timeval *time)
casc_priv = priv->timer[handle->num].cascade_handle; casc_priv = priv->timer[handle->num].cascade_handle;
if (casc_priv) { if (casc_priv) {
tmp_ticks = in_be32(&priv->regs[handle->num].gtccr); tmp_ticks = in_be32(&priv->regs[handle->num].gtccr);
tmp_ticks &= ~GTCCR_TOG;
ticks = ((u64)tmp_ticks & UINT_MAX) * (u64)MAX_TICKS_CASCADE; ticks = ((u64)tmp_ticks & UINT_MAX) * (u64)MAX_TICKS_CASCADE;
tmp_ticks = in_be32(&priv->regs[handle->num - 1].gtccr); tmp_ticks = in_be32(&priv->regs[handle->num - 1].gtccr);
ticks += tmp_ticks; ticks += tmp_ticks;
} else { } else {
ticks = in_be32(&priv->regs[handle->num].gtccr); ticks = in_be32(&priv->regs[handle->num].gtccr);
ticks &= ~GTCCR_TOG;
} }
convert_ticks_to_time(priv, ticks, time); convert_ticks_to_time(priv, ticks, time);
......
...@@ -366,7 +366,7 @@ config TRACE_SINK ...@@ -366,7 +366,7 @@ config TRACE_SINK
"Trace data router for MIPI P1149.7 cJTAG standard". "Trace data router for MIPI P1149.7 cJTAG standard".
config PPC_EPAPR_HV_BYTECHAN config PPC_EPAPR_HV_BYTECHAN
tristate "ePAPR hypervisor byte channel driver" bool "ePAPR hypervisor byte channel driver"
depends on PPC depends on PPC
select EPAPR_PARAVIRT select EPAPR_PARAVIRT
help help
......
...@@ -116,6 +116,7 @@ extern const void *of_flat_dt_match_machine(const void *default_match, ...@@ -116,6 +116,7 @@ extern const void *of_flat_dt_match_machine(const void *default_match,
extern void unflatten_device_tree(void); extern void unflatten_device_tree(void);
extern void unflatten_and_copy_device_tree(void); extern void unflatten_and_copy_device_tree(void);
extern void early_init_devtree(void *); extern void early_init_devtree(void *);
extern void early_get_first_memblock_info(void *, phys_addr_t *);
#else /* CONFIG_OF_FLATTREE */ #else /* CONFIG_OF_FLATTREE */
static inline const char *of_flat_dt_get_machine_name(void) { return NULL; } static inline const char *of_flat_dt_get_machine_name(void) { return NULL; }
static inline void unflatten_device_tree(void) {} static inline void unflatten_device_tree(void) {}
......
...@@ -685,7 +685,7 @@ do { \ ...@@ -685,7 +685,7 @@ do { \
else \ else \
{ \ { \
r = 0; \ r = 0; \
if (X##_s) \ if (!X##_s) \
r = ~r; \ r = ~r; \
} \ } \
FP_SET_EXCEPTION(FP_EX_INVALID); \ FP_SET_EXCEPTION(FP_EX_INVALID); \
...@@ -743,12 +743,17 @@ do { \ ...@@ -743,12 +743,17 @@ do { \
} \ } \
else \ else \
{ \ { \
int _lz0, _lz1; \
if (X##_e <= -_FP_WORKBITS - 1) \ if (X##_e <= -_FP_WORKBITS - 1) \
_FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
else \ else \
_FP_FRAC_SRS_##wc(X, _FP_FRACBITS_##fs - 1 - X##_e, \ _FP_FRAC_SRS_##wc(X, _FP_FRACBITS_##fs - 1 - X##_e, \
_FP_WFRACBITS_##fs); \ _FP_WFRACBITS_##fs); \
_FP_FRAC_CLZ_##wc(_lz0, X); \
_FP_ROUND(wc, X); \ _FP_ROUND(wc, X); \
_FP_FRAC_CLZ_##wc(_lz1, X); \
if (_lz1 < _lz0) \
X##_e++; /* For overflow detection. */ \
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
_FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
} \ } \
...@@ -762,7 +767,7 @@ do { \ ...@@ -762,7 +767,7 @@ do { \
if (!rsigned) \ if (!rsigned) \
{ \ { \
r = 0; \ r = 0; \
if (X##_s) \ if (!X##_s) \
r = ~r; \ r = ~r; \
} \ } \
else if (rsigned != 2) \ else if (rsigned != 2) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment