1
0
Fork 0

Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (144 commits)
  powerpc/44x: Support 16K/64K base page sizes on 44x
  powerpc: Force memory size to be a multiple of PAGE_SIZE
  powerpc/32: Wire up the trampoline code for kdump
  powerpc/32: Add the ability for a classic ppc kernel to be loaded at 32M
  powerpc/32: Allow __ioremap on RAM addresses for kdump kernel
  powerpc/32: Setup OF properties for kdump
  powerpc/32/kdump: Implement crash_setup_regs() using ppc_save_regs()
  powerpc: Prepare xmon_save_regs for use with kdump
  powerpc: Remove default kexec/crash_kernel ops assignments
  powerpc: Make default kexec/crash_kernel ops implicit
  powerpc: Setup OF properties for ppc32 kexec
  powerpc/pseries: Fix cpu hotplug
  powerpc: Fix KVM build on ppc440
  powerpc/cell: add QPACE as a separate Cell platform
  powerpc/cell: fix build breakage with CONFIG_SPUFS disabled
  powerpc/mpc5200: fix error paths in PSC UART probe function
  powerpc/mpc5200: add rts/cts handling in PSC UART driver
  powerpc/mpc5200: Make PSC UART driver update serial errors counters
  powerpc/mpc5200: Remove obsolete code from mpc5200 MDIO driver
  powerpc/mpc5200: Add MDMA/UDMA support to MPC5200 ATA driver
  ...

Fix trivial conflict in drivers/char/Makefile as per Paul's directions
hifive-unleashed-5.1
Linus Torvalds 2008-12-28 16:54:33 -08:00
commit 3c92ec8ae9
254 changed files with 7142 additions and 2732 deletions

View File

@ -285,6 +285,10 @@ config IOMMU_VMERGE
config IOMMU_HELPER
def_bool PPC64
config PPC_NEED_DMA_SYNC_OPS
def_bool y
depends on NOT_COHERENT_CACHE
config HOTPLUG_CPU
bool "Support for enabling/disabling CPUs"
depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC)
@ -322,7 +326,7 @@ config KEXEC
config CRASH_DUMP
bool "Build a kdump crash kernel"
depends on PPC_MULTIPLATFORM && PPC64 && RELOCATABLE
depends on (PPC64 && RELOCATABLE) || 6xx
help
Build a kernel suitable for use as a kdump capture kernel.
The same kernel binary can be used as production kernel and dump
@ -401,23 +405,53 @@ config PPC_HAS_HASH_64K
depends on PPC64
default n
config PPC_64K_PAGES
bool "64k page size"
depends on PPC64
select PPC_HAS_HASH_64K
choice
prompt "Page size"
default PPC_4K_PAGES
help
This option changes the kernel logical page size to 64k. On machines
without processor support for 64k pages, the kernel will simulate
them by loading each individual 4k page on demand transparently,
while on hardware with such support, it will be used to map
normal application pages.
Select the kernel logical page size. Increasing the page size
will reduce software overhead at each page boundary, allow
hardware prefetch mechanisms to be more effective, and allow
larger dma transfers increasing IO efficiency and reducing
overhead. However the utilization of memory will increase.
For example, each cached file will using a multiple of the
page size to hold its contents and the difference between the
end of file and the end of page is wasted.
Some dedicated systems, such as software raid serving with
accelerated calculations, have shown significant increases.
If you configure a 64 bit kernel for 64k pages but the
processor does not support them, then the kernel will simulate
them with 4k pages, loading them on demand, but with the
reduced software overhead and larger internal fragmentation.
For the 32 bit kernel, a large page option will not be offered
unless it is supported by the configured processor.
If unsure, choose 4K_PAGES.
config PPC_4K_PAGES
bool "4k page size"
config PPC_16K_PAGES
bool "16k page size" if 44x
config PPC_64K_PAGES
bool "64k page size" if 44x || PPC_STD_MMU_64
select PPC_HAS_HASH_64K if PPC_STD_MMU_64
endchoice
config FORCE_MAX_ZONEORDER
int "Maximum zone order"
range 9 64 if PPC_64K_PAGES
default "9" if PPC_64K_PAGES
range 13 64 if PPC64 && !PPC_64K_PAGES
default "13" if PPC64 && !PPC_64K_PAGES
range 9 64 if PPC_STD_MMU_64 && PPC_64K_PAGES
default "9" if PPC_STD_MMU_64 && PPC_64K_PAGES
range 13 64 if PPC_STD_MMU_64 && !PPC_64K_PAGES
default "13" if PPC_STD_MMU_64 && !PPC_64K_PAGES
range 9 64 if PPC_STD_MMU_32 && PPC_16K_PAGES
default "9" if PPC_STD_MMU_32 && PPC_16K_PAGES
range 7 64 if PPC_STD_MMU_32 && PPC_64K_PAGES
default "7" if PPC_STD_MMU_32 && PPC_64K_PAGES
range 11 64
default "11"
help
@ -437,7 +471,7 @@ config FORCE_MAX_ZONEORDER
config PPC_SUBPAGE_PROT
bool "Support setting protections for 4k subpages"
depends on PPC_64K_PAGES
depends on PPC_STD_MMU_64 && PPC_64K_PAGES
help
This option adds support for a system call to allow user programs
to set access permissions (read/write, readonly, or no access)

View File

@ -2,6 +2,15 @@ menu "Kernel hacking"
source "lib/Kconfig.debug"
config PRINT_STACK_DEPTH
int "Stack depth to print" if DEBUG_KERNEL
default 64
help
This option allows you to set the stack depth that the kernel
prints in stack traces. This can be useful if your display is
too small and stack traces cause important information to
scroll off the screen.
config DEBUG_STACKOVERFLOW
bool "Check for stack overflows"
depends on DEBUG_KERNEL

View File

@ -107,7 +107,6 @@ KBUILD_CFLAGS += $(call cc-option,-mno-altivec)
# (We use all available options to help semi-broken compilers)
KBUILD_CFLAGS += $(call cc-option,-mno-spe)
KBUILD_CFLAGS += $(call cc-option,-mspe=no)
KBUILD_CFLAGS += $(call cc-option,-mabi=no-spe)
# Enable unit-at-a-time mode when possible. It shrinks the
# kernel considerably.

View File

@ -194,6 +194,7 @@ image-$(CONFIG_PPC_MAPLE) += zImage.pseries
image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries
image-$(CONFIG_PPC_PS3) += dtbImage.ps3
image-$(CONFIG_PPC_CELLEB) += zImage.pseries
image-$(CONFIG_PPC_CELL_QPACE) += zImage.pseries
image-$(CONFIG_PPC_CHRP) += zImage.chrp
image-$(CONFIG_PPC_EFIKA) += zImage.chrp
image-$(CONFIG_PPC_PMAC) += zImage.pmac

View File

@ -213,7 +213,7 @@ static int find_range(u32 *reg, u32 *ranges, int nregaddr,
u32 range_addr[MAX_ADDR_CELLS];
u32 range_size[MAX_ADDR_CELLS];
copy_val(range_addr, ranges + i, naddr);
copy_val(range_addr, ranges + i, nregaddr);
copy_val(range_size, ranges + i + nregaddr + naddr, nsize);
if (compare_reg(reg, range_addr, range_size))

View File

@ -269,7 +269,8 @@
* later cannot be changed. Chip supports a second
* IO range but we don't use it for now
*/
ranges = <0x02000000 0x00000000 0xa0000000 0x00000000 0xa0000000 0x00000000 0x20000000
ranges = <0x02000000 0x00000000 0xa0000000 0x00000000 0xa0000000 0x00000000 0x40000000
0x02000000 0x00000000 0x00000000 0x00000000 0xe0000000 0x00000000 0x00100000
0x01000000 0x00000000 0x00000000 0x00000000 0xe8000000 0x00000000 0x00010000>;
/* Inbound 2GB range starting at 0 */

View File

@ -40,6 +40,7 @@
d-cache-size = <32768>;
dcr-controller;
dcr-access-method = "native";
next-level-cache = <&L2C0>;
};
};
@ -104,6 +105,16 @@
dcr-reg = <0x00c 0x002>;
};
L2C0: l2c {
compatible = "ibm,l2-cache-460ex", "ibm,l2-cache";
dcr-reg = <0x020 0x008 /* Internal SRAM DCR's */
0x030 0x008>; /* L2 cache DCR's */
cache-line-size = <32>; /* 32 bytes */
cache-size = <262144>; /* L2, 256K */
interrupt-parent = <&UIC1>;
interrupts = <11 1>;
};
plb {
compatible = "ibm,plb-460ex", "ibm,plb4";
#address-cells = <2>;
@ -343,6 +354,7 @@
* later cannot be changed
*/
ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000
0x02000000 0x00000000 0x00000000 0x0000000c 0x0ee00000 0x00000000 0x00100000
0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>;
/* Inbound 2GB range starting at 0 */
@ -373,6 +385,7 @@
* later cannot be changed
*/
ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000
0x02000000 0x00000000 0x00000000 0x0000000f 0x00000000 0x00000000 0x00100000
0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>;
/* Inbound 2GB range starting at 0 */
@ -414,6 +427,7 @@
* later cannot be changed
*/
ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000
0x02000000 0x00000000 0x00000000 0x0000000f 0x00100000 0x00000000 0x00100000
0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>;
/* Inbound 2GB range starting at 0 */

View File

@ -98,6 +98,12 @@
interrupt-parent = <&mpic>;
};
gef_gpio: gpio@7,14000 {
#gpio-cells = <2>;
compatible = "gef,sbc610-gpio";
reg = <0x7 0x14000 0x24>;
gpio-controller;
};
};
soc@fef00000 {
@ -119,6 +125,11 @@
interrupt-parent = <&mpic>;
dfsrr;
rtc@51 {
compatible = "epson,rx8581";
reg = <0x00000051>;
};
eti@6b {
compatible = "dallas,ds1682";
reg = <0x6b>;

View File

@ -76,7 +76,6 @@ XXXX add flash parts, rtc, ??
interrupt-parent = <&mpic>;
rtc@32 {
device_type = "rtc";
compatible = "ricoh,rs5c372a";
reg = <0x32>;
};

View File

@ -76,7 +76,6 @@ XXXX add flash parts, rtc, ??
interrupt-parent = <&mpic>;
rtc@32 {
device_type = "rtc";
compatible = "ricoh,rs5c372a";
reg = <0x32>;
};

View File

@ -130,7 +130,6 @@
rtc@800 { // Real time clock
compatible = "fsl,mpc5200-rtc";
device_type = "rtc";
reg = <0x800 0x100>;
interrupts = <1 5 0 1 6 0>;
interrupt-parent = <&mpc5200_pic>;

View File

@ -130,7 +130,6 @@
rtc@800 { // Real time clock
compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
device_type = "rtc";
reg = <0x800 0x100>;
interrupts = <1 5 0 1 6 0>;
interrupt-parent = <&mpc5200_pic>;

View File

@ -248,7 +248,6 @@
fsl5200-clocking;
rtc@68 {
device_type = "rtc";
compatible = "dallas,ds1339";
reg = <0x68>;
};

View File

@ -117,7 +117,6 @@
interrupt-parent = <&ipic>;
dfsrr;
rtc@68 {
device_type = "rtc";
compatible = "dallas,ds1339";
reg = <0x68>;
};

View File

@ -85,7 +85,6 @@
dfsrr;
rtc@68 {
device_type = "rtc";
compatible = "dallas,ds1339";
reg = <0x68>;
interrupts = <18 0x8>;

View File

@ -83,7 +83,6 @@
dfsrr;
rtc@68 {
device_type = "rtc";
compatible = "dallas,ds1339";
reg = <0x68>;
interrupts = <18 0x8>;

View File

@ -117,7 +117,6 @@
interrupt-parent = <&ipic>;
dfsrr;
rtc@68 {
device_type = "rtc";
compatible = "dallas,ds1339";
reg = <0x68>;
};

View File

@ -117,7 +117,6 @@
interrupt-parent = <&ipic>;
dfsrr;
rtc@68 {
device_type = "rtc";
compatible = "dallas,ds1339";
reg = <0x68>;
};

View File

@ -117,7 +117,6 @@
interrupt-parent = <&ipic>;
dfsrr;
rtc@68 {
device_type = "rtc";
compatible = "dallas,ds1339";
reg = <0x68>;
};

View File

@ -63,6 +63,119 @@
device_type = "memory";
};
localbus@ffe05000 {
#address-cells = <2>;
#size-cells = <1>;
compatible = "fsl,mpc8572-elbc", "fsl,elbc", "simple-bus";
reg = <0 0xffe05000 0 0x1000>;
interrupts = <19 2>;
interrupt-parent = <&mpic>;
ranges = <0x0 0x0 0x0 0xe8000000 0x08000000
0x1 0x0 0x0 0xe0000000 0x08000000
0x2 0x0 0x0 0xffa00000 0x00040000
0x3 0x0 0x0 0xffdf0000 0x00008000
0x4 0x0 0x0 0xffa40000 0x00040000
0x5 0x0 0x0 0xffa80000 0x00040000
0x6 0x0 0x0 0xffac0000 0x00040000>;
nor@0,0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "cfi-flash";
reg = <0x0 0x0 0x8000000>;
bank-width = <2>;
device-width = <1>;
ramdisk@0 {
reg = <0x0 0x03000000>;
readl-only;
};
diagnostic@3000000 {
reg = <0x03000000 0x00e00000>;
read-only;
};
dink@3e00000 {
reg = <0x03e00000 0x00200000>;
read-only;
};
kernel@4000000 {
reg = <0x04000000 0x00400000>;
read-only;
};
jffs2@4400000 {
reg = <0x04400000 0x03b00000>;
};
dtb@7f00000 {
reg = <0x07f00000 0x00080000>;
read-only;
};
u-boot@7f80000 {
reg = <0x07f80000 0x00080000>;
read-only;
};
};
nand@2,0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,mpc8572-fcm-nand",
"fsl,elbc-fcm-nand";
reg = <0x2 0x0 0x40000>;
u-boot@0 {
reg = <0x0 0x02000000>;
read-only;
};
jffs2@2000000 {
reg = <0x02000000 0x10000000>;
};
ramdisk@12000000 {
reg = <0x12000000 0x08000000>;
read-only;
};
kernel@1a000000 {
reg = <0x1a000000 0x04000000>;
};
dtb@1e000000 {
reg = <0x1e000000 0x01000000>;
read-only;
};
empty@1f000000 {
reg = <0x1f000000 0x21000000>;
};
};
nand@4,0 {
compatible = "fsl,mpc8572-fcm-nand",
"fsl,elbc-fcm-nand";
reg = <0x4 0x0 0x40000>;
};
nand@5,0 {
compatible = "fsl,mpc8572-fcm-nand",
"fsl,elbc-fcm-nand";
reg = <0x5 0x0 0x40000>;
};
nand@6,0 {
compatible = "fsl,mpc8572-fcm-nand",
"fsl,elbc-fcm-nand";
reg = <0x6 0x0 0x40000>;
};
};
soc8572@ffe00000 {
#address-cells = <1>;
#size-cells = <1>;

View File

@ -0,0 +1,483 @@
/*
* MPC8572 DS Core0 Device Tree Source in CAMP mode.
*
* In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
* can be shared, all the other devices must be assigned to one core only.
* This dts file allows core0 to have memory, l2, i2c, dma1, global-util, eth0,
* eth1, crypto, pci0, pci1.
*
* Copyright 2007, 2008 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.
*/
/dts-v1/;
/ {
model = "fsl,MPC8572DS";
compatible = "fsl,MPC8572DS", "fsl,MPC8572DS-CAMP";
#address-cells = <1>;
#size-cells = <1>;
aliases {
ethernet0 = &enet0;
ethernet1 = &enet1;
serial0 = &serial0;
pci0 = &pci0;
pci1 = &pci1;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
PowerPC,8572@0 {
device_type = "cpu";
reg = <0x0>;
d-cache-line-size = <32>; // 32 bytes
i-cache-line-size = <32>; // 32 bytes
d-cache-size = <0x8000>; // L1, 32K
i-cache-size = <0x8000>; // L1, 32K
timebase-frequency = <0>;
bus-frequency = <0>;
clock-frequency = <0>;
next-level-cache = <&L2>;
};
};
memory {
device_type = "memory";
reg = <0x0 0x0>; // Filled by U-Boot
};
soc8572@ffe00000 {
#address-cells = <1>;
#size-cells = <1>;
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0xffe00000 0x100000>;
reg = <0xffe00000 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed
bus-frequency = <0>; // Filled out by uboot.
memory-controller@2000 {
compatible = "fsl,mpc8572-memory-controller";
reg = <0x2000 0x1000>;
interrupt-parent = <&mpic>;
interrupts = <18 2>;
};
memory-controller@6000 {
compatible = "fsl,mpc8572-memory-controller";
reg = <0x6000 0x1000>;
interrupt-parent = <&mpic>;
interrupts = <18 2>;
};
L2: l2-cache-controller@20000 {
compatible = "fsl,mpc8572-l2-cache-controller";
reg = <0x20000 0x1000>;
cache-line-size = <32>; // 32 bytes
cache-size = <0x80000>; // L2, 512K
interrupt-parent = <&mpic>;
interrupts = <16 2>;
};
i2c@3000 {
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
compatible = "fsl-i2c";
reg = <0x3000 0x100>;
interrupts = <43 2>;
interrupt-parent = <&mpic>;
dfsrr;
};
i2c@3100 {
#address-cells = <1>;
#size-cells = <0>;
cell-index = <1>;
compatible = "fsl-i2c";
reg = <0x3100 0x100>;
interrupts = <43 2>;
interrupt-parent = <&mpic>;
dfsrr;
};
dma@21300 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,mpc8572-dma", "fsl,eloplus-dma";
reg = <0x21300 0x4>;
ranges = <0x0 0x21100 0x200>;
cell-index = <0>;
dma-channel@0 {
compatible = "fsl,mpc8572-dma-channel",
"fsl,eloplus-dma-channel";
reg = <0x0 0x80>;
cell-index = <0>;
interrupt-parent = <&mpic>;
interrupts = <20 2>;
};
dma-channel@80 {
compatible = "fsl,mpc8572-dma-channel",
"fsl,eloplus-dma-channel";
reg = <0x80 0x80>;
cell-index = <1>;
interrupt-parent = <&mpic>;
interrupts = <21 2>;
};
dma-channel@100 {
compatible = "fsl,mpc8572-dma-channel",
"fsl,eloplus-dma-channel";
reg = <0x100 0x80>;
cell-index = <2>;
interrupt-parent = <&mpic>;
interrupts = <22 2>;
};
dma-channel@180 {
compatible = "fsl,mpc8572-dma-channel",
"fsl,eloplus-dma-channel";
reg = <0x180 0x80>;
cell-index = <3>;
interrupt-parent = <&mpic>;
interrupts = <23 2>;
};
};
mdio@24520 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,gianfar-mdio";
reg = <0x24520 0x20>;
phy0: ethernet-phy@0 {
interrupt-parent = <&mpic>;
interrupts = <10 1>;
reg = <0x0>;
};
phy1: ethernet-phy@1 {
interrupt-parent = <&mpic>;
interrupts = <10 1>;
reg = <0x1>;
};
};
enet0: ethernet@24000 {
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
phy-handle = <&phy0>;
phy-connection-type = "rgmii-id";
};
enet1: ethernet@25000 {
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
phy-handle = <&phy1>;
phy-connection-type = "rgmii-id";
};
serial0: serial@4500 {
cell-index = <0>;
device_type = "serial";
compatible = "ns16550";
reg = <0x4500 0x100>;
clock-frequency = <0>;
};
global-utilities@e0000 { //global utilities block
compatible = "fsl,mpc8572-guts";
reg = <0xe0000 0x1000>;
fsl,has-rstcr;
};
crypto@30000 {
compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2",
"fsl,sec2.1", "fsl,sec2.0";
reg = <0x30000 0x10000>;
interrupts = <45 2 58 2>;
interrupt-parent = <&mpic>;
fsl,num-channels = <4>;
fsl,channel-fifo-len = <24>;
fsl,exec-units-mask = <0x9fe>;
fsl,descriptor-types-mask = <0x3ab0ebf>;
};
mpic: pic@40000 {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <2>;
reg = <0x40000 0x40000>;
compatible = "chrp,open-pic";
device_type = "open-pic";
protected-sources = <
31 32 33 37 38 39 /* enet2 enet3 */
76 77 78 79 27 42 /* dma2 pci2 serial*/
0xe0 0xe1 0xe2 0xe3 /* msi */
0xe4 0xe5 0xe6 0xe7
>;
};
};
pci0: pcie@ffe08000 {
cell-index = <0>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
reg = <0xffe08000 0x1000>;
bus-range = <0 255>;
ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000
0x1000000 0x0 0x0 0xffc00000 0x0 0x10000>;
clock-frequency = <33333333>;
interrupt-parent = <&mpic>;
interrupts = <24 2>;
interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x11 func 0 - PCI slot 1 */
0x8800 0x0 0x0 0x1 &mpic 0x2 0x1
0x8800 0x0 0x0 0x2 &mpic 0x3 0x1
0x8800 0x0 0x0 0x3 &mpic 0x4 0x1
0x8800 0x0 0x0 0x4 &mpic 0x1 0x1
/* IDSEL 0x11 func 1 - PCI slot 1 */
0x8900 0x0 0x0 0x1 &mpic 0x2 0x1
0x8900 0x0 0x0 0x2 &mpic 0x3 0x1
0x8900 0x0 0x0 0x3 &mpic 0x4 0x1
0x8900 0x0 0x0 0x4 &mpic 0x1 0x1
/* IDSEL 0x11 func 2 - PCI slot 1 */
0x8a00 0x0 0x0 0x1 &mpic 0x2 0x1
0x8a00 0x0 0x0 0x2 &mpic 0x3 0x1
0x8a00 0x0 0x0 0x3 &mpic 0x4 0x1
0x8a00 0x0 0x0 0x4 &mpic 0x1 0x1
/* IDSEL 0x11 func 3 - PCI slot 1 */
0x8b00 0x0 0x0 0x1 &mpic 0x2 0x1
0x8b00 0x0 0x0 0x2 &mpic 0x3 0x1
0x8b00 0x0 0x0 0x3 &mpic 0x4 0x1
0x8b00 0x0 0x0 0x4 &mpic 0x1 0x1
/* IDSEL 0x11 func 4 - PCI slot 1 */
0x8c00 0x0 0x0 0x1 &mpic 0x2 0x1
0x8c00 0x0 0x0 0x2 &mpic 0x3 0x1
0x8c00 0x0 0x0 0x3 &mpic 0x4 0x1
0x8c00 0x0 0x0 0x4 &mpic 0x1 0x1
/* IDSEL 0x11 func 5 - PCI slot 1 */
0x8d00 0x0 0x0 0x1 &mpic 0x2 0x1
0x8d00 0x0 0x0 0x2 &mpic 0x3 0x1
0x8d00 0x0 0x0 0x3 &mpic 0x4 0x1
0x8d00 0x0 0x0 0x4 &mpic 0x1 0x1
/* IDSEL 0x11 func 6 - PCI slot 1 */
0x8e00 0x0 0x0 0x1 &mpic 0x2 0x1
0x8e00 0x0 0x0 0x2 &mpic 0x3 0x1
0x8e00 0x0 0x0 0x3 &mpic 0x4 0x1
0x8e00 0x0 0x0 0x4 &mpic 0x1 0x1
/* IDSEL 0x11 func 7 - PCI slot 1 */
0x8f00 0x0 0x0 0x1 &mpic 0x2 0x1
0x8f00 0x0 0x0 0x2 &mpic 0x3 0x1
0x8f00 0x0 0x0 0x3 &mpic 0x4 0x1
0x8f00 0x0 0x0 0x4 &mpic 0x1 0x1
/* IDSEL 0x12 func 0 - PCI slot 2 */
0x9000 0x0 0x0 0x1 &mpic 0x3 0x1
0x9000 0x0 0x0 0x2 &mpic 0x4 0x1
0x9000 0x0 0x0 0x3 &mpic 0x1 0x1
0x9000 0x0 0x0 0x4 &mpic 0x2 0x1
/* IDSEL 0x12 func 1 - PCI slot 2 */
0x9100 0x0 0x0 0x1 &mpic 0x3 0x1
0x9100 0x0 0x0 0x2 &mpic 0x4 0x1
0x9100 0x0 0x0 0x3 &mpic 0x1 0x1
0x9100 0x0 0x0 0x4 &mpic 0x2 0x1
/* IDSEL 0x12 func 2 - PCI slot 2 */
0x9200 0x0 0x0 0x1 &mpic 0x3 0x1
0x9200 0x0 0x0 0x2 &mpic 0x4 0x1
0x9200 0x0 0x0 0x3 &mpic 0x1 0x1
0x9200 0x0 0x0 0x4 &mpic 0x2 0x1
/* IDSEL 0x12 func 3 - PCI slot 2 */
0x9300 0x0 0x0 0x1 &mpic 0x3 0x1
0x9300 0x0 0x0 0x2 &mpic 0x4 0x1
0x9300 0x0 0x0 0x3 &mpic 0x1 0x1
0x9300 0x0 0x0 0x4 &mpic 0x2 0x1
/* IDSEL 0x12 func 4 - PCI slot 2 */
0x9400 0x0 0x0 0x1 &mpic 0x3 0x1
0x9400 0x0 0x0 0x2 &mpic 0x4 0x1
0x9400 0x0 0x0 0x3 &mpic 0x1 0x1
0x9400 0x0 0x0 0x4 &mpic 0x2 0x1
/* IDSEL 0x12 func 5 - PCI slot 2 */
0x9500 0x0 0x0 0x1 &mpic 0x3 0x1
0x9500 0x0 0x0 0x2 &mpic 0x4 0x1
0x9500 0x0 0x0 0x3 &mpic 0x1 0x1
0x9500 0x0 0x0 0x4 &mpic 0x2 0x1
/* IDSEL 0x12 func 6 - PCI slot 2 */
0x9600 0x0 0x0 0x1 &mpic 0x3 0x1
0x9600 0x0 0x0 0x2 &mpic 0x4 0x1
0x9600 0x0 0x0 0x3 &mpic 0x1 0x1
0x9600 0x0 0x0 0x4 &mpic 0x2 0x1
/* IDSEL 0x12 func 7 - PCI slot 2 */
0x9700 0x0 0x0 0x1 &mpic 0x3 0x1
0x9700 0x0 0x0 0x2 &mpic 0x4 0x1
0x9700 0x0 0x0 0x3 &mpic 0x1 0x1
0x9700 0x0 0x0 0x4 &mpic 0x2 0x1
// IDSEL 0x1c USB
0xe000 0x0 0x0 0x1 &i8259 0xc 0x2
0xe100 0x0 0x0 0x2 &i8259 0x9 0x2
0xe200 0x0 0x0 0x3 &i8259 0xa 0x2
0xe300 0x0 0x0 0x4 &i8259 0xb 0x2
// IDSEL 0x1d Audio
0xe800 0x0 0x0 0x1 &i8259 0x6 0x2
// IDSEL 0x1e Legacy
0xf000 0x0 0x0 0x1 &i8259 0x7 0x2
0xf100 0x0 0x0 0x1 &i8259 0x7 0x2
// IDSEL 0x1f IDE/SATA
0xf800 0x0 0x0 0x1 &i8259 0xe 0x2
0xf900 0x0 0x0 0x1 &i8259 0x5 0x2
>;
pcie@0 {
reg = <0x0 0x0 0x0 0x0 0x0>;
#size-cells = <2>;
#address-cells = <3>;
device_type = "pci";
ranges = <0x2000000 0x0 0x80000000
0x2000000 0x0 0x80000000
0x0 0x20000000
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
uli1575@0 {
reg = <0x0 0x0 0x0 0x0 0x0>;
#size-cells = <2>;
#address-cells = <3>;
ranges = <0x2000000 0x0 0x80000000
0x2000000 0x0 0x80000000
0x0 0x20000000
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
isa@1e {
device_type = "isa";
#interrupt-cells = <2>;
#size-cells = <1>;
#address-cells = <2>;
reg = <0xf000 0x0 0x0 0x0 0x0>;
ranges = <0x1 0x0 0x1000000 0x0 0x0
0x1000>;
interrupt-parent = <&i8259>;
i8259: interrupt-controller@20 {
reg = <0x1 0x20 0x2
0x1 0xa0 0x2
0x1 0x4d0 0x2>;
interrupt-controller;
device_type = "interrupt-controller";
#address-cells = <0>;
#interrupt-cells = <2>;
compatible = "chrp,iic";
interrupts = <9 2>;
interrupt-parent = <&mpic>;
};
i8042@60 {
#size-cells = <0>;
#address-cells = <1>;
reg = <0x1 0x60 0x1 0x1 0x64 0x1>;
interrupts = <1 3 12 3>;
interrupt-parent =
<&i8259>;
keyboard@0 {
reg = <0x0>;
compatible = "pnpPNP,303";
};
mouse@1 {
reg = <0x1>;
compatible = "pnpPNP,f03";
};
};
rtc@70 {
compatible = "pnpPNP,b00";
reg = <0x1 0x70 0x2>;
};
gpio@400 {
reg = <0x1 0x400 0x80>;
};
};
};
};
};
pci1: pcie@ffe09000 {
cell-index = <1>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
reg = <0xffe09000 0x1000>;
bus-range = <0 255>;
ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
0x1000000 0x0 0x0 0xffc10000 0x0 0x10000>;
clock-frequency = <33333333>;
interrupt-parent = <&mpic>;
interrupts = <26 2>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x0 */
0000 0x0 0x0 0x1 &mpic 0x4 0x1
0000 0x0 0x0 0x2 &mpic 0x5 0x1
0000 0x0 0x0 0x3 &mpic 0x6 0x1
0000 0x0 0x0 0x4 &mpic 0x7 0x1
>;
pcie@0 {
reg = <0x0 0x0 0x0 0x0 0x0>;
#size-cells = <2>;
#address-cells = <3>;
device_type = "pci";
ranges = <0x2000000 0x0 0xa0000000
0x2000000 0x0 0xa0000000
0x0 0x20000000
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
};
};
};

View File

@ -0,0 +1,234 @@
/*
* MPC8572 DS Core1 Device Tree Source in CAMP mode.
*
* In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
* can be shared, all the other devices must be assigned to one core only.
* This dts allows core1 to have l2, dma2, eth2, eth3, pci2, msi.
*
* Please note to add "-b 1" for core1's dts compiling.
*
* Copyright 2007, 2008 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.
*/
/dts-v1/;
/ {
model = "fsl,MPC8572DS";
compatible = "fsl,MPC8572DS", "fsl,MPC8572DS-CAMP";
#address-cells = <1>;
#size-cells = <1>;
aliases {
ethernet2 = &enet2;
ethernet3 = &enet3;
serial0 = &serial0;
pci2 = &pci2;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
PowerPC,8572@1 {
device_type = "cpu";
reg = <0x1>;
d-cache-line-size = <32>; // 32 bytes
i-cache-line-size = <32>; // 32 bytes
d-cache-size = <0x8000>; // L1, 32K
i-cache-size = <0x8000>; // L1, 32K
timebase-frequency = <0>;
bus-frequency = <0>;
clock-frequency = <0>;
next-level-cache = <&L2>;
};
};
memory {
device_type = "memory";
reg = <0x0 0x0>; // Filled by U-Boot
};
soc8572@ffe00000 {
#address-cells = <1>;
#size-cells = <1>;
device_type = "soc";
compatible = "simple-bus";
ranges = <0x0 0xffe00000 0x100000>;
reg = <0xffe00000 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed
bus-frequency = <0>; // Filled out by uboot.
L2: l2-cache-controller@20000 {
compatible = "fsl,mpc8572-l2-cache-controller";
reg = <0x20000 0x1000>;
cache-line-size = <32>; // 32 bytes
cache-size = <0x80000>; // L2, 512K
interrupt-parent = <&mpic>;
};
dma@c300 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,mpc8572-dma", "fsl,eloplus-dma";
reg = <0xc300 0x4>;
ranges = <0x0 0xc100 0x200>;
cell-index = <0>;
dma-channel@0 {
compatible = "fsl,mpc8572-dma-channel",
"fsl,eloplus-dma-channel";
reg = <0x0 0x80>;
cell-index = <0>;
interrupt-parent = <&mpic>;
interrupts = <76 2>;
};
dma-channel@80 {
compatible = "fsl,mpc8572-dma-channel",
"fsl,eloplus-dma-channel";
reg = <0x80 0x80>;
cell-index = <1>;
interrupt-parent = <&mpic>;
interrupts = <77 2>;
};
dma-channel@100 {
compatible = "fsl,mpc8572-dma-channel",
"fsl,eloplus-dma-channel";
reg = <0x100 0x80>;
cell-index = <2>;
interrupt-parent = <&mpic>;
interrupts = <78 2>;
};
dma-channel@180 {
compatible = "fsl,mpc8572-dma-channel",
"fsl,eloplus-dma-channel";
reg = <0x180 0x80>;
cell-index = <3>;
interrupt-parent = <&mpic>;
interrupts = <79 2>;
};
};
mdio@24520 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,gianfar-mdio";
reg = <0x24520 0x20>;
phy2: ethernet-phy@2 {
interrupt-parent = <&mpic>;
reg = <0x2>;
};
phy3: ethernet-phy@3 {
interrupt-parent = <&mpic>;
reg = <0x3>;
};
};
enet2: ethernet@26000 {
cell-index = <2>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x26000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <31 2 32 2 33 2>;
interrupt-parent = <&mpic>;
phy-handle = <&phy2>;
phy-connection-type = "rgmii-id";
};
enet3: ethernet@27000 {
cell-index = <3>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x27000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <37 2 38 2 39 2>;
interrupt-parent = <&mpic>;
phy-handle = <&phy3>;
phy-connection-type = "rgmii-id";
};
msi@41600 {
compatible = "fsl,mpc8572-msi", "fsl,mpic-msi";
reg = <0x41600 0x80>;
msi-available-ranges = <0 0x100>;
interrupts = <
0xe0 0
0xe1 0
0xe2 0
0xe3 0
0xe4 0
0xe5 0
0xe6 0
0xe7 0>;
interrupt-parent = <&mpic>;
};
serial0: serial@4600 {
cell-index = <1>;
device_type = "serial";
compatible = "ns16550";
reg = <0x4600 0x100>;
clock-frequency = <0>;
};
mpic: pic@40000 {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <2>;
reg = <0x40000 0x40000>;
compatible = "chrp,open-pic";
device_type = "open-pic";
protected-sources = <
18 16 10 42 45 58 /* MEM L2 mdio serial crypto */
29 30 34 35 36 40 /* enet0 enet1 */
24 26 20 21 22 23 /* pcie0 pcie1 dma1 */
43 /* i2c */
0x1 0x2 0x3 0x4 /* pci slot */
0x9 0xa 0xb 0xc /* usb */
0x6 0x7 0xe 0x5 /* Audio elgacy SATA */
>;
};
};
pci2: pcie@ffe0a000 {
cell-index = <2>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
reg = <0xffe0a000 0x1000>;
bus-range = <0 255>;
ranges = <0x2000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000
0x1000000 0x0 0x0 0xffc20000 0x0 0x10000>;
clock-frequency = <33333333>;
interrupt-parent = <&mpic>;
interrupts = <27 2>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x0 */
0000 0x0 0x0 0x1 &mpic 0x0 0x1
0000 0x0 0x0 0x2 &mpic 0x1 0x1
0000 0x0 0x0 0x3 &mpic 0x2 0x1
0000 0x0 0x0 0x4 &mpic 0x3 0x1
>;
pcie@0 {
reg = <0x0 0x0 0x0 0x0 0x0>;
#size-cells = <2>;
#address-cells = <3>;
device_type = "pci";
ranges = <0x2000000 0x0 0xc0000000
0x2000000 0x0 0xc0000000
0x0 0x20000000
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
};
};
};

