Commit 719dbb2d authored by Michael Ellerman's avatar Michael Ellerman

Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux into next

Freescale updates from Scott:

"Highlights include more 8xx optimizations, device tree updates,
and MVME7100 support."
parents fbef66f0 9f595fd8
...@@ -41,3 +41,84 @@ Example: ...@@ -41,3 +41,84 @@ Example:
fsl,mdio-pin = <12>; fsl,mdio-pin = <12>;
fsl,mdc-pin = <13>; fsl,mdc-pin = <13>;
}; };
* HDLC
Currently defined compatibles:
- fsl,ucc-hdlc
Properties for fsl,ucc-hdlc:
- rx-clock-name
- tx-clock-name
Usage: required
Value type: <string>
Definition : Must be "brg1"-"brg16" for internal clock source,
Must be "clk1"-"clk24" for external clock source.
- fsl,tdm-interface
Usage: optional
Value type: <empty>
Definition : Specify that hdlc is based on tdm-interface
The property below is dependent on fsl,tdm-interface:
- fsl,rx-sync-clock
Usage: required
Value type: <string>
Definition : Must be "none", "rsync_pin", "brg9-11" and "brg13-15".
- fsl,tx-sync-clock
Usage: required
Value type: <string>
Definition : Must be "none", "tsync_pin", "brg9-11" and "brg13-15".
- fsl,tdm-framer-type
Usage: required for tdm interface
Value type: <string>
Definition : "e1" or "t1".Now e1 and t1 are used, other framer types
are not supported.
- fsl,tdm-id
Usage: required for tdm interface
Value type: <u32>
Definition : number of TDM ID
- fsl,tx-timeslot-mask
- fsl,rx-timeslot-mask
Usage: required for tdm interface
Value type: <u32>
Definition : time slot mask for TDM operation. Indicates which time
slots used for transmitting and receiving.
- fsl,siram-entry-id
Usage: required for tdm interface
Value type: <u32>
Definition : Must be 0,2,4...64. the number of TDM entry.
- fsl,tdm-internal-loopback
usage: optional for tdm interface
value type: <empty>
Definition : Internal loopback connecting on TDM layer.
Example for tdm interface:
ucc@2000 {
compatible = "fsl,ucc-hdlc";
rx-clock-name = "clk8";
tx-clock-name = "clk9";
fsl,rx-sync-clock = "rsync_pin";
fsl,tx-sync-clock = "tsync_pin";
fsl,tx-timeslot-mask = <0xfffffffe>;
fsl,rx-timeslot-mask = <0xfffffffe>;
fsl,tdm-framer-type = "e1";
fsl,tdm-id = <0>;
fsl,siram-entry-id = <0>;
fsl,tdm-interface;
};
Example for hdlc without tdm interface:
ucc@2000 {
compatible = "fsl,ucc-hdlc";
rx-clock-name = "brg1";
tx-clock-name = "brg1";
};
...@@ -69,6 +69,58 @@ Example: ...@@ -69,6 +69,58 @@ Example:
}; };
}; };
* Interrupt Controller (IC)
Required properties:
- compatible : should be "fsl,qe-ic".
- reg : Address range of IC register set.
- interrupts : interrupts generated by the device.
- interrupt-controller : this device is a interrupt controller.
Example:
qeic: interrupt-controller@80 {
interrupt-controller;
compatible = "fsl,qe-ic";
#address-cells = <0>;
#interrupt-cells = <1>;
reg = <0x80 0x80>;
interrupts = <95 2 0 0 94 2 0 0>;
};
* Serial Interface Block (SI)
The SI manages the routing of eight TDM lines to the QE block serial drivers
, the MCC and the UCCs, for receive and transmit.
Required properties:
- compatible : must be "fsl,<chip>-qe-si". For t1040, must contain
"fsl,t1040-qe-si".
- reg : Address range of SI register set.
Example:
si1: si@700 {
compatible = "fsl,t1040-qe-si";
reg = <0x700 0x80>;
};
* Serial Interface Block RAM(SIRAM)
store the routing entries of SI
Required properties:
- compatible : should be "fsl,<chip>-qe-siram". For t1040, must contain
"fsl,t1040-qe-siram".
- reg : Address range of SI RAM.
Example:
siram1: siram@1000 {
compatible = "fsl,t1040-qe-siram";
reg = <0x1000 0x800>;
};
* QE Firmware Node * QE Firmware Node
This node defines a firmware binary that is embedded in the device tree, for This node defines a firmware binary that is embedded in the device tree, for
......
* Serial
Required Properties:
compatible : must be "fsl,<chip>-ucc-uart". For t1040, must be
"fsl,t1040-ucc-uart".
port-number : port number of UCC-UART
tx/rx-clock-name : should be "brg1"-"brg16" for internal clock source,
should be "clk1"-"clk28" for external clock source.
Example:
ucc_serial: ucc@2200 {
compatible = "fsl,t1040-ucc-uart";
port-number = <0>;
rx-clock-name = "brg2";
tx-clock-name = "brg2";
};
...@@ -166,6 +166,7 @@ config PPC ...@@ -166,6 +166,7 @@ config PPC
select ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT select ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT
select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS
select GENERIC_CPU_AUTOPROBE select GENERIC_CPU_AUTOPROBE
select HAVE_VIRT_CPU_ACCOUNTING
config GENERIC_CSUM config GENERIC_CSUM
def_bool CPU_LITTLE_ENDIAN def_bool CPU_LITTLE_ENDIAN
...@@ -1056,6 +1057,11 @@ config CONSISTENT_SIZE ...@@ -1056,6 +1057,11 @@ config CONSISTENT_SIZE
config PIN_TLB config PIN_TLB
bool "Pinned Kernel TLBs (860 ONLY)" bool "Pinned Kernel TLBs (860 ONLY)"
depends on ADVANCED_OPTIONS && 8xx depends on ADVANCED_OPTIONS && 8xx
config PIN_TLB_IMMR
bool "Pinned TLB for IMMR"
depends on PIN_TLB
default y
endmenu endmenu
if PPC64 if PPC64
......
...@@ -212,7 +212,6 @@ config PPC_EARLY_DEBUG_40x ...@@ -212,7 +212,6 @@ config PPC_EARLY_DEBUG_40x
config PPC_EARLY_DEBUG_CPM config PPC_EARLY_DEBUG_CPM
bool "Early serial debugging for Freescale CPM-based serial ports" bool "Early serial debugging for Freescale CPM-based serial ports"
depends on SERIAL_CPM depends on SERIAL_CPM
select PIN_TLB if PPC_8xx
help help
Select this to enable early debugging for Freescale chips Select this to enable early debugging for Freescale chips
using a CPM-based serial port. This assumes that the bootwrapper using a CPM-based serial port. This assumes that the bootwrapper
......
...@@ -113,6 +113,7 @@ src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c ...@@ -113,6 +113,7 @@ src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c
src-plat-$(CONFIG_PPC_PSERIES) += pseries-head.S src-plat-$(CONFIG_PPC_PSERIES) += pseries-head.S
src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S
src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S
src-plat-$(CONFIG_MVME7100) += motload-head.S mvme7100.c
src-wlib := $(sort $(src-wlib-y)) src-wlib := $(sort $(src-wlib-y))
src-plat := $(sort $(src-plat-y)) src-plat := $(sort $(src-plat-y))
...@@ -296,6 +297,9 @@ image-$(CONFIG_TQM8560) += cuImage.tqm8560 ...@@ -296,6 +297,9 @@ image-$(CONFIG_TQM8560) += cuImage.tqm8560
image-$(CONFIG_SBC8548) += cuImage.sbc8548 image-$(CONFIG_SBC8548) += cuImage.sbc8548
image-$(CONFIG_KSI8560) += cuImage.ksi8560 image-$(CONFIG_KSI8560) += cuImage.ksi8560
# Board ports in arch/powerpc/platform/86xx/Kconfig
image-$(CONFIG_MVME7100) += dtbImage.mvme7100
# Board ports in arch/powerpc/platform/embedded6xx/Kconfig # Board ports in arch/powerpc/platform/embedded6xx/Kconfig
image-$(CONFIG_STORCENTER) += cuImage.storcenter image-$(CONFIG_STORCENTER) += cuImage.storcenter
image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2 image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2
......
...@@ -51,6 +51,7 @@ aliases { ...@@ -51,6 +51,7 @@ aliases {
serial2 = &serial2; serial2 = &serial2;
serial3 = &serial3; serial3 = &serial3;
pci0 = &pci0; pci0 = &pci0;
usb0 = &usb0;
dma0 = &dma0; dma0 = &dma0;
dma1 = &dma1; dma1 = &dma1;
sdhc = &sdhc; sdhc = &sdhc;
......
...@@ -51,6 +51,7 @@ aliases { ...@@ -51,6 +51,7 @@ aliases {
serial2 = &serial2; serial2 = &serial2;
serial3 = &serial3; serial3 = &serial3;
pci0 = &pci0; pci0 = &pci0;
usb0 = &usb0;
dma0 = &dma0; dma0 = &dma0;
dma1 = &dma1; dma1 = &dma1;
sdhc = &sdhc; sdhc = &sdhc;
......
...@@ -106,6 +106,43 @@ sata@220000 { ...@@ -106,6 +106,43 @@ sata@220000 {
sata@221000 { sata@221000 {
status = "disabled"; status = "disabled";
}; };
fman0: fman@400000 {
enet0: ethernet@e0000 {
phy-connection-type = "sgmii";
fixed-link {
speed = <1000>;
full-duplex;
};
};
mdio0: mdio@e1120 {
front_phy: ethernet-phy@11 {
reg = <0x11>;
};
};
enet1: ethernet@e2000 {
phy-connection-type = "sgmii";
fixed-link {
speed = <1000>;
full-duplex;
};
};
enet2: ethernet@e4000 {
status = "disabled";
};
enet3: ethernet@e6000 {
status = "disabled";
};
enet4: ethernet@e8000 {
phy-handle = <&front_phy>;
phy-connection-type = "rgmii";
};
enet5: ethernet@f0000 {
status = "disabled";
};
};
}; };
rio: rapidio@ffe0c0000 { rio: rapidio@ffe0c0000 {
......
/*
* Device tree source for the Emerson/Artesyn MVME7100
*
* Copyright 2016 Elettra-Sincrotrone Trieste S.C.p.A.
*
* Author: Alessio Igor Bogani <alessio.bogani@elettra.eu>
*
* 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/ "mpc8641si-pre.dtsi"
/ {
model = "MVME7100";
compatible = "artesyn,MVME7100";
memory {
device_type = "memory";
reg = <0x00000000 0x80000000>;
};
soc: soc@f1000000 {
ranges = <0x00000000 0xf1000000 0x00100000>;
i2c@3000 {
hwmon@4c {
compatible = "dallas,max6649";
reg = <0x4c>;
};
rtc@68 {
status = "disabled";
};
};
enet0: ethernet@24000 {
phy-handle = <&phy0>;
phy-connection-type = "rgmii-id";
};
mdio@24520 {
phy0: ethernet-phy@1 {
reg = <1>;
};
phy1: ethernet-phy@2 {
reg = <2>;
};
phy2: ethernet-phy@3 {
reg = <3>;
};
phy3: ethernet-phy@4 {
reg = <4>;
};
};
enet1: ethernet@25000 {
phy-handle = <&phy1>;
phy-connection-type = "rgmii-id";
};
mdio@25520 {
status = "disabled";
};
enet2: ethernet@26000 {
phy-handle = <&phy2>;
phy-connection-type = "rgmii-id";
};
mdio@26520 {
status = "disabled";
};
enet3: ethernet@27000 {
phy-handle = <&phy3>;
phy-connection-type = "rgmii-id";
};
mdio@27520 {
status = "disabled";
};
serial1: serial@4600 {
status = "disabled";
};
};
lbc: localbus@f1005000 {
reg = <0xf1005000 0x1000>;
ranges = <0 0 0xf8000000 0x08000000 // NOR Flash (128MB)
2 0 0xf2030000 0x00010000 // NAND Flash (8GB)
3 0 0xf2400000 0x00080000 // MRAM (512KB)
4 0 0xf2000000 0x00010000 // BCSR
5 0 0xf2010000 0x00010000>; // QUART
bcsr@4,0 {
compatible = "artesyn,mvme7100-bcsr";
reg = <4 0 0x10000>;
};
serial@5,1000 {
device_type = "serial";
compatible = "ns16550";
reg = <5 0x1000 0x100>;
clock-frequency = <1843200>;
interrupts = <11 1 0 0>;
};
serial@5,2000 {
device_type = "serial";
compatible = "ns16550";
reg = <5 0x2000 0x100>;
clock-frequency = <1843200>;
interrupts = <11 1 0 0>;
};
serial@5,3000 {
device_type = "serial";
compatible = "ns16550";
reg = <5 0x3000 0x100>;
clock-frequency = <1843200>;
interrupts = <11 1 0 0>;
};
serial@5,4000 {
device_type = "serial";
compatible = "ns16550";
reg = <5 0x4000 0x100>;
clock-frequency = <1843200>;
interrupts = <11 1 0 0>;
};
};
pci0: pcie@f1008000 {
status = "disabled";
};
pci1: pcie@f1009000 {
status = "disabled";
};
chosen {
linux,stdout-path = &serial0;
};
};
/include/ "mpc8641si-post.dtsi"
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
usb@210000 { usb0: usb@210000 {
compatible = "fsl-usb2-dr"; compatible = "fsl-usb2-dr";
reg = <0x210000 0x1000>; reg = <0x210000 0x1000>;
#address-cells = <1>; #address-cells = <1>;
......
...@@ -607,7 +607,7 @@ sdhc@114000 { ...@@ -607,7 +607,7 @@ sdhc@114000 {
/include/ "qoriq-gpio-3.dtsi" /include/ "qoriq-gpio-3.dtsi"
/include/ "qoriq-usb2-mph-0.dtsi" /include/ "qoriq-usb2-mph-0.dtsi"
usb0: usb@210000 { usb0: usb@210000 {
compatible = "fsl-usb2-mph-v2.4", "fsl-usb2-mph"; compatible = "fsl-usb2-mph-v2.5", "fsl-usb2-mph";
fsl,iommu-parent = <&pamu0>; fsl,iommu-parent = <&pamu0>;
fsl,liodn-reg = <&guts 0x520>; /* USB1LIODNR */ fsl,liodn-reg = <&guts 0x520>; /* USB1LIODNR */
phy_type = "utmi"; phy_type = "utmi";
...@@ -615,7 +615,7 @@ usb0: usb@210000 { ...@@ -615,7 +615,7 @@ usb0: usb@210000 {
}; };
/include/ "qoriq-usb2-dr-0.dtsi" /include/ "qoriq-usb2-dr-0.dtsi"
usb1: usb@211000 { usb1: usb@211000 {
compatible = "fsl-usb2-dr-v2.4", "fsl-usb2-dr"; compatible = "fsl-usb2-dr-v2.5", "fsl-usb2-dr";
fsl,iommu-parent = <&pamu0>; fsl,iommu-parent = <&pamu0>;
fsl,liodn-reg = <&guts 0x524>; /* USB2LIODNR */ fsl,liodn-reg = <&guts 0x524>; /* USB2LIODNR */
dr_mode = "host"; dr_mode = "host";
...@@ -673,3 +673,48 @@ mdio@fd000 { ...@@ -673,3 +673,48 @@ mdio@fd000 {
}; };
}; };
}; };
&qe {
#address-cells = <1>;
#size-cells = <1>;
device_type = "qe";
compatible = "fsl,qe";
fsl,qe-num-riscs = <1>;
fsl,qe-num-snums = <28>;
qeic: interrupt-controller@80 {
interrupt-controller;
compatible = "fsl,qe-ic";
#address-cells = <0>;
#interrupt-cells = <1>;
reg = <0x80 0x80>;
interrupts = <95 2 0 0 94 2 0 0>; //high:79 low:78
};
ucc@2000 {
cell-index = <1>;
reg = <0x2000 0x200>;
interrupts = <32>;
interrupt-parent = <&qeic>;
};
ucc@2200 {
cell-index = <3>;
reg = <0x2200 0x200>;
interrupts = <34>;
interrupt-parent = <&qeic>;
};
muram@10000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,qe-muram", "fsl,cpm-muram";
ranges = <0x0 0x10000 0x6000>;
data-only@0 {
compatible = "fsl,qe-muram-data",
"fsl,cpm-muram-data";
reg = <0x0 0x6000>;
};
};
};
...@@ -212,4 +212,42 @@ pcie@0 { ...@@ -212,4 +212,42 @@ pcie@0 {
0 0x00010000>; 0 0x00010000>;
}; };
}; };
qe: qe@ffe140000 {
ranges = <0x0 0xf 0xfe140000 0x40000>;
reg = <0xf 0xfe140000 0 0x480>;
brg-frequency = <0>;
bus-frequency = <0>;
si1: si@700 {
compatible = "fsl,t1040-qe-si";
reg = <0x700 0x80>;
};
siram1: siram@1000 {
compatible = "fsl,t1040-qe-siram";
reg = <0x1000 0x800>;
};
ucc_hdlc: ucc@2000 {
compatible = "fsl,ucc-hdlc";
rx-clock-name = "clk8";
tx-clock-name = "clk9";
fsl,rx-sync-clock = "rsync_pin";
fsl,tx-sync-clock = "tsync_pin";
fsl,tx-timeslot-mask = <0xfffffffe>;
fsl,rx-timeslot-mask = <0xfffffffe>;
fsl,tdm-framer-type = "e1";
fsl,tdm-id = <0>;
fsl,siram-entry-id = <0>;
fsl,tdm-interface;
};
ucc_serial: ucc@2200 {
compatible = "fsl,t1040-ucc-uart";
port-number = <0>;
rx-clock-name = "brg2";
tx-clock-name = "brg2";
};
};
}; };
...@@ -366,4 +366,42 @@ pcie@0 { ...@@ -366,4 +366,42 @@ pcie@0 {
0 0x00010000>; 0 0x00010000>;
}; };
}; };
qe: qe@ffe140000 {
ranges = <0x0 0xf 0xfe140000 0x40000>;
reg = <0xf 0xfe140000 0 0x480>;
brg-frequency = <0>;
bus-frequency = <0>;
si1: si@700 {
compatible = "fsl,t1040-qe-si";
reg = <0x700 0x80>;
};
siram1: siram@1000 {
compatible = "fsl,t1040-qe-siram";
reg = <0x1000 0x800>;
};
ucc_hdlc: ucc@2000 {
compatible = "fsl,ucc-hdlc";
rx-clock-name = "clk8";
tx-clock-name = "clk9";
fsl,rx-sync-clock = "rsync_pin";
fsl,tx-sync-clock = "tsync_pin";
fsl,tx-timeslot-mask = <0xfffffffe>;
fsl,rx-timeslot-mask = <0xfffffffe>;
fsl,tdm-framer-type = "e1";
fsl,tdm-id = <0>;
fsl,siram-entry-id = <0>;
fsl,tdm-interface;
};
ucc_serial: ucc@2200 {
compatible = "fsl,t1040-ucc-uart";
port-number = <0>;
rx-clock-name = "brg2";
tx-clock-name = "brg2";
};
};
}; };
...@@ -222,4 +222,42 @@ pcie@0 { ...@@ -222,4 +222,42 @@ pcie@0 {
0 0x00010000>; 0 0x00010000>;
}; };
}; };
qe: qe@ffe140000 {
ranges = <0x0 0xf 0xfe140000 0x40000>;
reg = <0xf 0xfe140000 0 0x480>;
brg-frequency = <0>;
bus-frequency = <0>;
si1: si@700 {
compatible = "fsl,t1040-qe-si";
reg = <0x700 0x80>;
};
siram1: siram@1000 {
compatible = "fsl,t1040-qe-siram";
reg = <0x1000 0x800>;
};
ucc_hdlc: ucc@2000 {
compatible = "fsl,ucc-hdlc";
rx-clock-name = "clk8";
tx-clock-name = "clk9";
fsl,rx-sync-clock = "rsync_pin";
fsl,tx-sync-clock = "tsync_pin";
fsl,tx-timeslot-mask = <0xfffffffe>;
fsl,rx-timeslot-mask = <0xfffffffe>;
fsl,tdm-framer-type = "e1";
fsl,tdm-id = <0>;
fsl,siram-entry-id = <0>;
fsl,tdm-interface;
};
ucc_serial: ucc@2200 {
compatible = "fsl,t1040-ucc-uart";
port-number = <0>;
rx-clock-name = "brg2";
tx-clock-name = "brg2";
};
};
}; };
...@@ -56,6 +56,8 @@ aliases { ...@@ -56,6 +56,8 @@ aliases {
pci1 = &pci1; pci1 = &pci1;
pci2 = &pci2; pci2 = &pci2;
pci3 = &pci3; pci3 = &pci3;
usb0 = &usb0;
usb1 = &usb1;
dma0 = &dma0; dma0 = &dma0;
dma1 = &dma1; dma1 = &dma1;
dma2 = &dma2; dma2 = &dma2;
......
#include "ppc_asm.h"
.text
.globl _zimage_start
_zimage_start:
mfmsr r10
rlwinm r10,r10,0,~(1<<15) /* Clear MSR_EE */
sync
mtmsr r10
isync
b _zimage_start_lib
/*
* Motload compatibility for the Emerson/Artesyn MVME7100
*
* Copyright 2016 Elettra-Sincrotrone Trieste S.C.p.A.
*
* Author: Alessio Igor Bogani <alessio.bogani@elettra.eu>
*
* 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 "ops.h"
#include "stdio.h"
#include "cuboot.h"
#define TARGET_86xx
#define TARGET_HAS_ETH1
#define TARGET_HAS_ETH2
#define TARGET_HAS_ETH3
#include "ppcboot.h"
static bd_t bd;
BSS_STACK(16384);
static void mvme7100_fixups(void)
{
void *devp;
unsigned long busfreq = bd.bi_busfreq * 1000000;
dt_fixup_cpu_clocks(bd.bi_intfreq * 1000000, busfreq / 4, busfreq);
devp = finddevice("/soc@f1000000");
if (devp)
setprop(devp, "bus-frequency", &busfreq, sizeof(busfreq));
devp = finddevice("/soc/serial@4500");
if (devp)
setprop(devp, "clock-frequency", &busfreq, sizeof(busfreq));
dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr);
dt_fixup_mac_address_by_alias("ethernet2", bd.bi_enet2addr);
dt_fixup_mac_address_by_alias("ethernet3", bd.bi_enet3addr);
}
void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
CUBOOT_INIT();
fdt_init(_dtb_start);
serial_console_init();
platform_ops.fixups = mvme7100_fixups;
}
...@@ -43,7 +43,7 @@ typedef struct bd_info { ...@@ -43,7 +43,7 @@ typedef struct bd_info {
unsigned long bi_sramstart; /* start of SRAM memory */ unsigned long bi_sramstart; /* start of SRAM memory */
unsigned long bi_sramsize; /* size of SRAM memory */ unsigned long bi_sramsize; /* size of SRAM memory */
#if defined(TARGET_8xx) || defined(TARGET_CPM2) || defined(TARGET_85xx) ||\ #if defined(TARGET_8xx) || defined(TARGET_CPM2) || defined(TARGET_85xx) ||\
defined(TARGET_83xx) defined(TARGET_83xx) || defined(TARGET_86xx)
unsigned long bi_immr_base; /* base of IMMR register */ unsigned long bi_immr_base; /* base of IMMR register */
#endif #endif
#if defined(TARGET_PPC_MPC52xx) #if defined(TARGET_PPC_MPC52xx)
......
...@@ -302,6 +302,11 @@ mvme5100) ...@@ -302,6 +302,11 @@ mvme5100)
platformo="$object/fixed-head.o $object/mvme5100.o" platformo="$object/fixed-head.o $object/mvme5100.o"
binary=y binary=y
;; ;;
mvme7100)
platformo="$object/motload-head.o $object/mvme7100.o"
link_address='0x4000000'
binary=y
;;
esac esac
vmz="$tmpdir/`basename \"$kernel\"`.$ext" vmz="$tmpdir/`basename \"$kernel\"`.$ext"
......
...@@ -74,9 +74,9 @@ CONFIG_SERIAL_8250_CONSOLE=y ...@@ -74,9 +74,9 @@ CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_DETECT_IRQ=y CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_NR_UARTS=2 CONFIG_SERIAL_8250_NR_UARTS=5
CONFIG_SERIAL_8250_RSA=y CONFIG_SERIAL_8250_RSA=y
CONFIG_SERIAL_8250_RUNTIME_UARTS=2 CONFIG_SERIAL_8250_RUNTIME_UARTS=5
CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250=y
CONFIG_SERIO_LIBPS2=y CONFIG_SERIO_LIBPS2=y
......
...@@ -8,3 +8,4 @@ CONFIG_GEF_SBC610=y ...@@ -8,3 +8,4 @@ CONFIG_GEF_SBC610=y
CONFIG_MPC8610_HPCD=y CONFIG_MPC8610_HPCD=y
CONFIG_MPC8641_HPCN=y CONFIG_MPC8641_HPCN=y
CONFIG_SBC8641D=y CONFIG_SBC8641D=y
CONFIG_MVME7100=y
...@@ -39,7 +39,6 @@ CONFIG_MTD_CFI_I4=y ...@@ -39,7 +39,6 @@ CONFIG_MTD_CFI_I4=y
CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_PHYSMAP_OF=y CONFIG_MTD_PHYSMAP_OF=y
CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_LOOP=y
CONFIG_IDE=y
CONFIG_NETDEVICES=y CONFIG_NETDEVICES=y
CONFIG_TUN=y CONFIG_TUN=y
CONFIG_FS_ENET=y CONFIG_FS_ENET=y
......
/*
* Common time accounting prototypes and such for all ppc machines.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef __POWERPC_ACCOUNTING_H
#define __POWERPC_ACCOUNTING_H
/* Stuff for accurate time accounting */
struct cpu_accounting_data {
unsigned long user_time; /* accumulated usermode TB ticks */
unsigned long system_time; /* accumulated system TB ticks */
unsigned long user_time_scaled; /* accumulated usermode SPURR ticks */
unsigned long starttime; /* TB value snapshot */
unsigned long starttime_user; /* TB value on exit to usermode */
unsigned long startspurr; /* SPURR value snapshot */
unsigned long utime_sspurr; /* ->user_time when ->startspurr set */
};
#endif
...@@ -90,11 +90,10 @@ static inline void setup_cputime_one_jiffy(void) ...@@ -90,11 +90,10 @@ static inline void setup_cputime_one_jiffy(void)
static inline cputime64_t jiffies64_to_cputime64(const u64 jif) static inline cputime64_t jiffies64_to_cputime64(const u64 jif)
{ {
u64 ct; u64 ct;
u64 sec; u64 sec = jif;
/* have to be a little careful about overflow */ /* have to be a little careful about overflow */
ct = jif % HZ; ct = do_div(sec, HZ);
sec = jif / HZ;
if (ct) { if (ct) {
ct *= tb_ticks_per_sec; ct *= tb_ticks_per_sec;
do_div(ct, HZ); do_div(ct, HZ);
...@@ -230,7 +229,16 @@ static inline cputime_t clock_t_to_cputime(const unsigned long clk) ...@@ -230,7 +229,16 @@ static inline cputime_t clock_t_to_cputime(const unsigned long clk)
#define cputime64_to_clock_t(ct) cputime_to_clock_t((cputime_t)(ct)) #define cputime64_to_clock_t(ct) cputime_to_clock_t((cputime_t)(ct))
/*
* PPC64 uses PACA which is task independent for storing accounting data while
* PPC32 uses struct thread_info, therefore at task switch the accounting data
* has to be populated in the new task
*/
#ifdef CONFIG_PPC64
static inline void arch_vtime_task_switch(struct task_struct *tsk) { } static inline void arch_vtime_task_switch(struct task_struct *tsk) { }
#else
void arch_vtime_task_switch(struct task_struct *tsk);
#endif
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
......
...@@ -287,7 +287,7 @@ do_kvm_##n: \ ...@@ -287,7 +287,7 @@ do_kvm_##n: \
std r0,GPR0(r1); /* save r0 in stackframe */ \ std r0,GPR0(r1); /* save r0 in stackframe */ \
std r10,GPR1(r1); /* save r1 in stackframe */ \ std r10,GPR1(r1); /* save r1 in stackframe */ \
beq 4f; /* if from kernel mode */ \ beq 4f; /* if from kernel mode */ \
ACCOUNT_CPU_USER_ENTRY(r9, r10); \ ACCOUNT_CPU_USER_ENTRY(r13, r9, r10); \
SAVE_PPR(area, r9, r10); \ SAVE_PPR(area, r9, r10); \
4: EXCEPTION_PROLOG_COMMON_2(area) \ 4: EXCEPTION_PROLOG_COMMON_2(area) \
EXCEPTION_PROLOG_COMMON_3(n) \ EXCEPTION_PROLOG_COMMON_3(n) \
......
...@@ -50,6 +50,13 @@ enum fixed_addresses { ...@@ -50,6 +50,13 @@ enum fixed_addresses {
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
#endif
#ifdef CONFIG_PPC_8xx
/* For IMMR we need an aligned 512K area */
#define FIX_IMMR_SIZE (512 * 1024 / PAGE_SIZE)
FIX_IMMR_START,
FIX_IMMR_BASE = __ALIGN_MASK(FIX_IMMR_START, FIX_IMMR_SIZE - 1) - 1 +
FIX_IMMR_SIZE,
#endif #endif
/* FIX_PCIE_MCFG, */ /* FIX_PCIE_MCFG, */
__end_of_fixed_addresses __end_of_fixed_addresses
......
...@@ -169,6 +169,9 @@ typedef struct { ...@@ -169,6 +169,9 @@ typedef struct {
unsigned int active; unsigned int active;
unsigned long vdso_base; unsigned long vdso_base;
} mm_context_t; } mm_context_t;
#define PHYS_IMMR_BASE (mfspr(SPRN_IMMR) & 0xfff80000)
#define VIRT_IMMR_BASE (__fix_to_virt(FIX_IMMR_BASE))
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#if defined(CONFIG_PPC_4K_PAGES) #if defined(CONFIG_PPC_4K_PAGES)
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
#include <asm/kvm_book3s_asm.h> #include <asm/kvm_book3s_asm.h>
#endif #endif
#include <asm/accounting.h>
register struct paca_struct *local_paca asm("r13"); register struct paca_struct *local_paca asm("r13");
...@@ -184,13 +185,7 @@ struct paca_struct { ...@@ -184,13 +185,7 @@ struct paca_struct {
#endif #endif
/* Stuff for accurate time accounting */ /* Stuff for accurate time accounting */
u64 user_time; /* accumulated usermode TB ticks */ struct cpu_accounting_data accounting;
u64 system_time; /* accumulated system TB ticks */
u64 user_time_scaled; /* accumulated usermode SPURR ticks */
u64 starttime; /* TB value snapshot */
u64 starttime_user; /* TB value on exit to usermode */
u64 startspurr; /* SPURR value snapshot */
u64 utime_sspurr; /* ->user_time when ->startspurr set */
u64 stolen_time; /* TB ticks taken by hypervisor */ u64 stolen_time; /* TB ticks taken by hypervisor */
u64 dtl_ridx; /* read index in dispatch log */ u64 dtl_ridx; /* read index in dispatch log */
struct dtl_entry *dtl_curr; /* pointer corresponding to dtl_ridx */ struct dtl_entry *dtl_curr; /* pointer corresponding to dtl_ridx */
......
...@@ -24,27 +24,27 @@ ...@@ -24,27 +24,27 @@
*/ */
#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
#define ACCOUNT_CPU_USER_ENTRY(ra, rb) #define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb)
#define ACCOUNT_CPU_USER_EXIT(ra, rb) #define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb)
#define ACCOUNT_STOLEN_TIME #define ACCOUNT_STOLEN_TIME
#else #else
#define ACCOUNT_CPU_USER_ENTRY(ra, rb) \ #define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb) \
MFTB(ra); /* get timebase */ \ MFTB(ra); /* get timebase */ \
ld rb,PACA_STARTTIME_USER(r13); \ PPC_LL rb, ACCOUNT_STARTTIME_USER(ptr); \
std ra,PACA_STARTTIME(r13); \ PPC_STL ra, ACCOUNT_STARTTIME(ptr); \
subf rb,rb,ra; /* subtract start value */ \ subf rb,rb,ra; /* subtract start value */ \
ld ra,PACA_USER_TIME(r13); \ PPC_LL ra, ACCOUNT_USER_TIME(ptr); \
add ra,ra,rb; /* add on to user time */ \ add ra,ra,rb; /* add on to user time */ \
std ra,PACA_USER_TIME(r13); \ PPC_STL ra, ACCOUNT_USER_TIME(ptr); \
#define ACCOUNT_CPU_USER_EXIT(ra, rb) \ #define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb) \
MFTB(ra); /* get timebase */ \ MFTB(ra); /* get timebase */ \
ld rb,PACA_STARTTIME(r13); \ PPC_LL rb, ACCOUNT_STARTTIME(ptr); \
std ra,PACA_STARTTIME_USER(r13); \ PPC_STL ra, ACCOUNT_STARTTIME_USER(ptr); \
subf rb,rb,ra; /* subtract start value */ \ subf rb,rb,ra; /* subtract start value */ \
ld ra,PACA_SYSTEM_TIME(r13); \ PPC_LL ra, ACCOUNT_SYSTEM_TIME(ptr); \
add ra,ra,rb; /* add on to system time */ \ add ra,ra,rb; /* add on to system time */ \
std ra,PACA_SYSTEM_TIME(r13) PPC_STL ra, ACCOUNT_SYSTEM_TIME(ptr)
#ifdef CONFIG_PPC_SPLPAR #ifdef CONFIG_PPC_SPLPAR
#define ACCOUNT_STOLEN_TIME \ #define ACCOUNT_STOLEN_TIME \
......
...@@ -1307,6 +1307,7 @@ static inline unsigned long mfvtb (void) ...@@ -1307,6 +1307,7 @@ static inline unsigned long mfvtb (void)
asm volatile("mfspr %0, %1" : "=r" (rval) : \ asm volatile("mfspr %0, %1" : "=r" (rval) : \
"i" (SPRN_TBRU)); rval;}) "i" (SPRN_TBRU)); rval;})
#endif #endif
#define mftb() mftbl()
#endif /* !__powerpc64__ */ #endif /* !__powerpc64__ */
#define mttbl(v) asm volatile("mttbl %0":: "r"(v)) #define mttbl(v) asm volatile("mttbl %0":: "r"(v))
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/page.h> #include <asm/page.h>
#include <linux/stringify.h> #include <linux/stringify.h>
#include <asm/accounting.h>
/* /*
* low level task data. * low level task data.
...@@ -45,6 +46,9 @@ struct thread_info { ...@@ -45,6 +46,9 @@ struct thread_info {
unsigned long local_flags; /* private flags for thread */ unsigned long local_flags; /* private flags for thread */
#ifdef CONFIG_LIVEPATCH #ifdef CONFIG_LIVEPATCH
unsigned long *livepatch_sp; unsigned long *livepatch_sp;
#endif
#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && defined(CONFIG_PPC32)
struct cpu_accounting_data accounting;
#endif #endif
/* low level flags - has atomic operations done on it */ /* low level flags - has atomic operations done on it */
unsigned long flags ____cacheline_aligned_in_smp; unsigned long flags ____cacheline_aligned_in_smp;
......
...@@ -68,6 +68,10 @@ ...@@ -68,6 +68,10 @@
#include "../mm/mmu_decl.h" #include "../mm/mmu_decl.h"
#endif #endif
#ifdef CONFIG_PPC_8xx
#include <asm/fixmap.h>
#endif
int main(void) int main(void)
{ {
DEFINE(THREAD, offsetof(struct task_struct, thread)); DEFINE(THREAD, offsetof(struct task_struct, thread));
...@@ -240,13 +244,28 @@ int main(void) ...@@ -240,13 +244,28 @@ int main(void)
DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state)); DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state));
DEFINE(PACA_DSCR_DEFAULT, offsetof(struct paca_struct, dscr_default)); DEFINE(PACA_DSCR_DEFAULT, offsetof(struct paca_struct, dscr_default));
DEFINE(PACA_STARTTIME, offsetof(struct paca_struct, starttime)); DEFINE(ACCOUNT_STARTTIME,
DEFINE(PACA_STARTTIME_USER, offsetof(struct paca_struct, starttime_user)); offsetof(struct paca_struct, accounting.starttime));
DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); DEFINE(ACCOUNT_STARTTIME_USER,
DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); offsetof(struct paca_struct, accounting.starttime_user));
DEFINE(ACCOUNT_USER_TIME,
offsetof(struct paca_struct, accounting.user_time));
DEFINE(ACCOUNT_SYSTEM_TIME,
offsetof(struct paca_struct, accounting.system_time));
DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save)); DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
DEFINE(PACA_NAPSTATELOST, offsetof(struct paca_struct, nap_state_lost)); DEFINE(PACA_NAPSTATELOST, offsetof(struct paca_struct, nap_state_lost));
DEFINE(PACA_SPRG_VDSO, offsetof(struct paca_struct, sprg_vdso)); DEFINE(PACA_SPRG_VDSO, offsetof(struct paca_struct, sprg_vdso));
#else /* CONFIG_PPC64 */
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
DEFINE(ACCOUNT_STARTTIME,
offsetof(struct thread_info, accounting.starttime));
DEFINE(ACCOUNT_STARTTIME_USER,
offsetof(struct thread_info, accounting.starttime_user));
DEFINE(ACCOUNT_USER_TIME,
offsetof(struct thread_info, accounting.user_time));
DEFINE(ACCOUNT_SYSTEM_TIME,
offsetof(struct thread_info, accounting.system_time));
#endif
#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC64 */
/* RTAS */ /* RTAS */
...@@ -734,5 +753,9 @@ int main(void) ...@@ -734,5 +753,9 @@ int main(void)
DEFINE(PPC_DBELL_SERVER, PPC_DBELL_SERVER); DEFINE(PPC_DBELL_SERVER, PPC_DBELL_SERVER);
#ifdef CONFIG_PPC_8xx
DEFINE(VIRT_IMMR_BASE, (u64)__fix_to_virt(FIX_IMMR_BASE));
#endif
return 0; return 0;
} }
...@@ -175,6 +175,12 @@ transfer_to_handler: ...@@ -175,6 +175,12 @@ transfer_to_handler:
addi r12,r12,-1 addi r12,r12,-1
stw r12,4(r11) stw r12,4(r11)
#endif #endif
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
CURRENT_THREAD_INFO(r9, r1)
tophys(r9, r9)
ACCOUNT_CPU_USER_ENTRY(r9, r11, r12)
#endif
b 3f b 3f
2: /* if from kernel, check interrupted DOZE/NAP mode and 2: /* if from kernel, check interrupted DOZE/NAP mode and
...@@ -398,6 +404,13 @@ BEGIN_FTR_SECTION ...@@ -398,6 +404,13 @@ BEGIN_FTR_SECTION
lwarx r7,0,r1 lwarx r7,0,r1
END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
stwcx. r0,0,r1 /* to clear the reservation */ stwcx. r0,0,r1 /* to clear the reservation */
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
andi. r4,r8,MSR_PR
beq 3f
CURRENT_THREAD_INFO(r4, r1)
ACCOUNT_CPU_USER_EXIT(r4, r5, r7)
3:
#endif
lwz r4,_LINK(r1) lwz r4,_LINK(r1)
lwz r5,_CCR(r1) lwz r5,_CCR(r1)
mtlr r4 mtlr r4
...@@ -769,6 +782,10 @@ restore_user: ...@@ -769,6 +782,10 @@ restore_user:
andis. r10,r0,DBCR0_IDM@h andis. r10,r0,DBCR0_IDM@h
bnel- load_dbcr0 bnel- load_dbcr0
#endif #endif
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
CURRENT_THREAD_INFO(r9, r1)
ACCOUNT_CPU_USER_EXIT(r9, r10, r11)
#endif
b restore b restore
......
...@@ -72,7 +72,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM) ...@@ -72,7 +72,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
std r0,GPR0(r1) std r0,GPR0(r1)
std r10,GPR1(r1) std r10,GPR1(r1)
beq 2f /* if from kernel mode */ beq 2f /* if from kernel mode */
ACCOUNT_CPU_USER_ENTRY(r10, r11) ACCOUNT_CPU_USER_ENTRY(r13, r10, r11)
2: std r2,GPR2(r1) 2: std r2,GPR2(r1)
std r3,GPR3(r1) std r3,GPR3(r1)
mfcr r2 mfcr r2
...@@ -246,7 +246,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) ...@@ -246,7 +246,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
ld r4,_LINK(r1) ld r4,_LINK(r1)
beq- 1f beq- 1f
ACCOUNT_CPU_USER_EXIT(r11, r12) ACCOUNT_CPU_USER_EXIT(r13, r11, r12)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
HMT_MEDIUM_LOW HMT_MEDIUM_LOW
...@@ -859,7 +859,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) ...@@ -859,7 +859,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
mtspr SPRN_PPR,r2 /* Restore PPR */ mtspr SPRN_PPR,r2 /* Restore PPR */
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
ACCOUNT_CPU_USER_EXIT(r2, r4) ACCOUNT_CPU_USER_EXIT(r13, r2, r4)
REST_GPR(13, r1) REST_GPR(13, r1)
1: 1:
mtspr SPRN_SRR1,r3 mtspr SPRN_SRR1,r3
......
...@@ -386,7 +386,7 @@ exc_##n##_common: \ ...@@ -386,7 +386,7 @@ exc_##n##_common: \
std r10,_NIP(r1); /* save SRR0 to stackframe */ \ std r10,_NIP(r1); /* save SRR0 to stackframe */ \
std r11,_MSR(r1); /* save SRR1 to stackframe */ \ std r11,_MSR(r1); /* save SRR1 to stackframe */ \
beq 2f; /* if from kernel mode */ \ beq 2f; /* if from kernel mode */ \
ACCOUNT_CPU_USER_ENTRY(r10,r11);/* accounting (uses cr0+eq) */ \ ACCOUNT_CPU_USER_ENTRY(r13,r10,r11);/* accounting (uses cr0+eq) */ \
2: ld r3,excf+EX_R10(r13); /* get back r10 */ \ 2: ld r3,excf+EX_R10(r13); /* get back r10 */ \
ld r4,excf+EX_R11(r13); /* get back r11 */ \ ld r4,excf+EX_R11(r13); /* get back r11 */ \
mfspr r5,scratch; /* get back r13 */ \ mfspr r5,scratch; /* get back r13 */ \
...@@ -1059,7 +1059,7 @@ fast_exception_return: ...@@ -1059,7 +1059,7 @@ fast_exception_return:
andi. r6,r10,MSR_PR andi. r6,r10,MSR_PR
REST_2GPRS(6, r1) REST_2GPRS(6, r1)
beq 1f beq 1f
ACCOUNT_CPU_USER_EXIT(r10, r11) ACCOUNT_CPU_USER_EXIT(r13, r10, r11)
ld r0,GPR13(r1) ld r0,GPR13(r1)
1: stdcx. r0,0,r1 /* to clear the reservation */ 1: stdcx. r0,0,r1 /* to clear the reservation */
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <asm/ppc_asm.h> #include <asm/ppc_asm.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/fixmap.h>
/* Macro to make the code more readable. */ /* Macro to make the code more readable. */
#ifdef CONFIG_8xx_CPU6 #ifdef CONFIG_8xx_CPU6
...@@ -383,28 +384,57 @@ InstructionTLBMiss: ...@@ -383,28 +384,57 @@ InstructionTLBMiss:
EXCEPTION_EPILOG_0 EXCEPTION_EPILOG_0
rfi rfi
/*
* Bottom part of DataStoreTLBMiss handler for IMMR area
* not enough space in the DataStoreTLBMiss area
*/
DTLBMissIMMR:
mtcr r10
/* Set 512k byte guarded page and mark it valid */
li r10, MD_PS512K | MD_GUARDED | MD_SVALID
MTSPR_CPU6(SPRN_MD_TWC, r10, r11)
mfspr r10, SPRN_IMMR /* Get current IMMR */
rlwinm r10, r10, 0, 0xfff80000 /* Get 512 kbytes boundary */
ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
_PAGE_PRESENT | _PAGE_NO_CACHE
MTSPR_CPU6(SPRN_MD_RPN, r10, r11) /* Update TLB entry */
li r11, RPN_PATTERN
mtspr SPRN_DAR, r11 /* Tag DAR */
EXCEPTION_EPILOG_0
rfi
. = 0x1200 . = 0x1200
DataStoreTLBMiss: DataStoreTLBMiss:
mtspr SPRN_SPRG_SCRATCH2, r3
EXCEPTION_PROLOG_0 EXCEPTION_PROLOG_0
mfcr r3 mfcr r10
/* If we are faulting a kernel address, we have to use the /* If we are faulting a kernel address, we have to use the
* kernel page tables. * kernel page tables.
*/ */
mfspr r10, SPRN_MD_EPN mfspr r11, SPRN_MD_EPN
IS_KERNEL(r11, r10) rlwinm r11, r11, 16, 0xfff8
#ifndef CONFIG_PIN_TLB_IMMR
cmpli cr0, r11, VIRT_IMMR_BASE@h
#endif
cmpli cr7, r11, PAGE_OFFSET@h
#ifndef CONFIG_PIN_TLB_IMMR
_ENTRY(DTLBMiss_jmp)
beq- DTLBMissIMMR
#endif
bge- cr7, 4f
mfspr r11, SPRN_M_TW /* Get level 1 table */ mfspr r11, SPRN_M_TW /* Get level 1 table */
BRANCH_UNLESS_KERNEL(3f)
lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
3: 3:
mtcr r10
#ifdef CONFIG_8xx_CPU6
mtspr SPRN_SPRG_SCRATCH2, r3
#endif
mfspr r10, SPRN_MD_EPN
/* Insert level 1 index */ /* Insert level 1 index */
rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */ lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
mtcr r11
bt- 28,DTLBMiss8M /* bit 28 = Large page (8M) */
mtcr r3
/* We have a pte table, so load fetch the pte from the table. /* We have a pte table, so load fetch the pte from the table.
*/ */
...@@ -452,29 +482,30 @@ DataStoreTLBMiss: ...@@ -452,29 +482,30 @@ DataStoreTLBMiss:
MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */ MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */
/* Restore registers */ /* Restore registers */
#ifdef CONFIG_8xx_CPU6
mfspr r3, SPRN_SPRG_SCRATCH2 mfspr r3, SPRN_SPRG_SCRATCH2
#endif
mtspr SPRN_DAR, r11 /* Tag DAR */ mtspr SPRN_DAR, r11 /* Tag DAR */
EXCEPTION_EPILOG_0 EXCEPTION_EPILOG_0
rfi rfi
DTLBMiss8M: 4:
mtcr r3 _ENTRY(DTLBMiss_cmp)
ori r11, r11, MD_SVALID cmpli cr0, r11, (PAGE_OFFSET + 0x1800000)@h
MTSPR_CPU6(SPRN_MD_TWC, r11, r3) lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
#ifdef CONFIG_PPC_16K_PAGES bge- 3b
/*
* In 16k pages mode, each PGD entry defines a 64M block. mtcr r10
* Here we select the 8M page within the block. /* Set 8M byte page and mark it valid */
*/ li r10, MD_PS8MEG | MD_SVALID
rlwimi r11, r10, 0, 0x03800000 MTSPR_CPU6(SPRN_MD_TWC, r10, r11)
#endif mfspr r10, SPRN_MD_EPN
rlwinm r10, r11, 0, 0xff800000 rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \ ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
_PAGE_PRESENT _PAGE_PRESENT
MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */ MTSPR_CPU6(SPRN_MD_RPN, r10, r11) /* Update TLB entry */
li r11, RPN_PATTERN li r11, RPN_PATTERN
mfspr r3, SPRN_SPRG_SCRATCH2
mtspr SPRN_DAR, r11 /* Tag DAR */ mtspr SPRN_DAR, r11 /* Tag DAR */
EXCEPTION_EPILOG_0 EXCEPTION_EPILOG_0
rfi rfi
...@@ -553,12 +584,14 @@ FixupDAR:/* Entry point for dcbx workaround. */ ...@@ -553,12 +584,14 @@ FixupDAR:/* Entry point for dcbx workaround. */
IS_KERNEL(r11, r10) IS_KERNEL(r11, r10)
mfspr r11, SPRN_M_TW /* Get level 1 table */ mfspr r11, SPRN_M_TW /* Get level 1 table */
BRANCH_UNLESS_KERNEL(3f) BRANCH_UNLESS_KERNEL(3f)
rlwinm r11, r10, 16, 0xfff8
_ENTRY(FixupDAR_cmp)
cmpli cr7, r11, (PAGE_OFFSET + 0x1800000)@h
blt- cr7, 200f
lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
/* Insert level 1 index */ /* Insert level 1 index */
3: rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 3: rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */ lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
mtcr r11
bt 28,200f /* bit 28 = Large page (8M) */
rlwinm r11, r11,0,0,19 /* Extract page descriptor page address */ rlwinm r11, r11,0,0,19 /* Extract page descriptor page address */
/* Insert level 2 index */ /* Insert level 2 index */
rlwimi r11, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29 rlwimi r11, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
...@@ -584,8 +617,8 @@ FixupDAR:/* Entry point for dcbx workaround. */ ...@@ -584,8 +617,8 @@ FixupDAR:/* Entry point for dcbx workaround. */
141: mfspr r10,SPRN_SPRG_SCRATCH2 141: mfspr r10,SPRN_SPRG_SCRATCH2
b DARFixed /* Nope, go back to normal TLB processing */ b DARFixed /* Nope, go back to normal TLB processing */
/* concat physical page address(r11) and page offset(r10) */ /* create physical page address from effective address */
200: rlwimi r11, r10, 0, 32 - (PAGE_SHIFT << 1), 31 200: tophys(r11, r10)
b 201b b 201b
144: mfspr r10, SPRN_DSISR 144: mfspr r10, SPRN_DSISR
...@@ -763,10 +796,18 @@ start_here: ...@@ -763,10 +796,18 @@ start_here:
* virtual to physical. Also, set the cache mode since that is defined * virtual to physical. Also, set the cache mode since that is defined
* by TLB entries and perform any additional mapping (like of the IMMR). * by TLB entries and perform any additional mapping (like of the IMMR).
* If configured to pin some TLBs, we pin the first 8 Mbytes of kernel, * If configured to pin some TLBs, we pin the first 8 Mbytes of kernel,
* 24 Mbytes of data, and the 8M IMMR space. Anything not covered by * 24 Mbytes of data, and the 512k IMMR space. Anything not covered by
* these mappings is mapped by page tables. * these mappings is mapped by page tables.
*/ */
initial_mmu: initial_mmu:
li r8, 0
mtspr SPRN_MI_CTR, r8 /* remove PINNED ITLB entries */
lis r10, MD_RESETVAL@h
#ifndef CONFIG_8xx_COPYBACK
oris r10, r10, MD_WTDEF@h
#endif
mtspr SPRN_MD_CTR, r10 /* remove PINNED DTLB entries */
tlbia /* Invalidate all TLB entries */ tlbia /* Invalidate all TLB entries */
/* Always pin the first 8 MB ITLB to prevent ITLB /* Always pin the first 8 MB ITLB to prevent ITLB
misses while mucking around with SRR0/SRR1 in asm misses while mucking around with SRR0/SRR1 in asm
...@@ -777,34 +818,20 @@ initial_mmu: ...@@ -777,34 +818,20 @@ initial_mmu:
mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */ mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */
#ifdef CONFIG_PIN_TLB #ifdef CONFIG_PIN_TLB
lis r10, (MD_RSV4I | MD_RESETVAL)@h oris r10, r10, MD_RSV4I@h
ori r10, r10, 0x1c00
mr r8, r10
#else
lis r10, MD_RESETVAL@h
#endif
#ifndef CONFIG_8xx_COPYBACK
oris r10, r10, MD_WTDEF@h
#endif
mtspr SPRN_MD_CTR, r10 /* Set data TLB control */ mtspr SPRN_MD_CTR, r10 /* Set data TLB control */
#endif
/* Now map the lower 8 Meg into the TLBs. For this quick hack, /* Now map the lower 8 Meg into the ITLB. */
* we can load the instruction and data TLB registers with the
* same values.
*/
lis r8, KERNELBASE@h /* Create vaddr for TLB */ lis r8, KERNELBASE@h /* Create vaddr for TLB */
ori r8, r8, MI_EVALID /* Mark it valid */ ori r8, r8, MI_EVALID /* Mark it valid */
mtspr SPRN_MI_EPN, r8 mtspr SPRN_MI_EPN, r8
mtspr SPRN_MD_EPN, r8
li r8, MI_PS8MEG | (2 << 5) /* Set 8M byte page, APG 2 */ li r8, MI_PS8MEG | (2 << 5) /* Set 8M byte page, APG 2 */
ori r8, r8, MI_SVALID /* Make it valid */ ori r8, r8, MI_SVALID /* Make it valid */
mtspr SPRN_MI_TWC, r8 mtspr SPRN_MI_TWC, r8
li r8, MI_PS8MEG /* Set 8M byte page, APG 0 */
ori r8, r8, MI_SVALID /* Make it valid */
mtspr SPRN_MD_TWC, r8
li r8, MI_BOOTINIT /* Create RPN for address 0 */ li r8, MI_BOOTINIT /* Create RPN for address 0 */
mtspr SPRN_MI_RPN, r8 /* Store TLB entry */ mtspr SPRN_MI_RPN, r8 /* Store TLB entry */
mtspr SPRN_MD_RPN, r8
lis r8, MI_APG_INIT@h /* Set protection modes */ lis r8, MI_APG_INIT@h /* Set protection modes */
ori r8, r8, MI_APG_INIT@l ori r8, r8, MI_APG_INIT@l
mtspr SPRN_MI_AP, r8 mtspr SPRN_MI_AP, r8
...@@ -812,51 +839,25 @@ initial_mmu: ...@@ -812,51 +839,25 @@ initial_mmu:
ori r8, r8, MD_APG_INIT@l ori r8, r8, MD_APG_INIT@l
mtspr SPRN_MD_AP, r8 mtspr SPRN_MD_AP, r8
/* Map another 8 MByte at the IMMR to get the processor /* Map a 512k page for the IMMR to get the processor
* internal registers (among other things). * internal registers (among other things).
*/ */
#ifdef CONFIG_PIN_TLB #ifdef CONFIG_PIN_TLB_IMMR
addi r10, r10, 0x0100 ori r10, r10, 0x1c00
mtspr SPRN_MD_CTR, r10 mtspr SPRN_MD_CTR, r10
#endif
mfspr r9, 638 /* Get current IMMR */ mfspr r9, 638 /* Get current IMMR */
andis. r9, r9, 0xff80 /* Get 8Mbyte boundary */ andis. r9, r9, 0xfff8 /* Get 512 kbytes boundary */
mr r8, r9 /* Create vaddr for TLB */ lis r8, VIRT_IMMR_BASE@h /* Create vaddr for TLB */
ori r8, r8, MD_EVALID /* Mark it valid */ ori r8, r8, MD_EVALID /* Mark it valid */
mtspr SPRN_MD_EPN, r8 mtspr SPRN_MD_EPN, r8
li r8, MD_PS8MEG /* Set 8M byte page */ li r8, MD_PS512K | MD_GUARDED /* Set 512k byte page */
ori r8, r8, MD_SVALID /* Make it valid */ ori r8, r8, MD_SVALID /* Make it valid */
mtspr SPRN_MD_TWC, r8 mtspr SPRN_MD_TWC, r8
mr r8, r9 /* Create paddr for TLB */ mr r8, r9 /* Create paddr for TLB */
ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */ ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
mtspr SPRN_MD_RPN, r8 mtspr SPRN_MD_RPN, r8
#ifdef CONFIG_PIN_TLB
/* Map two more 8M kernel data pages.
*/
addi r10, r10, 0x0100
mtspr SPRN_MD_CTR, r10
lis r8, KERNELBASE@h /* Create vaddr for TLB */
addis r8, r8, 0x0080 /* Add 8M */
ori r8, r8, MI_EVALID /* Mark it valid */
mtspr SPRN_MD_EPN, r8
li r9, MI_PS8MEG /* Set 8M byte page */
ori r9, r9, MI_SVALID /* Make it valid */
mtspr SPRN_MD_TWC, r9
li r11, MI_BOOTINIT /* Create RPN for address 0 */
addis r11, r11, 0x0080 /* Add 8M */
mtspr SPRN_MD_RPN, r11
addi r10, r10, 0x0100
mtspr SPRN_MD_CTR, r10
addis r8, r8, 0x0080 /* Add 8M */
mtspr SPRN_MD_EPN, r8
mtspr SPRN_MD_TWC, r9
addis r11, r11, 0x0080 /* Add 8M */
mtspr SPRN_MD_RPN, r11
#endif #endif
/* Since the cache is enabled according to the information we /* Since the cache is enabled according to the information we
......
...@@ -167,7 +167,15 @@ DEFINE_PER_CPU(unsigned long, cputime_scaled_last_delta); ...@@ -167,7 +167,15 @@ DEFINE_PER_CPU(unsigned long, cputime_scaled_last_delta);
cputime_t cputime_one_jiffy; cputime_t cputime_one_jiffy;
#ifdef CONFIG_PPC_SPLPAR
void (*dtl_consumer)(struct dtl_entry *, u64); void (*dtl_consumer)(struct dtl_entry *, u64);
#endif
#ifdef CONFIG_PPC64
#define get_accounting(tsk) (&get_paca()->accounting)
#else
#define get_accounting(tsk) (&task_thread_info(tsk)->accounting)
#endif
static void calc_cputime_factors(void) static void calc_cputime_factors(void)
{ {
...@@ -187,7 +195,7 @@ static void calc_cputime_factors(void) ...@@ -187,7 +195,7 @@ static void calc_cputime_factors(void)
* Read the SPURR on systems that have it, otherwise the PURR, * Read the SPURR on systems that have it, otherwise the PURR,
* or if that doesn't exist return the timebase value passed in. * or if that doesn't exist return the timebase value passed in.
*/ */
static u64 read_spurr(u64 tb) static unsigned long read_spurr(unsigned long tb)
{ {
if (cpu_has_feature(CPU_FTR_SPURR)) if (cpu_has_feature(CPU_FTR_SPURR))
return mfspr(SPRN_SPURR); return mfspr(SPRN_SPURR);
...@@ -250,8 +258,8 @@ static u64 scan_dispatch_log(u64 stop_tb) ...@@ -250,8 +258,8 @@ static u64 scan_dispatch_log(u64 stop_tb)
void accumulate_stolen_time(void) void accumulate_stolen_time(void)
{ {
u64 sst, ust; u64 sst, ust;
u8 save_soft_enabled = local_paca->soft_enabled; u8 save_soft_enabled = local_paca->soft_enabled;
struct cpu_accounting_data *acct = &local_paca->accounting;
/* We are called early in the exception entry, before /* We are called early in the exception entry, before
* soft/hard_enabled are sync'ed to the expected state * soft/hard_enabled are sync'ed to the expected state
...@@ -261,10 +269,10 @@ void accumulate_stolen_time(void) ...@@ -261,10 +269,10 @@ void accumulate_stolen_time(void)
*/ */
local_paca->soft_enabled = 0; local_paca->soft_enabled = 0;
sst = scan_dispatch_log(local_paca->starttime_user); sst = scan_dispatch_log(acct->starttime_user);
ust = scan_dispatch_log(local_paca->starttime); ust = scan_dispatch_log(acct->starttime);
local_paca->system_time -= sst; acct->system_time -= sst;
local_paca->user_time -= ust; acct->user_time -= ust;
local_paca->stolen_time += ust + sst; local_paca->stolen_time += ust + sst;
local_paca->soft_enabled = save_soft_enabled; local_paca->soft_enabled = save_soft_enabled;
...@@ -276,7 +284,7 @@ static inline u64 calculate_stolen_time(u64 stop_tb) ...@@ -276,7 +284,7 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx)) { if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx)) {
stolen = scan_dispatch_log(stop_tb); stolen = scan_dispatch_log(stop_tb);
get_paca()->system_time -= stolen; get_paca()->accounting.system_time -= stolen;
} }
stolen += get_paca()->stolen_time; stolen += get_paca()->stolen_time;
...@@ -296,27 +304,29 @@ static inline u64 calculate_stolen_time(u64 stop_tb) ...@@ -296,27 +304,29 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
* Account time for a transition between system, hard irq * Account time for a transition between system, hard irq
* or soft irq state. * or soft irq state.
*/ */
static u64 vtime_delta(struct task_struct *tsk, static unsigned long vtime_delta(struct task_struct *tsk,
u64 *sys_scaled, u64 *stolen) unsigned long *sys_scaled,
unsigned long *stolen)
{ {
u64 now, nowscaled, deltascaled; unsigned long now, nowscaled, deltascaled;
u64 udelta, delta, user_scaled; unsigned long udelta, delta, user_scaled;
struct cpu_accounting_data *acct = get_accounting(tsk);
WARN_ON_ONCE(!irqs_disabled()); WARN_ON_ONCE(!irqs_disabled());
now = mftb(); now = mftb();
nowscaled = read_spurr(now); nowscaled = read_spurr(now);
get_paca()->system_time += now - get_paca()->starttime; acct->system_time += now - acct->starttime;
get_paca()->starttime = now; acct->starttime = now;
deltascaled = nowscaled - get_paca()->startspurr; deltascaled = nowscaled - acct->startspurr;
get_paca()->startspurr = nowscaled; acct->startspurr = nowscaled;
*stolen = calculate_stolen_time(now); *stolen = calculate_stolen_time(now);
delta = get_paca()->system_time; delta = acct->system_time;
get_paca()->system_time = 0; acct->system_time = 0;
udelta = get_paca()->user_time - get_paca()->utime_sspurr; udelta = acct->user_time - acct->utime_sspurr;
get_paca()->utime_sspurr = get_paca()->user_time; acct->utime_sspurr = acct->user_time;
/* /*
* Because we don't read the SPURR on every kernel entry/exit, * Because we don't read the SPURR on every kernel entry/exit,
...@@ -338,14 +348,14 @@ static u64 vtime_delta(struct task_struct *tsk, ...@@ -338,14 +348,14 @@ static u64 vtime_delta(struct task_struct *tsk,
*sys_scaled = deltascaled; *sys_scaled = deltascaled;
} }
} }
get_paca()->user_time_scaled += user_scaled; acct->user_time_scaled += user_scaled;
return delta; return delta;
} }
void vtime_account_system(struct task_struct *tsk) void vtime_account_system(struct task_struct *tsk)
{ {
u64 delta, sys_scaled, stolen; unsigned long delta, sys_scaled, stolen;
delta = vtime_delta(tsk, &sys_scaled, &stolen); delta = vtime_delta(tsk, &sys_scaled, &stolen);
account_system_time(tsk, 0, delta, sys_scaled); account_system_time(tsk, 0, delta, sys_scaled);
...@@ -356,7 +366,7 @@ EXPORT_SYMBOL_GPL(vtime_account_system); ...@@ -356,7 +366,7 @@ EXPORT_SYMBOL_GPL(vtime_account_system);
void vtime_account_idle(struct task_struct *tsk) void vtime_account_idle(struct task_struct *tsk)
{ {
u64 delta, sys_scaled, stolen; unsigned long delta, sys_scaled, stolen;
delta = vtime_delta(tsk, &sys_scaled, &stolen); delta = vtime_delta(tsk, &sys_scaled, &stolen);
account_idle_time(delta + stolen); account_idle_time(delta + stolen);
...@@ -374,15 +384,32 @@ void vtime_account_idle(struct task_struct *tsk) ...@@ -374,15 +384,32 @@ void vtime_account_idle(struct task_struct *tsk)
void vtime_account_user(struct task_struct *tsk) void vtime_account_user(struct task_struct *tsk)
{ {
cputime_t utime, utimescaled; cputime_t utime, utimescaled;
struct cpu_accounting_data *acct = get_accounting(tsk);
utime = get_paca()->user_time; utime = acct->user_time;
utimescaled = get_paca()->user_time_scaled; utimescaled = acct->user_time_scaled;
get_paca()->user_time = 0; acct->user_time = 0;
get_paca()->user_time_scaled = 0; acct->user_time_scaled = 0;
get_paca()->utime_sspurr = 0; acct->utime_sspurr = 0;
account_user_time(tsk, utime, utimescaled); account_user_time(tsk, utime, utimescaled);
} }
#ifdef CONFIG_PPC32
/*
* Called from the context switch with interrupts disabled, to charge all
* accumulated times to the current process, and to prepare accounting on
* the next process.
*/
void arch_vtime_task_switch(struct task_struct *prev)
{
struct cpu_accounting_data *acct = get_accounting(current);
acct->starttime = get_accounting(prev)->starttime;
acct->system_time = 0;
acct->user_time = 0;
}
#endif /* CONFIG_PPC32 */
#else /* ! CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ #else /* ! CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
#define calc_cputime_factors() #define calc_cputime_factors()
#endif #endif
......
...@@ -13,62 +13,115 @@ ...@@ -13,62 +13,115 @@
*/ */
#include <linux/memblock.h> #include <linux/memblock.h>
#include <asm/fixmap.h>
#include <asm/code-patching.h>
#include "mmu_decl.h" #include "mmu_decl.h"
#define IMMR_SIZE (FIX_IMMR_SIZE << PAGE_SHIFT)
extern int __map_without_ltlbs; extern int __map_without_ltlbs;
/* /*
* MMU_init_hw does the chip-specific initialization of the MMU hardware. * Return PA for this VA if it is in IMMR area, or 0
*/ */
void __init MMU_init_hw(void) phys_addr_t v_block_mapped(unsigned long va)
{ {
/* Nothing to do for the time being but keep it similar to other PPC */ unsigned long p = PHYS_IMMR_BASE;
if (__map_without_ltlbs)
return 0;
if (va >= VIRT_IMMR_BASE && va < VIRT_IMMR_BASE + IMMR_SIZE)
return p + va - VIRT_IMMR_BASE;
return 0;
}
/*
* Return VA for a given PA or 0 if not mapped
*/
unsigned long p_block_mapped(phys_addr_t pa)
{
unsigned long p = PHYS_IMMR_BASE;
if (__map_without_ltlbs)
return 0;
if (pa >= p && pa < p + IMMR_SIZE)
return VIRT_IMMR_BASE + pa - p;
return 0;
} }
#define LARGE_PAGE_SIZE_4M (1<<22)
#define LARGE_PAGE_SIZE_8M (1<<23) #define LARGE_PAGE_SIZE_8M (1<<23)
#define LARGE_PAGE_SIZE_64M (1<<26)
unsigned long __init mmu_mapin_ram(unsigned long top) /*
* MMU_init_hw does the chip-specific initialization of the MMU hardware.
*/
void __init MMU_init_hw(void)
{ {
unsigned long v, s, mapped; /* PIN up to the 3 first 8Mb after IMMR in DTLB table */
phys_addr_t p; #ifdef CONFIG_PIN_TLB
unsigned long ctr = mfspr(SPRN_MD_CTR) & 0xfe000000;
unsigned long flags = 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY;
#ifdef CONFIG_PIN_TLB_IMMR
int i = 29;
#else
int i = 28;
#endif
unsigned long addr = 0;
unsigned long mem = total_lowmem;
for (; i < 32 && mem >= LARGE_PAGE_SIZE_8M; i++) {
mtspr(SPRN_MD_CTR, ctr | (i << 8));
mtspr(SPRN_MD_EPN, (unsigned long)__va(addr) | MD_EVALID);
mtspr(SPRN_MD_TWC, MD_PS8MEG | MD_SVALID);
mtspr(SPRN_MD_RPN, addr | flags | _PAGE_PRESENT);
addr += LARGE_PAGE_SIZE_8M;
mem -= LARGE_PAGE_SIZE_8M;
}
#endif
}
v = KERNELBASE; static void mmu_mapin_immr(void)
p = 0; {
s = top; unsigned long p = PHYS_IMMR_BASE;
unsigned long v = VIRT_IMMR_BASE;
unsigned long f = pgprot_val(PAGE_KERNEL_NCG);
int offset;
if (__map_without_ltlbs) for (offset = 0; offset < IMMR_SIZE; offset += PAGE_SIZE)
return 0; map_page(v + offset, p + offset, f);
}
#ifdef CONFIG_PPC_4K_PAGES /* Address of instructions to patch */
while (s >= LARGE_PAGE_SIZE_8M) { #ifndef CONFIG_PIN_TLB_IMMR
pmd_t *pmdp; extern unsigned int DTLBMiss_jmp;
unsigned long val = p | MD_PS8MEG; #endif
extern unsigned int DTLBMiss_cmp, FixupDAR_cmp;
pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v); void mmu_patch_cmp_limit(unsigned int *addr, unsigned long mapped)
*pmdp++ = __pmd(val); {
*pmdp++ = __pmd(val + LARGE_PAGE_SIZE_4M); unsigned int instr = *addr;
v += LARGE_PAGE_SIZE_8M; instr &= 0xffff0000;
p += LARGE_PAGE_SIZE_8M; instr |= (unsigned long)__va(mapped) >> 16;
s -= LARGE_PAGE_SIZE_8M; patch_instruction(addr, instr);
} }
#else /* CONFIG_PPC_16K_PAGES */
while (s >= LARGE_PAGE_SIZE_64M) {
pmd_t *pmdp;
unsigned long val = p | MD_PS8MEG;
pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v); unsigned long __init mmu_mapin_ram(unsigned long top)
*pmdp++ = __pmd(val); {
unsigned long mapped;
v += LARGE_PAGE_SIZE_64M; if (__map_without_ltlbs) {
p += LARGE_PAGE_SIZE_64M; mapped = 0;
s -= LARGE_PAGE_SIZE_64M; mmu_mapin_immr();
} #ifndef CONFIG_PIN_TLB_IMMR
patch_instruction(&DTLBMiss_jmp, PPC_INST_NOP);
#endif #endif
} else {
mapped = top & ~(LARGE_PAGE_SIZE_8M - 1);
}
mapped = top - s; mmu_patch_cmp_limit(&DTLBMiss_cmp, mapped);
mmu_patch_cmp_limit(&FixupDAR_cmp, mapped);
/* If the size of RAM is not an exact power of two, we may not /* If the size of RAM is not an exact power of two, we may not
* have covered RAM in its entirety with 8 MiB * have covered RAM in its entirety with 8 MiB
...@@ -77,7 +130,8 @@ unsigned long __init mmu_mapin_ram(unsigned long top) ...@@ -77,7 +130,8 @@ unsigned long __init mmu_mapin_ram(unsigned long top)
* coverage with normal-sized pages (or other reasons) do not * coverage with normal-sized pages (or other reasons) do not
* attempt to allocate outside the allowed range. * attempt to allocate outside the allowed range.
*/ */
memblock_set_current_limit(mapped); if (mapped)
memblock_set_current_limit(mapped);
return mapped; return mapped;
} }
...@@ -90,13 +144,8 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base, ...@@ -90,13 +144,8 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
*/ */
BUG_ON(first_memblock_base != 0); BUG_ON(first_memblock_base != 0);
#ifdef CONFIG_PIN_TLB
/* 8xx can only access 24MB at the moment */ /* 8xx can only access 24MB at the moment */
memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000)); memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000));
#else
/* 8xx can only access 8MB at the moment */
memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
#endif
} }
/* /*
......
...@@ -154,9 +154,10 @@ struct tlbcam { ...@@ -154,9 +154,10 @@ struct tlbcam {
}; };
#endif #endif
#if defined(CONFIG_6xx) || defined(CONFIG_FSL_BOOKE) #if defined(CONFIG_6xx) || defined(CONFIG_FSL_BOOKE) || defined(CONFIG_PPC_8xx)
/* 6xx have BATS */ /* 6xx have BATS */
/* FSL_BOOKE have TLBCAM */ /* FSL_BOOKE have TLBCAM */
/* 8xx have LTLB */
phys_addr_t v_block_mapped(unsigned long va); phys_addr_t v_block_mapped(unsigned long va);
unsigned long p_block_mapped(phys_addr_t pa); unsigned long p_block_mapped(phys_addr_t pa);
#else #else
......
...@@ -61,6 +61,11 @@ config GEF_SBC610 ...@@ -61,6 +61,11 @@ config GEF_SBC610
help help
This option enables support for the GE SBC610. This option enables support for the GE SBC610.
config MVME7100
bool "Artesyn MVME7100"
help
This option enables support for the Emerson/Artesyn MVME7100 board.
endif endif
config MPC8641 config MPC8641
...@@ -69,7 +74,8 @@ config MPC8641 ...@@ -69,7 +74,8 @@ config MPC8641
select FSL_PCI if PCI select FSL_PCI if PCI
select PPC_UDBG_16550 select PPC_UDBG_16550
select MPIC select MPIC
default y if MPC8641_HPCN || SBC8641D || GEF_SBC610 || GEF_SBC310 || GEF_PPC9A default y if MPC8641_HPCN || SBC8641D || GEF_SBC610 || GEF_SBC310 || GEF_PPC9A \
|| MVME7100
config MPC8610 config MPC8610
bool bool
......
...@@ -10,3 +10,4 @@ obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o ...@@ -10,3 +10,4 @@ obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o
obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o
obj-$(CONFIG_GEF_SBC310) += gef_sbc310.o obj-$(CONFIG_GEF_SBC310) += gef_sbc310.o
obj-$(CONFIG_GEF_PPC9A) += gef_ppc9a.o obj-$(CONFIG_GEF_PPC9A) += gef_ppc9a.o
obj-$(CONFIG_MVME7100) += mvme7100.o
/*
* Board setup routines for the Emerson/Artesyn MVME7100
*
* Copyright 2016 Elettra-Sincrotrone Trieste S.C.p.A.
*
* Author: Alessio Igor Bogani <alessio.bogani@elettra.eu>
*
* Based on earlier code by:
*
* Ajit Prem <ajit.prem@emerson.com>
* Copyright 2008 Emerson
*
* USB host fixup is borrowed by:
*
* Martyn Welch <martyn.welch@ge.com>
* Copyright 2008 GE Intelligent Platforms Embedded Systems, 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 <linux/pci.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <asm/udbg.h>
#include <asm/mpic.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
#include "mpc86xx.h"
#define MVME7100_INTERRUPT_REG_2_OFFSET 0x05
#define MVME7100_DS1375_MASK 0x40
#define MVME7100_MAX6649_MASK 0x20
#define MVME7100_ABORT_MASK 0x10
/*
* Setup the architecture
*/
static void __init mvme7100_setup_arch(void)
{
struct device_node *bcsr_node;
void __iomem *mvme7100_regs = NULL;
u8 reg;
if (ppc_md.progress)
ppc_md.progress("mvme7100_setup_arch()", 0);
#ifdef CONFIG_SMP
mpc86xx_smp_init();
#endif
fsl_pci_assign_primary();
/* Remap BCSR registers */
bcsr_node = of_find_compatible_node(NULL, NULL,
"artesyn,mvme7100-bcsr");
if (bcsr_node) {
mvme7100_regs = of_iomap(bcsr_node, 0);
of_node_put(bcsr_node);
}
if (mvme7100_regs) {
/* Disable ds1375, max6649, and abort interrupts */
reg = readb(mvme7100_regs + MVME7100_INTERRUPT_REG_2_OFFSET);
reg |= MVME7100_DS1375_MASK | MVME7100_MAX6649_MASK
| MVME7100_ABORT_MASK;
writeb(reg, mvme7100_regs + MVME7100_INTERRUPT_REG_2_OFFSET);
} else
pr_warn("Unable to map board registers\n");
pr_info("MVME7100 board from Artesyn\n");
}
/*
* Called very early, device-tree isn't unflattened
*/
static int __init mvme7100_probe(void)
{
unsigned long root = of_get_flat_dt_root();
return of_flat_dt_is_compatible(root, "artesyn,MVME7100");
}
static void mvme7100_usb_host_fixup(struct pci_dev *pdev)
{
unsigned int val;
if (!machine_is(mvme7100))
return;
/* Ensure only ports 1 & 2 are enabled */
pci_read_config_dword(pdev, 0xe0, &val);
pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x2);
/* System clock is 48-MHz Oscillator and EHCI Enabled. */
pci_write_config_dword(pdev, 0xe4, 1 << 5);
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
mvme7100_usb_host_fixup);
machine_arch_initcall(mvme7100, mpc86xx_common_publish_devices);
define_machine(mvme7100) {
.name = "MVME7100",
.probe = mvme7100_probe,
.setup_arch = mvme7100_setup_arch,
.init_IRQ = mpc86xx_init_irq,
.get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
.time_init = mpc86xx_time_init,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
#ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
#endif
};
config PPC64 config PPC64
bool "64-bit kernel" bool "64-bit kernel"
default n default n
select HAVE_VIRT_CPU_ACCOUNTING
select ZLIB_DEFLATE select ZLIB_DEFLATE
help help
This option selects whether a 32-bit or a 64-bit kernel This option selects whether a 32-bit or a 64-bit kernel
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <asm/udbg.h> #include <asm/udbg.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/cpm.h> #include <asm/cpm.h>
#include <asm/fixmap.h>
#include <soc/fsl/qe/qe.h> #include <soc/fsl/qe/qe.h>
#include <mm/mmu_decl.h> #include <mm/mmu_decl.h>
...@@ -37,25 +38,36 @@ ...@@ -37,25 +38,36 @@
#endif #endif
#ifdef CONFIG_PPC_EARLY_DEBUG_CPM #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
static u32 __iomem *cpm_udbg_txdesc = static u32 __iomem *cpm_udbg_txdesc;
(u32 __iomem __force *)CONFIG_PPC_EARLY_DEBUG_CPM_ADDR; static u8 __iomem *cpm_udbg_txbuf;
static void udbg_putc_cpm(char c) static void udbg_putc_cpm(char c)
{ {
u8 __iomem *txbuf = (u8 __iomem __force *)in_be32(&cpm_udbg_txdesc[1]);
if (c == '\n') if (c == '\n')
udbg_putc_cpm('\r'); udbg_putc_cpm('\r');
while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000) while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000)
; ;
out_8(txbuf, c); out_8(cpm_udbg_txbuf, c);
out_be32(&cpm_udbg_txdesc[0], 0xa0000001); out_be32(&cpm_udbg_txdesc[0], 0xa0000001);
} }
void __init udbg_init_cpm(void) void __init udbg_init_cpm(void)
{ {
#ifdef CONFIG_PPC_8xx
cpm_udbg_txdesc = (u32 __iomem __force *)
(CONFIG_PPC_EARLY_DEBUG_CPM_ADDR - PHYS_IMMR_BASE +
VIRT_IMMR_BASE);
cpm_udbg_txbuf = (u8 __iomem __force *)
(in_be32(&cpm_udbg_txdesc[1]) - PHYS_IMMR_BASE +
VIRT_IMMR_BASE);
#else
cpm_udbg_txdesc = (u32 __iomem __force *)
CONFIG_PPC_EARLY_DEBUG_CPM_ADDR;
cpm_udbg_txbuf = (u8 __iomem __force *)in_be32(&cpm_udbg_txdesc[1]);
#endif
if (cpm_udbg_txdesc) { if (cpm_udbg_txdesc) {
#ifdef CONFIG_CPM2 #ifdef CONFIG_CPM2
setbat(1, 0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG); setbat(1, 0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG);
......
...@@ -90,12 +90,8 @@ static int mpc85xx_l2ctlr_of_probe(struct platform_device *dev) ...@@ -90,12 +90,8 @@ static int mpc85xx_l2ctlr_of_probe(struct platform_device *dev)
} }
l2cache_size = *prop; l2cache_size = *prop;
if (get_cache_sram_params(&sram_params)) { if (get_cache_sram_params(&sram_params))
dev_err(&dev->dev, return 0; /* fall back to L2 cache only */
"Entire L2 as cache, provide valid sram offset and size\n");
return -EINVAL;
}
rem = l2cache_size % sram_params.sram_size; rem = l2cache_size % sram_params.sram_size;
ways = LOCK_WAYS_FULL * sram_params.sram_size / l2cache_size; ways = LOCK_WAYS_FULL * sram_params.sram_size / l2cache_size;
......
...@@ -2284,13 +2284,13 @@ static void dump_one_paca(int cpu) ...@@ -2284,13 +2284,13 @@ static void dump_one_paca(int cpu)
DUMP(p, subcore_sibling_mask, "x"); DUMP(p, subcore_sibling_mask, "x");
#endif #endif
DUMP(p, user_time, "llx"); DUMP(p, accounting.user_time, "llx");
DUMP(p, system_time, "llx"); DUMP(p, accounting.system_time, "llx");
DUMP(p, user_time_scaled, "llx"); DUMP(p, accounting.user_time_scaled, "llx");
DUMP(p, starttime, "llx"); DUMP(p, accounting.starttime, "llx");
DUMP(p, starttime_user, "llx"); DUMP(p, accounting.starttime_user, "llx");
DUMP(p, startspurr, "llx"); DUMP(p, accounting.startspurr, "llx");
DUMP(p, utime_sspurr, "llx"); DUMP(p, accounting.utime_sspurr, "llx");
DUMP(p, stolen_time, "llx"); DUMP(p, stolen_time, "llx");
#undef DUMP #undef DUMP
......
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