View File

@ -143,7 +143,6 @@
rtc@800 { // Real time clock
compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
device_type = "rtc";
reg = <0x800 0x100>;
interrupts = <0x1 0x5 0x0 0x1 0x6 0x0>;
interrupt-parent = <&mpc5200_pic>;
@ -301,7 +300,6 @@
interrupt-parent = <&mpc5200_pic>;
fsl5200-clocking;
rtc@51 {
device_type = "rtc";
compatible = "nxp,pcf8563";
reg = <0x51>;
};

View File

@ -181,7 +181,6 @@
fsl5200-clocking;
rtc@68 {
device_type = "rtc";
compatible = "dallas,ds1307";
reg = <0x68>;
};

View File

@ -185,7 +185,7 @@ void fdt_init(void *blob)
/* Make sure the dt blob is the right version and so forth */
fdt = blob;
bufsize = fdt_totalsize(fdt) + 4;
bufsize = fdt_totalsize(fdt) + EXPAND_GRANULARITY;
buf = malloc(bufsize);
if(!buf)
fatal("malloc failed. can't relocate the device tree\n\r");

View File

@ -1397,8 +1397,11 @@ CONFIG_USB_STORAGE=y
# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
CONFIG_RTC_LIB=m
CONFIG_RTC_CLASS=m
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
# CONFIG_RTC_DEBUG is not set
#
# RTC interfaces
@ -1424,6 +1427,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
CONFIG_RTC_DRV_RX8581=y
#
# SPI RTC drivers

View File

@ -267,7 +267,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
@ -354,7 +354,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_IP_SCTP is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
CONFIG_BRIDGE=m
# CONFIG_NET_DSA is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
@ -579,7 +579,7 @@ CONFIG_NETDEVICES=y
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
CONFIG_TUN=m
# CONFIG_VETH is not set
# CONFIG_ARCNET is not set
# CONFIG_PHYLIB is not set
@ -1001,11 +1001,11 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_TMC is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
#
#
# may also be needed; see USB_STORAGE Help for more information
# see USB_STORAGE Help for more information
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
@ -1418,6 +1418,6 @@ CONFIG_CRYPTO_LZO=m
# CONFIG_PPC_CLOCK is not set
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=y
CONFIG_KVM_BOOKE_HOST=y
CONFIG_KVM_440=y
# CONFIG_VIRTIO_PCI is not set
# CONFIG_VIRTIO_BALLOON is not set

View File

@ -111,7 +111,7 @@ static __inline__ void atomic_inc(atomic_t *v)
bne- 1b"
: "=&r" (t), "+m" (v->counter)
: "r" (&v->counter)
: "cc");
: "cc", "xer");
}
static __inline__ int atomic_inc_return(atomic_t *v)
@ -128,7 +128,7 @@ static __inline__ int atomic_inc_return(atomic_t *v)
ISYNC_ON_SMP
: "=&r" (t)
: "r" (&v->counter)
: "cc", "memory");
: "cc", "xer", "memory");
return t;
}
@ -155,7 +155,7 @@ static __inline__ void atomic_dec(atomic_t *v)
bne- 1b"
: "=&r" (t), "+m" (v->counter)
: "r" (&v->counter)
: "cc");
: "cc", "xer");
}
static __inline__ int atomic_dec_return(atomic_t *v)
@ -172,7 +172,7 @@ static __inline__ int atomic_dec_return(atomic_t *v)
ISYNC_ON_SMP
: "=&r" (t)
: "r" (&v->counter)
: "cc", "memory");
: "cc", "xer", "memory");
return t;
}
@ -346,7 +346,7 @@ static __inline__ void atomic64_inc(atomic64_t *v)
bne- 1b"
: "=&r" (t), "+m" (v->counter)
: "r" (&v->counter)
: "cc");
: "cc", "xer");
}
static __inline__ long atomic64_inc_return(atomic64_t *v)
@ -362,7 +362,7 @@ static __inline__ long atomic64_inc_return(atomic64_t *v)
ISYNC_ON_SMP
: "=&r" (t)
: "r" (&v->counter)
: "cc", "memory");
: "cc", "xer", "memory");
return t;
}
@ -388,7 +388,7 @@ static __inline__ void atomic64_dec(atomic64_t *v)
bne- 1b"
: "=&r" (t), "+m" (v->counter)
: "r" (&v->counter)
: "cc");
: "cc", "xer");
}
static __inline__ long atomic64_dec_return(atomic64_t *v)
@ -404,7 +404,7 @@ static __inline__ long atomic64_dec_return(atomic64_t *v)
ISYNC_ON_SMP
: "=&r" (t)
: "r" (&v->counter)
: "cc", "memory");
: "cc", "xer", "memory");
return t;
}
@ -431,7 +431,7 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
"\n\
2:" : "=&r" (t)
: "r" (&v->counter)
: "cc", "memory");
: "cc", "xer", "memory");
return t;
}

View File

@ -3,6 +3,7 @@
#ifdef __KERNEL__
#include <asm/asm-compat.h>
/*
* Define an illegal instr to trap on the bug.
* We don't use 0 because that marks the end of a function
@ -14,6 +15,7 @@
#ifdef CONFIG_BUG
#ifdef __ASSEMBLY__
#include <asm/asm-offsets.h>
#ifdef CONFIG_DEBUG_BUGVERBOSE
.macro EMIT_BUG_ENTRY addr,file,line,flags
.section __bug_table,"a"
@ -26,7 +28,7 @@
.previous
.endm
#else
.macro EMIT_BUG_ENTRY addr,file,line,flags
.macro EMIT_BUG_ENTRY addr,file,line,flags
.section __bug_table,"a"
5001: PPC_LONG \addr
.short \flags
@ -113,6 +115,13 @@
#define HAVE_ARCH_BUG_ON
#define HAVE_ARCH_WARN_ON
#endif /* __ASSEMBLY __ */
#else
#ifdef __ASSEMBLY__
.macro EMIT_BUG_ENTRY addr,file,line,flags
.endm
#else /* !__ASSEMBLY__ */
#define _EMIT_BUG_ENTRY
#endif
#endif /* CONFIG_BUG */
#include <asm-generic/bug.h>

View File

@ -11,6 +11,8 @@
#include <asm/types.h>
#include <linux/compiler.h>
#define __BIG_ENDIAN
#ifdef __GNUC__
#ifdef __KERNEL__
@ -21,12 +23,19 @@ static __inline__ __u16 ld_le16(const volatile __u16 *addr)
__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
return val;
}
#define __arch_swab16p ld_le16
static __inline__ void st_le16(volatile __u16 *addr, const __u16 val)
{
__asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
}
static inline void __arch_swab16s(__u16 *addr)
{
st_le16(addr, *addr);
}
#define __arch_swab16s __arch_swab16s
static __inline__ __u32 ld_le32(const volatile __u32 *addr)
{
__u32 val;
@ -34,13 +43,20 @@ static __inline__ __u32 ld_le32(const volatile __u32 *addr)
__asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
return val;
}
#define __arch_swab32p ld_le32
static __inline__ void st_le32(volatile __u32 *addr, const __u32 val)
{
__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
}
static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
static inline void __arch_swab32s(__u32 *addr)
{
st_le32(addr, *addr);
}
#define __arch_swab32s __arch_swab32s
static inline __attribute_const__ __u16 __arch_swab16(__u16 value)
{
__u16 result;
@ -49,8 +65,9 @@ static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
: "r" (value), "0" (value >> 8));
return result;
}
#define __arch_swab16 __arch_swab16
static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
static inline __attribute_const__ __u32 __arch_swab32(__u32 value)
{
__u32 result;
@ -61,29 +78,16 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
: "r" (value), "0" (value >> 24));
return result;
}
#define __arch__swab16(x) ___arch__swab16(x)
#define __arch__swab32(x) ___arch__swab32(x)
/* The same, but returns converted value from the location pointer by addr. */
#define __arch__swab16p(addr) ld_le16(addr)
#define __arch__swab32p(addr) ld_le32(addr)
/* The same, but do the conversion in situ, ie. put the value back to addr. */
#define __arch__swab16s(addr) st_le16(addr,*addr)
#define __arch__swab32s(addr) st_le32(addr,*addr)
#define __arch_swab32 __arch_swab32
#endif /* __KERNEL__ */
#ifndef __STRICT_ANSI__
#define __BYTEORDER_HAS_U64__
#ifndef __powerpc64__
#define __SWAB_64_THRU_32__
#endif /* __powerpc64__ */
#endif /* __STRICT_ANSI__ */
#endif /* __GNUC__ */
#include <linux/byteorder/big_endian.h>
#include <linux/byteorder.h>
#endif /* _ASM_POWERPC_BYTEORDER_H */

View File

@ -82,6 +82,7 @@ struct cpu_spec {
char *cpu_name;
unsigned long cpu_features; /* Kernel features */
unsigned int cpu_user_features; /* Userland features */
unsigned int mmu_features; /* MMU features */
/* cache line sizes */
unsigned int icache_bsize;
@ -144,17 +145,14 @@ extern const char *powerpc_base_platform;
#define CPU_FTR_USE_TB ASM_CONST(0x0000000000000040)
#define CPU_FTR_L2CSR ASM_CONST(0x0000000000000080)
#define CPU_FTR_601 ASM_CONST(0x0000000000000100)
#define CPU_FTR_HPTE_TABLE ASM_CONST(0x0000000000000200)
#define CPU_FTR_CAN_NAP ASM_CONST(0x0000000000000400)
#define CPU_FTR_L3CR ASM_CONST(0x0000000000000800)
#define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x0000000000001000)
#define CPU_FTR_NAP_DISABLE_L2_PR ASM_CONST(0x0000000000002000)
#define CPU_FTR_DUAL_PLL_750FX ASM_CONST(0x0000000000004000)
#define CPU_FTR_NO_DPM ASM_CONST(0x0000000000008000)
#define CPU_FTR_HAS_HIGH_BATS ASM_CONST(0x0000000000010000)
#define CPU_FTR_NEED_COHERENT ASM_CONST(0x0000000000020000)
#define CPU_FTR_NO_BTIC ASM_CONST(0x0000000000040000)
#define CPU_FTR_BIG_PHYS ASM_CONST(0x0000000000080000)
#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000000000100000)
#define CPU_FTR_PPC_LE ASM_CONST(0x0000000000200000)
#define CPU_FTR_REAL_LE ASM_CONST(0x0000000000400000)
@ -163,6 +161,8 @@ extern const char *powerpc_base_platform;
#define CPU_FTR_SPE ASM_CONST(0x0000000002000000)
#define CPU_FTR_NEED_PAIRED_STWCX ASM_CONST(0x0000000004000000)
#define CPU_FTR_LWSYNC ASM_CONST(0x0000000008000000)
#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000010000000)
#define CPU_FTR_INDEXED_DCR ASM_CONST(0x0000000020000000)
/*
* Add the 64-bit processor unique features in the top half of the word;
@ -177,7 +177,6 @@ extern const char *powerpc_base_platform;
#define CPU_FTR_SLB LONG_ASM_CONST(0x0000000100000000)
#define CPU_FTR_16M_PAGE LONG_ASM_CONST(0x0000000200000000)
#define CPU_FTR_TLBIEL LONG_ASM_CONST(0x0000000400000000)
#define CPU_FTR_NOEXECUTE LONG_ASM_CONST(0x0000000800000000)
#define CPU_FTR_IABR LONG_ASM_CONST(0x0000002000000000)
#define CPU_FTR_MMCRA LONG_ASM_CONST(0x0000004000000000)
#define CPU_FTR_CTRL LONG_ASM_CONST(0x0000008000000000)
@ -194,6 +193,7 @@ extern const char *powerpc_base_platform;
#define CPU_FTR_VSX LONG_ASM_CONST(0x0010000000000000)
#define CPU_FTR_SAO LONG_ASM_CONST(0x0020000000000000)
#define CPU_FTR_CP_USE_DCBTZ LONG_ASM_CONST(0x0040000000000000)
#define CPU_FTR_UNALIGNED_LD_STD LONG_ASM_CONST(0x0080000000000000)
#ifndef __ASSEMBLY__
@ -264,164 +264,159 @@ extern const char *powerpc_base_platform;
!defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \
!defined(CONFIG_BOOKE))
#define CPU_FTRS_PPC601 (CPU_FTR_COMMON | CPU_FTR_601 | CPU_FTR_HPTE_TABLE | \
#define CPU_FTRS_PPC601 (CPU_FTR_COMMON | CPU_FTR_601 | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE)
#define CPU_FTRS_603 (CPU_FTR_COMMON | \
CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE)
#define CPU_FTRS_604 (CPU_FTR_COMMON | \
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_PPC_LE)
CPU_FTR_USE_TB | CPU_FTR_PPC_LE)
#define CPU_FTRS_740_NOTAU (CPU_FTR_COMMON | \
CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE)
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE)
#define CPU_FTRS_740 (CPU_FTR_COMMON | \
CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \
CPU_FTR_TAU | CPU_FTR_MAYBE_CAN_NAP | \
CPU_FTR_PPC_LE)
#define CPU_FTRS_750 (CPU_FTR_COMMON | \
CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \
CPU_FTR_TAU | CPU_FTR_MAYBE_CAN_NAP | \
CPU_FTR_PPC_LE)
#define CPU_FTRS_750CL (CPU_FTRS_750 | CPU_FTR_HAS_HIGH_BATS)
#define CPU_FTRS_750CL (CPU_FTRS_750)
#define CPU_FTRS_750FX1 (CPU_FTRS_750 | CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM)
#define CPU_FTRS_750FX2 (CPU_FTRS_750 | CPU_FTR_NO_DPM)
#define CPU_FTRS_750FX (CPU_FTRS_750 | CPU_FTR_DUAL_PLL_750FX | \
CPU_FTR_HAS_HIGH_BATS)
#define CPU_FTRS_750FX (CPU_FTRS_750 | CPU_FTR_DUAL_PLL_750FX)
#define CPU_FTRS_750GX (CPU_FTRS_750FX)
#define CPU_FTRS_7400_NOTAU (CPU_FTR_COMMON | \
CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | \
CPU_FTR_ALTIVEC_COMP | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE)
#define CPU_FTRS_7400 (CPU_FTR_COMMON | \
CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | \
CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE)
#define CPU_FTRS_7450_20 (CPU_FTR_COMMON | \
CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
CPU_FTR_L3CR | CPU_FTR_SPEC7450 | \
CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)
#define CPU_FTRS_7450_21 (CPU_FTR_COMMON | \
CPU_FTR_USE_TB | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
CPU_FTR_L3CR | CPU_FTR_SPEC7450 | \
CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | \
CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)
#define CPU_FTRS_7450_23 (CPU_FTR_COMMON | \
CPU_FTR_USE_TB | CPU_FTR_NEED_PAIRED_STWCX | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
CPU_FTR_L3CR | CPU_FTR_SPEC7450 | \
CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
#define CPU_FTRS_7455_1 (CPU_FTR_COMMON | \
CPU_FTR_USE_TB | CPU_FTR_NEED_PAIRED_STWCX | \
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | \
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS | \
CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
CPU_FTR_SPEC7450 | CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
#define CPU_FTRS_7455_20 (CPU_FTR_COMMON | \
CPU_FTR_USE_TB | CPU_FTR_NEED_PAIRED_STWCX | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
CPU_FTR_L3CR | CPU_FTR_SPEC7450 | \
CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | \
CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS | CPU_FTR_PPC_LE)
CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
#define CPU_FTRS_7455 (CPU_FTR_COMMON | \
CPU_FTR_USE_TB | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
CPU_FTR_L3CR | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR | \
CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)
#define CPU_FTRS_7447_10 (CPU_FTR_COMMON | \
CPU_FTR_USE_TB | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
CPU_FTR_L3CR | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR | \
CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC | CPU_FTR_PPC_LE | \
CPU_FTR_NEED_PAIRED_STWCX)
#define CPU_FTRS_7447 (CPU_FTR_COMMON | \
CPU_FTR_USE_TB | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
CPU_FTR_L3CR | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR | \
CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)
#define CPU_FTRS_7447A (CPU_FTR_COMMON | \
CPU_FTR_USE_TB | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR | \
CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)
#define CPU_FTRS_7448 (CPU_FTR_COMMON | \
CPU_FTR_USE_TB | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR | \
CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)
#define CPU_FTRS_82XX (CPU_FTR_COMMON | \
CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB)
#define CPU_FTRS_G2_LE (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \
CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS)
CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP)
#define CPU_FTRS_E300 (CPU_FTR_MAYBE_CAN_DOZE | \
CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS | \
CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | \
CPU_FTR_COMMON)
#define CPU_FTRS_E300C2 (CPU_FTR_MAYBE_CAN_DOZE | \
CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS | \
CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | \
CPU_FTR_COMMON | CPU_FTR_FPU_UNAVAILABLE)
#define CPU_FTRS_CLASSIC32 (CPU_FTR_COMMON | \
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE)
#define CPU_FTRS_CLASSIC32 (CPU_FTR_COMMON | CPU_FTR_USE_TB)
#define CPU_FTRS_8XX (CPU_FTR_USE_TB)
#define CPU_FTRS_40X (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN)
#define CPU_FTRS_44X (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN)
#define CPU_FTRS_40X (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
#define CPU_FTRS_44X (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
#define CPU_FTRS_440x6 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE | \
CPU_FTR_INDEXED_DCR)
#define CPU_FTRS_E200 (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \
CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \
CPU_FTR_UNIFIED_ID_CACHE)
CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE)
#define CPU_FTRS_E500 (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \
CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN)
CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \
CPU_FTR_NOEXECUTE)
#define CPU_FTRS_E500_2 (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \
CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_BIG_PHYS | \
CPU_FTR_NODSISRALIGN)
CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | \
CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
#define CPU_FTRS_E500MC (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN | \
CPU_FTR_L2CSR | CPU_FTR_LWSYNC)
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \
CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE)
#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
/* 64-bit CPUs */
#define CPU_FTRS_POWER3 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | CPU_FTR_PPC_LE)
CPU_FTR_IABR | CPU_FTR_PPC_LE)
#define CPU_FTRS_RS64 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | \
CPU_FTR_IABR | \
CPU_FTR_MMCRA | CPU_FTR_CTRL)
#define CPU_FTRS_POWER4 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_CP_USE_DCBTZ)
#define CPU_FTRS_PPC970 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA | \
CPU_FTR_CP_USE_DCBTZ)
#define CPU_FTRS_POWER5 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_PURR)
#define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
CPU_FTR_DSCR)
CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD)
#define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
CPU_FTR_DSCR | CPU_FTR_SAO)
#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | \
CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ)
CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ | \
CPU_FTR_UNALIGNED_LD_STD)
#define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
CPU_FTR_PPCAS_ARCH_V2 | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_NO_SLBIE_B)
#define CPU_FTRS_COMPATIBLE (CPU_FTR_USE_TB | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2)
#define CPU_FTRS_COMPATIBLE (CPU_FTR_USE_TB | CPU_FTR_PPCAS_ARCH_V2)
#ifdef __powerpc64__
#define CPU_FTRS_POSSIBLE \
@ -452,7 +447,7 @@ enum {
CPU_FTRS_40X |
#endif
#ifdef CONFIG_44x
CPU_FTRS_44X |
CPU_FTRS_44X | CPU_FTRS_440x6 |
#endif
#ifdef CONFIG_E200
CPU_FTRS_E200 |
@ -492,7 +487,7 @@ enum {
CPU_FTRS_40X &
#endif
#ifdef CONFIG_44x
CPU_FTRS_44X &
CPU_FTRS_44X & CPU_FTRS_440x6 &
#endif
#ifdef CONFIG_E200
CPU_FTRS_E200 &

View File

@ -23,6 +23,7 @@
#ifndef __ASSEMBLY__
#include <linux/spinlock.h>
#include <asm/cputable.h>
typedef struct {
unsigned int base;
@ -39,23 +40,45 @@ static inline bool dcr_map_ok_native(dcr_host_native_t host)
#define dcr_read_native(host, dcr_n) mfdcr(dcr_n + host.base)
#define dcr_write_native(host, dcr_n, value) mtdcr(dcr_n + host.base, value)
/* Device Control Registers */
void __mtdcr(int reg, unsigned int val);
unsigned int __mfdcr(int reg);
/* Table based DCR accessors */
extern void __mtdcr(unsigned int reg, unsigned int val);
extern unsigned int __mfdcr(unsigned int reg);
/* mfdcrx/mtdcrx instruction based accessors. We hand code
* the opcodes in order not to depend on newer binutils
*/
static inline unsigned int mfdcrx(unsigned int reg)
{
unsigned int ret;
asm volatile(".long 0x7c000206 | (%0 << 21) | (%1 << 16)"
: "=r" (ret) : "r" (reg));
return ret;
}
static inline void mtdcrx(unsigned int reg, unsigned int val)
{
asm volatile(".long 0x7c000306 | (%0 << 21) | (%1 << 16)"
: : "r" (val), "r" (reg));
}
#define mfdcr(rn) \
({unsigned int rval; \
if (__builtin_constant_p(rn)) \
if (__builtin_constant_p(rn) && rn < 1024) \
asm volatile("mfdcr %0," __stringify(rn) \
: "=r" (rval)); \
else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR))) \
rval = mfdcrx(rn); \
else \
rval = __mfdcr(rn); \
rval;})
#define mtdcr(rn, v) \
do { \
if (__builtin_constant_p(rn)) \
if (__builtin_constant_p(rn) && rn < 1024) \
asm volatile("mtdcr " __stringify(rn) ",%0" \
: : "r" (v)); \
else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR))) \
mtdcrx(rn, v); \
else \
__mtdcr(rn, v); \
} while (0)
@ -69,8 +92,13 @@ static inline unsigned __mfdcri(int base_addr, int base_data, int reg)
unsigned int val;
spin_lock_irqsave(&dcr_ind_lock, flags);
__mtdcr(base_addr, reg);
val = __mfdcr(base_data);
if (cpu_has_feature(CPU_FTR_INDEXED_DCR)) {
mtdcrx(base_addr, reg);
val = mfdcrx(base_data);
} else {
__mtdcr(base_addr, reg);
val = __mfdcr(base_data);
}
spin_unlock_irqrestore(&dcr_ind_lock, flags);
return val;
}
@ -81,8 +109,13 @@ static inline void __mtdcri(int base_addr, int base_data, int reg,
unsigned long flags;
spin_lock_irqsave(&dcr_ind_lock, flags);
__mtdcr(base_addr, reg);
__mtdcr(base_data, val);
if (cpu_has_feature(CPU_FTR_INDEXED_DCR)) {
mtdcrx(base_addr, reg);
mtdcrx(base_data, val);
} else {
__mtdcr(base_addr, reg);
__mtdcr(base_data, val);
}
spin_unlock_irqrestore(&dcr_ind_lock, flags);
}
@ -93,9 +126,15 @@ static inline void __dcri_clrset(int base_addr, int base_data, int reg,
unsigned int val;
spin_lock_irqsave(&dcr_ind_lock, flags);
__mtdcr(base_addr, reg);
val = (__mfdcr(base_data) & ~clr) | set;
__mtdcr(base_data, val);
if (cpu_has_feature(CPU_FTR_INDEXED_DCR)) {
mtdcrx(base_addr, reg);
val = (mfdcrx(base_data) & ~clr) | set;
mtdcrx(base_data, val);
} else {
__mtdcr(base_addr, reg);
val = (__mfdcr(base_data) & ~clr) | set;
__mtdcr(base_data, val);
}
spin_unlock_irqrestore(&dcr_ind_lock, flags);
}

View File

@ -68,9 +68,9 @@ typedef dcr_host_mmio_t dcr_host_t;
* additional helpers to read the DCR * base from the device-tree
*/
struct device_node;
extern unsigned int dcr_resource_start(struct device_node *np,
extern unsigned int dcr_resource_start(const struct device_node *np,
unsigned int index);
extern unsigned int dcr_resource_len(struct device_node *np,
extern unsigned int dcr_resource_len(const struct device_node *np,
unsigned int index);
#endif /* CONFIG_PPC_DCR */
#endif /* __ASSEMBLY__ */

View File

@ -18,4 +18,16 @@ struct dev_archdata {
void *dma_data;
};
static inline void dev_archdata_set_node(struct dev_archdata *ad,
struct device_node *np)
{
ad->of_node = np;
}
static inline struct device_node *
dev_archdata_get_node(const struct dev_archdata *ad)
{
return ad->of_node;
}
#endif /* _ASM_POWERPC_DEVICE_H */

View File

@ -60,12 +60,6 @@ struct dma_mapping_ops {
dma_addr_t *dma_handle, gfp_t flag);
void (*free_coherent)(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
dma_addr_t (*map_single)(struct device *dev, void *ptr,
size_t size, enum dma_data_direction direction,
struct dma_attrs *attrs);
void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
size_t size, enum dma_data_direction direction,
struct dma_attrs *attrs);
int (*map_sg)(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction direction,
struct dma_attrs *attrs);
@ -82,6 +76,22 @@ struct dma_mapping_ops {
dma_addr_t dma_address, size_t size,
enum dma_data_direction direction,
struct dma_attrs *attrs);
#ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS
void (*sync_single_range_for_cpu)(struct device *hwdev,
dma_addr_t dma_handle, unsigned long offset,
size_t size,
enum dma_data_direction direction);
void (*sync_single_range_for_device)(struct device *hwdev,
dma_addr_t dma_handle, unsigned long offset,
size_t size,
enum dma_data_direction direction);
void (*sync_sg_for_cpu)(struct device *hwdev,
struct scatterlist *sg, int nelems,
enum dma_data_direction direction);
void (*sync_sg_for_device)(struct device *hwdev,
struct scatterlist *sg, int nelems,
enum dma_data_direction direction);
#endif
};
/*
@ -149,10 +159,9 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask)
}
/*
* TODO: map_/unmap_single will ideally go away, to be completely
* replaced by map/unmap_page. Until then, we allow dma_ops to have
* one or the other, or both by checking to see if the specific
* function requested exists; and if not, falling back on the other set.
* map_/unmap_single actually call through to map/unmap_page now that all the
* dma_mapping_ops have been converted over. We just have to get the page and
* offset to pass through to map_page
*/
static inline dma_addr_t dma_map_single_attrs(struct device *dev,
void *cpu_addr,
@ -164,10 +173,6 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev,
BUG_ON(!dma_ops);
if (dma_ops->map_single)
return dma_ops->map_single(dev, cpu_addr, size, direction,
attrs);
return dma_ops->map_page(dev, virt_to_page(cpu_addr),
(unsigned long)cpu_addr % PAGE_SIZE, size,
direction, attrs);
@ -183,11 +188,6 @@ static inline void dma_unmap_single_attrs(struct device *dev,
BUG_ON(!dma_ops);
if (dma_ops->unmap_single) {
dma_ops->unmap_single(dev, dma_addr, size, direction, attrs);
return;
}
dma_ops->unmap_page(dev, dma_addr, size, direction, attrs);
}
@ -201,12 +201,7 @@ static inline dma_addr_t dma_map_page_attrs(struct device *dev,
BUG_ON(!dma_ops);
if (dma_ops->map_page)
return dma_ops->map_page(dev, page, offset, size, direction,
attrs);
return dma_ops->map_single(dev, page_address(page) + offset, size,
direction, attrs);
return dma_ops->map_page(dev, page, offset, size, direction, attrs);
}
static inline void dma_unmap_page_attrs(struct device *dev,
@ -219,12 +214,7 @@ static inline void dma_unmap_page_attrs(struct device *dev,
BUG_ON(!dma_ops);
if (dma_ops->unmap_page) {
dma_ops->unmap_page(dev, dma_address, size, direction, attrs);
return;
}
dma_ops->unmap_single(dev, dma_address, size, direction, attrs);
dma_ops->unmap_page(dev, dma_address, size, direction, attrs);
}
static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
@ -308,48 +298,108 @@ static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
dma_unmap_sg_attrs(dev, sg, nhwentries, direction, NULL);
}
#ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS
static inline void dma_sync_single_for_cpu(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
__dma_sync(bus_to_virt(dma_handle), size, direction);
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
BUG_ON(!dma_ops);
dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0,
size, direction);
}
static inline void dma_sync_single_for_device(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
__dma_sync(bus_to_virt(dma_handle), size, direction);
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
BUG_ON(!dma_ops);
dma_ops->sync_single_range_for_device(dev, dma_handle,
0, size, direction);
}
static inline void dma_sync_sg_for_cpu(struct device *dev,
struct scatterlist *sgl, int nents,
enum dma_data_direction direction)
{
struct scatterlist *sg;
int i;
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
BUG_ON(direction == DMA_NONE);
for_each_sg(sgl, sg, nents, i)
__dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
BUG_ON(!dma_ops);
dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction);
}
static inline void dma_sync_sg_for_device(struct device *dev,
struct scatterlist *sgl, int nents,
enum dma_data_direction direction)
{
struct scatterlist *sg;
int i;
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
BUG_ON(direction == DMA_NONE);
for_each_sg(sgl, sg, nents, i)
__dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
BUG_ON(!dma_ops);
dma_ops->sync_sg_for_device(dev, sgl, nents, direction);
}
static inline void dma_sync_single_range_for_cpu(struct device *dev,
dma_addr_t dma_handle, unsigned long offset, size_t size,
enum dma_data_direction direction)
{
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
BUG_ON(!dma_ops);
dma_ops->sync_single_range_for_cpu(dev, dma_handle,
offset, size, direction);
}
static inline void dma_sync_single_range_for_device(struct device *dev,
dma_addr_t dma_handle, unsigned long offset, size_t size,
enum dma_data_direction direction)
{
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
BUG_ON(!dma_ops);
dma_ops->sync_single_range_for_device(dev, dma_handle, offset,
size, direction);
}
#else /* CONFIG_PPC_NEED_DMA_SYNC_OPS */
static inline void dma_sync_single_for_cpu(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
{
}
static inline void dma_sync_single_for_device(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
{
}
static inline void dma_sync_sg_for_cpu(struct device *dev,
struct scatterlist *sgl, int nents,
enum dma_data_direction direction)
{
}
static inline void dma_sync_sg_for_device(struct device *dev,
struct scatterlist *sgl, int nents,
enum dma_data_direction direction)
{
}
static inline void dma_sync_single_range_for_cpu(struct device *dev,
dma_addr_t dma_handle, unsigned long offset, size_t size,
enum dma_data_direction direction)
{
}
static inline void dma_sync_single_range_for_device(struct device *dev,
dma_addr_t dma_handle, unsigned long offset, size_t size,
enum dma_data_direction direction)
{
}
#endif
static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
#ifdef CONFIG_PPC64
@ -382,22 +432,6 @@ static inline int dma_get_cache_alignment(void)
#endif
}
static inline void dma_sync_single_range_for_cpu(struct device *dev,
dma_addr_t dma_handle, unsigned long offset, size_t size,
enum dma_data_direction direction)
{
/* just sync everything for now */
dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
}
static inline void dma_sync_single_range_for_device(struct device *dev,
dma_addr_t dma_handle, unsigned long offset, size_t size,
enum dma_data_direction direction)
{
/* just sync everything for now */
dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
}
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
{

View File

@ -17,8 +17,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _PPC64_EEH_H
#define _PPC64_EEH_H
#ifndef _POWERPC_EEH_H
#define _POWERPC_EEH_H
#ifdef __KERNEL__
#include <linux/init.h>
@ -110,6 +110,7 @@ static inline void eeh_remove_bus_device(struct pci_dev *dev) { }
#define EEH_IO_ERROR_VALUE(size) (-1UL)
#endif /* CONFIG_EEH */
#ifdef CONFIG_PPC64
/*
* MMIO read/write operations with EEH support.
*/
@ -207,5 +208,6 @@ static inline void eeh_readsl(const volatile void __iomem *addr, void * buf,
eeh_check_failure(addr, *(u32*)buf);
}
#endif /* CONFIG_PPC64 */
#endif /* __KERNEL__ */
#endif /* _PPC64_EEH_H */
#endif /* _POWERPC_EEH_H */

View File

@ -81,6 +81,36 @@ label##5: \
#define ALT_FTR_SECTION_END_IFCLR(msk) \
ALT_FTR_SECTION_END_NESTED_IFCLR(msk, 97)
/* MMU feature dependent sections */
#define BEGIN_MMU_FTR_SECTION_NESTED(label) START_FTR_SECTION(label)
#define BEGIN_MMU_FTR_SECTION START_FTR_SECTION(97)
#define END_MMU_FTR_SECTION_NESTED(msk, val, label) \
FTR_SECTION_ELSE_NESTED(label) \
MAKE_FTR_SECTION_ENTRY(msk, val, label, __mmu_ftr_fixup)
#define END_MMU_FTR_SECTION(msk, val) \
END_MMU_FTR_SECTION_NESTED(msk, val, 97)
#define END_MMU_FTR_SECTION_IFSET(msk) END_MMU_FTR_SECTION((msk), (msk))
#define END_MMU_FTR_SECTION_IFCLR(msk) END_MMU_FTR_SECTION((msk), 0)
/* MMU feature sections with alternatives, use BEGIN_FTR_SECTION to start */
#define MMU_FTR_SECTION_ELSE_NESTED(label) FTR_SECTION_ELSE_NESTED(label)
#define MMU_FTR_SECTION_ELSE MMU_FTR_SECTION_ELSE_NESTED(97)
#define ALT_MMU_FTR_SECTION_END_NESTED(msk, val, label) \
MAKE_FTR_SECTION_ENTRY(msk, val, label, __mmu_ftr_fixup)
#define ALT_MMU_FTR_SECTION_END_NESTED_IFSET(msk, label) \
ALT_MMU_FTR_SECTION_END_NESTED(msk, msk, label)
#define ALT_MMU_FTR_SECTION_END_NESTED_IFCLR(msk, label) \
ALT_MMU_FTR_SECTION_END_NESTED(msk, 0, label)
#define ALT_MMU_FTR_SECTION_END(msk, val) \
ALT_MMU_FTR_SECTION_END_NESTED(msk, val, 97)
#define ALT_MMU_FTR_SECTION_END_IFSET(msk) \
ALT_MMU_FTR_SECTION_END_NESTED_IFSET(msk, 97)
#define ALT_MMU_FTR_SECTION_END_IFCLR(msk) \
ALT_MMU_FTR_SECTION_END_NESTED_IFCLR(msk, 97)
/* Firmware feature dependent sections */
#define BEGIN_FW_FTR_SECTION_NESTED(label) START_FTR_SECTION(label)
#define BEGIN_FW_FTR_SECTION START_FTR_SECTION(97)

View File

@ -38,9 +38,24 @@ extern pte_t *pkmap_page_table;
* easily, subsequent pte tables have to be allocated in one physical
* chunk of RAM.
*/
#define LAST_PKMAP (1 << PTE_SHIFT)
#define LAST_PKMAP_MASK (LAST_PKMAP-1)
/*
* We use one full pte table with 4K pages. And with 16K/64K pages pte
* table covers enough memory (32MB and 512MB resp.) that both FIXMAP
* and PKMAP can be placed in single pte table. We use 1024 pages for
* PKMAP in case of 16K/64K pages.
*/
#ifdef CONFIG_PPC_4K_PAGES
#define PKMAP_ORDER PTE_SHIFT
#else
#define PKMAP_ORDER 10
#endif
#define LAST_PKMAP (1 << PKMAP_ORDER)
#ifndef CONFIG_PPC_4K_PAGES
#define PKMAP_BASE (FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1))
#else
#define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK)
#endif
#define LAST_PKMAP_MASK (LAST_PKMAP-1)
#define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT)
#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
@ -85,7 +100,7 @@ static inline void *kmap_atomic_prot(struct page *page, enum km_type type, pgpro
BUG_ON(!pte_none(*(kmap_pte-idx)));
#endif
__set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot));
flush_tlb_page(NULL, vaddr);
local_flush_tlb_page(NULL, vaddr);
return (void*) vaddr;
}
@ -113,7 +128,7 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type)
* this pte without first remap it
*/
pte_clear(&init_mm, vaddr, kmap_pte-idx);
flush_tlb_page(NULL, vaddr);
local_flush_tlb_page(NULL, vaddr);
#endif
pagefault_enable();
}

View File

@ -713,13 +713,6 @@ static inline void * phys_to_virt(unsigned long address)
*/
#define page_to_phys(page) ((phys_addr_t)page_to_pfn(page) << PAGE_SHIFT)
/* We do NOT want virtual merging, it would put too much pressure on
* our iommu allocator. Instead, we want drivers to be smart enough
* to coalesce sglists that happen to have been mapped in a contiguous
* way by the iommu
*/
#define BIO_VMERGE_BOUNDARY 0
/*
* 32 bits still uses virt_to_bus() for it's implementation of DMA
* mappings se we have to keep it defined here. We also have some old

View File

@ -1,6 +1,8 @@
#ifndef _PPC64_KDUMP_H
#define _PPC64_KDUMP_H
#include <asm/page.h>
/* Kdump kernel runs at 32 MB, change at your peril. */
#define KDUMP_KERNELBASE 0x2000000
@ -11,8 +13,19 @@
#ifdef CONFIG_CRASH_DUMP
/*
* On PPC64 translation is disabled during trampoline setup, so we use
* physical addresses. Though on PPC32 translation is already enabled,
* so we can't do the same. Luckily create_trampoline() creates relative
* branches, so we can just add the PAGE_OFFSET and don't worry about it.
*/
#ifdef __powerpc64__
#define KDUMP_TRAMPOLINE_START 0x0100
#define KDUMP_TRAMPOLINE_END 0x3000
#else
#define KDUMP_TRAMPOLINE_START (0x0100 + PAGE_OFFSET)
#define KDUMP_TRAMPOLINE_END (0x3000 + PAGE_OFFSET)
#endif /* __powerpc64__ */
#define KDUMP_MIN_TCE_ENTRIES 2048

View File

@ -33,12 +33,12 @@
#ifndef __ASSEMBLY__
#include <linux/cpumask.h>
#include <asm/reg.h>
typedef void (*crash_shutdown_t)(void);
#ifdef CONFIG_KEXEC
#ifdef __powerpc64__
/*
* This function is responsible for capturing register states if coming
* via panic or invoking dump using sysrq-trigger.
@ -48,6 +48,7 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
{
if (oldregs)
memcpy(newregs, oldregs, sizeof(*newregs));
#ifdef __powerpc64__
else {
/* FIXME Merge this with xmon_save_regs ?? */
unsigned long tmp1, tmp2;
@ -100,15 +101,11 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
: "b" (newregs)
: "memory");
}
}
#else
/*
* Provide a dummy definition to avoid build failures. Will remain
* empty till crash dump support is enabled.
*/
static inline void crash_setup_regs(struct pt_regs *newregs,
struct pt_regs *oldregs) { }
#endif /* !__powerpc64 __ */
else
ppc_save_regs(newregs);
#endif /* __powerpc64__ */
}
extern void kexec_smp_wait(void); /* get and clear naca physid, wait for
master to copy new code to 0 */

View File

@ -67,7 +67,7 @@ static __inline__ long local_inc_return(local_t *l)
bne- 1b"
: "=&r" (t)
: "r" (&(l->a.counter))
: "cc", "memory");
: "cc", "xer", "memory");
return t;
}
@ -94,7 +94,7 @@ static __inline__ long local_dec_return(local_t *l)
bne- 1b"
: "=&r" (t)
: "r" (&(l->a.counter))
: "cc", "memory");
: "cc", "xer", "memory");
return t;
}

View File

@ -133,7 +133,8 @@ struct lppaca {
//=============================================================================
// CACHE_LINE_4-5 0x0180 - 0x027F Contains PMC interrupt data
//=============================================================================
u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF
u32 page_ins; // CMO Hint - # page ins by OS x00-x04
u8 pmc_save_area[252]; // PMC interrupt Area x04-xFF
} __attribute__((__aligned__(0x400)));
extern struct lppaca lppaca[];

View File

@ -54,8 +54,9 @@
#ifndef __ASSEMBLY__
typedef struct {
unsigned long id;
unsigned long vdso_base;
unsigned int id;
unsigned int active;
unsigned long vdso_base;
} mm_context_t;
#endif /* !__ASSEMBLY__ */

View File

@ -4,6 +4,8 @@
* PPC440 support
*/
#include <asm/page.h>
#define PPC44x_MMUCR_TID 0x000000ff
#define PPC44x_MMUCR_STS 0x00010000
@ -56,8 +58,9 @@
extern unsigned int tlb_44x_hwater;
typedef struct {
unsigned long id;
unsigned long vdso_base;
unsigned int id;
unsigned int active;
unsigned long vdso_base;
} mm_context_t;
#endif /* !__ASSEMBLY__ */
@ -73,4 +76,19 @@ typedef struct {
/* Size of the TLBs used for pinning in lowmem */
#define PPC_PIN_SIZE (1 << 28) /* 256M */
#if (PAGE_SHIFT == 12)
#define PPC44x_TLBE_SIZE PPC44x_TLB_4K
#elif (PAGE_SHIFT == 14)
#define PPC44x_TLBE_SIZE PPC44x_TLB_16K
#elif (PAGE_SHIFT == 16)
#define PPC44x_TLBE_SIZE PPC44x_TLB_64K
#else
#error "Unsupported PAGE_SIZE"
#endif
#define PPC44x_PGD_OFF_SHIFT (32 - PGDIR_SHIFT + PGD_T_LOG2)
#define PPC44x_PGD_OFF_MASK_BIT (PGDIR_SHIFT - PGD_T_LOG2)
#define PPC44x_PTE_ADD_SHIFT (32 - PGDIR_SHIFT + PTE_SHIFT + PTE_T_LOG2)
#define PPC44x_PTE_ADD_MASK_BIT (32 - PTE_T_LOG2 - PTE_SHIFT)
#endif /* _ASM_POWERPC_MMU_44X_H_ */

View File

@ -137,7 +137,8 @@
#ifndef __ASSEMBLY__
typedef struct {
unsigned long id;
unsigned int id;
unsigned int active;
unsigned long vdso_base;
} mm_context_t;
#endif /* !__ASSEMBLY__ */

View File

@ -40,6 +40,8 @@
#define MAS2_M 0x00000004
#define MAS2_G 0x00000002
#define MAS2_E 0x00000001
#define MAS2_EPN_MASK(size) (~0 << (2*(size) + 10))
#define MAS2_VAL(addr, size, flags) ((addr) & MAS2_EPN_MASK(size) | (flags))
#define MAS3_RPN 0xFFFFF000
#define MAS3_U0 0x00000200
@ -74,8 +76,9 @@
#ifndef __ASSEMBLY__
typedef struct {
unsigned long id;
unsigned long vdso_base;
unsigned int id;
unsigned int active;
unsigned long vdso_base;
} mm_context_t;
#endif /* !__ASSEMBLY__ */

View File

@ -2,6 +2,63 @@
#define _ASM_POWERPC_MMU_H_
#ifdef __KERNEL__
#include <asm/asm-compat.h>
#include <asm/feature-fixups.h>
/*
* MMU features bit definitions
*/
/*
* First half is MMU families
*/
#define MMU_FTR_HPTE_TABLE ASM_CONST(0x00000001)
#define MMU_FTR_TYPE_8xx ASM_CONST(0x00000002)
#define MMU_FTR_TYPE_40x ASM_CONST(0x00000004)
#define MMU_FTR_TYPE_44x ASM_CONST(0x00000008)
#define MMU_FTR_TYPE_FSL_E ASM_CONST(0x00000010)
/*
* This is individual features
*/
/* Enable use of high BAT registers */
#define MMU_FTR_USE_HIGH_BATS ASM_CONST(0x00010000)
/* Enable >32-bit physical addresses on 32-bit processor, only used
* by CONFIG_6xx currently as BookE supports that from day 1
*/
#define MMU_FTR_BIG_PHYS ASM_CONST(0x00020000)
/* Enable use of broadcast TLB invalidations. We don't always set it
* on processors that support it due to other constraints with the
* use of such invalidations
*/
#define MMU_FTR_USE_TLBIVAX_BCAST ASM_CONST(0x00040000)
/* Enable use of tlbilx invalidate-by-PID variant.
*/
#define MMU_FTR_USE_TLBILX_PID ASM_CONST(0x00080000)
/* This indicates that the processor cannot handle multiple outstanding
* broadcast tlbivax or tlbsync. This makes the code use a spinlock
* around such invalidate forms.
*/
#define MMU_FTR_LOCK_BCAST_INVAL ASM_CONST(0x00100000)
#ifndef __ASSEMBLY__
#include <asm/cputable.h>
static inline int mmu_has_feature(unsigned long feature)
{
return (cur_cpu_spec->mmu_features & feature);
}
extern unsigned int __start___mmu_ftr_fixup, __stop___mmu_ftr_fixup;
#endif /* !__ASSEMBLY__ */
#ifdef CONFIG_PPC64
/* 64-bit classic hash table MMU */
# include <asm/mmu-hash64.h>

View File

@ -2,237 +2,26 @@
#define __ASM_POWERPC_MMU_CONTEXT_H
#ifdef __KERNEL__
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <asm/mmu.h>
#include <asm/cputable.h>
#include <asm-generic/mm_hooks.h>
#ifndef CONFIG_PPC64
#include <asm/atomic.h>
#include <linux/bitops.h>
#include <asm/cputhreads.h>
/*
* On 32-bit PowerPC 6xx/7xx/7xxx CPUs, we use a set of 16 VSIDs
* (virtual segment identifiers) for each context. Although the
* hardware supports 24-bit VSIDs, and thus >1 million contexts,
* we only use 32,768 of them. That is ample, since there can be
* at most around 30,000 tasks in the system anyway, and it means
* that we can use a bitmap to indicate which contexts are in use.
* Using a bitmap means that we entirely avoid all of the problems
* that we used to have when the context number overflowed,
* particularly on SMP systems.
* -- paulus.
* Most if the context management is out of line
*/
/*
* This function defines the mapping from contexts to VSIDs (virtual
* segment IDs). We use a skew on both the context and the high 4 bits
* of the 32-bit virtual address (the "effective segment ID") in order
* to spread out the entries in the MMU hash table. Note, if this
* function is changed then arch/ppc/mm/hashtable.S will have to be
* changed to correspond.
*/
#define CTX_TO_VSID(ctx, va) (((ctx) * (897 * 16) + ((va) >> 28) * 0x111) \
& 0xffffff)
/*
The MPC8xx has only 16 contexts. We rotate through them on each
task switch. A better way would be to keep track of tasks that
own contexts, and implement an LRU usage. That way very active
tasks don't always have to pay the TLB reload overhead. The
kernel pages are mapped shared, so the kernel can run on behalf
of any task that makes a kernel entry. Shared does not mean they
are not protected, just that the ASID comparison is not performed.
-- Dan
The IBM4xx has 256 contexts, so we can just rotate through these
as a way of "switching" contexts. If the TID of the TLB is zero,
the PID/TID comparison is disabled, so we can use a TID of zero
to represent all kernel pages as shared among all contexts.
-- Dan
*/
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
{
}
#ifdef CONFIG_8xx
#define NO_CONTEXT 16
#define LAST_CONTEXT 15
#define FIRST_CONTEXT 0
#elif defined(CONFIG_4xx)
#define NO_CONTEXT 256
#define LAST_CONTEXT 255
#define FIRST_CONTEXT 1
#elif defined(CONFIG_E200) || defined(CONFIG_E500)
#define NO_CONTEXT 256
#define LAST_CONTEXT 255
#define FIRST_CONTEXT 1
#else
/* PPC 6xx, 7xx CPUs */
#define NO_CONTEXT ((unsigned long) -1)
#define LAST_CONTEXT 32767
#define FIRST_CONTEXT 1
#endif
/*
* Set the current MMU context.
* On 32-bit PowerPCs (other than the 8xx embedded chips), this is done by
* loading up the segment registers for the user part of the address space.
*
* Since the PGD is immediately available, it is much faster to simply
* pass this along as a second parameter, which is required for 8xx and
* can be used for debugging on all processors (if you happen to have
* an Abatron).
*/
extern void set_context(unsigned long contextid, pgd_t *pgd);
/*
* Bitmap of contexts in use.
* The size of this bitmap is LAST_CONTEXT + 1 bits.
*/
extern unsigned long context_map[];
/*
* This caches the next context number that we expect to be free.
* Its use is an optimization only, we can't rely on this context
* number to be free, but it usually will be.
*/
extern unsigned long next_mmu_context;
/*
* If we don't have sufficient contexts to give one to every task
* that could be in the system, we need to be able to steal contexts.
* These variables support that.
*/
#if LAST_CONTEXT < 30000
#define FEW_CONTEXTS 1
extern atomic_t nr_free_contexts;
extern struct mm_struct *context_mm[LAST_CONTEXT+1];
extern void steal_context(void);
#endif
/*
* Get a new mmu context for the address space described by `mm'.
*/
static inline void get_mmu_context(struct mm_struct *mm)
{
unsigned long ctx;
if (mm->context.id != NO_CONTEXT)
return;
#ifdef FEW_CONTEXTS
while (atomic_dec_if_positive(&nr_free_contexts) < 0)
steal_context();
#endif
ctx = next_mmu_context;
while (test_and_set_bit(ctx, context_map)) {
ctx = find_next_zero_bit(context_map, LAST_CONTEXT+1, ctx);
if (ctx > LAST_CONTEXT)
ctx = 0;
}
next_mmu_context = (ctx + 1) & LAST_CONTEXT;
mm->context.id = ctx;
#ifdef FEW_CONTEXTS
context_mm[ctx] = mm;
#endif
}
/*
* Set up the context for a new address space.
*/
static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
{
mm->context.id = NO_CONTEXT;
return 0;
}
/*
* We're finished using the context for an address space.
*/
static inline void destroy_context(struct mm_struct *mm)
{
preempt_disable();
if (mm->context.id != NO_CONTEXT) {
clear_bit(mm->context.id, context_map);
mm->context.id = NO_CONTEXT;
#ifdef FEW_CONTEXTS
atomic_inc(&nr_free_contexts);
#endif
}
preempt_enable();
}
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk)
{
#ifdef CONFIG_ALTIVEC
if (cpu_has_feature(CPU_FTR_ALTIVEC))
asm volatile ("dssall;\n"
#ifndef CONFIG_POWER4
"sync;\n" /* G4 needs a sync here, G5 apparently not */
#endif
: : );
#endif /* CONFIG_ALTIVEC */
tsk->thread.pgdir = next->pgd;
/* No need to flush userspace segments if the mm doesnt change */
if (prev == next)
return;
/* Setup new userspace context */
get_mmu_context(next);
set_context(next->context.id, next->pgd);
}
#define deactivate_mm(tsk,mm) do { } while (0)
/*
* After we have set current->mm to a new value, this activates
* the context for the new mm so we see the new mappings.
*/
#define activate_mm(active_mm, mm) switch_mm(active_mm, mm, current)
extern void mmu_context_init(void);
#else
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/sched.h>
/*
* Copyright (C) 2001 PPC 64 Team, IBM Corp
*
* 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.
*/
static inline void enter_lazy_tlb(struct mm_struct *mm,
struct task_struct *tsk)
{
}
/*
* The proto-VSID space has 2^35 - 1 segments available for user mappings.
* Each segment contains 2^28 bytes. Each context maps 2^44 bytes,
* so we can support 2^19-1 contexts (19 == 35 + 28 - 44).
*/
#define NO_CONTEXT 0
#define MAX_CONTEXT ((1UL << 19) - 1)
extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
extern void destroy_context(struct mm_struct *mm);
extern void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next);
extern void switch_stab(struct task_struct *tsk, struct mm_struct *mm);
extern void switch_slb(struct task_struct *tsk, struct mm_struct *mm);
extern void set_context(unsigned long id, pgd_t *pgd);
/*
* switch_mm is the entry point called from the architecture independent
@ -241,22 +30,39 @@ extern void switch_slb(struct task_struct *tsk, struct mm_struct *mm);
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk)
{
if (!cpu_isset(smp_processor_id(), next->cpu_vm_mask))
cpu_set(smp_processor_id(), next->cpu_vm_mask);
/* Mark this context has been used on the new CPU */
cpu_set(smp_processor_id(), next->cpu_vm_mask);
/* No need to flush userspace segments if the mm doesnt change */
/* 32-bit keeps track of the current PGDIR in the thread struct */
#ifdef CONFIG_PPC32
tsk->thread.pgdir = next->pgd;
#endif /* CONFIG_PPC32 */
/* Nothing else to do if we aren't actually switching */
if (prev == next)
return;
/* We must stop all altivec streams before changing the HW
* context
*/
#ifdef CONFIG_ALTIVEC
if (cpu_has_feature(CPU_FTR_ALTIVEC))
asm volatile ("dssall");
#endif /* CONFIG_ALTIVEC */
/* The actual HW switching method differs between the various
* sub architectures.
*/
#ifdef CONFIG_PPC_STD_MMU_64
if (cpu_has_feature(CPU_FTR_SLB))
switch_slb(tsk, next);
else
switch_stab(tsk, next);
#else
/* Out of line for now */
switch_mmu_context(prev, next);
#endif
}
#define deactivate_mm(tsk,mm) do { } while (0)
@ -274,6 +80,11 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
local_irq_restore(flags);
}
#endif /* CONFIG_PPC64 */
/* We don't currently use enter_lazy_tlb() for anything */
static inline void enter_lazy_tlb(struct mm_struct *mm,
struct task_struct *tsk)
{
}
#endif /* __KERNEL__ */
#endif /* __ASM_POWERPC_MMU_CONTEXT_H */

View File

@ -239,6 +239,25 @@ struct mpc52xx_cdm {
u16 mclken_div_psc6; /* CDM + 0x36 reg13 byte2,3 */
};
/* Interrupt controller Register set */
struct mpc52xx_intr {
u32 per_mask; /* INTR + 0x00 */
u32 per_pri1; /* INTR + 0x04 */
u32 per_pri2; /* INTR + 0x08 */
u32 per_pri3; /* INTR + 0x0c */
u32 ctrl; /* INTR + 0x10 */
u32 main_mask; /* INTR + 0x14 */
u32 main_pri1; /* INTR + 0x18 */
u32 main_pri2; /* INTR + 0x1c */
u32 reserved1; /* INTR + 0x20 */
u32 enc_status; /* INTR + 0x24 */
u32 crit_status; /* INTR + 0x28 */
u32 main_status; /* INTR + 0x2c */
u32 per_status; /* INTR + 0x30 */
u32 reserved2; /* INTR + 0x34 */
u32 per_error; /* INTR + 0x38 */
};
#endif /* __ASSEMBLY__ */

View File

@ -68,12 +68,20 @@
#define MPC52xx_PSC_IMR_ORERR 0x1000
#define MPC52xx_PSC_IMR_IPC 0x8000
/* PSC input port change bit */
/* PSC input port change bits */
#define MPC52xx_PSC_CTS 0x01
#define MPC52xx_PSC_DCD 0x02
#define MPC52xx_PSC_D_CTS 0x10
#define MPC52xx_PSC_D_DCD 0x20
/* PSC acr bits */
#define MPC52xx_PSC_IEC_CTS 0x01
#define MPC52xx_PSC_IEC_DCD 0x02
/* PSC output port bits */
#define MPC52xx_PSC_OP_RTS 0x01
#define MPC52xx_PSC_OP_RES 0x02
/* PSC mode fields */
#define MPC52xx_PSC_MODE_5_BITS 0x00
#define MPC52xx_PSC_MODE_6_BITS 0x01
@ -91,6 +99,7 @@
#define MPC52xx_PSC_MODE_ONE_STOP_5_BITS 0x00
#define MPC52xx_PSC_MODE_ONE_STOP 0x07
#define MPC52xx_PSC_MODE_TWO_STOP 0x0f
#define MPC52xx_PSC_MODE_TXCTS 0x10
#define MPC52xx_PSC_RFNUM_MASK 0x01ff

View File

@ -1,9 +1,134 @@
/*
* Pull in the generic implementation for the mutex fastpath.
*
* TODO: implement optimized primitives instead, or leave the generic
* implementation in place, or pick the atomic_xchg() based generic
* implementation. (see asm-generic/mutex-xchg.h for details)
* Optimised mutex implementation of include/asm-generic/mutex-dec.h algorithm
*/
#ifndef _ASM_POWERPC_MUTEX_H
#define _ASM_POWERPC_MUTEX_H
#include <asm-generic/mutex-dec.h>
static inline int __mutex_cmpxchg_lock(atomic_t *v, int old, int new)
{
int t;
__asm__ __volatile__ (
"1: lwarx %0,0,%1 # mutex trylock\n\
cmpw 0,%0,%2\n\
bne- 2f\n"
PPC405_ERR77(0,%1)
" stwcx. %3,0,%1\n\
bne- 1b"
ISYNC_ON_SMP
"\n\
2:"
: "=&r" (t)
: "r" (&v->counter), "r" (old), "r" (new)
: "cc", "memory");
return t;
}
static inline int __mutex_dec_return_lock(atomic_t *v)
{
int t;
__asm__ __volatile__(
"1: lwarx %0,0,%1 # mutex lock\n\
addic %0,%0,-1\n"
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1\n\
bne- 1b"
ISYNC_ON_SMP
: "=&r" (t)
: "r" (&v->counter)
: "cc", "memory");
return t;
}
static inline int __mutex_inc_return_unlock(atomic_t *v)
{
int t;
__asm__ __volatile__(
LWSYNC_ON_SMP
"1: lwarx %0,0,%1 # mutex unlock\n\
addic %0,%0,1\n"
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1 \n\
bne- 1b"
: "=&r" (t)
: "r" (&v->counter)
: "cc", "memory");
return t;
}
/**
* __mutex_fastpath_lock - try to take the lock by moving the count
* from 1 to a 0 value
* @count: pointer of type atomic_t
* @fail_fn: function to call if the original value was not 1
*
* Change the count from 1 to a value lower than 1, and call <fail_fn> if
* it wasn't 1 originally. This function MUST leave the value lower than
* 1 even when the "1" assertion wasn't true.
*/
static inline void
__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
{
if (unlikely(__mutex_dec_return_lock(count) < 0))
fail_fn(count);
}
/**
* __mutex_fastpath_lock_retval - try to take the lock by moving the count
* from 1 to a 0 value
* @count: pointer of type atomic_t
* @fail_fn: function to call if the original value was not 1
*
* Change the count from 1 to a value lower than 1, and call <fail_fn> if
* it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
* or anything the slow path function returns.
*/
static inline int
__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
{
if (unlikely(__mutex_dec_return_lock(count) < 0))
return fail_fn(count);
return 0;
}
/**
* __mutex_fastpath_unlock - try to promote the count from 0 to 1
* @count: pointer of type atomic_t
* @fail_fn: function to call if the original value was not 0
*
* Try to promote the count from 0 to 1. If it wasn't 0, call <fail_fn>.
* In the failure case, this function is allowed to either set the value to
* 1, or to set it to a value lower than 1.
*/
static inline void
__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
{
if (unlikely(__mutex_inc_return_unlock(count) <= 0))
fail_fn(count);
}
#define __mutex_slowpath_needs_to_unlock() 1
/**
* __mutex_fastpath_trylock - try to acquire the mutex, without waiting
*
* @count: pointer of type atomic_t
* @fail_fn: fallback function
*
* Change the count from 1 to 0, and return 1 (success), or if the count
* was not 1, then return 0 (failure).
*/
static inline int
__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
{
if (likely(__mutex_cmpxchg_lock(count, 1, 0) == 1))
return 1;
return 0;
}
#endif

View File

@ -19,12 +19,15 @@
#include <asm/kdump.h>
/*
* On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software
* On regular PPC32 page size is 4K (but we support 4K/16K/64K pages
* on PPC44x). For PPC64 we support either 4K or 64K software
* page size. When using 64K pages however, whether we are really supporting
* 64K pages in HW or not is irrelevant to those definitions.
*/
#ifdef CONFIG_PPC_64K_PAGES
#if defined(CONFIG_PPC_64K_PAGES)
#define PAGE_SHIFT 16
#elif defined(CONFIG_PPC_16K_PAGES)
#define PAGE_SHIFT 14
#else
#define PAGE_SHIFT 12
#endif
@ -151,7 +154,7 @@ typedef struct { pte_basic_t pte; } pte_t;
/* 64k pages additionally define a bigger "real PTE" type that gathers
* the "second half" part of the PTE for pseudo 64k pages
*/
#ifdef CONFIG_PPC_64K_PAGES
#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64)
typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
#else
typedef struct { pte_t pte; } real_pte_t;
@ -191,10 +194,10 @@ typedef pte_basic_t pte_t;
#define pte_val(x) (x)
#define __pte(x) (x)
#ifdef CONFIG_PPC_64K_PAGES
#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64)
typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
#else
typedef unsigned long real_pte_t;
typedef pte_t real_pte_t;
#endif

View File

@ -19,6 +19,8 @@
#define PTE_FLAGS_OFFSET 0
#endif
#define PTE_SHIFT (PAGE_SHIFT - PTE_T_LOG2) /* full page */
#ifndef __ASSEMBLY__
/*
* The basic type of a PTE - 64 bits for those CPUs with > 32 bit
@ -26,10 +28,8 @@
*/
#ifdef CONFIG_PTE_64BIT
typedef unsigned long long pte_basic_t;
#define PTE_SHIFT (PAGE_SHIFT - 3) /* 512 ptes per page */
#else
typedef unsigned long pte_basic_t;
#define PTE_SHIFT (PAGE_SHIFT - 2) /* 1024 ptes per page */
#endif
struct page;
@ -39,6 +39,9 @@ extern void copy_page(void *to, void *from);
#include <asm-generic/page.h>
#define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1)
#define PTE_T_LOG2 (__builtin_ffs(sizeof(pte_t)) - 1)
#endif /* __ASSEMBLY__ */
#endif /* _ASM_POWERPC_PAGE_32_H */

View File

@ -13,7 +13,6 @@
struct device_node;
extern unsigned int ppc_pci_flags;
enum {
/* Force re-assigning all resources (ignore firmware
* setup completely)
@ -36,6 +35,31 @@ enum {
/* ... except for domain 0 */
PPC_PCI_COMPAT_DOMAIN_0 = 0x00000020,
};
#ifdef CONFIG_PCI
extern unsigned int ppc_pci_flags;
static inline void ppc_pci_set_flags(int flags)
{
ppc_pci_flags = flags;
}
static inline void ppc_pci_add_flags(int flags)
{
ppc_pci_flags |= flags;
}
static inline int ppc_pci_has_flag(int flag)
{
return (ppc_pci_flags & flag);
}
#else
static inline void ppc_pci_set_flags(int flags) { }
static inline void ppc_pci_add_flags(int flags) { }
static inline int ppc_pci_has_flag(int flag)
{
return 0;
}
#endif
/*
@ -241,9 +265,6 @@ extern void pcibios_remove_pci_devices(struct pci_bus *bus);
/** Discover new pci devices under this bus, and add them */
extern void pcibios_add_pci_devices(struct pci_bus *bus);
extern void pcibios_fixup_new_pci_devices(struct pci_bus *bus);
extern int pcibios_remove_root_bus(struct pci_controller *phb);
static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
{
@ -290,6 +311,7 @@ extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
/* Allocate & free a PCI host bridge structure */
extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
extern void pcibios_free_controller(struct pci_controller *phb);
extern void pcibios_setup_phb_resources(struct pci_controller *hose);
#ifdef CONFIG_PCI
extern unsigned long pci_address_to_pio(phys_addr_t address);

View File

@ -38,8 +38,8 @@ struct pci_dev;
* Set this to 1 if you want the kernel to re-assign all PCI
* bus numbers (don't do that on ppc64 yet !)
*/
#define pcibios_assign_all_busses() (ppc_pci_flags & \
PPC_PCI_REASSIGN_ALL_BUS)
#define pcibios_assign_all_busses() \
(ppc_pci_has_flag(PPC_PCI_REASSIGN_ALL_BUS))
#define pcibios_scan_all_fns(a, b) 0
static inline void pcibios_set_master(struct pci_dev *dev)
@ -204,15 +204,14 @@ static inline struct resource *pcibios_select_root(struct pci_dev *pdev,
return root;
}
extern void pcibios_setup_new_device(struct pci_dev *dev);
extern void pcibios_claim_one_bus(struct pci_bus *b);
extern void pcibios_allocate_bus_resources(struct pci_bus *bus);
extern void pcibios_finish_adding_to_bus(struct pci_bus *bus);
extern void pcibios_resource_survey(void);
extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
extern int remove_phb_dynamic(struct pci_controller *phb);
extern struct pci_dev *of_create_pci_dev(struct device_node *node,
struct pci_bus *bus, int devfn);
@ -221,6 +220,7 @@ extern void of_scan_pci_bridge(struct device_node *node,
struct pci_dev *dev);
extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus);
extern int pci_read_irq_line(struct pci_dev *dev);
@ -235,9 +235,8 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
const struct resource *rsrc,
resource_size_t *start, resource_size_t *end);
extern void pcibios_do_bus_setup(struct pci_bus *bus);
extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus);
extern void pcibios_setup_bus_devices(struct pci_bus *bus);
extern void pcibios_setup_bus_self(struct pci_bus *bus);
#endif /* __KERNEL__ */
#endif /* __ASM_POWERPC_PCI_H */

View File

@ -3,6 +3,8 @@
#include <linux/threads.h>
#define PTE_NONCACHE_NUM 0 /* dummy for now to share code w/ppc64 */
extern void __bad_pte(pmd_t *pmd);
extern pgd_t *pgd_alloc(struct mm_struct *mm);
@ -33,10 +35,13 @@ extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr);
extern void pte_free_kernel(struct mm_struct *mm, pte_t *pte);
extern void pte_free(struct mm_struct *mm, pgtable_t pte);
#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, (pte))
static inline void pgtable_free(pgtable_free_t pgf)
{
void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);
free_page((unsigned long)p);
}
#define check_pgt_cache() do { } while (0)

View File

@ -7,7 +7,6 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/cpumask.h>
#include <linux/percpu.h>
@ -108,31 +107,6 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
return page;
}
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
{
free_page((unsigned long)pte);
}
static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
{
pgtable_page_dtor(ptepage);
__free_page(ptepage);
}
#define PGF_CACHENUM_MASK 0x7
typedef struct pgtable_free {
unsigned long val;
} pgtable_free_t;
static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
unsigned long mask)
{
BUG_ON(cachenum > PGF_CACHENUM_MASK);
return (pgtable_free_t){.val = ((unsigned long) p & ~mask) | cachenum};
}
static inline void pgtable_free(pgtable_free_t pgf)
{
void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);
@ -144,14 +118,6 @@ static inline void pgtable_free(pgtable_free_t pgf)
kmem_cache_free(pgtable_cache[cachenum], p);
}
extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
#define __pte_free_tlb(tlb,ptepage) \
do { \
pgtable_page_dtor(ptepage); \
pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \
PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1)); \
} while (0)
#define __pmd_free_tlb(tlb, pmd) \
pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \
PMD_CACHE_NUM, PMD_TABLE_SIZE-1))

View File

@ -2,11 +2,52 @@
#define _ASM_POWERPC_PGALLOC_H
#ifdef __KERNEL__
#include <linux/mm.h>
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
{
free_page((unsigned long)pte);
}
static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
{
pgtable_page_dtor(ptepage);
__free_page(ptepage);
}
typedef struct pgtable_free {
unsigned long val;
} pgtable_free_t;
#define PGF_CACHENUM_MASK 0x7
static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
unsigned long mask)
{
BUG_ON(cachenum > PGF_CACHENUM_MASK);
return (pgtable_free_t){.val = ((unsigned long) p & ~mask) | cachenum};
}
#ifdef CONFIG_PPC64
#include <asm/pgalloc-64.h>
#else
#include <asm/pgalloc-32.h>
#endif
extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
#ifdef CONFIG_SMP
#define __pte_free_tlb(tlb,ptepage) \
do { \
pgtable_page_dtor(ptepage); \
pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \
PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1)); \
} while (0)
#else
#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, (pte))
#endif
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_PGALLOC_H */

View File

@ -228,9 +228,10 @@ extern int icache_44x_need_flush;
* - FILE *must* be in the bottom three bits because swap cache
* entries use the top 29 bits for TLB2.
*
* - CACHE COHERENT bit (M) has no effect on PPC440 core, because it
* doesn't support SMP. So we can use this as software bit, like
* DIRTY.
* - CACHE COHERENT bit (M) has no effect on original PPC440 cores,
* because it doesn't support SMP. However, some later 460 variants
* have -some- form of SMP support and so I keep the bit there for
* future use
*
* With the PPC 44x Linux implementation, the 0-11th LSBs of the PTE are used
* for memory protection related functions (see PTE structure in
@ -436,20 +437,23 @@ extern int icache_44x_need_flush;
_PAGE_USER | _PAGE_ACCESSED | \
_PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \
_PAGE_EXEC | _PAGE_HWEXEC)
/*
* Note: the _PAGE_COHERENT bit automatically gets set in the hardware
* PTE if CONFIG_SMP is defined (hash_page does this); there is no need
* to have it in the Linux PTE, and in fact the bit could be reused for
* another purpose. -- paulus.
*/
#ifdef CONFIG_44x
#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED)
/*
* We define 2 sets of base prot bits, one for basic pages (ie,
* cacheable kernel and user pages) and one for non cacheable
* pages. We always set _PAGE_COHERENT when SMP is enabled or
* the processor might need it for DMA coherency.
*/
#if defined(CONFIG_SMP) || defined(CONFIG_PPC_STD_MMU)
#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT)
#else
#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED)
#endif
#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_NO_CACHE)
#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE)
#define _PAGE_KERNEL (_PAGE_BASE | _PAGE_SHARED | _PAGE_WRENABLE)
#define _PAGE_KERNEL_NC (_PAGE_BASE_NC | _PAGE_SHARED | _PAGE_WRENABLE)
#ifdef CONFIG_PPC_STD_MMU
/* On standard PPC MMU, no user access implies kernel read/write access,
@ -459,7 +463,7 @@ extern int icache_44x_need_flush;
#define _PAGE_KERNEL_RO (_PAGE_BASE | _PAGE_SHARED)
#endif
#define _PAGE_IO (_PAGE_KERNEL | _PAGE_NO_CACHE | _PAGE_GUARDED)
#define _PAGE_IO (_PAGE_KERNEL_NC | _PAGE_GUARDED)
#define _PAGE_RAM (_PAGE_KERNEL | _PAGE_HWEXEC)
#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) ||\
@ -552,9 +556,6 @@ static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;
static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; }
static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; }
static inline pte_t pte_wrprotect(pte_t pte) {
pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); return pte; }
static inline pte_t pte_mkclean(pte_t pte) {
@ -693,10 +694,11 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
#endif
}
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte)
{
#if defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP)
#if defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP) && defined(CONFIG_DEBUG_VM)
WARN_ON(pte_present(*ptep));
#endif
__set_pte_at(mm, addr, ptep, pte);
@ -760,16 +762,6 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
__changed; \
})
/*
* Macro to mark a page protection value as "uncacheable".
*/
#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
struct file;
extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot);
#define __HAVE_PHYS_MEM_ACCESS_PROT
#define __HAVE_ARCH_PTE_SAME
#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)

View File

@ -100,7 +100,7 @@
#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY)
/* __pgprot defined in arch/powerpc/incliude/asm/page.h */
/* __pgprot defined in arch/powerpc/include/asm/page.h */
#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER)
@ -245,9 +245,6 @@ static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;}
static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE;}
static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; }
static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; }
static inline pte_t pte_wrprotect(pte_t pte) {
pte_val(pte) &= ~(_PAGE_RW); return pte; }
static inline pte_t pte_mkclean(pte_t pte) {
@ -405,16 +402,6 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
__changed; \
})
/*
* Macro to mark a page protection value as "uncacheable".
*/
#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
struct file;
extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot);
#define __HAVE_PHYS_MEM_ACCESS_PROT
#define __HAVE_ARCH_PTE_SAME
#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)

View File

@ -16,6 +16,32 @@ struct mm_struct;
#endif
#ifndef __ASSEMBLY__
/*
* Macro to mark a page protection value as "uncacheable".
*/
#define _PAGE_CACHE_CTL (_PAGE_COHERENT | _PAGE_GUARDED | _PAGE_NO_CACHE | \
_PAGE_WRITETHRU)
#define pgprot_noncached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
_PAGE_NO_CACHE | _PAGE_GUARDED))
#define pgprot_noncached_wc(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
_PAGE_NO_CACHE))
#define pgprot_cached(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
_PAGE_COHERENT))
#define pgprot_cached_wthru(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
_PAGE_COHERENT | _PAGE_WRITETHRU))
struct file;
extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot);
#define __HAVE_PHYS_MEM_ACCESS_PROT
/*
* ZERO_PAGE is a global shared page that is always zero: used
* for zero-mapped memory areas etc..

View File

@ -425,14 +425,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
#define fromreal(rd) tovirt(rd,rd)
#define tophys(rd,rs) \
0: addis rd,rs,-KERNELBASE@h; \
0: addis rd,rs,-PAGE_OFFSET@h; \
.section ".vtop_fixup","aw"; \
.align 1; \
.long 0b; \
.previous
#define tovirt(rd,rs) \
0: addis rd,rs,KERNELBASE@h; \
0: addis rd,rs,PAGE_OFFSET@h; \
.section ".ptov_fixup","aw"; \
.align 1; \
.long 0b; \

View File

@ -69,8 +69,6 @@ extern int _prep_type;
#ifdef __KERNEL__
extern int have_of;
struct task_struct;
void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
void release_thread(struct task_struct *);
@ -207,6 +205,11 @@ struct thread_struct {
#define INIT_SP_LIMIT \
(_ALIGN_UP(sizeof(init_thread_info), 16) + (unsigned long) &init_stack)
#ifdef CONFIG_SPE
#define SPEFSCR_INIT .spefscr = SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE | SPEFSCR_FOVFE,
#else
#define SPEFSCR_INIT
#endif
#ifdef CONFIG_PPC32
#define INIT_THREAD { \
@ -215,6 +218,7 @@ struct thread_struct {
.fs = KERNEL_DS, \
.pgdir = swapper_pg_dir, \
.fpexc_mode = MSR_FE0 | MSR_FE1, \
SPEFSCR_INIT \
}
#else
#define INIT_THREAD { \

View File

@ -253,6 +253,9 @@ extern void kdump_move_device_tree(void);
/* CPU OF node matching */
struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
/* cache lookup */
struct device_node *of_find_next_cache_node(struct device_node *np);
/* Get the MAC address */
extern const void *of_get_mac_address(struct device_node *np);

View File

@ -305,30 +305,34 @@ static inline const char* ps3_result(int result)
/* system bus routines */
enum ps3_match_id {
PS3_MATCH_ID_EHCI = 1,
PS3_MATCH_ID_OHCI = 2,
PS3_MATCH_ID_GELIC = 3,
PS3_MATCH_ID_AV_SETTINGS = 4,
PS3_MATCH_ID_SYSTEM_MANAGER = 5,
PS3_MATCH_ID_STOR_DISK = 6,
PS3_MATCH_ID_STOR_ROM = 7,
PS3_MATCH_ID_STOR_FLASH = 8,
PS3_MATCH_ID_SOUND = 9,
PS3_MATCH_ID_GRAPHICS = 10,
PS3_MATCH_ID_LPM = 11,
PS3_MATCH_ID_EHCI = 1,
PS3_MATCH_ID_OHCI = 2,
PS3_MATCH_ID_GELIC = 3,
PS3_MATCH_ID_AV_SETTINGS = 4,
PS3_MATCH_ID_SYSTEM_MANAGER = 5,
PS3_MATCH_ID_STOR_DISK = 6,
PS3_MATCH_ID_STOR_ROM = 7,
PS3_MATCH_ID_STOR_FLASH = 8,
PS3_MATCH_ID_SOUND = 9,
PS3_MATCH_ID_GPU = 10,
PS3_MATCH_ID_LPM = 11,
};
#define PS3_MODULE_ALIAS_EHCI "ps3:1"
#define PS3_MODULE_ALIAS_OHCI "ps3:2"
#define PS3_MODULE_ALIAS_GELIC "ps3:3"
#define PS3_MODULE_ALIAS_AV_SETTINGS "ps3:4"
#define PS3_MODULE_ALIAS_SYSTEM_MANAGER "ps3:5"
#define PS3_MODULE_ALIAS_STOR_DISK "ps3:6"
#define PS3_MODULE_ALIAS_STOR_ROM "ps3:7"
#define PS3_MODULE_ALIAS_STOR_FLASH "ps3:8"
#define PS3_MODULE_ALIAS_SOUND "ps3:9"
#define PS3_MODULE_ALIAS_GRAPHICS "ps3:10"
#define PS3_MODULE_ALIAS_LPM "ps3:11"
enum ps3_match_sub_id {
PS3_MATCH_SUB_ID_GPU_FB = 1,
};
#define PS3_MODULE_ALIAS_EHCI "ps3:1:0"
#define PS3_MODULE_ALIAS_OHCI "ps3:2:0"
#define PS3_MODULE_ALIAS_GELIC "ps3:3:0"
#define PS3_MODULE_ALIAS_AV_SETTINGS "ps3:4:0"
#define PS3_MODULE_ALIAS_SYSTEM_MANAGER "ps3:5:0"
#define PS3_MODULE_ALIAS_STOR_DISK "ps3:6:0"
#define PS3_MODULE_ALIAS_STOR_ROM "ps3:7:0"
#define PS3_MODULE_ALIAS_STOR_FLASH "ps3:8:0"
#define PS3_MODULE_ALIAS_SOUND "ps3:9:0"
#define PS3_MODULE_ALIAS_GPU_FB "ps3:10:1"
#define PS3_MODULE_ALIAS_LPM "ps3:11:0"
enum ps3_system_bus_device_type {
PS3_DEVICE_TYPE_IOC0 = 1,
@ -337,11 +341,6 @@ enum ps3_system_bus_device_type {
PS3_DEVICE_TYPE_LPM,
};
enum ps3_match_sub_id {
/* for PS3_MATCH_ID_GRAPHICS */
PS3_MATCH_SUB_ID_FB = 1,
};
/**
* struct ps3_system_bus_device - a device on the system bus
*/
@ -516,4 +515,7 @@ void ps3_sync_irq(int node);
u32 ps3_get_hw_thread_id(int cpu);
u64 ps3_get_spe_id(void *arg);
/* mutex synchronizing GPU accesses and video mode changes */
extern struct mutex ps3_gpu_mutex;
#endif

View File

@ -740,8 +740,4 @@ extern int ps3av_audio_mute(int);
extern int ps3av_audio_mute_analog(int);
extern int ps3av_dev_open(void);
extern int ps3av_dev_close(void);
extern void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data),
void *flip_data);
extern void ps3av_flip_ctl(int on);
#endif /* _ASM_POWERPC_PS3AV_H_ */

View File

@ -783,6 +783,10 @@ extern void scom970_write(unsigned int address, unsigned long value);
#define __get_SP() ({unsigned long sp; \
asm volatile("mr %0,1": "=r" (sp)); sp;})
struct pt_regs;
extern void ppc_save_regs(struct pt_regs *regs);
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_REG_H */

View File

@ -168,6 +168,7 @@ extern void rtas_os_term(char *str);
extern int rtas_get_sensor(int sensor, int index, int *state);
extern int rtas_get_power_level(int powerdomain, int *level);
extern int rtas_set_power_level(int powerdomain, int level, int *setlevel);
extern bool rtas_indicator_present(int token, int *maxindex);
extern int rtas_set_indicator(int indicator, int index, int new_value);
extern int rtas_set_indicator_fast(int indicator, int index, int new_value);
extern void rtas_progress(char *s, unsigned short hex);

View File

@ -82,7 +82,7 @@
#define _FP_MUL_MEAT_S(R,X,Y) _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
#define _FP_MUL_MEAT_D(R,X,Y) _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y)
#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(S,R,X,Y)
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
/* These macros define what NaN looks like. They're supposed to expand to
@ -97,6 +97,20 @@
#define _FP_KEEPNANFRACP 1
#ifdef FP_EX_BOOKE_E500_SPE
#define FP_EX_INEXACT (1 << 21)
#define FP_EX_INVALID (1 << 20)
#define FP_EX_DIVZERO (1 << 19)
#define FP_EX_UNDERFLOW (1 << 18)
#define FP_EX_OVERFLOW (1 << 17)
#define FP_INHIBIT_RESULTS 0
#define __FPU_FPSCR (current->thread.spefscr)
#define __FPU_ENABLED_EXC \
({ \
(__FPU_FPSCR >> 2) & 0x1f; \
})
#else
/* Exception flags. We use the bit positions of the appropriate bits
in the FPSCR, which also correspond to the FE_* bits. This makes
everything easier ;-). */
@ -111,22 +125,6 @@
#define FP_EX_DIVZERO (1 << (31 - 5))
#define FP_EX_INEXACT (1 << (31 - 6))
/* This macro appears to be called when both X and Y are NaNs, and
* has to choose one and copy it to R. i386 goes for the larger of the
* two, sparc64 just picks Y. I don't understand this at all so I'll
* go with sparc64 because it's shorter :-> -- PMM
*/
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
do { \
R##_s = Y##_s; \
_FP_FRAC_COPY_##wc(R,Y); \
R##_c = FP_CLS_NAN; \
} while (0)
#include <linux/kernel.h>
#include <linux/sched.h>
#define __FPU_FPSCR (current->thread.fpscr.val)
/* We only actually write to the destination register
@ -137,6 +135,32 @@
(__FPU_FPSCR >> 3) & 0x1f; \
})
#endif
/*
* If one NaN is signaling and the other is not,
* we choose that one, otherwise we choose X.
*/
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
do { \
if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs) \
&& !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
{ \
R##_s = X##_s; \
_FP_FRAC_COPY_##wc(R,X); \
} \
else \
{ \
R##_s = Y##_s; \
_FP_FRAC_COPY_##wc(R,Y); \
} \
R##_c = FP_CLS_NAN; \
} while (0)
#include <linux/kernel.h>
#include <linux/sched.h>
#define __FPU_TRAP_P(bits) \
((__FPU_ENABLED_EXC & (bits)) != 0)

View File

@ -81,6 +81,13 @@ extern int cpu_to_core_id(int cpu);
#define PPC_MSG_CALL_FUNC_SINGLE 2
#define PPC_MSG_DEBUGGER_BREAK 3
/*
* irq controllers that have dedicated ipis per message and don't
* need additional code in the action handler may use this
*/
extern int smp_request_message_ipi(int virq, int message);
extern const char *smp_ipi_name[];
void smp_init_iSeries(void);
void smp_init_pSeries(void);
void smp_init_cell(void);

View File

@ -277,7 +277,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw)
bne- 1b"
: "=&r"(tmp)
: "r"(&rw->lock)
: "cr0", "memory");
: "cr0", "xer", "memory");
}
static inline void __raw_write_unlock(raw_rwlock_t *rw)

View File

@ -5,6 +5,10 @@
#include <linux/stringify.h>
#include <asm/feature-fixups.h>
#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC)
#define __SUBARCH_HAS_LWSYNC
#endif
#ifndef __ASSEMBLY__
extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup;
extern void do_lwsync_fixups(unsigned long value, void *fixup_start,

View File

@ -23,15 +23,17 @@
* read_barrier_depends() prevents data-dependent loads being reordered
* across this point (nop on PPC).
*
* We have to use the sync instructions for mb(), since lwsync doesn't
* order loads with respect to previous stores. Lwsync is fine for
* rmb(), though. Note that rmb() actually uses a sync on 32-bit
* architectures.
* *mb() variants without smp_ prefix must order all types of memory
* operations with one another. sync is the only instruction sufficient
* to do this.
*
* For wmb(), we use sync since wmb is used in drivers to order
* stores to system memory with respect to writes to the device.
* However, smp_wmb() can be a lighter-weight lwsync or eieio barrier
* on SMP since it is only used to order updates to system memory.
* For the smp_ barriers, ordering is for cacheable memory operations
* only. We have to use the sync instruction for smp_mb(), since lwsync
* doesn't order loads with respect to previous stores. Lwsync can be
* used for smp_rmb() and smp_wmb().
*
* However, on CPUs that don't support lwsync, lwsync actually maps to a
* heavy-weight sync, so smp_wmb() can be a lighter-weight eieio.
*/
#define mb() __asm__ __volatile__ ("sync" : : : "memory")
#define rmb() __asm__ __volatile__ ("sync" : : : "memory")
@ -45,14 +47,14 @@
#ifdef CONFIG_SMP
#ifdef __SUBARCH_HAS_LWSYNC
# define SMPWMB lwsync
# define SMPWMB LWSYNC
#else
# define SMPWMB eieio
#endif
#define smp_mb() mb()
#define smp_rmb() rmb()
#define smp_wmb() __asm__ __volatile__ (__stringify(SMPWMB) : : :"memory")
#define smp_rmb() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : :"memory")
#define smp_wmb() __asm__ __volatile__ (stringify_in_c(SMPWMB) : : :"memory")
#define smp_read_barrier_depends() read_barrier_depends()
#else
#define smp_mb() barrier()

View File

@ -48,26 +48,6 @@ extern unsigned long ppc_proc_freq;
extern unsigned long ppc_tb_freq;
#define DEFAULT_TB_FREQ 125000000UL
/*
* By putting all of this stuff into a single struct we
* reduce the number of cache lines touched by do_gettimeofday.
* Both by collecting all of the data in one cache line and
* by touching only one TOC entry on ppc64.
*/
struct gettimeofday_vars {
u64 tb_to_xs;
u64 stamp_xsec;
u64 tb_orig_stamp;
};
struct gettimeofday_struct {
unsigned long tb_ticks_per_sec;
struct gettimeofday_vars vars[2];
struct gettimeofday_vars * volatile varp;
unsigned var_idx;
unsigned tb_to_us;
};
struct div_result {
u64 result_high;
u64 result_low;

View File

@ -6,6 +6,9 @@
*
* - flush_tlb_mm(mm) flushes the specified mm context TLB's
* - flush_tlb_page(vma, vmaddr) flushes one page
* - local_flush_tlb_mm(mm) flushes the specified mm context on
* the local processor
* - local_flush_tlb_page(vma, vmaddr) flushes one page on the local processor
* - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB
* - flush_tlb_range(vma, start, end) flushes a range of pages
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
@ -17,7 +20,7 @@
*/
#ifdef __KERNEL__
#if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE)
#ifdef CONFIG_PPC_MMU_NOHASH
/*
* TLB flushing for software loaded TLB chips
*
@ -28,63 +31,49 @@
#include <linux/mm.h>
extern void _tlbie(unsigned long address, unsigned int pid);
extern void _tlbil_all(void);
extern void _tlbil_pid(unsigned int pid);
extern void _tlbil_va(unsigned long address, unsigned int pid);
#define MMU_NO_CONTEXT ((unsigned int)-1)
#if defined(CONFIG_40x) || defined(CONFIG_8xx)
#define _tlbia() asm volatile ("tlbia; sync" : : : "memory")
#else /* CONFIG_44x || CONFIG_FSL_BOOKE */
extern void _tlbia(void);
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
extern void local_flush_tlb_mm(struct mm_struct *mm);
extern void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
#ifdef CONFIG_SMP
extern void flush_tlb_mm(struct mm_struct *mm);
extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
#else
#define flush_tlb_mm(mm) local_flush_tlb_mm(mm)
#define flush_tlb_page(vma,addr) local_flush_tlb_page(vma,addr)
#endif
#define flush_tlb_page_nohash(vma,addr) flush_tlb_page(vma,addr)
static inline void flush_tlb_mm(struct mm_struct *mm)
{
_tlbil_pid(mm->context.id);
}
#elif defined(CONFIG_PPC_STD_MMU_32)
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{
_tlbil_va(vmaddr, vma ? vma->vm_mm->context.id : 0);
}
static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
unsigned long vmaddr)
{
flush_tlb_page(vma, vmaddr);
}
static inline void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
_tlbil_pid(vma->vm_mm->context.id);
}
static inline void flush_tlb_kernel_range(unsigned long start,
unsigned long end)
{
_tlbil_pid(0);
}
#elif defined(CONFIG_PPC32)
/*
* TLB flushing for "classic" hash-MMMU 32-bit CPUs, 6xx, 7xx, 7xxx
* TLB flushing for "classic" hash-MMU 32-bit CPUs, 6xx, 7xx, 7xxx
*/
extern void _tlbie(unsigned long address);
extern void _tlbia(void);
extern void flush_tlb_mm(struct mm_struct *mm);
extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
extern void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr);
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
static inline void local_flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{
flush_tlb_page(vma, vmaddr);
}
static inline void local_flush_tlb_mm(struct mm_struct *mm)
{
flush_tlb_mm(mm);
}
#elif defined(CONFIG_PPC_STD_MMU_64)
#else
/*
* TLB flushing for 64-bit has-MMU CPUs
* TLB flushing for 64-bit hash-MMU CPUs
*/
#include <linux/percpu.h>
@ -134,10 +123,19 @@ extern void flush_hash_page(unsigned long va, real_pte_t pte, int psize,
extern void flush_hash_range(unsigned long number, int local);
static inline void local_flush_tlb_mm(struct mm_struct *mm)
{
}
static inline void flush_tlb_mm(struct mm_struct *mm)
{
}
static inline void local_flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{
}
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{
@ -162,7 +160,8 @@ static inline void flush_tlb_kernel_range(unsigned long start,
extern void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
unsigned long end);
#else
#error Unsupported MMU type
#endif
#endif /*__KERNEL__ */

View File

@ -39,6 +39,7 @@
#ifndef __ASSEMBLY__
#include <linux/unistd.h>
#include <linux/time.h>
#define SYSCALL_MAP_SIZE ((__NR_syscalls + 31) / 32)
@ -83,6 +84,7 @@ struct vdso_data {
__u32 icache_log_block_size; /* L1 i-cache log block size */
__s32 wtom_clock_sec; /* Wall to monotonic clock */
__s32 wtom_clock_nsec;
struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */
__u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */
__u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
};
@ -102,6 +104,7 @@ struct vdso_data {
__u32 tz_dsttime; /* Type of dst correction 0x5C */
__s32 wtom_clock_sec; /* Wall to monotonic clock */
__s32 wtom_clock_nsec;
struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */
__u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
__u32 dcache_block_size; /* L1 d-cache block size */
__u32 icache_block_size; /* L1 i-cache block size */

View File

@ -103,6 +103,10 @@ endif
obj-$(CONFIG_PPC64) += $(obj64-y)
ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC),)
obj-y += ppc_save_regs.o
endif
extra-$(CONFIG_PPC_FPU) += fpu.o
extra-$(CONFIG_PPC64) += entry_64.o

View File

@ -60,6 +60,7 @@ int main(void)
{
DEFINE(THREAD, offsetof(struct task_struct, thread));
DEFINE(MM, offsetof(struct task_struct, mm));
DEFINE(MMCONTEXTID, offsetof(struct mm_struct, context.id));
#ifdef CONFIG_PPC64
DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
#else
@ -306,6 +307,7 @@ int main(void)
DEFINE(CFG_SYSCALL_MAP32, offsetof(struct vdso_data, syscall_map_32));
DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec));
DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
DEFINE(STAMP_XTIME, offsetof(struct vdso_data, stamp_xtime));
DEFINE(CFG_ICACHE_BLOCKSZ, offsetof(struct vdso_data, icache_block_size));
DEFINE(CFG_DCACHE_BLOCKSZ, offsetof(struct vdso_data, dcache_block_size));
DEFINE(CFG_ICACHE_LOGBLOCKSZ, offsetof(struct vdso_data, icache_log_block_size));
@ -378,6 +380,10 @@ int main(void)
DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
#endif
#ifdef CONFIG_44x
DEFINE(PGD_T_LOG2, PGD_T_LOG2);
DEFINE(PTE_T_LOG2, PTE_T_LOG2);
#endif
return 0;
}

View File

@ -19,6 +19,7 @@
#include <asm/oprofile_impl.h>
#include <asm/cputable.h>
#include <asm/prom.h> /* for PTRRELOC on ARCH=ppc */
#include <asm/mmu.h>
struct cpu_spec* cur_cpu_spec = NULL;
EXPORT_SYMBOL(cur_cpu_spec);
@ -94,6 +95,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "POWER3 (630)",
.cpu_features = CPU_FTRS_POWER3,
.cpu_user_features = COMMON_USER_PPC64|PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
@ -109,6 +111,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "POWER3 (630+)",
.cpu_features = CPU_FTRS_POWER3,
.cpu_user_features = COMMON_USER_PPC64|PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
@ -124,6 +127,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "RS64-II (northstar)",
.cpu_features = CPU_FTRS_RS64,
.cpu_user_features = COMMON_USER_PPC64,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
@ -139,6 +143,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "RS64-III (pulsar)",
.cpu_features = CPU_FTRS_RS64,
.cpu_user_features = COMMON_USER_PPC64,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
@ -154,6 +159,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "RS64-III (icestar)",
.cpu_features = CPU_FTRS_RS64,
.cpu_user_features = COMMON_USER_PPC64,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
@ -169,6 +175,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "RS64-IV (sstar)",
.cpu_features = CPU_FTRS_RS64,
.cpu_user_features = COMMON_USER_PPC64,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
@ -184,6 +191,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "POWER4 (gp)",
.cpu_features = CPU_FTRS_POWER4,
.cpu_user_features = COMMON_USER_POWER4,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
@ -199,6 +207,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "POWER4+ (gq)",
.cpu_features = CPU_FTRS_POWER4,
.cpu_user_features = COMMON_USER_POWER4,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
@ -215,6 +224,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_PPC970,
.cpu_user_features = COMMON_USER_POWER4 |
PPC_FEATURE_HAS_ALTIVEC_COMP,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
@ -233,6 +243,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_PPC970,
.cpu_user_features = COMMON_USER_POWER4 |
PPC_FEATURE_HAS_ALTIVEC_COMP,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
@ -251,6 +262,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_PPC970,
.cpu_user_features = COMMON_USER_POWER4 |
PPC_FEATURE_HAS_ALTIVEC_COMP,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
@ -269,6 +281,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_PPC970,
.cpu_user_features = COMMON_USER_POWER4 |
PPC_FEATURE_HAS_ALTIVEC_COMP,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
@ -287,6 +300,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_PPC970,
.cpu_user_features = COMMON_USER_POWER4 |
PPC_FEATURE_HAS_ALTIVEC_COMP,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
@ -303,6 +317,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "POWER5 (gr)",
.cpu_features = CPU_FTRS_POWER5,
.cpu_user_features = COMMON_USER_POWER5,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 6,
@ -323,6 +338,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "POWER5+ (gs)",
.cpu_features = CPU_FTRS_POWER5,
.cpu_user_features = COMMON_USER_POWER5_PLUS,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 6,
@ -339,6 +355,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "POWER5+ (gs)",
.cpu_features = CPU_FTRS_POWER5,
.cpu_user_features = COMMON_USER_POWER5_PLUS,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 6,
@ -356,6 +373,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "POWER5+",
.cpu_features = CPU_FTRS_POWER5,
.cpu_user_features = COMMON_USER_POWER5_PLUS,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.machine_check = machine_check_generic,
@ -369,6 +387,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_POWER6,
.cpu_user_features = COMMON_USER_POWER6 |
PPC_FEATURE_POWER6_EXT,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 6,
@ -388,6 +407,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "POWER6 (architected)",
.cpu_features = CPU_FTRS_POWER6,
.cpu_user_features = COMMON_USER_POWER6,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.machine_check = machine_check_generic,
@ -400,6 +420,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "POWER7 (architected)",
.cpu_features = CPU_FTRS_POWER7,
.cpu_user_features = COMMON_USER_POWER7,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.machine_check = machine_check_generic,
@ -412,6 +433,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "POWER7 (raw)",
.cpu_features = CPU_FTRS_POWER7,
.cpu_user_features = COMMON_USER_POWER7,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 6,
@ -434,6 +456,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_PPC64 |
PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP |
PPC_FEATURE_SMT,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 4,
@ -449,6 +472,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "PA6T",
.cpu_features = CPU_FTRS_PA6T,
.cpu_user_features = COMMON_USER_PA6T,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 64,
.dcache_bsize = 64,
.num_pmcs = 6,
@ -466,6 +490,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "POWER4 (compatible)",
.cpu_features = CPU_FTRS_COMPATIBLE,
.cpu_user_features = COMMON_USER_PPC64,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 6,
@ -483,6 +508,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_PPC601,
.cpu_user_features = COMMON_USER | PPC_FEATURE_601_INSTR |
PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_generic,
@ -494,6 +520,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "603",
.cpu_features = CPU_FTRS_603,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = 0,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603,
@ -506,6 +533,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "603e",
.cpu_features = CPU_FTRS_603,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = 0,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603,
@ -518,6 +546,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "603ev",
.cpu_features = CPU_FTRS_603,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = 0,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603,
@ -530,6 +559,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "604",
.cpu_features = CPU_FTRS_604,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 2,
@ -543,6 +573,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "604e",
.cpu_features = CPU_FTRS_604,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -556,6 +587,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "604r",
.cpu_features = CPU_FTRS_604,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -569,6 +601,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "604ev",
.cpu_features = CPU_FTRS_604,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -582,6 +615,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "740/750",
.cpu_features = CPU_FTRS_740_NOTAU,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -595,6 +629,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "750CX",
.cpu_features = CPU_FTRS_750,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -608,6 +643,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "750CX",
.cpu_features = CPU_FTRS_750,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -622,6 +658,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "750CXe",
.cpu_features = CPU_FTRS_750,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -636,6 +673,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "750CXe",
.cpu_features = CPU_FTRS_750,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -650,6 +688,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "750CL",
.cpu_features = CPU_FTRS_750CL,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -664,6 +703,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "745/755",
.cpu_features = CPU_FTRS_750,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -678,6 +718,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "750FX",
.cpu_features = CPU_FTRS_750FX1,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -692,6 +733,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "750FX",
.cpu_features = CPU_FTRS_750FX2,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -706,6 +748,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "750FX",
.cpu_features = CPU_FTRS_750FX,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -720,6 +763,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "750GX",
.cpu_features = CPU_FTRS_750GX,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -734,6 +778,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "740/750",
.cpu_features = CPU_FTRS_740,
.cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -749,6 +794,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_7400_NOTAU,
.cpu_user_features = COMMON_USER |
PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -764,6 +810,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_7400,
.cpu_user_features = COMMON_USER |
PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -779,6 +826,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_7400,
.cpu_user_features = COMMON_USER |
PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -794,6 +842,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_7450_20,
.cpu_user_features = COMMON_USER |
PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@ -811,6 +860,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_7450_21,
.cpu_user_features = COMMON_USER |
PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@ -828,6 +878,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_7450_23,
.cpu_user_features = COMMON_USER |
PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@ -845,6 +896,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_7455_1,
.cpu_user_features = COMMON_USER |
PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@ -862,6 +914,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_7455_20,
.cpu_user_features = COMMON_USER |
PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@ -879,6 +932,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_7455,
.cpu_user_features = COMMON_USER |
PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@ -896,6 +950,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_7447_10,
.cpu_user_features = COMMON_USER |
PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@ -913,6 +968,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_7447_10,
.cpu_user_features = COMMON_USER |
PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@ -929,6 +985,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "7447/7457",
.cpu_features = CPU_FTRS_7447,
.cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@ -946,6 +1003,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_7447A,
.cpu_user_features = COMMON_USER |
PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@ -963,6 +1021,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_7448,
.cpu_user_features = COMMON_USER |
PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
.mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
@ -979,6 +1038,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "82xx",
.cpu_features = CPU_FTRS_82XX,
.cpu_user_features = COMMON_USER,
.mmu_features = 0,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603,
@ -991,6 +1051,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "G2_LE",
.cpu_features = CPU_FTRS_G2_LE,
.cpu_user_features = COMMON_USER,
.mmu_features = MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603,
@ -1003,6 +1064,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "e300c1",
.cpu_features = CPU_FTRS_E300,
.cpu_user_features = COMMON_USER,
.mmu_features = MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603,
@ -1015,6 +1077,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "e300c2",
.cpu_features = CPU_FTRS_E300C2,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.mmu_features = MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603,
@ -1027,6 +1090,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "e300c3",
.cpu_features = CPU_FTRS_E300,
.cpu_user_features = COMMON_USER,
.mmu_features = MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603,
@ -1041,6 +1105,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "e300c4",
.cpu_features = CPU_FTRS_E300,
.cpu_user_features = COMMON_USER,
.mmu_features = MMU_FTR_USE_HIGH_BATS,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603,
@ -1056,6 +1121,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "(generic PPC)",
.cpu_features = CPU_FTRS_CLASSIC32,
.cpu_user_features = COMMON_USER,
.mmu_features = MMU_FTR_HPTE_TABLE,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_generic,
@ -1071,6 +1137,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
* if the 8xx code is there.... */
.cpu_features = CPU_FTRS_8XX,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.mmu_features = MMU_FTR_TYPE_8xx,
.icache_bsize = 16,
.dcache_bsize = 16,
.platform = "ppc823",
@ -1083,6 +1150,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "403GC",
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 16,
.dcache_bsize = 16,
.machine_check = machine_check_4xx,
@ -1095,6 +1163,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 16,
.dcache_bsize = 16,
.machine_check = machine_check_4xx,
@ -1106,6 +1175,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "403G ??",
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 16,
.dcache_bsize = 16,
.machine_check = machine_check_4xx,
@ -1118,6 +1188,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1130,6 +1201,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1142,6 +1214,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1154,6 +1227,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1166,6 +1240,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1178,6 +1253,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1190,6 +1266,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1202,6 +1279,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1213,6 +1291,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "405LP",
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1225,6 +1304,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1237,6 +1317,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1249,6 +1330,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1261,6 +1343,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1273,6 +1356,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1286,6 +1370,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1298,6 +1383,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_features = CPU_FTRS_40X,
.cpu_user_features = PPC_FEATURE_32 |
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.mmu_features = MMU_FTR_TYPE_40x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1312,6 +1398,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440GR Rev. A",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1323,6 +1410,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440EP Rev. A",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_440ep,
@ -1335,6 +1423,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440GR Rev. B",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1346,6 +1435,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440EP Rev. C",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_440ep,
@ -1358,6 +1448,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440EP Rev. B",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_440ep,
@ -1370,6 +1461,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440GRX",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_440grx,
@ -1382,6 +1474,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440EPX",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_440epx,
@ -1394,6 +1487,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440GP Rev. B",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1405,6 +1499,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440GP Rev. C",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1416,6 +1511,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440GX Rev. A",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_440gx,
@ -1428,6 +1524,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440GX Rev. B",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_440gx,
@ -1440,6 +1537,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440GX Rev. C",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_440gx,
@ -1452,6 +1550,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440GX Rev. F",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_440gx,
@ -1464,6 +1563,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440SP Rev. A",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1475,6 +1575,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440SPe Rev. A",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_440spe,
@ -1487,6 +1588,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440SPe Rev. B",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_440spe,
@ -1499,6 +1601,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "440 in Virtex-5 FXT",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_440x5,
@ -1509,8 +1612,9 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pvr_mask = 0xffff0002,
.pvr_value = 0x13020002,
.cpu_name = "460EX",
.cpu_features = CPU_FTRS_44X,
.cpu_features = CPU_FTRS_440x6,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_460ex,
@ -1521,8 +1625,9 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pvr_mask = 0xffff0002,
.pvr_value = 0x13020000,
.cpu_name = "460GT",
.cpu_features = CPU_FTRS_44X,
.cpu_features = CPU_FTRS_440x6,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_460gt,
@ -1535,6 +1640,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "(generic 44x PPC)",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
.mmu_features = MMU_FTR_TYPE_44x,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_4xx,
@ -1551,6 +1657,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE |
PPC_FEATURE_HAS_EFP_SINGLE |
PPC_FEATURE_UNIFIED_CACHE,
.mmu_features = MMU_FTR_TYPE_FSL_E,
.dcache_bsize = 32,
.machine_check = machine_check_e200,
.platform = "ppc5554",
@ -1565,6 +1672,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_SPE_COMP |
PPC_FEATURE_HAS_EFP_SINGLE_COMP |
PPC_FEATURE_UNIFIED_CACHE,
.mmu_features = MMU_FTR_TYPE_FSL_E,
.dcache_bsize = 32,
.machine_check = machine_check_e200,
.platform = "ppc5554",
@ -1577,6 +1685,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE |
PPC_FEATURE_HAS_EFP_SINGLE |
PPC_FEATURE_UNIFIED_CACHE,
.mmu_features = MMU_FTR_TYPE_FSL_E,
.dcache_bsize = 32,
.machine_check = machine_check_e200,
.platform = "ppc5554",
@ -1591,6 +1700,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE |
PPC_FEATURE_HAS_SPE_COMP |
PPC_FEATURE_HAS_EFP_SINGLE_COMP,
.mmu_features = MMU_FTR_TYPE_FSL_E,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -1608,6 +1718,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_SPE_COMP |
PPC_FEATURE_HAS_EFP_SINGLE_COMP |
PPC_FEATURE_HAS_EFP_DOUBLE_COMP,
.mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@ -1622,6 +1733,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "e500mc",
.cpu_features = CPU_FTRS_E500MC,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS,
.icache_bsize = 64,
.dcache_bsize = 64,
.num_pmcs = 4,
@ -1638,6 +1750,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE |
PPC_FEATURE_HAS_SPE_COMP |
PPC_FEATURE_HAS_EFP_SINGLE_COMP,
.mmu_features = MMU_FTR_TYPE_FSL_E,
.icache_bsize = 32,
.dcache_bsize = 32,
.machine_check = machine_check_e500,

View File

@ -120,6 +120,26 @@ static inline void dma_direct_unmap_page(struct device *dev,
{
}
#ifdef CONFIG_NOT_COHERENT_CACHE
static inline void dma_direct_sync_sg(struct device *dev,
struct scatterlist *sgl, int nents,
enum dma_data_direction direction)
{
struct scatterlist *sg;
int i;
for_each_sg(sgl, sg, nents, i)
__dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
}
static inline void dma_direct_sync_single_range(struct device *dev,
dma_addr_t dma_handle, unsigned long offset, size_t size,
enum dma_data_direction direction)
{
__dma_sync(bus_to_virt(dma_handle+offset), size, direction);
}
#endif
struct dma_mapping_ops dma_direct_ops = {
.alloc_coherent = dma_direct_alloc_coherent,
.free_coherent = dma_direct_free_coherent,
@ -128,5 +148,11 @@ struct dma_mapping_ops dma_direct_ops = {
.dma_supported = dma_direct_dma_supported,
.map_page = dma_direct_map_page,
.unmap_page = dma_direct_unmap_page,
#ifdef CONFIG_NOT_COHERENT_CACHE
.sync_single_range_for_cpu = dma_direct_sync_single_range,
.sync_single_range_for_device = dma_direct_sync_single_range,
.sync_sg_for_cpu = dma_direct_sync_sg,
.sync_sg_for_device = dma_direct_sync_sg,
#endif
};
EXPORT_SYMBOL(dma_direct_ops);

View File

@ -31,6 +31,7 @@
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
#include <asm/ptrace.h>
#include <asm/bug.h>
/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
#define LOAD_BAT(n, reg, RA, RB) \
@ -182,7 +183,8 @@ __after_mmu_off:
bl reloc_offset
mr r26,r3
addis r4,r3,KERNELBASE@h /* current address of _start */
cmpwi 0,r4,0 /* are we already running at 0? */
lis r5,PHYSICAL_START@h
cmplw 0,r4,r5 /* already running at PHYSICAL_START? */
bne relocate_kernel
/*
* we now have the 1st 16M of ram mapped with the bats.
@ -810,13 +812,13 @@ giveup_altivec:
/*
* This code is jumped to from the startup code to copy
* the kernel image to physical address 0.
* the kernel image to physical address PHYSICAL_START.
*/
relocate_kernel:
addis r9,r26,klimit@ha /* fetch klimit */
lwz r25,klimit@l(r9)
addis r25,r25,-KERNELBASE@h
li r3,0 /* Destination base address */
lis r3,PHYSICAL_START@h /* Destination base address */
li r6,0 /* Destination offset */
li r5,0x4000 /* # bytes of memory to copy */
bl copy_and_flush /* copy the first 0x4000 bytes */
@ -989,12 +991,12 @@ load_up_mmu:
LOAD_BAT(1,r3,r4,r5)
LOAD_BAT(2,r3,r4,r5)
LOAD_BAT(3,r3,r4,r5)
BEGIN_FTR_SECTION
BEGIN_MMU_FTR_SECTION
LOAD_BAT(4,r3,r4,r5)
LOAD_BAT(5,r3,r4,r5)
LOAD_BAT(6,r3,r4,r5)
LOAD_BAT(7,r3,r4,r5)
END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
blr
/*
@ -1070,9 +1072,14 @@ start_here:
RFI
/*
* void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next);
*
* Set up the segment registers for a new context.
*/
_ENTRY(set_context)
_ENTRY(switch_mmu_context)
lwz r3,MMCONTEXTID(r4)
cmpwi cr0,r3,0
blt- 4f
mulli r3,r3,897 /* multiply context by skew factor */
rlwinm r3,r3,4,8,27 /* VSID = (context & 0xfffff) << 4 */
addis r3,r3,0x6000 /* Set Ks, Ku bits */
@ -1083,6 +1090,7 @@ _ENTRY(set_context)
/* Context switch the PTE pointer for the Abatron BDI2000.
* The PGDIR is passed as second argument.
*/
lwz r4,MM_PGD(r4)
lis r5, KERNELBASE@h
lwz r5, 0xf0(r5)
stw r4, 0x4(r5)
@ -1098,6 +1106,9 @@ _ENTRY(set_context)
sync
isync
blr
4: trap
EMIT_BUG_ENTRY 4b,__FILE__,__LINE__,0
blr
/*
* An undocumented "feature" of 604e requires that the v bit
@ -1131,7 +1142,7 @@ clear_bats:
mtspr SPRN_IBAT2L,r10
mtspr SPRN_IBAT3U,r10
mtspr SPRN_IBAT3L,r10
BEGIN_FTR_SECTION
BEGIN_MMU_FTR_SECTION
/* Here's a tweak: at this point, CPU setup have
* not been called yet, so HIGH_BAT_EN may not be
* set in HID0 for the 745x processors. However, it
@ -1154,7 +1165,7 @@ BEGIN_FTR_SECTION
mtspr SPRN_IBAT6L,r10
mtspr SPRN_IBAT7U,r10
mtspr SPRN_IBAT7L,r10
END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
blr
flush_tlbs:
@ -1178,11 +1189,11 @@ mmu_off:
/*
* Use the first pair of BAT registers to map the 1st 16MB
* of RAM to KERNELBASE. From this point on we can't safely
* of RAM to PAGE_OFFSET. From this point on we can't safely
* call OF any more.
*/
initial_bats:
lis r11,KERNELBASE@h
lis r11,PAGE_OFFSET@h
mfspr r9,SPRN_PVR
rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
cmpwi 0,r9,1

View File

@ -68,6 +68,17 @@ _ENTRY(_start);
mr r27,r7
li r24,0 /* CPU number */
/*
* In case the firmware didn't do it, we apply some workarounds
* that are good for all 440 core variants here
*/
mfspr r3,SPRN_CCR0
rlwinm r3,r3,0,0,27 /* disable icache prefetch */
isync
mtspr SPRN_CCR0,r3
isync
sync
/*
* Set up the initial MMU state
*
@ -391,12 +402,14 @@ interrupt_base:
rlwimi r13,r12,10,30,30
/* Load the PTE */
rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */
/* Compute pgdir/pmd offset */
rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29
lwzx r11, r12, r11 /* Get pgd/pmd entry */
rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */
beq 2f /* Bail if no table */
rlwimi r12, r10, 23, 20, 28 /* Compute pte address */
/* Compute pte address */
rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK_BIT, 28
lwz r11, 0(r12) /* Get high word of pte entry */
lwz r12, 4(r12) /* Get low word of pte entry */
@ -485,12 +498,14 @@ tlb_44x_patch_hwater_D:
/* Make up the required permissions */
li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC
rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */
/* Compute pgdir/pmd offset */
rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29
lwzx r11, r12, r11 /* Get pgd/pmd entry */
rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */
beq 2f /* Bail if no table */
rlwimi r12, r10, 23, 20, 28 /* Compute pte address */
/* Compute pte address */
rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK_BIT, 28
lwz r11, 0(r12) /* Get high word of pte entry */
lwz r12, 4(r12) /* Get low word of pte entry */
@ -554,15 +569,16 @@ tlb_44x_patch_hwater_I:
*/
finish_tlb_load:
/* Combine RPN & ERPN an write WS 0 */
rlwimi r11,r12,0,0,19
rlwimi r11,r12,0,0,31-PAGE_SHIFT
tlbwe r11,r13,PPC44x_TLB_XLAT
/*
* Create WS1. This is the faulting address (EPN),
* page size, and valid flag.
*/
li r11,PPC44x_TLB_VALID | PPC44x_TLB_4K
rlwimi r10,r11,0,20,31 /* Insert valid and page size*/
li r11,PPC44x_TLB_VALID | PPC44x_TLBE_SIZE
/* Insert valid and page size */
rlwimi r10,r11,0,PPC44x_PTE_ADD_MASK_BIT,31
tlbwe r10,r13,PPC44x_TLB_PAGEID /* Write PAGEID */
/* And WS 2 */
@ -634,12 +650,12 @@ _GLOBAL(set_context)
* goes at the beginning of the data segment, which is page-aligned.
*/
.data
.align 12
.align PAGE_SHIFT
.globl sdata
sdata:
.globl empty_zero_page
empty_zero_page:
.space 4096
.space PAGE_SIZE
/*
* To support >32-bit physical addresses, we use an 8KB pgdir.

View File

@ -92,6 +92,7 @@ _ENTRY(_start);
* if needed
*/
_ENTRY(__early_start)
/* 1. Find the index of the entry we're executing in */
bl invstr /* Find our address */
invstr: mflr r6 /* Make it accessible */
@ -235,36 +236,40 @@ skpinv: addi r6,r6,1 /* Increment */
tlbivax 0,r9
TLBSYNC
/* The mapping only needs to be cache-coherent on SMP */
#ifdef CONFIG_SMP
#define M_IF_SMP MAS2_M
#else
#define M_IF_SMP 0
#endif
/* 6. Setup KERNELBASE mapping in TLB1[0] */
lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
mtspr SPRN_MAS0,r6
lis r6,(MAS1_VALID|MAS1_IPROT)@h
ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l
mtspr SPRN_MAS1,r6
li r7,0
lis r6,PAGE_OFFSET@h
ori r6,r6,PAGE_OFFSET@l
rlwimi r6,r7,0,20,31
lis r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@h
ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@l
mtspr SPRN_MAS2,r6
mtspr SPRN_MAS3,r8
tlbwe
/* 7. Jump to KERNELBASE mapping */
lis r6,KERNELBASE@h
ori r6,r6,KERNELBASE@l
rlwimi r6,r7,0,20,31
lis r6,(KERNELBASE & ~0xfff)@h
ori r6,r6,(KERNELBASE & ~0xfff)@l
lis r7,MSR_KERNEL@h
ori r7,r7,MSR_KERNEL@l
bl 1f /* Find our address */
1: mflr r9
rlwimi r6,r9,0,20,31
addi r6,r6,24
addi r6,r6,(2f - 1b)
mtspr SPRN_SRR0,r6
mtspr SPRN_SRR1,r7
rfi /* start execution out of TLB1[0] entry */
/* 8. Clear out the temp mapping */
lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
2: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */
mtspr SPRN_MAS0,r7
tlbre
@ -344,6 +349,15 @@ skpinv: addi r6,r6,1 /* Increment */
mtspr SPRN_DBSR,r2
#endif
#ifdef CONFIG_SMP
/* Check to see if we're the second processor, and jump
* to the secondary_start code if so
*/
mfspr r24,SPRN_PIR
cmpwi r24,0
bne __secondary_start
#endif
/*
* This is where the main kernel code starts.
*/
@ -685,12 +699,13 @@ interrupt_base:
/* SPE Floating Point Data */
#ifdef CONFIG_SPE
EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE);
#else
EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE)
#endif /* CONFIG_SPE */
/* SPE Floating Point Round */
EXCEPTION(0x2050, SPEFloatingPointRound, SPEFloatingPointRoundException, EXC_XFER_EE)
#else
EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE)
EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE)
#endif /* CONFIG_SPE */
/* Performance Monitor */
EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD)
@ -734,6 +749,9 @@ finish_tlb_load:
rlwimi r12, r11, 26, 24, 31 /* extract ...WIMGE from pte */
#else
rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */
#endif
#ifdef CONFIG_SMP
ori r12, r12, MAS2_M
#endif
mtspr SPRN_MAS2, r12
@ -746,15 +764,15 @@ finish_tlb_load:
iseleq r12, r12, r10
#ifdef CONFIG_PTE_64BIT
2: rlwimi r12, r13, 24, 0, 7 /* grab RPN[32:39] */
rlwimi r12, r13, 24, 0, 7 /* grab RPN[32:39] */
rlwimi r12, r11, 24, 8, 19 /* grab RPN[40:51] */
mtspr SPRN_MAS3, r12
BEGIN_FTR_SECTION
BEGIN_MMU_FTR_SECTION
srwi r10, r13, 8 /* grab RPN[8:31] */
mtspr SPRN_MAS7, r10
END_FTR_SECTION_IFSET(CPU_FTR_BIG_PHYS)
END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
#else
2: rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */
rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */
mtspr SPRN_MAS3, r11
#endif
#ifdef CONFIG_E200
@ -1037,6 +1055,63 @@ _GLOBAL(flush_dcache_L1)
blr
#ifdef CONFIG_SMP
/* When we get here, r24 needs to hold the CPU # */
.globl __secondary_start
__secondary_start:
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
lis r3,tlbcam_index@ha
lwz r3,tlbcam_index@l(r3)
mtctr r3
li r26,0 /* r26 safe? */
/* Load each CAM entry */
1: mr r3,r26
bl loadcam_entry
addi r26,r26,1
bdnz 1b
/* get current_thread_info and current */
lis r1,secondary_ti@ha
lwz r1,secondary_ti@l(r1)
lwz r2,TI_TASK(r1)
/* stack */
addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
li r0,0
stw r0,0(r1)
/* ptr to current thread */
addi r4,r2,THREAD /* address of our thread_struct */
mtspr SPRN_SPRG3,r4
/* Setup the defaults for TLB entries */
li r4,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l
mtspr SPRN_MAS4,r4
/* Jump to start_secondary */
lis r4,MSR_KERNEL@h
ori r4,r4,MSR_KERNEL@l
lis r3,start_secondary@h
ori r3,r3,start_secondary@l
mtspr SPRN_SRR0,r3
mtspr SPRN_SRR1,r4
sync
rfi
sync
.globl __secondary_hold_acknowledge
__secondary_hold_acknowledge:
.long -1
#endif
/*
* 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.

View File

@ -47,7 +47,7 @@
#include <asm/abs_addr.h>
static struct device ibmebus_bus_device = { /* fake "parent" device */
.bus_id = "ibmebus",
.init_name = "ibmebus",
};
struct bus_type ibmebus_bus_type;
@ -231,6 +231,7 @@ void ibmebus_free_irq(u32 ist, void *dev_id)
unsigned int irq = irq_find_mapping(NULL, ist);
free_irq(irq, dev_id);
irq_dispose_mapping(irq);
}
EXPORT_SYMBOL(ibmebus_free_irq);

View File

@ -13,13 +13,17 @@
#include <linux/reboot.h>
#include <linux/threads.h>
#include <linux/lmb.h>
#include <linux/of.h>
#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/sections.h>
void machine_crash_shutdown(struct pt_regs *regs)
{
if (ppc_md.machine_crash_shutdown)
ppc_md.machine_crash_shutdown(regs);
else
default_machine_crash_shutdown(regs);
}
/*
@ -31,11 +35,8 @@ int machine_kexec_prepare(struct kimage *image)
{
if (ppc_md.machine_kexec_prepare)
return ppc_md.machine_kexec_prepare(image);
/*
* Fail if platform doesn't provide its own machine_kexec_prepare
* implementation.
*/
return -ENOSYS;
else
return default_machine_kexec_prepare(image);
}
void machine_kexec_cleanup(struct kimage *image)
@ -52,13 +53,11 @@ void machine_kexec(struct kimage *image)
{
if (ppc_md.machine_kexec)
ppc_md.machine_kexec(image);
else {
/*
* Fall back to normal restart if platform doesn't provide
* its own kexec function, and user insist to kexec...
*/
machine_restart(NULL);
}
else
default_machine_kexec(image);
/* Fall back to normal restart if we're still alive. */
machine_restart(NULL);
for(;;);
}
@ -118,3 +117,71 @@ int overlaps_crashkernel(unsigned long start, unsigned long size)
{
return (start + size) > crashk_res.start && start <= crashk_res.end;
}
/* Values we need to export to the second kernel via the device tree. */
static unsigned long kernel_end;
static unsigned long crashk_size;
static struct property kernel_end_prop = {
.name = "linux,kernel-end",
.length = sizeof(unsigned long),
.value = &kernel_end,
};
static struct property crashk_base_prop = {
.name = "linux,crashkernel-base",
.length = sizeof(unsigned long),
.value = &crashk_res.start,
};
static struct property crashk_size_prop = {
.name = "linux,crashkernel-size",
.length = sizeof(unsigned long),
.value = &crashk_size,
};
static void __init export_crashk_values(struct device_node *node)
{
struct property *prop;
/* There might be existing crash kernel properties, but we can't
* be sure what's in them, so remove them. */
prop = of_find_property(node, "linux,crashkernel-base", NULL);
if (prop)
prom_remove_property(node, prop);
prop = of_find_property(node, "linux,crashkernel-size", NULL);
if (prop)
prom_remove_property(node, prop);
if (crashk_res.start != 0) {
prom_add_property(node, &crashk_base_prop);
crashk_size = crashk_res.end - crashk_res.start + 1;
prom_add_property(node, &crashk_size_prop);
}
}
static int __init kexec_setup(void)
{
struct device_node *node;
struct property *prop;
node = of_find_node_by_path("/chosen");
if (!node)
return -ENOENT;
/* remove any stale properties so ours can be found */
prop = of_find_property(node, kernel_end_prop.name, NULL);
if (prop)
prom_remove_property(node, prop);
/* information needed by userspace when using default_machine_kexec */
kernel_end = __pa(_end);
prom_add_property(node, &kernel_end_prop);
export_crashk_values(node);
of_node_put(node);
return 0;
}
late_initcall(kexec_setup);

View File

@ -289,7 +289,7 @@ void default_machine_kexec(struct kimage *image)
}
/* Values we need to export to the second kernel via the device tree. */
static unsigned long htab_base, kernel_end;
static unsigned long htab_base;
static struct property htab_base_prop = {
.name = "linux,htab-base",
@ -303,25 +303,20 @@ static struct property htab_size_prop = {
.value = &htab_size_bytes,
};
static struct property kernel_end_prop = {
.name = "linux,kernel-end",
.length = sizeof(unsigned long),
.value = &kernel_end,
};
static void __init export_htab_values(void)
static int __init export_htab_values(void)
{
struct device_node *node;
struct property *prop;
/* On machines with no htab htab_address is NULL */
if (!htab_address)
return -ENODEV;
node = of_find_node_by_path("/chosen");
if (!node)
return;
return -ENODEV;
/* remove any stale propertys so ours can be found */
prop = of_find_property(node, kernel_end_prop.name, NULL);
if (prop)
prom_remove_property(node, prop);
prop = of_find_property(node, htab_base_prop.name, NULL);
if (prop)
prom_remove_property(node, prop);
@ -329,68 +324,11 @@ static void __init export_htab_values(void)
if (prop)
prom_remove_property(node, prop);
/* information needed by userspace when using default_machine_kexec */
kernel_end = __pa(_end);
prom_add_property(node, &kernel_end_prop);
/* On machines with no htab htab_address is NULL */
if (NULL == htab_address)
goto out;
htab_base = __pa(htab_address);
prom_add_property(node, &htab_base_prop);
prom_add_property(node, &htab_size_prop);
out:
of_node_put(node);
}
static struct property crashk_base_prop = {
.name = "linux,crashkernel-base",
.length = sizeof(unsigned long),
.value = &crashk_res.start,
};
static unsigned long crashk_size;
static struct property crashk_size_prop = {
.name = "linux,crashkernel-size",
.length = sizeof(unsigned long),
.value = &crashk_size,
};
static void __init export_crashk_values(void)
{
struct device_node *node;
struct property *prop;
node = of_find_node_by_path("/chosen");
if (!node)
return;
/* There might be existing crash kernel properties, but we can't
* be sure what's in them, so remove them. */
prop = of_find_property(node, "linux,crashkernel-base", NULL);
if (prop)
prom_remove_property(node, prop);
prop = of_find_property(node, "linux,crashkernel-size", NULL);
if (prop)
prom_remove_property(node, prop);
if (crashk_res.start != 0) {
prom_add_property(node, &crashk_base_prop);
crashk_size = crashk_res.end - crashk_res.start + 1;
prom_add_property(node, &crashk_size_prop);
}
of_node_put(node);
}
static int __init kexec_setup(void)
{
export_htab_values();
export_crashk_values();
return 0;
}
__initcall(kexec_setup);
late_initcall(export_htab_values);

View File

@ -29,6 +29,7 @@
#include <asm/asm-offsets.h>
#include <asm/processor.h>
#include <asm/kexec.h>
#include <asm/bug.h>
.text
@ -271,231 +272,6 @@ _GLOBAL(real_writeb)
#endif /* CONFIG_40x */
/*
* Flush MMU TLB
*/
#ifndef CONFIG_FSL_BOOKE
_GLOBAL(_tlbil_all)
_GLOBAL(_tlbil_pid)
#endif
_GLOBAL(_tlbia)
#if defined(CONFIG_40x)
sync /* Flush to memory before changing mapping */
tlbia
isync /* Flush shadow TLB */
#elif defined(CONFIG_44x)
li r3,0
sync
/* Load high watermark */
lis r4,tlb_44x_hwater@ha
lwz r5,tlb_44x_hwater@l(r4)
1: tlbwe r3,r3,PPC44x_TLB_PAGEID
addi r3,r3,1
cmpw 0,r3,r5
ble 1b
isync
#elif defined(CONFIG_FSL_BOOKE)
/* Invalidate all entries in TLB0 */
li r3, 0x04
tlbivax 0,3
/* Invalidate all entries in TLB1 */
li r3, 0x0c
tlbivax 0,3
msync
#ifdef CONFIG_SMP
tlbsync
#endif /* CONFIG_SMP */
#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
#if defined(CONFIG_SMP)
rlwinm r8,r1,0,0,(31-THREAD_SHIFT)
lwz r8,TI_CPU(r8)
oris r8,r8,10
mfmsr r10
SYNC
rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
rlwinm r0,r0,0,28,26 /* clear DR */
mtmsr r0
SYNC_601
isync
lis r9,mmu_hash_lock@h
ori r9,r9,mmu_hash_lock@l
tophys(r9,r9)
10: lwarx r7,0,r9
cmpwi 0,r7,0
bne- 10b
stwcx. r8,0,r9
bne- 10b
sync
tlbia
sync
TLBSYNC
li r0,0
stw r0,0(r9) /* clear mmu_hash_lock */
mtmsr r10
SYNC_601
isync
#else /* CONFIG_SMP */
sync
tlbia
sync
#endif /* CONFIG_SMP */
#endif /* ! defined(CONFIG_40x) */
blr
/*
* Flush MMU TLB for a particular address
*/
#ifndef CONFIG_FSL_BOOKE
_GLOBAL(_tlbil_va)
#endif
_GLOBAL(_tlbie)
#if defined(CONFIG_40x)
/* We run the search with interrupts disabled because we have to change
* the PID and I don't want to preempt when that happens.
*/
mfmsr r5
mfspr r6,SPRN_PID
wrteei 0
mtspr SPRN_PID,r4
tlbsx. r3, 0, r3
mtspr SPRN_PID,r6
wrtee r5
bne 10f
sync
/* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
* Since 25 is the V bit in the TLB_TAG, loading this value will invalidate
* the TLB entry. */
tlbwe r3, r3, TLB_TAG
isync
10:
#elif defined(CONFIG_44x)
mfspr r5,SPRN_MMUCR
rlwimi r5,r4,0,24,31 /* Set TID */
/* We have to run the search with interrupts disabled, even critical
* and debug interrupts (in fact the only critical exceptions we have
* are debug and machine check). Otherwise an interrupt which causes
* a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
mfmsr r4
lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
andc r6,r4,r6
mtmsr r6
mtspr SPRN_MMUCR,r5
tlbsx. r3, 0, r3
mtmsr r4
bne 10f
sync
/* There are only 64 TLB entries, so r3 < 64,
* which means bit 22, is clear. Since 22 is
* the V bit in the TLB_PAGEID, loading this
* value will invalidate the TLB entry.
*/
tlbwe r3, r3, PPC44x_TLB_PAGEID
isync
10:
#elif defined(CONFIG_FSL_BOOKE)
rlwinm r4, r3, 0, 0, 19
ori r5, r4, 0x08 /* TLBSEL = 1 */
tlbivax 0, r4
tlbivax 0, r5
msync
#if defined(CONFIG_SMP)
tlbsync
#endif /* CONFIG_SMP */
#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
#if defined(CONFIG_SMP)
rlwinm r8,r1,0,0,(31-THREAD_SHIFT)
lwz r8,TI_CPU(r8)
oris r8,r8,11
mfmsr r10
SYNC
rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */
rlwinm r0,r0,0,28,26 /* clear DR */
mtmsr r0
SYNC_601
isync
lis r9,mmu_hash_lock@h
ori r9,r9,mmu_hash_lock@l
tophys(r9,r9)
10: lwarx r7,0,r9
cmpwi 0,r7,0
bne- 10b
stwcx. r8,0,r9
bne- 10b
eieio
tlbie r3
sync
TLBSYNC
li r0,0
stw r0,0(r9) /* clear mmu_hash_lock */
mtmsr r10
SYNC_601
isync
#else /* CONFIG_SMP */
tlbie r3
sync
#endif /* CONFIG_SMP */
#endif /* ! CONFIG_40x */
blr
#if defined(CONFIG_FSL_BOOKE)
/*
* Flush MMU TLB, but only on the local processor (no broadcast)
*/
_GLOBAL(_tlbil_all)
#define MMUCSR0_TLBFI (MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \
MMUCSR0_TLB2FI | MMUCSR0_TLB3FI)
li r3,(MMUCSR0_TLBFI)@l
mtspr SPRN_MMUCSR0, r3
1:
mfspr r3,SPRN_MMUCSR0
andi. r3,r3,MMUCSR0_TLBFI@l
bne 1b
blr
/*
* Flush MMU TLB for a particular process id, but only on the local processor
* (no broadcast)
*/
_GLOBAL(_tlbil_pid)
/* we currently do an invalidate all since we don't have per pid invalidate */
li r3,(MMUCSR0_TLBFI)@l
mtspr SPRN_MMUCSR0, r3
1:
mfspr r3,SPRN_MMUCSR0
andi. r3,r3,MMUCSR0_TLBFI@l
bne 1b
msync
isync
blr
/*
* Flush MMU TLB for a particular address, but only on the local processor
* (no broadcast)
*/
_GLOBAL(_tlbil_va)
mfmsr r10
wrteei 0
slwi r4,r4,16
mtspr SPRN_MAS6,r4 /* assume AS=0 for now */
tlbsx 0,r3
mfspr r4,SPRN_MAS1 /* check valid */
andis. r3,r4,MAS1_VALID@h
beq 1f
rlwinm r4,r4,0,1,31
mtspr SPRN_MAS1,r4
tlbwe
msync
isync
1: wrtee r10
blr
#endif /* CONFIG_FSL_BOOKE */
/*
* Flush instruction cache.
@ -650,8 +426,8 @@ _GLOBAL(__flush_dcache_icache)
BEGIN_FTR_SECTION
blr
END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
rlwinm r3,r3,0,0,19 /* Get page base address */
li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */
rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */
li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */
mtctr r4
mr r6,r3
0: dcbst 0,r3 /* Write line to ram */
@ -691,8 +467,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
rlwinm r0,r10,0,28,26 /* clear DR */
mtmsr r0
isync
rlwinm r3,r3,0,0,19 /* Get page base address */
li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */
rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */
li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */
mtctr r4
mr r6,r3
0: dcbst 0,r3 /* Write line to ram */
@ -716,7 +492,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
* void clear_pages(void *page, int order) ;
*/
_GLOBAL(clear_pages)
li r0,4096/L1_CACHE_BYTES
li r0,PAGE_SIZE/L1_CACHE_BYTES
slw r0,r0,r4
mtctr r0
#ifdef CONFIG_8xx
@ -774,7 +550,7 @@ _GLOBAL(copy_page)
dcbt r5,r4
li r11,L1_CACHE_BYTES+4
#endif /* MAX_COPY_PREFETCH */
li r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH
li r0,PAGE_SIZE/L1_CACHE_BYTES - MAX_COPY_PREFETCH
crclr 4*cr0+eq
2:
mtctr r0

View File

@ -78,6 +78,12 @@ int module_finalize(const Elf_Ehdr *hdr,
(void *)sect->sh_addr,
(void *)sect->sh_addr + sect->sh_size);
sect = find_section(hdr, sechdrs, "__mmu_ftr_fixup");
if (sect != NULL)
do_feature_fixups(cur_cpu_spec->mmu_features,
(void *)sect->sh_addr,
(void *)sect->sh_addr + sect->sh_size);
#ifdef CONFIG_PPC64
sect = find_section(hdr, sechdrs, "__fw_ftr_fixup");
if (sect != NULL)

View File

@ -14,7 +14,6 @@ static void of_device_make_bus_id(struct of_device *dev)
{
static atomic_t bus_no_reg_magic;
struct device_node *node = dev->node;
char *name = dev->dev.bus_id;
const u32 *reg;
u64 addr;
int magic;
@ -27,14 +26,12 @@ static void of_device_make_bus_id(struct of_device *dev)
reg = of_get_property(node, "dcr-reg", NULL);
if (reg) {
#ifdef CONFIG_PPC_DCR_NATIVE
snprintf(name, BUS_ID_SIZE, "d%x.%s",
*reg, node->name);
dev_set_name(&dev->dev, "d%x.%s", *reg, node->name);
#else /* CONFIG_PPC_DCR_NATIVE */
addr = of_translate_dcr_address(node, *reg, NULL);
if (addr != OF_BAD_ADDR) {
snprintf(name, BUS_ID_SIZE,
"D%llx.%s", (unsigned long long)addr,
node->name);
dev_set_name(&dev->dev, "D%llx.%s",
(unsigned long long)addr, node->name);
return;
}
#endif /* !CONFIG_PPC_DCR_NATIVE */
@ -48,9 +45,8 @@ static void of_device_make_bus_id(struct of_device *dev)
if (reg) {
addr = of_translate_address(node, reg);
if (addr != OF_BAD_ADDR) {
snprintf(name, BUS_ID_SIZE,
"%llx.%s", (unsigned long long)addr,
node->name);
dev_set_name(&dev->dev, "%llx.%s",
(unsigned long long)addr, node->name);
return;
}
}
@ -60,7 +56,7 @@ static void of_device_make_bus_id(struct of_device *dev)
* counter (and pray...)
*/
magic = atomic_add_return(1, &bus_no_reg_magic);
snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1);
dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1);
}
struct of_device *of_device_alloc(struct device_node *np,
@ -80,7 +76,7 @@ struct of_device *of_device_alloc(struct device_node *np,
dev->dev.archdata.of_node = np;
if (bus_id)
strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
dev_set_name(&dev->dev, bus_id);
else
of_device_make_bus_id(dev);

View File

@ -37,6 +37,7 @@ struct lppaca lppaca[] = {
.end_of_quantum = 0xfffffffffffffffful,
.slb_count = 64,
.vmxregs_in_use = 0,
.page_ins = 0,
},
};

View File

@ -37,13 +37,7 @@
#include <asm/machdep.h>
#include <asm/ppc-pci.h>
#include <asm/firmware.h>
#ifdef DEBUG
#include <asm/udbg.h>
#define DBG(fmt...) printk(fmt)
#else
#define DBG(fmt...)
#endif
#include <asm/eeh.h>
static DEFINE_SPINLOCK(hose_spinlock);
@ -53,8 +47,9 @@ static int global_phb_number; /* Global phb counter */
/* ISA Memory physical address */
resource_size_t isa_mem_base;
/* Default PCI flags is 0 */
unsigned int ppc_pci_flags;
/* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */
unsigned int ppc_pci_flags = 0;
static struct dma_mapping_ops *pci_dma_ops;
@ -165,8 +160,6 @@ EXPORT_SYMBOL(pci_domain_nr);
*/
struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
{
if (!have_of)
return NULL;
while(node) {
struct pci_controller *hose, *tmp;
list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
@ -208,26 +201,6 @@ char __devinit *pcibios_setup(char *str)
return str;
}
void __devinit pcibios_setup_new_device(struct pci_dev *dev)
{
struct dev_archdata *sd = &dev->dev.archdata;
sd->of_node = pci_device_to_OF_node(dev);
DBG("PCI: device %s OF node: %s\n", pci_name(dev),
sd->of_node ? sd->of_node->full_name : "<none>");
sd->dma_ops = pci_dma_ops;
#ifdef CONFIG_PPC32
sd->dma_data = (void *)PCI_DRAM_OFFSET;
#endif
set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
if (ppc_md.pci_dma_dev_setup)
ppc_md.pci_dma_dev_setup(dev);
}
EXPORT_SYMBOL(pcibios_setup_new_device);
/*
* Reads the interrupt pin to determine if interrupt is use by card.
* If the interrupt is used, then gets the interrupt line from the
@ -252,7 +225,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
return -1;
#endif
DBG("Try to map irq for %s...\n", pci_name(pci_dev));
pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev));
#ifdef DEBUG
memset(&oirq, 0xff, sizeof(oirq));
@ -276,26 +249,26 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
line == 0xff || line == 0) {
return -1;
}
DBG(" -> no map ! Using line %d (pin %d) from PCI config\n",
line, pin);
pr_debug(" No map ! Using line %d (pin %d) from PCI config\n",
line, pin);
virq = irq_create_mapping(NULL, line);
if (virq != NO_IRQ)
set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
} else {
DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
oirq.size, oirq.specifier[0], oirq.specifier[1],
pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
oirq.size, oirq.specifier[0], oirq.specifier[1],
oirq.controller->full_name);
virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
oirq.size);
}
if(virq == NO_IRQ) {
DBG(" -> failed to map !\n");
pr_debug(" Failed to map !\n");
return -1;
}
DBG(" -> mapped to linux irq %d\n", virq);
pr_debug(" Mapped to linux irq %d\n", virq);
pci_dev->irq = virq;
@ -397,13 +370,10 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
}
/* XXX would be nice to have a way to ask for write-through */
prot |= _PAGE_NO_CACHE;
if (write_combine)
prot &= ~_PAGE_GUARDED;
return pgprot_noncached_wc(prot);
else
prot |= _PAGE_GUARDED;
return __pgprot(prot);
return pgprot_noncached(prot);
}
/*
@ -414,19 +384,17 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
pgprot_t pci_phys_mem_access_prot(struct file *file,
unsigned long pfn,
unsigned long size,
pgprot_t protection)
pgprot_t prot)
{
struct pci_dev *pdev = NULL;
struct resource *found = NULL;
unsigned long prot = pgprot_val(protection);
resource_size_t offset = ((resource_size_t)pfn) << PAGE_SHIFT;
int i;
if (page_is_ram(pfn))
return __pgprot(prot);
prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
return prot;
prot = pgprot_noncached(prot);
for_each_pci_dev(pdev) {
for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
struct resource *rp = &pdev->resource[i];
@ -447,14 +415,14 @@ pgprot_t pci_phys_mem_access_prot(struct file *file,
}
if (found) {
if (found->flags & IORESOURCE_PREFETCH)
prot &= ~_PAGE_GUARDED;
prot = pgprot_noncached_wc(prot);
pci_dev_put(pdev);
}
DBG("non-PCI map for %llx, prot: %lx\n",
(unsigned long long)offset, prot);
pr_debug("PCI: Non-PCI map for %llx, prot: %lx\n",
(unsigned long long)offset, pgprot_val(prot));
return __pgprot(prot);
return prot;
}
@ -610,8 +578,7 @@ int pci_mmap_legacy_page_range(struct pci_bus *bus,
pr_debug(" -> mapping phys %llx\n", (unsigned long long)offset);
vma->vm_pgoff = offset >> PAGE_SHIFT;
vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
| _PAGE_NO_CACHE | _PAGE_GUARDED);
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
@ -853,15 +820,12 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
int pci_proc_domain(struct pci_bus *bus)
{
struct pci_controller *hose = pci_bus_to_host(bus);
#ifdef CONFIG_PPC64
return hose->buid != 0;
#else
if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS))
return 0;
if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0)
return hose->global_number != 0;
return 1;
#endif
}
void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
@ -1083,27 +1047,50 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
}
}
static void __devinit __pcibios_fixup_bus(struct pci_bus *bus)
void __devinit pcibios_setup_bus_self(struct pci_bus *bus)
{
struct pci_dev *dev = bus->self;
pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB");
/* Fixup PCI<->PCI bridges. Host bridges are handled separately, for
* now differently between 32 and 64 bits.
*/
if (dev != NULL)
/* Fix up the bus resources for P2P bridges */
if (bus->self != NULL)
pcibios_fixup_bridge(bus);
/* Additional setup that is different between 32 and 64 bits for now */
pcibios_do_bus_setup(bus);
/* Platform specific bus fixups */
/* Platform specific bus fixups. This is currently only used
* by fsl_pci and I'm hoping to get rid of it at some point
*/
if (ppc_md.pcibios_fixup_bus)
ppc_md.pcibios_fixup_bus(bus);
/* Read default IRQs and fixup if necessary */
/* Setup bus DMA mappings */
if (ppc_md.pci_dma_bus_setup)
ppc_md.pci_dma_bus_setup(bus);
}
void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
{
struct pci_dev *dev;
pr_debug("PCI: Fixup bus devices %d (%s)\n",
bus->number, bus->self ? pci_name(bus->self) : "PHB");
list_for_each_entry(dev, &bus->devices, bus_list) {
struct dev_archdata *sd = &dev->dev.archdata;
/* Setup OF node pointer in archdata */
sd->of_node = pci_device_to_OF_node(dev);
/* Fixup NUMA node as it may not be setup yet by the generic
* code and is needed by the DMA init
*/
set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
/* Hook up default DMA ops */
sd->dma_ops = pci_dma_ops;
sd->dma_data = (void *)PCI_DRAM_OFFSET;
/* Additional platform DMA/iommu setup */
if (ppc_md.pci_dma_dev_setup)
ppc_md.pci_dma_dev_setup(dev);
/* Read default IRQs and fixup if necessary */
pci_read_irq_line(dev);
if (ppc_md.pci_irq_fixup)
ppc_md.pci_irq_fixup(dev);
@ -1113,23 +1100,20 @@ static void __devinit __pcibios_fixup_bus(struct pci_bus *bus)
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
{
/* When called from the generic PCI probe, read PCI<->PCI bridge
* bases before proceeding
* bases. This is -not- called when generating the PCI tree from
* the OF device-tree.
*/
if (bus->self != NULL)
pci_read_bridge_bases(bus);
__pcibios_fixup_bus(bus);
/* Now fixup the bus bus */
pcibios_setup_bus_self(bus);
/* Now fixup devices on that bus */
pcibios_setup_bus_devices(bus);
}
EXPORT_SYMBOL(pcibios_fixup_bus);
/* When building a bus from the OF tree rather than probing, we need a
* slightly different version of the fixup which doesn't read the
* bridge bases using config space accesses
*/
void __devinit pcibios_fixup_of_probed_bus(struct pci_bus *bus)
{
__pcibios_fixup_bus(bus);
}
static int skip_isa_ioresource_align(struct pci_dev *dev)
{
if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) &&
@ -1198,10 +1182,10 @@ static int __init reparent_resources(struct resource *parent,
*pp = NULL;
for (p = res->child; p != NULL; p = p->sibling) {
p->parent = res;
DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n",
p->name,
(unsigned long long)p->start,
(unsigned long long)p->end, res->name);
pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n",
p->name,
(unsigned long long)p->start,
(unsigned long long)p->end, res->name);
}
return 0;
}
@ -1245,9 +1229,12 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
int i;
struct resource *res, *pr;
pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
pci_domain_nr(bus), bus->number);
for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
if ((res = bus->resource[i]) == NULL || !res->flags
|| res->start > res->end)
|| res->start > res->end || res->parent)
continue;
if (bus->parent == NULL)
pr = (res->flags & IORESOURCE_IO) ?
@ -1271,14 +1258,14 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
}
}
DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
"[0x%x], parent %p (%s)\n",
bus->self ? pci_name(bus->self) : "PHB",
bus->number, i,
(unsigned long long)res->start,
(unsigned long long)res->end,
(unsigned int)res->flags,
pr, (pr && pr->name) ? pr->name : "nil");
pr_debug("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
"[0x%x], parent %p (%s)\n",
bus->self ? pci_name(bus->self) : "PHB",
bus->number, i,
(unsigned long long)res->start,
(unsigned long long)res->end,
(unsigned int)res->flags,
pr, (pr && pr->name) ? pr->name : "nil");
if (pr && !(pr->flags & IORESOURCE_UNSET)) {
if (request_resource(pr, res) == 0)
@ -1305,11 +1292,11 @@ static inline void __devinit alloc_resource(struct pci_dev *dev, int idx)
{
struct resource *pr, *r = &dev->resource[idx];
DBG("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n",
pci_name(dev), idx,
(unsigned long long)r->start,
(unsigned long long)r->end,
(unsigned int)r->flags);
pr_debug("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n",
pci_name(dev), idx,
(unsigned long long)r->start,
(unsigned long long)r->end,
(unsigned int)r->flags);
pr = pci_find_parent_resource(dev, r);
if (!pr || (pr->flags & IORESOURCE_UNSET) ||
@ -1317,10 +1304,11 @@ static inline void __devinit alloc_resource(struct pci_dev *dev, int idx)
printk(KERN_WARNING "PCI: Cannot allocate resource region %d"
" of device %s, will remap\n", idx, pci_name(dev));
if (pr)
DBG("PCI: parent is %p: %016llx-%016llx [%x]\n", pr,
(unsigned long long)pr->start,
(unsigned long long)pr->end,
(unsigned int)pr->flags);
pr_debug("PCI: parent is %p: %016llx-%016llx [%x]\n",
pr,
(unsigned long long)pr->start,
(unsigned long long)pr->end,
(unsigned int)pr->flags);
/* We'll assign a new address later */
r->flags |= IORESOURCE_UNSET;
r->end -= r->start;
@ -1358,7 +1346,8 @@ static void __init pcibios_allocate_resources(int pass)
* but keep it unregistered.
*/
u32 reg;
DBG("PCI: Switching off ROM of %s\n", pci_name(dev));
pr_debug("PCI: Switching off ROM of %s\n",
pci_name(dev));
r->flags &= ~IORESOURCE_ROM_ENABLE;
pci_read_config_dword(dev, dev->rom_base_reg, &reg);
pci_write_config_dword(dev, dev->rom_base_reg,
@ -1383,7 +1372,7 @@ void __init pcibios_resource_survey(void)
}
if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
DBG("PCI: Assigning unassigned resouces...\n");
pr_debug("PCI: Assigning unassigned resouces...\n");
pci_assign_unassigned_resources();
}
@ -1393,9 +1382,11 @@ void __init pcibios_resource_survey(void)
}
#ifdef CONFIG_HOTPLUG
/* This is used by the pSeries hotplug driver to allocate resource
/* This is used by the PCI hotplug driver to allocate resource
* of newly plugged busses. We can try to consolidate with the
* rest of the code later, for now, keep it as-is
* rest of the code later, for now, keep it as-is as our main
* resource allocation function doesn't deal with sub-trees yet.
*/
void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
{
@ -1410,6 +1401,14 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
if (r->parent || !r->start || !r->flags)
continue;
pr_debug("PCI: Claiming %s: "
"Resource %d: %016llx..%016llx [%x]\n",
pci_name(dev), i,
(unsigned long long)r->start,
(unsigned long long)r->end,
(unsigned int)r->flags);
pci_claim_resource(dev, i);
}
}
@ -1418,6 +1417,31 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
pcibios_claim_one_bus(child_bus);
}
EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
/* pcibios_finish_adding_to_bus
*
* This is to be called by the hotplug code after devices have been
* added to a bus, this include calling it for a PHB that is just
* being added
*/
void pcibios_finish_adding_to_bus(struct pci_bus *bus)
{
pr_debug("PCI: Finishing adding to hotplug bus %04x:%02x\n",
pci_domain_nr(bus), bus->number);
/* Allocate bus and devices resources */
pcibios_allocate_bus_resources(bus);
pcibios_claim_one_bus(bus);
/* Add new devices to global lists. Register in proc, sysfs. */
pci_bus_add_devices(bus);
/* Fixup EEH */
eeh_add_device_tree_late(bus);
}
EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus);
#endif /* CONFIG_HOTPLUG */
int pcibios_enable_device(struct pci_dev *dev, int mask)
@ -1428,3 +1452,61 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
return pci_enable_resources(dev, mask);
}
void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
{
struct pci_bus *bus = hose->bus;
struct resource *res;
int i;
/* Hookup PHB IO resource */
bus->resource[0] = res = &hose->io_resource;
if (!res->flags) {
printk(KERN_WARNING "PCI: I/O resource not set for host"
" bridge %s (domain %d)\n",
hose->dn->full_name, hose->global_number);
#ifdef CONFIG_PPC32
/* Workaround for lack of IO resource only on 32-bit */
res->start = (unsigned long)hose->io_base_virt - isa_io_base;
res->end = res->start + IO_SPACE_LIMIT;
res->flags = IORESOURCE_IO;
#endif /* CONFIG_PPC32 */
}
pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n",
(unsigned long long)res->start,
(unsigned long long)res->end,
(unsigned long)res->flags);
/* Hookup PHB Memory resources */
for (i = 0; i < 3; ++i) {
res = &hose->mem_resources[i];
if (!res->flags) {
if (i > 0)
continue;
printk(KERN_ERR "PCI: Memory resource 0 not set for "
"host bridge %s (domain %d)\n",
hose->dn->full_name, hose->global_number);
#ifdef CONFIG_PPC32
/* Workaround for lack of MEM resource only on 32-bit */
res->start = hose->pci_mem_offset;
res->end = (resource_size_t)-1LL;
res->flags = IORESOURCE_MEM;
#endif /* CONFIG_PPC32 */
}
bus->resource[i+1] = res;
pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i,
(unsigned long long)res->start,
(unsigned long long)res->end,
(unsigned long)res->flags);
}
pr_debug("PCI: PHB MEM offset = %016llx\n",
(unsigned long long)hose->pci_mem_offset);
pr_debug("PCI: PHB IO offset = %08lx\n",
(unsigned long)hose->io_base_virt - _IO_BASE);
}

View File

@ -26,12 +26,6 @@
#undef DEBUG
#ifdef DEBUG
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#endif
unsigned long isa_io_base = 0;
unsigned long pci_dram_offset = 0;
int pcibios_assign_bus_offset = 1;
@ -272,17 +266,14 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
{
struct device_node *parent, *np;
if (!have_of)
return NULL;
DBG("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn);
pr_debug("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn);
parent = scan_OF_for_pci_bus(bus);
if (parent == NULL)
return NULL;
DBG(" parent is %s\n", parent ? parent->full_name : "<NULL>");
pr_debug(" parent is %s\n", parent ? parent->full_name : "<NULL>");
np = scan_OF_for_pci_dev(parent, devfn);
of_node_put(parent);
DBG(" result is %s\n", np ? np->full_name : "<NULL>");
pr_debug(" result is %s\n", np ? np->full_name : "<NULL>");
/* XXX most callers don't release the returned node
* mostly because ppc64 doesn't increase the refcount,
@ -315,8 +306,6 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
struct pci_controller* hose;
struct pci_dev* dev = NULL;
if (!have_of)
return -ENODEV;
/* Make sure it's really a PCI device */
hose = pci_find_hose_for_OF_device(node);
if (!hose || !hose->dn)
@ -379,10 +368,41 @@ void pcibios_make_OF_bus_map(void)
}
#endif /* CONFIG_PPC_OF */
static void __devinit pcibios_scan_phb(struct pci_controller *hose)
{
struct pci_bus *bus;
struct device_node *node = hose->dn;
unsigned long io_offset;
struct resource *res = &hose->io_resource;
pr_debug("PCI: Scanning PHB %s\n",
node ? node->full_name : "<NO NAME>");
/* Create an empty bus for the toplevel */
bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
if (bus == NULL) {
printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
hose->global_number);
return;
}
bus->secondary = hose->first_busno;
hose->bus = bus;
/* Fixup IO space offset */
io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
res->start = (res->start + io_offset) & 0xffffffffu;
res->end = (res->end + io_offset) & 0xffffffffu;
/* Wire up PHB bus resources */
pcibios_setup_phb_resources(hose);
/* Scan children */
hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
}
static int __init pcibios_init(void)
{
struct pci_controller *hose, *tmp;
struct pci_bus *bus;
int next_busno = 0;
printk(KERN_INFO "PCI: Probing PCI hardware\n");
@ -395,12 +415,8 @@ static int __init pcibios_init(void)
if (pci_assign_all_buses)
hose->first_busno = next_busno;
hose->last_busno = 0xff;
bus = pci_scan_bus_parented(hose->parent, hose->first_busno,
hose->ops, hose);
if (bus) {
pci_bus_add_devices(bus);
hose->last_busno = bus->subordinate;
}
pcibios_scan_phb(hose);
pci_bus_add_devices(hose->bus);
if (pci_assign_all_buses || next_busno <= hose->last_busno)
next_busno = hose->last_busno + pcibios_assign_bus_offset;
}
@ -410,7 +426,7 @@ static int __init pcibios_init(void)
* numbers vs. kernel bus numbers since we may have to
* remap them.
*/
if (pci_assign_all_buses && have_of)
if (pci_assign_all_buses)
pcibios_make_OF_bus_map();
/* Call common code to handle resource allocation */
@ -425,54 +441,6 @@ static int __init pcibios_init(void)
subsys_initcall(pcibios_init);
void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
{
struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
unsigned long io_offset;
struct resource *res;
int i;
struct pci_dev *dev;
/* Hookup PHB resources */
io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
if (bus->parent == NULL) {
/* This is a host bridge - fill in its resources */
hose->bus = bus;
bus->resource[0] = res = &hose->io_resource;
if (!res->flags) {
if (io_offset)
printk(KERN_ERR "I/O resource not set for host"
" bridge %d\n", hose->global_number);
res->start = 0;
res->end = IO_SPACE_LIMIT;
res->flags = IORESOURCE_IO;
}
res->start = (res->start + io_offset) & 0xffffffffu;
res->end = (res->end + io_offset) & 0xffffffffu;
for (i = 0; i < 3; ++i) {
res = &hose->mem_resources[i];
if (!res->flags) {
if (i > 0)
continue;
printk(KERN_ERR "Memory resource not set for "
"host bridge %d\n", hose->global_number);
res->start = hose->pci_mem_offset;
res->end = ~0U;
res->flags = IORESOURCE_MEM;
}
bus->resource[i+1] = res;
}
}
if (ppc_md.pci_dma_bus_setup)
ppc_md.pci_dma_bus_setup(bus);
list_for_each_entry(dev, &bus->devices, bus_list)
pcibios_setup_new_device(dev);
}
/* the next one is stolen from the alpha port... */
void __init
pcibios_update_irq(struct pci_dev *dev, int irq)

View File

@ -32,13 +32,6 @@
#include <asm/machdep.h>
#include <asm/ppc-pci.h>
#ifdef DEBUG
#include <asm/udbg.h>
#define DBG(fmt...) printk(fmt)
#else
#define DBG(fmt...)
#endif
unsigned long pci_probe_only = 1;
/* pci_io_base -- the base address from which io bars are offsets.
@ -102,7 +95,7 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
addrs = of_get_property(node, "assigned-addresses", &proplen);
if (!addrs)
return;
DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs);
pr_debug(" parse addresses (%d bytes) @ %p\n", proplen, addrs);
for (; proplen >= 20; proplen -= 20, addrs += 5) {
flags = pci_parse_of_flags(addrs[0]);
if (!flags)
@ -112,8 +105,9 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
if (!size)
continue;
i = addrs[0] & 0xff;
DBG(" base: %llx, size: %llx, i: %x\n",
(unsigned long long)base, (unsigned long long)size, i);
pr_debug(" base: %llx, size: %llx, i: %x\n",
(unsigned long long)base,
(unsigned long long)size, i);
if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
@ -144,7 +138,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
if (type == NULL)
type = "";
DBG(" create device, devfn: %x, type: %s\n", devfn, type);
pr_debug(" create device, devfn: %x, type: %s\n", devfn, type);
dev->bus = bus;
dev->sysdata = node;
@ -165,8 +159,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
dev->class = get_int_prop(node, "class-code", 0);
dev->revision = get_int_prop(node, "revision-id", 0);
DBG(" class: 0x%x\n", dev->class);
DBG(" revision: 0x%x\n", dev->revision);
pr_debug(" class: 0x%x\n", dev->class);
pr_debug(" revision: 0x%x\n", dev->revision);
dev->current_state = 4; /* unknown power state */
dev->error_state = pci_channel_io_normal;
@ -187,7 +181,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
pci_parse_of_addrs(node, dev);
DBG(" adding to system ...\n");
pr_debug(" adding to system ...\n");
pci_device_add(dev, bus);
@ -195,19 +189,20 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
}
EXPORT_SYMBOL(of_create_pci_dev);
void __devinit of_scan_bus(struct device_node *node,
struct pci_bus *bus)
static void __devinit __of_scan_bus(struct device_node *node,
struct pci_bus *bus, int rescan_existing)
{
struct device_node *child;
const u32 *reg;
int reglen, devfn;
struct pci_dev *dev;
DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number);
pr_debug("of_scan_bus(%s) bus no %d... \n",
node->full_name, bus->number);
/* Scan direct children */
for_each_child_of_node(node, child) {
DBG(" * %s\n", child->full_name);
pr_debug(" * %s\n", child->full_name);
reg = of_get_property(child, "reg", &reglen);
if (reg == NULL || reglen < 20)
continue;
@ -217,11 +212,15 @@ void __devinit of_scan_bus(struct device_node *node,
dev = of_create_pci_dev(child, bus, devfn);
if (!dev)
continue;
DBG(" dev header type: %x\n", dev->hdr_type);
pr_debug(" dev header type: %x\n", dev->hdr_type);
}
/* Ally all fixups */
pcibios_fixup_of_probed_bus(bus);
/* Apply all fixups necessary. We don't fixup the bus "self"
* for an existing bridge that is being rescanned
*/
if (!rescan_existing)
pcibios_setup_bus_self(bus);
pcibios_setup_bus_devices(bus);
/* Now scan child busses */
list_for_each_entry(dev, &bus->devices, bus_list) {
@ -233,7 +232,20 @@ void __devinit of_scan_bus(struct device_node *node,
}
}
}
EXPORT_SYMBOL(of_scan_bus);
void __devinit of_scan_bus(struct device_node *node,
struct pci_bus *bus)
{
__of_scan_bus(node, bus, 0);
}
EXPORT_SYMBOL_GPL(of_scan_bus);
void __devinit of_rescan_bus(struct device_node *node,
struct pci_bus *bus)
{
__of_scan_bus(node, bus, 1);
}
EXPORT_SYMBOL_GPL(of_rescan_bus);
void __devinit of_scan_pci_bridge(struct device_node *node,
struct pci_dev *dev)
@ -245,7 +257,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
unsigned int flags;
u64 size;
DBG("of_scan_pci_bridge(%s)\n", node->full_name);
pr_debug("of_scan_pci_bridge(%s)\n", node->full_name);
/* parse bus-range property */
busrange = of_get_property(node, "bus-range", &len);
@ -309,12 +321,12 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
}
sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
bus->number);
DBG(" bus name: %s\n", bus->name);
pr_debug(" bus name: %s\n", bus->name);
mode = PCI_PROBE_NORMAL;
if (ppc_md.pci_probe_mode)
mode = ppc_md.pci_probe_mode(bus);
DBG(" probe mode: %d\n", mode);
pr_debug(" probe mode: %d\n", mode);
if (mode == PCI_PROBE_DEVTREE)
of_scan_bus(node, bus);
@ -327,9 +339,10 @@ void __devinit scan_phb(struct pci_controller *hose)
{
struct pci_bus *bus;
struct device_node *node = hose->dn;
int i, mode;
int mode;
DBG("PCI: Scanning PHB %s\n", node ? node->full_name : "<NO NAME>");
pr_debug("PCI: Scanning PHB %s\n",
node ? node->full_name : "<NO NAME>");
/* Create an empty bus for the toplevel */
bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node);
@ -345,26 +358,13 @@ void __devinit scan_phb(struct pci_controller *hose)
pcibios_map_io_space(bus);
/* Wire up PHB bus resources */
DBG("PCI: PHB IO resource = %016lx-%016lx [%lx]\n",
hose->io_resource.start, hose->io_resource.end,
hose->io_resource.flags);
bus->resource[0] = &hose->io_resource;
for (i = 0; i < 3; ++i) {
DBG("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i,
hose->mem_resources[i].start,
hose->mem_resources[i].end,
hose->mem_resources[i].flags);
bus->resource[i+1] = &hose->mem_resources[i];
}
DBG("PCI: PHB MEM offset = %016lx\n", hose->pci_mem_offset);
DBG("PCI: PHB IO offset = %08lx\n",
(unsigned long)hose->io_base_virt - _IO_BASE);
pcibios_setup_phb_resources(hose);
/* Get probe mode and perform scan */
mode = PCI_PROBE_NORMAL;
if (node && ppc_md.pci_probe_mode)
mode = ppc_md.pci_probe_mode(bus);
DBG(" probe mode: %d\n", mode);
pr_debug(" probe mode: %d\n", mode);
if (mode == PCI_PROBE_DEVTREE) {
bus->subordinate = hose->last_busno;
of_scan_bus(node, bus);
@ -380,7 +380,7 @@ static int __init pcibios_init(void)
printk(KERN_INFO "PCI: Probing PCI hardware\n");
/* For now, override phys_mem_access_prot. If we need it,
/* For now, override phys_mem_access_prot. If we need it,g
* later, we may move that initialization to each ppc_md
*/
ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
@ -388,6 +388,11 @@ static int __init pcibios_init(void)
if (pci_probe_only)
ppc_pci_flags |= PPC_PCI_PROBE_ONLY;
/* On ppc64, we always enable PCI domains and we keep domain 0
* backward compatible in /proc for video cards
*/
ppc_pci_flags |= PPC_PCI_ENABLE_PROC_DOMAINS | PPC_PCI_COMPAT_DOMAIN_0;
/* Scan all of the recorded PCI controllers. */
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
scan_phb(hose);
@ -422,8 +427,8 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
if (bus->self) {
struct resource *res = bus->resource[0];
DBG("IO unmapping for PCI-PCI bridge %s\n",
pci_name(bus->self));
pr_debug("IO unmapping for PCI-PCI bridge %s\n",
pci_name(bus->self));
__flush_hash_table_range(&init_mm, res->start + _IO_BASE,
res->end + _IO_BASE + 1);
@ -437,8 +442,8 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
if (hose->io_base_alloc == 0)
return 0;
DBG("IO unmapping for PHB %s\n", hose->dn->full_name);
DBG(" alloc=0x%p\n", hose->io_base_alloc);
pr_debug("IO unmapping for PHB %s\n", hose->dn->full_name);
pr_debug(" alloc=0x%p\n", hose->io_base_alloc);
/* This is a PHB, we fully unmap the IO area */
vunmap(hose->io_base_alloc);
@ -463,11 +468,11 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
* thus HPTEs will be faulted in when needed
*/
if (bus->self) {
DBG("IO mapping for PCI-PCI bridge %s\n",
pci_name(bus->self));
DBG(" virt=0x%016lx...0x%016lx\n",
bus->resource[0]->start + _IO_BASE,
bus->resource[0]->end + _IO_BASE);
pr_debug("IO mapping for PCI-PCI bridge %s\n",
pci_name(bus->self));
pr_debug(" virt=0x%016lx...0x%016lx\n",
bus->resource[0]->start + _IO_BASE,
bus->resource[0]->end + _IO_BASE);
return 0;
}
@ -496,11 +501,11 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
hose->io_base_virt = (void __iomem *)(area->addr +
hose->io_base_phys - phys_page);
DBG("IO mapping for PHB %s\n", hose->dn->full_name);
DBG(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n",
hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc);
DBG(" size=0x%016lx (alloc=0x%016lx)\n",
hose->pci_io_size, size_page);
pr_debug("IO mapping for PHB %s\n", hose->dn->full_name);
pr_debug(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n",
hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc);
pr_debug(" size=0x%016lx (alloc=0x%016lx)\n",
hose->pci_io_size, size_page);
/* Establish the mapping */
if (__ioremap_at(phys_page, area->addr, size_page,
@ -512,24 +517,13 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
hose->io_resource.start += io_virt_offset;
hose->io_resource.end += io_virt_offset;
DBG(" hose->io_resource=0x%016lx...0x%016lx\n",
hose->io_resource.start, hose->io_resource.end);
pr_debug(" hose->io_resource=0x%016lx...0x%016lx\n",
hose->io_resource.start, hose->io_resource.end);
return 0;
}
EXPORT_SYMBOL_GPL(pcibios_map_io_space);
void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
{
struct pci_dev *dev;
if (ppc_md.pci_dma_bus_setup)
ppc_md.pci_dma_bus_setup(bus);
list_for_each_entry(dev, &bus->devices, bus_list)
pcibios_setup_new_device(dev);
}
unsigned long pci_address_to_pio(phys_addr_t address)
{
struct pci_controller *hose, *tmp;

View File

@ -116,12 +116,6 @@ EXPORT_SYMBOL(giveup_spe);
#ifndef CONFIG_PPC64
EXPORT_SYMBOL(flush_instruction_cache);
EXPORT_SYMBOL(flush_tlb_kernel_range);
EXPORT_SYMBOL(flush_tlb_page);
EXPORT_SYMBOL(_tlbie);
#if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE)
EXPORT_SYMBOL(_tlbil_va);
#endif
#endif
EXPORT_SYMBOL(__flush_icache_range);
EXPORT_SYMBOL(flush_dcache_range);
@ -174,8 +168,7 @@ EXPORT_SYMBOL(cacheable_memcpy);
#endif
#ifdef CONFIG_PPC32
EXPORT_SYMBOL(next_mmu_context);
EXPORT_SYMBOL(set_context);
EXPORT_SYMBOL(switch_mmu_context);
#endif
#ifdef CONFIG_PPC_STD_MMU_32

View File

@ -22,7 +22,7 @@
* that will be different for 32-bit and 64-bit, because of the
* different ABIs, though).
*/
_GLOBAL(xmon_save_regs)
_GLOBAL(ppc_save_regs)
PPC_STL r0,0*SZL(r3)
PPC_STL r2,2*SZL(r3)
PPC_STL r3,3*SZL(r3)

View File

@ -467,6 +467,8 @@ static struct regbit {
{MSR_VEC, "VEC"},
{MSR_VSX, "VSX"},
{MSR_ME, "ME"},
{MSR_CE, "CE"},
{MSR_DE, "DE"},
{MSR_IR, "IR"},
{MSR_DR, "DR"},
{0, NULL}
@ -998,7 +1000,7 @@ unsigned long get_wchan(struct task_struct *p)
return 0;
}
static int kstack_depth_to_print = 64;
static int kstack_depth_to_print = CONFIG_PRINT_STACK_DEPTH;
void show_stack(struct task_struct *tsk, unsigned long *stack)
{

View File

@ -1160,6 +1160,8 @@ static inline void __init phyp_dump_reserve_mem(void) {}
void __init early_init_devtree(void *params)
{
unsigned long limit;
DBG(" -> early_init_devtree(%p)\n", params);
/* Setup flat device-tree pointer */
@ -1200,7 +1202,19 @@ void __init early_init_devtree(void *params)
early_reserve_mem();
phyp_dump_reserve_mem();
lmb_enforce_memory_limit(memory_limit);
limit = memory_limit;
if (! limit) {
unsigned long memsize;
/* Ensure that total memory size is page-aligned, because
* otherwise mark_bootmem() gets upset. */
lmb_analyze();
memsize = lmb_phys_mem_size();
if ((memsize & PAGE_MASK) != memsize)
limit = memsize & PAGE_MASK;
}
lmb_enforce_memory_limit(limit);
lmb_analyze();
DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
@ -1270,6 +1284,37 @@ struct device_node *of_find_node_by_phandle(phandle handle)
}
EXPORT_SYMBOL(of_find_node_by_phandle);
/**
* of_find_next_cache_node - Find a node's subsidiary cache
* @np: node of type "cpu" or "cache"
*
* Returns a node pointer with refcount incremented, use
* of_node_put() on it when done. Caller should hold a reference
* to np.
*/
struct device_node *of_find_next_cache_node(struct device_node *np)
{
struct device_node *child;
const phandle *handle;
handle = of_get_property(np, "l2-cache", NULL);
if (!handle)
handle = of_get_property(np, "next-level-cache", NULL);
if (handle)
return of_find_node_by_phandle(*handle);
/* OF on pmac has nodes instead of properties named "l2-cache"
* beneath CPU nodes.
*/
if (!strcmp(np->type, "cpu"))
for_each_child_of_node(np, child)
if (!strcmp(child->type, "cache"))
return child;
return NULL;
}
/**
* of_find_all_nodes - Get next node in global list
* @prev: Previous node or NULL to start iteration

View File

@ -734,10 +734,7 @@ void of_irq_map_init(unsigned int flags)
if (flags & OF_IMAP_NO_PHANDLE) {
struct device_node *np;
for(np = NULL; (np = of_find_all_nodes(np)) != NULL;) {
if (of_get_property(np, "interrupt-controller", NULL)
== NULL)
continue;
for_each_node_with_property(np, "interrupt-controller") {
/* Skip /chosen/interrupt-controller */
if (strcmp(np->name, "chosen") == 0)
continue;

View File

@ -566,6 +566,32 @@ int rtas_get_sensor(int sensor, int index, int *state)
}
EXPORT_SYMBOL(rtas_get_sensor);
bool rtas_indicator_present(int token, int *maxindex)
{
int proplen, count, i;
const struct indicator_elem {
u32 token;
u32 maxindex;
} *indicators;
indicators = of_get_property(rtas.dev, "rtas-indicators", &proplen);
if (!indicators)
return false;
count = proplen / sizeof(struct indicator_elem);
for (i = 0; i < count; i++) {
if (indicators[i].token != token)
continue;
if (maxindex)
*maxindex = indicators[i].maxindex;
return true;
}
return false;
}
EXPORT_SYMBOL(rtas_indicator_present);
int rtas_set_indicator(int indicator, int index, int new_value)
{
int token = rtas_token("set-indicator");

Some files were not shown because too many files have changed in this diff Show More