diff options
Diffstat (limited to 'arch')
187 files changed, 9078 insertions, 565 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index df39d20f742..f504c801792 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -356,7 +356,7 @@ config ARCH_IXP4XX select GENERIC_GPIO select GENERIC_TIME select GENERIC_CLOCKEVENTS - select ZONE_DMA if PCI + select DMABOUNCE if PCI help Support for Intel's IXP4XX (XScale) family of processors. @@ -1256,6 +1256,8 @@ source "drivers/hid/Kconfig" source "drivers/usb/Kconfig" +source "drivers/uwb/Kconfig" + source "drivers/mmc/Kconfig" source "drivers/memstick/Kconfig" diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 2e32acca02f..86b5e698266 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -13,10 +13,10 @@ config ICST307 config SA1111 bool select DMABOUNCE if !ARCH_PXA - select ZONE_DMA if !ARCH_PXA config DMABOUNCE bool + select ZONE_DMA config TIMER_ACORN bool diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index fb86f248aab..47ccec95f3e 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -581,6 +581,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, goto out; } +#ifdef CONFIG_DMABOUNCE /* * If the parent device has a DMA mask associated with it, * propagate it down to the children. @@ -598,6 +599,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, } } } +#endif out: return ret; @@ -937,7 +939,7 @@ static int sa1111_resume(struct platform_device *dev) #define sa1111_resume NULL #endif -static int sa1111_probe(struct platform_device *pdev) +static int __devinit sa1111_probe(struct platform_device *pdev) { struct resource *mem; int irq; diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig index 8b7a431a8bf..9033d147f05 100644 --- a/arch/arm/configs/trizeps4_defconfig +++ b/arch/arm/configs/trizeps4_defconfig @@ -147,6 +147,7 @@ CONFIG_ARCH_PXA=y # CONFIG_MACH_MAINSTONE is not set # CONFIG_ARCH_PXA_IDP is not set # CONFIG_PXA_SHARPSL is not set +CONFIG_TRIZEPS_PXA=y CONFIG_MACH_TRIZEPS4=y CONFIG_MACH_TRIZEPS4_CONXS=y # CONFIG_MACH_TRIZEPS4_ANY is not set diff --git a/arch/arm/mach-clps711x/include/mach/memory.h b/arch/arm/mach-clps711x/include/mach/memory.h index 71c2fa70c8e..98ec30c97bb 100644 --- a/arch/arm/mach-clps711x/include/mach/memory.h +++ b/arch/arm/mach-clps711x/include/mach/memory.h @@ -89,6 +89,8 @@ * node 3: 0xd8000000 - 0xdfffffff */ #define NODE_MEM_SIZE_BITS 24 +#define SECTION_SIZE_BITS 24 +#define MAX_PHYSMEM_BITS 32 #endif diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index db8b5fe06c0..2c5a02b8520 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -167,11 +167,6 @@ config MACH_GTWX5715 comment "IXP4xx Options" -config DMABOUNCE - bool - default y - depends on PCI - config IXP4XX_INDIRECT_PCI bool "Use indirect PCI memory access" depends on PCI diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 85cad05d8c5..0bb1fbd84cc 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -16,6 +16,7 @@ #include <linux/mv643xx_eth.h> #include <linux/ata_platform.h> #include <linux/spi/orion_spi.h> +#include <net/dsa.h> #include <asm/page.h> #include <asm/timex.h> #include <asm/mach/map.h> @@ -152,6 +153,40 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) /***************************************************************************** + * Ethernet switch + ****************************************************************************/ +static struct resource kirkwood_switch_resources[] = { + { + .start = 0, + .end = 0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device kirkwood_switch_device = { + .name = "dsa", + .id = 0, + .num_resources = 0, + .resource = kirkwood_switch_resources, +}; + +void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq) +{ + if (irq != NO_IRQ) { + kirkwood_switch_resources[0].start = irq; + kirkwood_switch_resources[0].end = irq; + kirkwood_switch_device.num_resources = 1; + } + + d->mii_bus = &kirkwood_ge00_shared.dev; + d->netdev = &kirkwood_ge00.dev; + kirkwood_switch_device.dev.platform_data = d; + + platform_device_register(&kirkwood_switch_device); +} + + +/***************************************************************************** * SoC RTC ****************************************************************************/ static struct resource kirkwood_rtc_resource = { diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index 8fa0f6a2763..5774632a67e 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h @@ -11,6 +11,7 @@ #ifndef __ARCH_KIRKWOOD_COMMON_H #define __ARCH_KIRKWOOD_COMMON_H +struct dsa_platform_data; struct mv643xx_eth_platform_data; struct mv_sata_platform_data; @@ -29,6 +30,7 @@ void kirkwood_pcie_id(u32 *dev, u32 *rev); void kirkwood_ehci_init(void); void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data); +void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq); void kirkwood_pcie_init(void); void kirkwood_rtc_init(void); void kirkwood_sata_init(struct mv_sata_platform_data *sata_data); diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c index f785093e433..175054abd63 100644 --- a/arch/arm/mach-kirkwood/rd88f6281-setup.c +++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c @@ -19,6 +19,7 @@ #include <linux/ata_platform.h> #include <linux/mv643xx_eth.h> #include <linux/ethtool.h> +#include <net/dsa.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/pci.h> @@ -74,6 +75,15 @@ static struct mv643xx_eth_platform_data rd88f6281_ge00_data = { .duplex = DUPLEX_FULL, }; +static struct dsa_platform_data rd88f6281_switch_data = { + .port_names[0] = "lan1", + .port_names[1] = "lan2", + .port_names[2] = "lan3", + .port_names[3] = "lan4", + .port_names[4] = "wan", + .port_names[5] = "cpu", +}; + static struct mv_sata_platform_data rd88f6281_sata_data = { .n_ports = 2, }; @@ -87,6 +97,7 @@ static void __init rd88f6281_init(void) kirkwood_ehci_init(); kirkwood_ge00_init(&rd88f6281_ge00_data); + kirkwood_ge00_switch_init(&rd88f6281_switch_data, NO_IRQ); kirkwood_rtc_init(); kirkwood_sata_init(&rd88f6281_sata_data); kirkwood_uart0_init(); diff --git a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c index 49f434c39eb..2e285bbb7bb 100644 --- a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c +++ b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c @@ -13,6 +13,7 @@ #include <linux/platform_device.h> #include <linux/ata_platform.h> #include <linux/mv643xx_eth.h> +#include <linux/ethtool.h> #include <mach/mv78xx0.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -28,10 +29,14 @@ static struct mv643xx_eth_platform_data db78x00_ge01_data = { static struct mv643xx_eth_platform_data db78x00_ge10_data = { .phy_addr = MV643XX_ETH_PHY_NONE, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, }; static struct mv643xx_eth_platform_data db78x00_ge11_data = { .phy_addr = MV643XX_ETH_PHY_NONE, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, }; static struct mv_sata_platform_data db78x00_sata_data = { diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 9625ef5975d..437065c25c9 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -19,6 +19,7 @@ #include <linux/mv643xx_i2c.h> #include <linux/ata_platform.h> #include <linux/spi/orion_spi.h> +#include <net/dsa.h> #include <asm/page.h> #include <asm/setup.h> #include <asm/timex.h> @@ -198,6 +199,40 @@ void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data) /***************************************************************************** + * Ethernet switch + ****************************************************************************/ +static struct resource orion5x_switch_resources[] = { + { + .start = 0, + .end = 0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device orion5x_switch_device = { + .name = "dsa", + .id = 0, + .num_resources = 0, + .resource = orion5x_switch_resources, +}; + +void __init orion5x_eth_switch_init(struct dsa_platform_data *d, int irq) +{ + if (irq != NO_IRQ) { + orion5x_switch_resources[0].start = irq; + orion5x_switch_resources[0].end = irq; + orion5x_switch_device.num_resources = 1; + } + + d->mii_bus = &orion5x_eth_shared.dev; + d->netdev = &orion5x_eth.dev; + orion5x_switch_device.dev.platform_data = d; + + platform_device_register(&orion5x_switch_device); +} + + +/***************************************************************************** * I2C ****************************************************************************/ static struct mv64xxx_i2c_pdata orion5x_i2c_pdata = { @@ -275,7 +310,8 @@ void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data) * SPI ****************************************************************************/ static struct orion_spi_info orion5x_spi_plat_data = { - .tclk = 0, + .tclk = 0, + .enable_clock_fix = 1, }; static struct resource orion5x_spi_resources[] = { diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h index 1f8b2da676a..a000c7c6ee9 100644 --- a/arch/arm/mach-orion5x/common.h +++ b/arch/arm/mach-orion5x/common.h @@ -1,6 +1,7 @@ #ifndef __ARCH_ORION5X_COMMON_H #define __ARCH_ORION5X_COMMON_H +struct dsa_platform_data; struct mv643xx_eth_platform_data; struct mv_sata_platform_data; @@ -29,6 +30,7 @@ void orion5x_setup_pcie_wa_win(u32 base, u32 size); void orion5x_ehci0_init(void); void orion5x_ehci1_init(void); void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data); +void orion5x_eth_switch_init(struct dsa_platform_data *d, int irq); void orion5x_i2c_init(void); void orion5x_sata_init(struct mv_sata_platform_data *sata_data); void orion5x_spi_init(void); diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c index 500cdadaf09..15f53235ee3 100644 --- a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c +++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c @@ -16,6 +16,7 @@ #include <linux/mtd/physmap.h> #include <linux/mv643xx_eth.h> #include <linux/ethtool.h> +#include <net/dsa.h> #include <asm/mach-types.h> #include <asm/gpio.h> #include <asm/leds.h> @@ -93,6 +94,15 @@ static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = { .duplex = DUPLEX_FULL, }; +static struct dsa_platform_data rd88f5181l_fxo_switch_data = { + .port_names[0] = "lan2", + .port_names[1] = "lan1", + .port_names[2] = "wan", + .port_names[3] = "cpu", + .port_names[5] = "lan4", + .port_names[7] = "lan3", +}; + static void __init rd88f5181l_fxo_init(void) { /* @@ -107,6 +117,7 @@ static void __init rd88f5181l_fxo_init(void) */ orion5x_ehci0_init(); orion5x_eth_init(&rd88f5181l_fxo_eth_data); + orion5x_eth_switch_init(&rd88f5181l_fxo_switch_data, NO_IRQ); orion5x_uart0_init(); orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE, diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c index ebde8141649..8ad3934399d 100644 --- a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c +++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c @@ -17,6 +17,7 @@ #include <linux/mv643xx_eth.h> #include <linux/ethtool.h> #include <linux/i2c.h> +#include <net/dsa.h> #include <asm/mach-types.h> #include <asm/gpio.h> #include <asm/leds.h> @@ -94,6 +95,15 @@ static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = { .duplex = DUPLEX_FULL, }; +static struct dsa_platform_data rd88f5181l_ge_switch_data = { + .port_names[0] = "lan2", + .port_names[1] = "lan1", + .port_names[2] = "wan", + .port_names[3] = "cpu", + .port_names[5] = "lan4", + .port_names[7] = "lan3", +}; + static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = { I2C_BOARD_INFO("ds1338", 0x68), }; @@ -112,6 +122,7 @@ static void __init rd88f5181l_ge_init(void) */ orion5x_ehci0_init(); orion5x_eth_init(&rd88f5181l_ge_eth_data); + orion5x_eth_switch_init(&rd88f5181l_ge_switch_data, gpio_to_irq(8)); orion5x_i2c_init(); orion5x_uart0_init(); diff --git a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c index 40e04953909..262e25e4dac 100644 --- a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c +++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c @@ -19,6 +19,7 @@ #include <linux/spi/orion_spi.h> #include <linux/spi/flash.h> #include <linux/ethtool.h> +#include <net/dsa.h> #include <asm/mach-types.h> #include <asm/gpio.h> #include <asm/leds.h> @@ -34,6 +35,15 @@ static struct mv643xx_eth_platform_data rd88f6183ap_ge_eth_data = { .duplex = DUPLEX_FULL, }; +static struct dsa_platform_data rd88f6183ap_ge_switch_data = { + .port_names[0] = "lan1", + .port_names[1] = "lan2", + .port_names[2] = "lan3", + .port_names[3] = "lan4", + .port_names[4] = "wan", + .port_names[5] = "cpu", +}; + static struct mtd_partition rd88f6183ap_ge_partitions[] = { { .name = "kernel", @@ -79,6 +89,7 @@ static void __init rd88f6183ap_ge_init(void) */ orion5x_ehci0_init(); orion5x_eth_init(&rd88f6183ap_ge_eth_data); + orion5x_eth_switch_init(&rd88f6183ap_ge_switch_data, gpio_to_irq(3)); spi_register_board_info(rd88f6183ap_ge_spi_slave_info, ARRAY_SIZE(rd88f6183ap_ge_spi_slave_info)); orion5x_spi_init(); diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c index 9a4fd525646..cc8f8920086 100644 --- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c +++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c @@ -15,6 +15,7 @@ #include <linux/mtd/physmap.h> #include <linux/mv643xx_eth.h> #include <linux/ethtool.h> +#include <net/dsa.h> #include <asm/mach-types.h> #include <asm/gpio.h> #include <asm/mach/arch.h> @@ -105,6 +106,15 @@ static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = { .duplex = DUPLEX_FULL, }; +static struct dsa_platform_data wrt350n_v2_switch_data = { + .port_names[0] = "lan2", + .port_names[1] = "lan1", + .port_names[2] = "wan", + .port_names[3] = "cpu", + .port_names[5] = "lan3", + .port_names[7] = "lan4", +}; + static void __init wrt350n_v2_init(void) { /* @@ -119,6 +129,7 @@ static void __init wrt350n_v2_init(void) */ orion5x_ehci0_init(); orion5x_eth_init(&wrt350n_v2_eth_data); + orion5x_eth_switch_init(&wrt350n_v2_switch_data, NO_IRQ); orion5x_uart0_init(); orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE, diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index f27f6b3d6e6..f781873431f 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -257,7 +257,6 @@ config MACH_ARMCORE bool "CompuLab CM-X255/CM-X270 modules" select PXA27x select IWMMXT - select ZONE_DMA if PCI select PXA25x select PXA_SSP diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h index 9c163e19ada..32bb4a2eb7f 100644 --- a/arch/arm/mach-pxa/include/mach/irqs.h +++ b/arch/arm/mach-pxa/include/mach/irqs.h @@ -9,7 +9,8 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - +#ifndef __ASM_MACH_IRQS_H +#define __ASM_MACH_IRQS_H #ifdef CONFIG_PXA_HAVE_ISA_IRQS #define PXA_ISA_IRQ(x) (x) @@ -264,3 +265,5 @@ #endif #endif /* CONFIG_PCI_HOST_ITE8152 */ + +#endif /* __ASM_MACH_IRQS_H */ diff --git a/arch/arm/mach-pxa/include/mach/spitz.h b/arch/arm/mach-pxa/include/mach/spitz.h index 31ac26b55bc..e8488dfb7e9 100644 --- a/arch/arm/mach-pxa/include/mach/spitz.h +++ b/arch/arm/mach-pxa/include/mach/spitz.h @@ -142,7 +142,7 @@ #define SPITZ_SCP2_GPIO_BASE (NR_BUILTIN_GPIO + 12) #define SPITZ_GPIO_IR_ON (SPITZ_SCP2_GPIO_BASE + 0) -#define SPITZ_GPIO_AKIN_PULLUP (SPITZ_SCP2_GPIO_BASE + 1 +#define SPITZ_GPIO_AKIN_PULLUP (SPITZ_SCP2_GPIO_BASE + 1) #define SPITZ_GPIO_RESERVED_1 (SPITZ_SCP2_GPIO_BASE + 2) #define SPITZ_GPIO_RESERVED_2 (SPITZ_SCP2_GPIO_BASE + 3) #define SPITZ_GPIO_RESERVED_3 (SPITZ_SCP2_GPIO_BASE + 4) diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c index 316cd986da5..74e2ead8cee 100644 --- a/arch/arm/mach-pxa/pwm.c +++ b/arch/arm/mach-pxa/pwm.c @@ -60,7 +60,7 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) do_div(c, 1000000000); period_cycles = c; - if (period_cycles < 0) + if (period_cycles < 1) period_cycles = 1; prescale = (period_cycles - 1) / 1024; pv = period_cycles / (prescale + 1) - 1; diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index a13dbf3c2c0..a72e3add743 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -399,7 +399,7 @@ static void trizeps4_irda_transceiver_mode(struct device *dev, int mode) /* Switch mode */ if (mode & IR_SIRMODE) trizeps_conxs_ircr &= ~ConXS_IRCR_MODE; /* Slow mode */ - else if (mode & IR_FIRMODE) { + else if (mode & IR_FIRMODE) trizeps_conxs_ircr |= ConXS_IRCR_MODE; /* Fast mode */ /* Switch power */ diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index 2f60bf6b8d4..f854e7385e3 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c @@ -1033,8 +1033,7 @@ void __init s3c2443_init_clocks(int xtal) fclk = pll / s3c2443_fclk_div(clkdiv0); hclk = s3c2443_prediv_getrate(&clk_prediv); - hclk = hclk / s3c2443_get_hdiv(clkdiv0); - hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1); + hclk /= s3c2443_get_hdiv(clkdiv0); pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1); s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S index 33926c9fcda..5786adf1004 100644 --- a/arch/arm/mm/cache-v4.S +++ b/arch/arm/mm/cache-v4.S @@ -29,7 +29,7 @@ ENTRY(v4_flush_user_cache_all) * Clean and invalidate the entire cache. */ ENTRY(v4_flush_kern_cache_all) -#ifdef CPU_CP15 +#ifdef CONFIG_CPU_CP15 mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ flush ID cache mov pc, lr @@ -48,7 +48,7 @@ ENTRY(v4_flush_kern_cache_all) * - flags - vma_area_struct flags describing address space */ ENTRY(v4_flush_user_cache_range) -#ifdef CPU_CP15 +#ifdef CONFIG_CPU_CP15 mov ip, #0 mcreq p15, 0, ip, c7, c7, 0 @ flush ID cache mov pc, lr @@ -116,7 +116,7 @@ ENTRY(v4_dma_inv_range) * - end - virtual end address */ ENTRY(v4_dma_flush_range) -#ifdef CPU_CP15 +#ifdef CONFIG_CPU_CP15 mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ flush ID cache #endif diff --git a/arch/arm/plat-s3c24xx/pwm-clock.c b/arch/arm/plat-s3c24xx/pwm-clock.c index b8e854f1b1d..3fad68a1e6b 100644 --- a/arch/arm/plat-s3c24xx/pwm-clock.c +++ b/arch/arm/plat-s3c24xx/pwm-clock.c @@ -315,7 +315,7 @@ static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent) if (parent == s3c24xx_pwmclk_tclk(id)) bits = S3C2410_TCFG1_MUX_TCLK << shift; else if (parent == s3c24xx_pwmclk_tdiv(id)) - bits = clk_pwm_tdiv_bits(to_tdiv(clk)) << shift; + bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift; else return -EINVAL; diff --git a/arch/arm/plat-s3c24xx/pwm.c b/arch/arm/plat-s3c24xx/pwm.c index feb770f2e84..ec56b88866c 100644 --- a/arch/arm/plat-s3c24xx/pwm.c +++ b/arch/arm/plat-s3c24xx/pwm.c @@ -56,7 +56,7 @@ static struct clk *clk_scaler[2]; } \ } -#define DEFINE_TIMER(_tmr_no, _irq) \ +#define DEFINE_S3C_TIMER(_tmr_no, _irq) \ .name = "s3c24xx-pwm", \ .id = _tmr_no, \ .num_resources = TIMER_RESOURCE_SIZE, \ @@ -67,11 +67,11 @@ static struct clk *clk_scaler[2]; */ struct platform_device s3c_device_timer[] = { - [0] = { DEFINE_TIMER(0, IRQ_TIMER0) }, - [1] = { DEFINE_TIMER(1, IRQ_TIMER1) }, - [2] = { DEFINE_TIMER(2, IRQ_TIMER2) }, - [3] = { DEFINE_TIMER(3, IRQ_TIMER3) }, - [4] = { DEFINE_TIMER(4, IRQ_TIMER4) }, + [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) }, + [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) }, + [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) }, + [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) }, + [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) }, }; static inline int pwm_is_tdiv(struct pwm_device *pwm) diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 07335e719bf..b17aeea8d62 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -679,6 +679,8 @@ source "fs/Kconfig" source "drivers/usb/Kconfig" +source "drivers/uwb/Kconfig" + source "arch/cris/Kconfig.debug" source "security/Kconfig" diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index bd1995403c6..28f06fd9b7b 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -216,6 +216,8 @@ source "drivers/hwmon/Kconfig" source "drivers/usb/Kconfig" +source "drivers/uwb/Kconfig" + endmenu source "fs/Kconfig" diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 912c57db2d2..27eec71429b 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -23,6 +23,7 @@ config IA64 select HAVE_KRETPROBES select HAVE_DMA_ATTRS select HAVE_KVM + select HAVE_ARCH_TRACEHOOK default y help The Itanium Processor Family is Intel's 64-bit successor to @@ -110,6 +111,33 @@ config AUDIT_ARCH bool default y +menuconfig PARAVIRT_GUEST + bool "Paravirtualized guest support" + help + Say Y here to get to see options related to running Linux under + various hypervisors. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. + +if PARAVIRT_GUEST + +config PARAVIRT + bool "Enable paravirtualization code" + depends on PARAVIRT_GUEST + default y + bool + default y + help + This changes the kernel so it can modify itself when it is run + under a hypervisor, potentially improving performance significantly + over full virtualization. However, when run without a hypervisor + the kernel is theoretically slower and slightly larger. + + +source "arch/ia64/xen/Kconfig" + +endif + choice prompt "System type" default IA64_GENERIC @@ -119,6 +147,7 @@ config IA64_GENERIC select NUMA select ACPI_NUMA select SWIOTLB + select PCI_MSI help This selects the system type of your hardware. A "generic" kernel will run on any supported IA-64 system. However, if you configure @@ -126,11 +155,13 @@ config IA64_GENERIC generic For any supported IA-64 system DIG-compliant For DIG ("Developer's Interface Guide") compliant systems + DIG+Intel+IOMMU For DIG systems with Intel IOMMU HP-zx1/sx1000 For HP systems HP-zx1/sx1000+swiotlb For HP systems with (broken) DMA-constrained devices. SGI-SN2 For SGI Altix systems SGI-UV For SGI UV systems Ski-simulator For the HP simulator <http://www.hpl.hp.com/research/linux/ski/> + Xen-domU For xen domU system If you don't know what to do, choose "generic". @@ -138,6 +169,11 @@ config IA64_DIG bool "DIG-compliant" select SWIOTLB +config IA64_DIG_VTD + bool "DIG+Intel+IOMMU" + select DMAR + select PCI_MSI + config IA64_HP_ZX1 bool "HP-zx1/sx1000" help @@ -181,6 +217,10 @@ config IA64_HP_SIM bool "Ski-simulator" select SWIOTLB +config IA64_XEN_GUEST + bool "Xen guest" + depends on XEN + endchoice choice @@ -583,6 +623,16 @@ source "drivers/pci/hotplug/Kconfig" source "drivers/pcmcia/Kconfig" +config DMAR + bool "Support for DMA Remapping Devices (EXPERIMENTAL)" + depends on IA64_GENERIC && ACPI && EXPERIMENTAL + help + DMA remapping (DMAR) devices support enables independent address + translations for Direct Memory Access (DMA) from devices. + These DMA remapping devices are reported via ACPI tables + and include PCI device scope covered by these DMA + remapping devices. + endmenu endif diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 905d25b13d5..58a7e46affd 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -53,12 +53,15 @@ libs-y += arch/ia64/lib/ core-y += arch/ia64/kernel/ arch/ia64/mm/ core-$(CONFIG_IA32_SUPPORT) += arch/ia64/ia32/ core-$(CONFIG_IA64_DIG) += arch/ia64/dig/ +core-$(CONFIG_IA64_DIG_VTD) += arch/ia64/dig/ core-$(CONFIG_IA64_GENERIC) += arch/ia64/dig/ core-$(CONFIG_IA64_HP_ZX1) += arch/ia64/dig/ core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/ +core-$(CONFIG_IA64_XEN_GUEST) += arch/ia64/dig/ core-$(CONFIG_IA64_SGI_SN2) += arch/ia64/sn/ core-$(CONFIG_IA64_SGI_UV) += arch/ia64/uv/ core-$(CONFIG_KVM) += arch/ia64/kvm/ +core-$(CONFIG_XEN) += arch/ia64/xen/ drivers-$(CONFIG_PCI) += arch/ia64/pci/ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig index 9f483976228..e05f9e1d3fa 100644 --- a/arch/ia64/configs/generic_defconfig +++ b/arch/ia64/configs/generic_defconfig @@ -233,6 +233,8 @@ CONFIG_DMIID=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m +# CONFIG_DMAR is not set + # # Power management and ACPI # diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig index 797acf9066c..c522edf23c6 100644 --- a/arch/ia64/configs/tiger_defconfig +++ b/arch/ia64/configs/tiger_defconfig @@ -172,6 +172,8 @@ CONFIG_DMIID=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m +# CONFIG_DMAR is not set + # # Power management and ACPI # diff --git a/arch/ia64/dig/Makefile b/arch/ia64/dig/Makefile index 971cd7870dd..5c0283830bd 100644 --- a/arch/ia64/dig/Makefile +++ b/arch/ia64/dig/Makefile @@ -6,4 +6,9 @@ # obj-y := setup.o +ifeq ($(CONFIG_DMAR), y) +obj-$(CONFIG_IA64_GENERIC) += machvec.o machvec_vtd.o dig_vtd_iommu.o +else obj-$(CONFIG_IA64_GENERIC) += machvec.o +endif +obj-$(CONFIG_IA64_DIG_VTD) += dig_vtd_iommu.o diff --git a/arch/ia64/dig/dig_vtd_iommu.c b/arch/ia64/dig/dig_vtd_iommu.c new file mode 100644 index 00000000000..1c8a079017a --- /dev/null +++ b/arch/ia64/dig/dig_vtd_iommu.c @@ -0,0 +1,59 @@ +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/intel-iommu.h> + +void * +vtd_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, + gfp_t flags) +{ + return intel_alloc_coherent(dev, size, dma_handle, flags); +} +EXPORT_SYMBOL_GPL(vtd_alloc_coherent); + +void +vtd_free_coherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle) +{ + intel_free_coherent(dev, size, vaddr, dma_handle); +} +EXPORT_SYMBOL_GPL(vtd_free_coherent); + +dma_addr_t +vtd_map_single_attrs(struct device *dev, void *addr, size_t size, + int dir, struct dma_attrs *attrs) +{ + return intel_map_single(dev, (phys_addr_t)addr, size, dir); +} +EXPORT_SYMBOL_GPL(vtd_map_single_attrs); + +void +vtd_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, + int dir, struct dma_attrs *attrs) +{ + intel_unmap_single(dev, iova, size, dir); +} +EXPORT_SYMBOL_GPL(vtd_unmap_single_attrs); + +int +vtd_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, + int dir, struct dma_attrs *attrs) +{ + return intel_map_sg(dev, sglist, nents, dir); +} +EXPORT_SYMBOL_GPL(vtd_map_sg_attrs); + +void +vtd_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, + int nents, int dir, struct dma_attrs *attrs) +{ + intel_unmap_sg(dev, sglist, nents, dir); +} +EXPORT_SYMBOL_GPL(vtd_unmap_sg_attrs); + +int +vtd_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return 0; +} +EXPORT_SYMBOL_GPL(vtd_dma_mapping_error); diff --git a/arch/ia64/dig/machvec_vtd.c b/arch/ia64/dig/machvec_vtd.c new file mode 100644 index 00000000000..7cd3eb471ca --- /dev/null +++ b/arch/ia64/dig/machvec_vtd.c @@ -0,0 +1,3 @@ +#define MACHVEC_PLATFORM_NAME dig_vtd +#define MACHVEC_PLATFORM_HEADER <asm/machvec_dig_vtd.h> +#include <asm/machvec_init.h> diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S index 53505bb0477..a8cf1995885 100644 --- a/arch/ia64/ia32/ia32_entry.S +++ b/arch/ia64/ia32/ia32_entry.S @@ -108,6 +108,11 @@ GLOBAL_ENTRY(ia32_trace_syscall) ;; st8 [r2]=r3 // initialize return code to -ENOSYS br.call.sptk.few rp=syscall_trace_enter // give parent a chance to catch syscall args + cmp.lt p6,p0=r8,r0 // check tracehook + adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8 + ;; +(p6) st8.spill [r2]=r8 // store return value in slot for r8 +(p6) br.spnt.few .ret4 .ret2: // Need to reload arguments (they may be changed by the tracing process) adds r2=IA64_PT_REGS_R1_OFFSET+16,sp // r2 = &pt_regs.r1 adds r3=IA64_PT_REGS_R13_OFFSET+16,sp // r3 = &pt_regs.r13 @@ -199,10 +204,10 @@ ia32_syscall_table: data8 sys_setuid /* 16-bit version */ data8 sys_getuid /* 16-bit version */ data8 compat_sys_stime /* 25 */ - data8 sys32_ptrace + data8 compat_sys_ptrace data8 sys32_alarm data8 sys_ni_syscall - data8 sys32_pause + data8 sys_pause data8 compat_sys_utime /* 30 */ data8 sys_ni_syscall /* old stty syscall holder */ data8 sys_ni_syscall /* old gtty syscall holder */ @@ -215,7 +220,7 @@ ia32_syscall_table: data8 sys_mkdir data8 sys_rmdir /* 40 */ data8 sys_dup - data8 sys32_pipe + data8 sys_pipe data8 compat_sys_times data8 sys_ni_syscall /* old prof syscall holder */ data8 sys32_brk /* 45 */ diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index f4430bb4bbd..5e92ae00bdb 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c @@ -1098,21 +1098,6 @@ sys32_mremap (unsigned int addr, unsigned int old_len, unsigned int new_len, return ret; } -asmlinkage long -sys32_pipe (int __user *fd) -{ - int retval; - int fds[2]; - - retval = do_pipe_flags(fds, 0); - if (retval) - goto out; - if (copy_to_user(fd, fds, sizeof(fds))) - retval = -EFAULT; - out: - return retval; -} - asmlinkage unsigned long sys32_alarm (unsigned int seconds) { @@ -1209,25 +1194,6 @@ sys32_waitpid (int pid, unsigned int *stat_addr, int options) return compat_sys_wait4(pid, stat_addr, options, NULL); } -static unsigned int -ia32_peek (struct task_struct *child, unsigned long addr, unsigned int *val) -{ - size_t copied; - unsigned int ret; - - copied = access_process_vm(child, addr, val, sizeof(*val), 0); - return (copied != sizeof(ret)) ? -EIO : 0; -} - -static unsigned int -ia32_poke (struct task_struct *child, unsigned long addr, unsigned int val) -{ - - if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val)) - return -EIO; - return 0; -} - /* * The order in which registers are stored in the ptrace regs structure */ @@ -1525,49 +1491,15 @@ restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __u return 0; } -asmlinkage long -sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data) +long compat_arch_ptrace(struct task_struct *child, compat_long_t request, + compat_ulong_t caddr, compat_ulong_t cdata) { - struct task_struct *child; - unsigned int value, tmp; + unsigned long addr = caddr; + unsigned long data = cdata; + unsigned int tmp; long i, ret; - lock_kernel(); - if (request == PTRACE_TRACEME) { - ret = ptrace_traceme(); - goto out; - } - - child = ptrace_get_task_struct(pid); - if (IS_ERR(child)) { - ret = PTR_ERR(child); - goto out; - } - - if (request == PTRACE_ATTACH) { - ret = sys_ptrace(request, pid, addr, data); - goto out_tsk; - } - - ret = ptrace_check_attach(child, request == PTRACE_KILL); - if (ret < 0) - goto out_tsk; - switch (request) { - case PTRACE_PEEKTEXT: - case PTRACE_PEEKDATA: /* read word at location addr */ - ret = ia32_peek(child, addr, &value); - if (ret == 0) - ret = put_user(value, (unsigned int __user *) compat_ptr(data)); - else - ret = -EIO; - goto out_tsk; - - case PTRACE_POKETEXT: - case PTRACE_POKEDATA: /* write the word at location addr */ - ret = ia32_poke(child, addr, data); - goto out_tsk; - case PTRACE_PEEKUSR: /* read word at addr in USER area */ ret = -EIO; if ((addr & 3) || addr > 17*sizeof(int)) @@ -1632,27 +1564,9 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data) compat_ptr(data)); break; - case PTRACE_GETEVENTMSG: - ret = put_user(child->ptrace_message, (unsigned int __user *) compat_ptr(data)); - break; - - case PTRACE_SYSCALL: /* continue, stop after next syscall */ - case PTRACE_CONT: /* restart after signal. */ - case PTRACE_KILL: - case PTRACE_SINGLESTEP: /* execute chile for one instruction */ - case PTRACE_DETACH: /* detach a process */ - ret = sys_ptrace(request, pid, addr, data); - break; - default: - ret = ptrace_request(child, request, addr, data); - break; - + return compat_ptrace_request(child, request, caddr, cdata); } - out_tsk: - put_task_struct(child); - out: - unlock_kernel(); return ret; } @@ -1704,14 +1618,6 @@ out: } asmlinkage int -sys32_pause (void) -{ - current->state = TASK_INTERRUPTIBLE; - schedule(); - return -ERESTARTNOHAND; -} - -asmlinkage int sys32_msync (unsigned int start, unsigned int len, int flags) { unsigned int addr; diff --git a/arch/ia64/include/asm/break.h b/arch/ia64/include/asm/break.h index f0340203989..e90c40ec9ed 100644 --- a/arch/ia64/include/asm/break.h +++ b/arch/ia64/include/asm/break.h @@ -20,4 +20,13 @@ */ #define __IA64_BREAK_SYSCALL 0x100000 +/* + * Xen specific break numbers: + */ +#define __IA64_XEN_HYPERCALL 0x1000 +/* [__IA64_XEN_HYPERPRIVOP_START, __IA64_XEN_HYPERPRIVOP_MAX] is used + for xen hyperprivops */ +#define __IA64_XEN_HYPERPRIVOP_START 0x1 +#define __IA64_XEN_HYPERPRIVOP_MAX 0x1a + #endif /* _ASM_IA64_BREAK_H */ diff --git a/arch/ia64/include/asm/cacheflush.h b/arch/ia64/include/asm/cacheflush.h index afcfbda76e2..c8ce2719fee 100644 --- a/arch/ia64/include/asm/cacheflush.h +++ b/arch/ia64/include/asm/cacheflush.h @@ -34,6 +34,8 @@ do { \ #define flush_dcache_mmap_unlock(mapping) do { } while (0) extern void flush_icache_range (unsigned long start, unsigned long end); +extern void clflush_cache_range(void *addr, int size); + #define flush_icache_user_range(vma, page, user_addr, len) \ do { \ diff --git a/arch/ia64/include/asm/device.h b/arch/ia64/include/asm/device.h index 3db6daf7f25..41ab85d66f3 100644 --- a/arch/ia64/include/asm/device.h +++ b/arch/ia64/include/asm/device.h @@ -10,6 +10,9 @@ struct dev_archdata { #ifdef CONFIG_ACPI void *acpi_handle; #endif +#ifdef CONFIG_DMAR + void *iommu; /* hook for IOMMU specific extension */ +#endif }; #endif /* _ASM_IA64_DEVICE_H */ diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h index 06ff1ba2146..bbab7e2b0fc 100644 --- a/arch/ia64/include/asm/dma-mapping.h +++ b/arch/ia64/include/asm/dma-mapping.h @@ -7,6 +7,49 @@ */ #include <asm/machvec.h> #include <linux/scatterlist.h> +#include <asm/swiotlb.h> + +struct dma_mapping_ops { + int (*mapping_error)(struct device *dev, + dma_addr_t dma_addr); + void* (*alloc_coherent)(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp); + void (*free_coherent)(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle); + dma_addr_t (*map_single)(struct device *hwdev, unsigned long ptr, + size_t size, int direction); + void (*unmap_single)(struct device *dev, dma_addr_t addr, + size_t size, int direction); + void (*sync_single_for_cpu)(struct device *hwdev, + dma_addr_t dma_handle, size_t size, + int direction); + void (*sync_single_for_device)(struct device *hwdev, + dma_addr_t dma_handle, size_t size, + int direction); + void (*sync_single_range_for_cpu)(struct device *hwdev, + dma_addr_t dma_handle, unsigned long offset, + size_t size, int direction); + void (*sync_single_range_for_device)(struct device *hwdev, + dma_addr_t dma_handle, unsigned long offset, + size_t size, int direction); + void (*sync_sg_for_cpu)(struct device *hwdev, + struct scatterlist *sg, int nelems, + int direction); + void (*sync_sg_for_device)(struct device *hwdev, + struct scatterlist *sg, int nelems, + int direction); + int (*map_sg)(struct device *hwdev, struct scatterlist *sg, + int nents, int direction); + void (*unmap_sg)(struct device *hwdev, + struct scatterlist *sg, int nents, + int direction); + int (*dma_supported_op)(struct device *hwdev, u64 mask); + int is_phys; +}; + +extern struct dma_mapping_ops *dma_ops; +extern struct ia64_machine_vector ia64_mv; +extern void set_iommu_machvec(void); #define dma_alloc_coherent(dev, size, handle, gfp) \ platform_dma_alloc_coherent(dev, size, handle, (gfp) | GFP_DMA) @@ -96,4 +139,11 @@ dma_cache_sync (struct device *dev, void *vaddr, size_t size, #define dma_is_consistent(d, h) (1) /* all we do is coherent memory... */ +static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) +{ + return dma_ops; +} + + + #endif /* _ASM_IA64_DMA_MAPPING_H */ diff --git a/arch/ia64/include/asm/iommu.h b/arch/ia64/include/asm/iommu.h new file mode 100644 index 00000000000..5fb2bb93de3 --- /dev/null +++ b/arch/ia64/include/asm/iommu.h @@ -0,0 +1,16 @@ +#ifndef _ASM_IA64_IOMMU_H +#define _ASM_IA64_IOMMU_H 1 + +#define cpu_has_x2apic 0 +/* 10 seconds */ +#define DMAR_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10) + +extern void pci_iommu_shutdown(void); +extern void no_iommu_init(void); +extern int force_iommu, no_iommu; +extern int iommu_detected; +extern void iommu_dma_init(void); +extern void machvec_init(const char *name); +extern int forbid_dac; + +#endif diff --git a/arch/ia64/include/asm/kregs.h b/arch/ia64/include/asm/kregs.h index aefcdfee7f2..39e65f6639f 100644 --- a/arch/ia64/include/asm/kregs.h +++ b/arch/ia64/include/asm/kregs.h @@ -32,7 +32,7 @@ #define IA64_TR_CURRENT_STACK 1 /* dtr1: maps kernel's memory- & register-stacks */ #define IA64_TR_ALLOC_BASE 2 /* itr&dtr: Base of dynamic TR resource*/ -#define IA64_TR_ALLOC_MAX 32 /* Max number for dynamic use*/ +#define IA64_TR_ALLOC_MAX 64 /* Max number for dynamic use*/ /* Processor status register bits: */ #define IA64_PSR_BE_BIT 1 diff --git a/arch/ia64/include/asm/machvec.h b/arch/ia64/include/asm/machvec.h index 2b850ccafef..1ea28bcee33 100644 --- a/arch/ia64/include/asm/machvec.h +++ b/arch/ia64/include/asm/machvec.h @@ -120,6 +120,8 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *); # include <asm/machvec_hpsim.h> # elif defined (CONFIG_IA64_DIG) # include <asm/machvec_dig.h> +# elif defined(CONFIG_IA64_DIG_VTD) +# include <asm/machvec_dig_vtd.h> # elif defined (CONFIG_IA64_HP_ZX1) # include <asm/machvec_hpzx1.h> # elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB) @@ -128,6 +130,8 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *); # include <asm/machvec_sn2.h> # elif defined (CONFIG_IA64_SGI_UV) # include <asm/machvec_uv.h> +# elif defined (CONFIG_IA64_XEN_GUEST) +# include <asm/machvec_xen.h> # elif defined (CONFIG_IA64_GENERIC) # ifdef MACHVEC_PLATFORM_HEADER diff --git a/arch/ia64/include/asm/machvec_dig_vtd.h b/arch/ia64/include/asm/machvec_dig_vtd.h new file mode 100644 index 00000000000..3400b561e71 --- /dev/null +++ b/arch/ia64/include/asm/machvec_dig_vtd.h @@ -0,0 +1,38 @@ +#ifndef _ASM_IA64_MACHVEC_DIG_VTD_h +#define _ASM_IA64_MACHVEC_DIG_VTD_h + +extern ia64_mv_setup_t dig_setup; +extern ia64_mv_dma_alloc_coherent vtd_alloc_coherent; +extern ia64_mv_dma_free_coherent vtd_free_coherent; +extern ia64_mv_dma_map_single_attrs vtd_map_single_attrs; +extern ia64_mv_dma_unmap_single_attrs vtd_unmap_single_attrs; +extern ia64_mv_dma_map_sg_attrs vtd_map_sg_attrs; +extern ia64_mv_dma_unmap_sg_attrs vtd_unmap_sg_attrs; +extern ia64_mv_dma_supported iommu_dma_supported; +extern ia64_mv_dma_mapping_error vtd_dma_mapping_error; +extern ia64_mv_dma_init pci_iommu_alloc; + +/* + * This stuff has dual use! + * + * For a generic kernel, the macros are used to initialize the + * platform's machvec structure. When compiling a non-generic kernel, + * the macros are used directly. + */ +#define platform_name "dig_vtd" +#define platform_setup dig_setup +#define platform_dma_init pci_iommu_alloc +#define platform_dma_alloc_coherent vtd_alloc_coherent +#define platform_dma_free_coherent vtd_free_coherent +#define platform_dma_map_single_attrs vtd_map_single_attrs +#define platform_dma_unmap_single_attrs vtd_unmap_single_attrs +#define platform_dma_map_sg_attrs vtd_map_sg_attrs +#define platform_dma_unmap_sg_attrs vtd_unmap_sg_attrs +#define platform_dma_sync_single_for_cpu machvec_dma_sync_single +#define platform_dma_sync_sg_for_cpu machvec_dma_sync_sg +#define platform_dma_sync_single_for_device machvec_dma_sync_single +#define platform_dma_sync_sg_for_device machvec_dma_sync_sg +#define platform_dma_supported iommu_dma_supported +#define platform_dma_mapping_error vtd_dma_mapping_error + +#endif /* _ASM_IA64_MACHVEC_DIG_VTD_h */ diff --git a/arch/ia64/include/asm/machvec_init.h b/arch/ia64/include/asm/machvec_init.h index 7f21249fba3..ef964b28684 100644 --- a/arch/ia64/include/asm/machvec_init.h +++ b/arch/ia64/include/asm/machvec_init.h @@ -1,3 +1,4 @@ +#include <asm/iommu.h> #include <asm/machvec.h> extern ia64_mv_send_ipi_t ia64_send_ipi; diff --git a/arch/ia64/include/asm/machvec_xen.h b/arch/ia64/include/asm/machvec_xen.h new file mode 100644 index 00000000000..55f9228056c --- /dev/null +++ b/arch/ia64/include/asm/machvec_xen.h @@ -0,0 +1,22 @@ +#ifndef _ASM_IA64_MACHVEC_XEN_h +#define _ASM_IA64_MACHVEC_XEN_h + +extern ia64_mv_setup_t dig_setup; +extern ia64_mv_cpu_init_t xen_cpu_init; +extern ia64_mv_irq_init_t xen_irq_init; +extern ia64_mv_send_ipi_t xen_platform_send_ipi; + +/* + * This stuff has dual use! + * + * For a generic kernel, the macros are used to initialize the + * platform's machvec structure. When compiling a non-generic kernel, + * the macros are used directly. + */ +#define platform_name "xen" +#define platform_setup dig_setup +#define platform_cpu_init xen_cpu_init +#define platform_irq_init xen_irq_init +#define platform_send_ipi xen_platform_send_ipi + +#endif /* _ASM_IA64_MACHVEC_XEN_h */ diff --git a/arch/ia64/include/asm/meminit.h b/arch/ia64/include/asm/meminit.h index 7245a578159..6bc96ee5432 100644 --- a/arch/ia64/include/asm/meminit.h +++ b/arch/ia64/include/asm/meminit.h @@ -18,10 +18,11 @@ * - crash dumping code reserved region * - Kernel memory map built from EFI memory map * - ELF core header + * - xen start info if CONFIG_XEN * * More could be added if necessary */ -#define IA64_MAX_RSVD_REGIONS 8 +#define IA64_MAX_RSVD_REGIONS 9 struct rsvd_region { unsigned long start; /* virtual address of beginning of element */ diff --git a/arch/ia64/include/asm/native/inst.h b/arch/ia64/include/asm/native/inst.h index c8efbf7b849..0a1026cca4f 100644 --- a/arch/ia64/include/asm/native/inst.h +++ b/arch/ia64/include/asm/native/inst.h @@ -36,8 +36,13 @@ ;; \ movl clob = PARAVIRT_POISON; \ ;; +# define CLOBBER_PRED(pred_clob) \ + ;; \ + cmp.eq pred_clob, p0 = r0, r0 \ + ;; #else -# define CLOBBER(clob) /* nothing */ +# define CLOBBER(clob) /* nothing */ +# define CLOBBER_PRED(pred_clob) /* nothing */ #endif #define MOV_FROM_IFA(reg) \ @@ -136,7 +141,8 @@ #define SSM_PSR_I(pred, pred_clob, clob) \ (pred) ssm psr.i \ - CLOBBER(clob) + CLOBBER(clob) \ + CLOBBER_PRED(pred_clob) #define RSM_PSR_I(pred, clob0, clob1) \ (pred) rsm psr.i \ diff --git a/arch/ia64/include/asm/native/pvchk_inst.h b/arch/ia64/include/asm/native/pvchk_inst.h new file mode 100644 index 00000000000..b8e6eb1090d --- /dev/null +++ b/arch/ia64/include/asm/native/pvchk_inst.h @@ -0,0 +1,263 @@ +#ifndef _ASM_NATIVE_PVCHK_INST_H +#define _ASM_NATIVE_PVCHK_INST_H + +/****************************************************************************** + * arch/ia64/include/asm/native/pvchk_inst.h + * Checker for paravirtualizations of privileged operations. + * + * Copyright (C) 2005 Hewlett-Packard Co + * Dan Magenheimer <dan.magenheimer@hp.com> + * + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/********************************************** + * Instructions paravirtualized for correctness + **********************************************/ + +/* "fc" and "thash" are privilege-sensitive instructions, meaning they + * may have different semantics depending on whether they are executed + * at PL0 vs PL!=0. When paravirtualized, these instructions mustn't + * be allowed to execute directly, lest incorrect semantics result. + */ + +#define fc .error "fc should not be used directly." +#define thash .error "thash should not be used directly." + +/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag" + * is not currently used (though it may be in a long-format VHPT system!) + * and the semantics of cover only change if psr.ic is off which is very + * rare (and currently non-existent outside of assembly code + */ +#define ttag .error "ttag should not be used directly." +#define cover .error "cover should not be used directly." + +/* There are also privilege-sensitive registers. These registers are + * readable at any privilege level but only writable at PL0. + */ +#define cpuid .error "cpuid should not be used directly." +#define pmd .error "pmd should not be used directly." + +/* + * mov ar.eflag = + * mov = ar.eflag + */ + +/********************************************** + * Instructions paravirtualized for performance + **********************************************/ +/* + * Those instructions include '.' which can't be handled by cpp. + * or can't be handled by cpp easily. + * They are handled by sed instead of cpp. + */ + +/* for .S + * itc.i + * itc.d + * + * bsw.0 + * bsw.1 + * + * ssm psr.ic | PSR_DEFAULT_BITS + * ssm psr.ic + * rsm psr.ic + * ssm psr.i + * rsm psr.i + * rsm psr.i | psr.ic + * rsm psr.dt + * ssm psr.dt + * + * mov = cr.ifa + * mov = cr.itir + * mov = cr.isr + * mov = cr.iha + * mov = cr.ipsr + * mov = cr.iim + * mov = cr.iip + * mov = cr.ivr + * mov = psr + * + * mov cr.ifa = + * mov cr.itir = + * mov cr.iha = + * mov cr.ipsr = + * mov cr.ifs = + * mov cr.iip = + * mov cr.kr = + */ + +/* for intrinsics + * ssm psr.i + * rsm psr.i + * mov = psr + * mov = ivr + * mov = tpr + * mov cr.itm = + * mov eoi = + * mov rr[] = + * mov = rr[] + * mov = kr + * mov kr = + * ptc.ga + */ + +/************************************************************* + * define paravirtualized instrcution macros as nop to ingore. + * and check whether arguments are appropriate. + *************************************************************/ + +/* check whether reg is a regular register */ +.macro is_rreg_in reg + .ifc "\reg", "r0" + nop 0 + .exitm + .endif + ;; + mov \reg = r0 + ;; +.endm +#define IS_RREG_IN(reg) is_rreg_in reg ; + +#define IS_RREG_OUT(reg) \ + ;; \ + mov reg = r0 \ + ;; + +#define IS_RREG_CLOB(reg) IS_RREG_OUT(reg) + +/* check whether pred is a predicate register */ +#define IS_PRED_IN(pred) \ + ;; \ + (pred) nop 0 \ + ;; + +#define IS_PRED_OUT(pred) \ + ;; \ + cmp.eq pred, p0 = r0, r0 \ + ;; + +#define IS_PRED_CLOB(pred) IS_PRED_OUT(pred) + + +#define DO_SAVE_MIN(__COVER, SAVE_IFS, EXTRA, WORKAROUND) \ + nop 0 +#define MOV_FROM_IFA(reg) \ + IS_RREG_OUT(reg) +#define MOV_FROM_ITIR(reg) \ + IS_RREG_OUT(reg) +#define MOV_FROM_ISR(reg) \ + IS_RREG_OUT(reg) +#define MOV_FROM_IHA(reg) \ + IS_RREG_OUT(reg) +#define MOV_FROM_IPSR(pred, reg) \ + IS_PRED_IN(pred) \ + IS_RREG_OUT(reg) +#define MOV_FROM_IIM(reg) \ + IS_RREG_OUT(reg) +#define MOV_FROM_IIP(reg) \ + IS_RREG_OUT(reg) +#define MOV_FROM_IVR(reg, clob) \ + IS_RREG_OUT(reg) \ + IS_RREG_CLOB(clob) +#define MOV_FROM_PSR(pred, reg, clob) \ + IS_PRED_IN(pred) \ + IS_RREG_OUT(reg) \ + IS_RREG_CLOB(clob) +#define MOV_TO_IFA(reg, clob) \ + IS_RREG_IN(reg) \ + IS_RREG_CLOB(clob) +#define MOV_TO_ITIR(pred, reg, clob) \ + IS_PRED_IN(pred) \ + IS_RREG_IN(reg) \ + IS_RREG_CLOB(clob) +#define MOV_TO_IHA(pred, reg, clob) \ + IS_PRED_IN(pred) \ + IS_RREG_IN(reg) \ + IS_RREG_CLOB(clob) +#define MOV_TO_IPSR(pred, reg, clob) \ + IS_PRED_IN(pred) \ + IS_RREG_IN(reg) \ + IS_RREG_CLOB(clob) +#define MOV_TO_IFS(pred, reg, clob) \ + IS_PRED_IN(pred) \ + IS_RREG_IN(reg) \ + IS_RREG_CLOB(clob) +#define MOV_TO_IIP(reg, clob) \ + IS_RREG_IN(reg) \ + IS_RREG_CLOB(clob) +#define MOV_TO_KR(kr, reg, clob0, clob1) \ + IS_RREG_IN(reg) \ + IS_RREG_CLOB(clob0) \ + IS_RREG_CLOB(clob1) +#define ITC_I(pred, reg, clob) \ + IS_PRED_IN(pred) \ + IS_RREG_IN(reg) \ + IS_RREG_CLOB(clob) +#define ITC_D(pred, reg, clob) \ + IS_PRED_IN(pred) \ + IS_RREG_IN(reg) \ + IS_RREG_CLOB(clob) +#define ITC_I_AND_D(pred_i, pred_d, reg, clob) \ + IS_PRED_IN(pred_i) \ + IS_PRED_IN(pred_d) \ + IS_RREG_IN(reg) \ + IS_RREG_CLOB(clob) +#define THASH(pred, reg0, reg1, clob) \ + IS_PRED_IN(pred) \ + IS_RREG_OUT(reg0) \ + IS_RREG_IN(reg1) \ + IS_RREG_CLOB(clob) +#define SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(clob0, clob1) \ + IS_RREG_CLOB(clob0) \ + IS_RREG_CLOB(clob1) +#define SSM_PSR_IC_AND_SRLZ_D(clob0, clob1) \ + IS_RREG_CLOB(clob0) \ + IS_RREG_CLOB(clob1) +#define RSM_PSR_IC(clob) \ + IS_RREG_CLOB(clob) +#define SSM_PSR_I(pred, pred_clob, clob) \ + IS_PRED_IN(pred) \ + IS_PRED_CLOB(pred_clob) \ + IS_RREG_CLOB(clob) +#define RSM_PSR_I(pred, clob0, clob1) \ + IS_PRED_IN(pred) \ + IS_RREG_CLOB(clob0) \ + IS_RREG_CLOB(clob1) +#define RSM_PSR_I_IC(clob0, clob1, clob2) \ + IS_RREG_CLOB(clob0) \ + IS_RREG_CLOB(clob1) \ + IS_RREG_CLOB(clob2) +#define RSM_PSR_DT \ + nop 0 +#define SSM_PSR_DT_AND_SRLZ_I \ + nop 0 +#define BSW_0(clob0, clob1, clob2) \ + IS_RREG_CLOB(clob0) \ + IS_RREG_CLOB(clob1) \ + IS_RREG_CLOB(clob2) +#define BSW_1(clob0, clob1) \ + IS_RREG_CLOB(clob0) \ + IS_RREG_CLOB(clob1) +#define COVER \ + nop 0 +#define RFI \ + br.ret.sptk.many rp /* defining nop causes dependency error */ + +#endif /* _ASM_NATIVE_PVCHK_INST_H */ diff --git a/arch/ia64/include/asm/paravirt.h b/arch/ia64/include/asm/paravirt.h index 660cab04483..2bf3636473f 100644 --- a/arch/ia64/include/asm/paravirt.h +++ b/arch/ia64/include/asm/paravirt.h @@ -117,7 +117,7 @@ static inline void paravirt_post_smp_prepare_boot_cpu(void) struct pv_iosapic_ops { void (*pcat_compat_init)(void); - struct irq_chip *(*get_irq_chip)(unsigned long trigger); + struct irq_chip *(*__get_irq_chip)(unsigned long trigger); unsigned int (*__read)(char __iomem *iosapic, unsigned int reg); void (*__write)(char __iomem *iosapic, unsigned int reg, u32 val); @@ -135,7 +135,7 @@ iosapic_pcat_compat_init(void) static inline struct irq_chip* iosapic_get_irq_chip(unsigned long trigger) { - return pv_iosapic_ops.get_irq_chip(trigger); + return pv_iosapic_ops.__get_irq_chip(trigger); } static inline unsigned int diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h index ce342fb7424..1d660d89db0 100644 --- a/arch/ia64/include/asm/pci.h +++ b/arch/ia64/include/asm/pci.h @@ -156,4 +156,7 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) return channel ? isa_irq_to_vector(15) : isa_irq_to_vector(14); } +#ifdef CONFIG_DMAR +extern void pci_iommu_alloc(void); +#endif #endif /* _ASM_IA64_PCI_H */ diff --git a/arch/ia64/include/asm/ptrace.h b/arch/ia64/include/asm/ptrace.h index 15f8dcfe6ee..6417c1ecb44 100644 --- a/arch/ia64/include/asm/ptrace.h +++ b/arch/ia64/include/asm/ptrace.h @@ -240,6 +240,12 @@ struct switch_stack { */ # define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri) +static inline unsigned long user_stack_pointer(struct pt_regs *regs) +{ + /* FIXME: should this be bspstore + nr_dirty regs? */ + return regs->ar_bspstore; +} + #define regs_return_value(regs) ((regs)->r8) /* Conserve space in histogram by encoding slot bits in address @@ -319,6 +325,8 @@ struct switch_stack { #define arch_has_block_step() (1) extern void user_enable_block_step(struct task_struct *); +#define __ARCH_WANT_COMPAT_SYS_PTRACE + #endif /* !__KERNEL__ */ /* pt_all_user_regs is used for PTRACE_GETREGS PTRACE_SETREGS */ diff --git a/arch/ia64/include/asm/pvclock-abi.h b/arch/ia64/include/asm/pvclock-abi.h new file mode 100644 index 00000000000..44ef9ef8f5b --- /dev/null +++ b/arch/ia64/include/asm/pvclock-abi.h @@ -0,0 +1,48 @@ +/* + * same structure to x86's + * Hopefully asm-x86/pvclock-abi.h would be moved to somewhere more generic. + * For now, define same duplicated definitions. + */ + +#ifndef _ASM_IA64__PVCLOCK_ABI_H +#define _ASM_IA64__PVCLOCK_ABI_H +#ifndef __ASSEMBLY__ + +/* + * These structs MUST NOT be changed. + * They are the ABI between hypervisor and guest OS. + * Both Xen and KVM are using this. + * + * pvclock_vcpu_time_info holds the system time and the tsc timestamp + * of the last update. So the guest can use the tsc delta to get a + * more precise system time. There is one per virtual cpu. + * + * pvclock_wall_clock references the point in time when the system + * time was zero (usually boot time), thus the guest calculates the + * current wall clock by adding the system time. + * + * Protocol for the "version" fields is: hypervisor raises it (making + * it uneven) before it starts updating the fields and raises it again + * (making it even) when it is done. Thus the guest can make sure the + * time values it got are consistent by checking the version before + * and after reading them. + */ + +struct pvclock_vcpu_time_info { + u32 version; + u32 pad0; + u64 tsc_timestamp; + u64 system_time; + u32 tsc_to_system_mul; + s8 tsc_shift; + u8 pad[3]; +} __attribute__((__packed__)); /* 32 bytes */ + +struct pvclock_wall_clock { + u32 version; + u32 sec; + u32 nsec; +} __attribute__((__packed__)); + +#endif /* __ASSEMBLY__ */ +#endif /* _ASM_IA64__PVCLOCK_ABI_H */ diff --git a/arch/ia64/include/asm/swiotlb.h b/arch/ia64/include/asm/swiotlb.h new file mode 100644 index 00000000000..fb79423834d --- /dev/null +++ b/arch/ia64/include/asm/swiotlb.h @@ -0,0 +1,56 @@ +#ifndef ASM_IA64__SWIOTLB_H +#define ASM_IA64__SWIOTLB_H + +#include <linux/dma-mapping.h> + +/* SWIOTLB interface */ + +extern dma_addr_t swiotlb_map_single(struct device *hwdev, void *ptr, + size_t size, int dir); +extern void *swiotlb_alloc_coherent(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, gfp_t flags); +extern void swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, + size_t size, int dir); +extern void swiotlb_sync_single_for_cpu(struct device *hwdev, + dma_addr_t dev_addr, + size_t size, int dir); +extern void swiotlb_sync_single_for_device(struct device *hwdev, + dma_addr_t dev_addr, + size_t size, int dir); +extern void swiotlb_sync_single_range_for_cpu(struct device *hwdev, + dma_addr_t dev_addr, + unsigned long offset, + size_t size, int dir); +extern void swiotlb_sync_single_range_for_device(struct device *hwdev, + dma_addr_t dev_addr, + unsigned long offset, + size_t size, int dir); +extern void swiotlb_sync_sg_for_cpu(struct device *hwdev, + struct scatterlist *sg, int nelems, + int dir); +extern void swiotlb_sync_sg_for_device(struct device *hwdev, + struct scatterlist *sg, int nelems, + int dir); +extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, + int nents, int direction); +extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, + int nents, int direction); +extern int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); +extern void swiotlb_free_coherent(struct device *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle); +extern int swiotlb_dma_supported(struct device *hwdev, u64 mask); +extern void swiotlb_init(void); + +extern int swiotlb_force; + +#ifdef CONFIG_SWIOTLB +extern int swiotlb; +extern void pci_swiotlb_init(void); +#else +#define swiotlb 0 +static inline void pci_swiotlb_init(void) +{ +} +#endif + +#endif /* ASM_IA64__SWIOTLB_H */ diff --git a/arch/ia64/include/asm/sync_bitops.h b/arch/ia64/include/asm/sync_bitops.h new file mode 100644 index 00000000000..593c12eeb27 --- /dev/null +++ b/arch/ia64/include/asm/sync_bitops.h @@ -0,0 +1,51 @@ +#ifndef _ASM_IA64_SYNC_BITOPS_H +#define _ASM_IA64_SYNC_BITOPS_H + +/* + * Copyright (C) 2008 Isaku Yamahata <yamahata at valinux co jp> + * + * Based on synch_bitops.h which Dan Magenhaimer wrote. + * + * bit operations which provide guaranteed strong synchronisation + * when communicating with Xen or other guest OSes running on other CPUs. + */ + +static inline void sync_set_bit(int nr, volatile void *addr) +{ + set_bit(nr, addr); +} + +static inline void sync_clear_bit(int nr, volatile void *addr) +{ + clear_bit(nr, addr); +} + +static inline void sync_change_bit(int nr, volatile void *addr) +{ + change_bit(nr, addr); +} + +static inline int sync_test_and_set_bit(int nr, volatile void *addr) +{ + return test_and_set_bit(nr, addr); +} + +static inline int sync_test_and_clear_bit(int nr, volatile void *addr) +{ + return test_and_clear_bit(nr, addr); +} + +static inline int sync_test_and_change_bit(int nr, volatile void *addr) +{ + return test_and_change_bit(nr, addr); +} + +static inline int sync_test_bit(int nr, const volatile void *addr) +{ + return test_bit(nr, addr); +} + +#define sync_cmpxchg(ptr, old, new) \ + ((__typeof__(*(ptr)))cmpxchg_acq((ptr), (old), (new))) + +#endif /* _ASM_IA64_SYNC_BITOPS_H */ diff --git a/arch/ia64/include/asm/syscall.h b/arch/ia64/include/asm/syscall.h new file mode 100644 index 00000000000..2f758a42f94 --- /dev/null +++ b/arch/ia64/include/asm/syscall.h @@ -0,0 +1,163 @@ +/* + * Access to user system call parameters and results + * + * Copyright (C) 2008 Intel Corp. Shaohua Li <shaohua.li@intel.com> + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2. + * + * See asm-generic/syscall.h for descriptions of what we must do here. + */ + +#ifndef _ASM_SYSCALL_H +#define _ASM_SYSCALL_H 1 + +#include <linux/sched.h> +#include <linux/err.h> + +static inline long syscall_get_nr(struct task_struct *task, + struct pt_regs *regs) +{ + if ((long)regs->cr_ifs < 0) /* Not a syscall */ + return -1; + +#ifdef CONFIG_IA32_SUPPORT + if (IS_IA32_PROCESS(regs)) + return regs->r1; +#endif + + return regs->r15; +} + +static inline void syscall_rollback(struct task_struct *task, + struct pt_regs *regs) +{ +#ifdef CONFIG_IA32_SUPPORT + if (IS_IA32_PROCESS(regs)) + regs->r8 = regs->r1; +#endif + + /* do nothing */ +} + +static inline long syscall_get_error(struct task_struct *task, + struct pt_regs *regs) +{ +#ifdef CONFIG_IA32_SUPPORT + if (IS_IA32_PROCESS(regs)) + return regs->r8; +#endif + + return regs->r10 == -1 ? regs->r8:0; +} + +static inline long syscall_get_return_value(struct task_struct *task, + struct pt_regs *regs) +{ + return regs->r8; +} + +static inline void syscall_set_return_value(struct task_struct *task, + struct pt_regs *regs, + int error, long val) +{ +#ifdef CONFIG_IA32_SUPPORT + if (IS_IA32_PROCESS(regs)) { + regs->r8 = (long) error ? error : val; + return; + } +#endif + + if (error) { + /* error < 0, but ia64 uses > 0 return value */ + regs->r8 = -error; + regs->r10 = -1; + } else { + regs->r8 = val; + regs->r10 = 0; + } +} + +extern void ia64_syscall_get_set_arguments(struct task_struct *task, + struct pt_regs *regs, unsigned int i, unsigned int n, + unsigned long *args, int rw); +static inline void syscall_get_arguments(struct task_struct *task, + struct pt_regs *regs, + unsigned int i, unsigned int n, + unsigned long *args) +{ + BUG_ON(i + n > 6); + +#ifdef CONFIG_IA32_SUPPORT + if (IS_IA32_PROCESS(regs)) { + switch (i + n) { + case 6: + if (!n--) break; + *args++ = regs->r13; + case 5: + if (!n--) break; + *args++ = regs->r15; + case 4: + if (!n--) break; + *args++ = regs->r14; + case 3: + if (!n--) break; + *args++ = regs->r10; + case 2: + if (!n--) break; + *args++ = regs->r9; + case 1: + if (!n--) break; + *args++ = regs->r11; + case 0: + if (!n--) break; + default: + BUG(); + break; + } + + return; + } +#endif + ia64_syscall_get_set_arguments(task, regs, i, n, args, 0); +} + +static inline void syscall_set_arguments(struct task_struct *task, + struct pt_regs *regs, + unsigned int i, unsigned int n, + unsigned long *args) +{ + BUG_ON(i + n > 6); + +#ifdef CONFIG_IA32_SUPPORT + if (IS_IA32_PROCESS(regs)) { + switch (i + n) { + case 6: + if (!n--) break; + regs->r13 = *args++; + case 5: + if (!n--) break; + regs->r15 = *args++; + case 4: + if (!n--) break; + regs->r14 = *args++; + case 3: + if (!n--) break; + regs->r10 = *args++; + case 2: + if (!n--) break; + regs->r9 = *args++; + case 1: + if (!n--) break; + regs->r11 = *args++; + case 0: + if (!n--) break; + } + + return; + } +#endif + ia64_syscall_get_set_arguments(task, regs, i, n, args, 1); +} +#endif /* _ASM_SYSCALL_H */ diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h index 7c60fcdd2ef..ae6922626bf 100644 --- a/arch/ia64/include/asm/thread_info.h +++ b/arch/ia64/include/asm/thread_info.h @@ -87,9 +87,6 @@ struct thread_info { #define alloc_task_struct() ((struct task_struct *)__get_free_pages(GFP_KERNEL | __GFP_COMP, KERNEL_STACK_SIZE_ORDER)) #define free_task_struct(tsk) free_pages((unsigned long) (tsk), KERNEL_STACK_SIZE_ORDER) -#define tsk_set_notify_resume(tsk) \ - set_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME) -extern void tsk_clear_notify_resume(struct task_struct *tsk); #endif /* !__ASSEMBLY */ /* diff --git a/arch/ia64/include/asm/timex.h b/arch/ia64/include/asm/timex.h index 05a6baf8a47..4e03cfe74a0 100644 --- a/arch/ia64/include/asm/timex.h +++ b/arch/ia64/include/asm/timex.h @@ -39,4 +39,6 @@ get_cycles (void) return ret; } +extern void ia64_cpu_local_tick (void); + #endif /* _ASM_IA64_TIMEX_H */ diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h index d535833aab5..f791576355a 100644 --- a/arch/ia64/include/asm/unistd.h +++ b/arch/ia64/include/asm/unistd.h @@ -337,6 +337,7 @@ # define __ARCH_WANT_SYS_NICE # define __ARCH_WANT_SYS_OLD_GETRLIMIT # define __ARCH_WANT_SYS_OLDUMOUNT +# define __ARCH_WANT_SYS_PAUSE # define __ARCH_WANT_SYS_SIGPENDING # define __ARCH_WANT_SYS_SIGPROCMASK # define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND diff --git a/arch/ia64/include/asm/xen/events.h b/arch/ia64/include/asm/xen/events.h new file mode 100644 index 00000000000..73248781fba --- /dev/null +++ b/arch/ia64/include/asm/xen/events.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * arch/ia64/include/asm/xen/events.h + * + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _ASM_IA64_XEN_EVENTS_H +#define _ASM_IA64_XEN_EVENTS_H + +enum ipi_vector { + XEN_RESCHEDULE_VECTOR, + XEN_IPI_VECTOR, + XEN_CMCP_VECTOR, + XEN_CPEP_VECTOR, + + XEN_NR_IPIS, +}; + +static inline int xen_irqs_disabled(struct pt_regs *regs) +{ + return !(ia64_psr(regs)->i); +} + +static inline void xen_do_IRQ(int irq, struct pt_regs *regs) +{ + struct pt_regs *old_regs; + old_regs = set_irq_regs(regs); + irq_enter(); + __do_IRQ(irq); + irq_exit(); + set_irq_regs(old_regs); +} +#define irq_ctx_init(cpu) do { } while (0) + +#endif /* _ASM_IA64_XEN_EVENTS_H */ diff --git a/arch/ia64/include/asm/xen/grant_table.h b/arch/ia64/include/asm/xen/grant_table.h new file mode 100644 index 00000000000..2b1fae0e2d1 --- /dev/null +++ b/arch/ia64/include/asm/xen/grant_table.h @@ -0,0 +1,29 @@ +/****************************************************************************** + * arch/ia64/include/asm/xen/grant_table.h + * + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _ASM_IA64_XEN_GRANT_TABLE_H +#define _ASM_IA64_XEN_GRANT_TABLE_H + +struct vm_struct *xen_alloc_vm_area(unsigned long size); +void xen_free_vm_area(struct vm_struct *area); + +#endif /* _ASM_IA64_XEN_GRANT_TABLE_H */ diff --git a/arch/ia64/include/asm/xen/hypercall.h b/arch/ia64/include/asm/xen/hypercall.h new file mode 100644 index 00000000000..96fc62366aa --- /dev/null +++ b/arch/ia64/include/asm/xen/hypercall.h @@ -0,0 +1,265 @@ +/****************************************************************************** + * hypercall.h + * + * Linux-specific hypervisor handling. + * + * Copyright (c) 2002-2004, K A Fraser + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _ASM_IA64_XEN_HYPERCALL_H +#define _ASM_IA64_XEN_HYPERCALL_H + +#include <xen/interface/xen.h> +#include <xen/interface/physdev.h> +#include <xen/interface/sched.h> +#include <asm/xen/xcom_hcall.h> +struct xencomm_handle; +extern unsigned long __hypercall(unsigned long a1, unsigned long a2, + unsigned long a3, unsigned long a4, + unsigned long a5, unsigned long cmd); + +/* + * Assembler stubs for hyper-calls. + */ + +#define _hypercall0(type, name) \ +({ \ + long __res; \ + __res = __hypercall(0, 0, 0, 0, 0, __HYPERVISOR_##name);\ + (type)__res; \ +}) + +#define _hypercall1(type, name, a1) \ +({ \ + long __res; \ + __res = __hypercall((unsigned long)a1, \ + 0, 0, 0, 0, __HYPERVISOR_##name); \ + (type)__res; \ +}) + +#define _hypercall2(type, name, a1, a2) \ +({ \ + long __res; \ + __res = __hypercall((unsigned long)a1, \ + (unsigned long)a2, \ + 0, 0, 0, __HYPERVISOR_##name); \ + (type)__res; \ +}) + +#define _hypercall3(type, name, a1, a2, a3) \ +({ \ + long __res; \ + __res = __hypercall((unsigned long)a1, \ + (unsigned long)a2, \ + (unsigned long)a3, \ + 0, 0, __HYPERVISOR_##name); \ + (type)__res; \ +}) + +#define _hypercall4(type, name, a1, a2, a3, a4) \ +({ \ + long __res; \ + __res = __hypercall((unsigned long)a1, \ + (unsigned long)a2, \ + (unsigned long)a3, \ + (unsigned long)a4, \ + 0, __HYPERVISOR_##name); \ + (type)__res; \ +}) + +#define _hypercall5(type, name, a1, a2, a3, a4, a5) \ +({ \ + long __res; \ + __res = __hypercall((unsigned long)a1, \ + (unsigned long)a2, \ + (unsigned long)a3, \ + (unsigned long)a4, \ + (unsigned long)a5, \ + __HYPERVISOR_##name); \ + (type)__res; \ +}) + + +static inline int +xencomm_arch_hypercall_sched_op(int cmd, struct xencomm_handle *arg) +{ + return _hypercall2(int, sched_op_new, cmd, arg); +} + +static inline long +HYPERVISOR_set_timer_op(u64 timeout) +{ + unsigned long timeout_hi = (unsigned long)(timeout >> 32); + unsigned long timeout_lo = (unsigned long)timeout; + return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi); +} + +static inline int +xencomm_arch_hypercall_multicall(struct xencomm_handle *call_list, + int nr_calls) +{ + return _hypercall2(int, multicall, call_list, nr_calls); +} + +static inline int +xencomm_arch_hypercall_memory_op(unsigned int cmd, struct xencomm_handle *arg) +{ + return _hypercall2(int, memory_op, cmd, arg); +} + +static inline int +xencomm_arch_hypercall_event_channel_op(int cmd, struct xencomm_handle *arg) +{ + return _hypercall2(int, event_channel_op, cmd, arg); +} + +static inline int +xencomm_arch_hypercall_xen_version(int cmd, struct xencomm_handle *arg) +{ + return _hypercall2(int, xen_version, cmd, arg); +} + +static inline int +xencomm_arch_hypercall_console_io(int cmd, int count, + struct xencomm_handle *str) +{ + return _hypercall3(int, console_io, cmd, count, str); +} + +static inline int +xencomm_arch_hypercall_physdev_op(int cmd, struct xencomm_handle *arg) +{ + return _hypercall2(int, physdev_op, cmd, arg); +} + +static inline int +xencomm_arch_hypercall_grant_table_op(unsigned int cmd, + struct xencomm_handle *uop, + unsigned int count) +{ + return _hypercall3(int, grant_table_op, cmd, uop, count); +} + +int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count); + +extern int xencomm_arch_hypercall_suspend(struct xencomm_handle *arg); + +static inline int +xencomm_arch_hypercall_callback_op(int cmd, struct xencomm_handle *arg) +{ + return _hypercall2(int, callback_op, cmd, arg); +} + +static inline long +xencomm_arch_hypercall_vcpu_op(int cmd, int cpu, void *arg) +{ + return _hypercall3(long, vcpu_op, cmd, cpu, arg); +} + +static inline int +HYPERVISOR_physdev_op(int cmd, void *arg) +{ + switch (cmd) { + case PHYSDEVOP_eoi: + return _hypercall1(int, ia64_fast_eoi, + ((struct physdev_eoi *)arg)->irq); + default: + return xencomm_hypercall_physdev_op(cmd, arg); + } +} + +static inline long +xencomm_arch_hypercall_opt_feature(struct xencomm_handle *arg) +{ + return _hypercall1(long, opt_feature, arg); +} + +/* for balloon driver */ +#define HYPERVISOR_update_va_mapping(va, new_val, flags) (0) + +/* Use xencomm to do hypercalls. */ +#define HYPERVISOR_sched_op xencomm_hypercall_sched_op +#define HYPERVISOR_event_channel_op xencomm_hypercall_event_channel_op +#define HYPERVISOR_callback_op xencomm_hypercall_callback_op +#define HYPERVISOR_multicall xencomm_hypercall_multicall +#define HYPERVISOR_xen_version xencomm_hypercall_xen_version +#define HYPERVISOR_console_io xencomm_hypercall_console_io +#define HYPERVISOR_memory_op xencomm_hypercall_memory_op +#define HYPERVISOR_suspend xencomm_hypercall_suspend +#define HYPERVISOR_vcpu_op xencomm_hypercall_vcpu_op +#define HYPERVISOR_opt_feature xencomm_hypercall_opt_feature + +/* to compile gnttab_copy_grant_page() in drivers/xen/core/gnttab.c */ +#define HYPERVISOR_mmu_update(req, count, success_count, domid) ({ BUG(); 0; }) + +static inline int +HYPERVISOR_shutdown( + unsigned int reason) +{ + struct sched_shutdown sched_shutdown = { + .reason = reason + }; + + int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown); + + return rc; +} + +/* for netfront.c, netback.c */ +#define MULTI_UVMFLAGS_INDEX 0 /* XXX any value */ + +static inline void +MULTI_update_va_mapping( + struct multicall_entry *mcl, unsigned long va, + pte_t new_val, unsigned long flags) +{ + mcl->op = __HYPERVISOR_update_va_mapping; + mcl->result = 0; +} + +static inline void +MULTI_grant_table_op(struct multicall_entry *mcl, unsigned int cmd, + void *uop, unsigned int count) +{ + mcl->op = __HYPERVISOR_grant_table_op; + mcl->args[0] = cmd; + mcl->args[1] = (unsigned long)uop; + mcl->args[2] = count; +} + +static inline void +MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req, + int count, int *success_count, domid_t domid) +{ + mcl->op = __HYPERVISOR_mmu_update; + mcl->args[0] = (unsigned long)req; + mcl->args[1] = count; + mcl->args[2] = (unsigned long)success_count; + mcl->args[3] = domid; +} + +#endif /* _ASM_IA64_XEN_HYPERCALL_H */ diff --git a/arch/ia64/include/asm/xen/hypervisor.h b/arch/ia64/include/asm/xen/hypervisor.h new file mode 100644 index 00000000000..7a804e80fc6 --- /dev/null +++ b/arch/ia64/include/asm/xen/hypervisor.h @@ -0,0 +1,89 @@ +/****************************************************************************** + * hypervisor.h + * + * Linux-specific hypervisor handling. + * + * Copyright (c) 2002-2004, K A Fraser + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _ASM_IA64_XEN_HYPERVISOR_H +#define _ASM_IA64_XEN_HYPERVISOR_H + +#ifdef CONFIG_XEN + +#include <linux/init.h> +#include <xen/interface/xen.h> +#include <xen/interface/version.h> /* to compile feature.c */ +#include <xen/features.h> /* to comiple xen-netfront.c */ +#include <asm/xen/hypercall.h> + +/* xen_domain_type is set before executing any C code by early_xen_setup */ +enum xen_domain_type { + XEN_NATIVE, + XEN_PV_DOMAIN, + XEN_HVM_DOMAIN, +}; + +extern enum xen_domain_type xen_domain_type; + +#define xen_domain() (xen_domain_type != XEN_NATIVE) +#define xen_pv_domain() (xen_domain_type == XEN_PV_DOMAIN) +#define xen_initial_domain() (xen_pv_domain() && \ + (xen_start_info->flags & SIF_INITDOMAIN)) +#define xen_hvm_domain() (xen_domain_type == XEN_HVM_DOMAIN) + +/* deprecated. remove this */ +#define is_running_on_xen() (xen_domain_type == XEN_PV_DOMAIN) + +extern struct shared_info *HYPERVISOR_shared_info; +extern struct start_info *xen_start_info; + +void __init xen_setup_vcpu_info_placement(void); +void force_evtchn_callback(void); + +/* for drivers/xen/balloon/balloon.c */ +#ifdef CONFIG_XEN_SCRUB_PAGES +#define scrub_pages(_p, _n) memset((void *)(_p), 0, (_n) << PAGE_SHIFT) +#else +#define scrub_pages(_p, _n) ((void)0) +#endif + +/* For setup_arch() in arch/ia64/kernel/setup.c */ +void xen_ia64_enable_opt_feature(void); + +#else /* CONFIG_XEN */ + +#define xen_domain() (0) +#define xen_pv_domain() (0) +#define xen_initial_domain() (0) +#define xen_hvm_domain() (0) +#define is_running_on_xen() (0) /* deprecated. remove this */ +#endif + +#define is_initial_xendomain() (0) /* deprecated. remove this */ + +#endif /* _ASM_IA64_XEN_HYPERVISOR_H */ diff --git a/arch/ia64/include/asm/xen/inst.h b/arch/ia64/include/asm/xen/inst.h new file mode 100644 index 00000000000..19c2ae1d878 --- /dev/null +++ b/arch/ia64/include/asm/xen/inst.h @@ -0,0 +1,458 @@ +/****************************************************************************** + * arch/ia64/include/asm/xen/inst.h + * + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <asm/xen/privop.h> + +#define ia64_ivt xen_ivt +#define DO_SAVE_MIN XEN_DO_SAVE_MIN + +#define __paravirt_switch_to xen_switch_to +#define __paravirt_leave_syscall xen_leave_syscall +#define __paravirt_work_processed_syscall xen_work_processed_syscall +#define __paravirt_leave_kernel xen_leave_kernel +#define __paravirt_pending_syscall_end xen_work_pending_syscall_end +#define __paravirt_work_processed_syscall_target \ + xen_work_processed_syscall + +#define MOV_FROM_IFA(reg) \ + movl reg = XSI_IFA; \ + ;; \ + ld8 reg = [reg] + +#define MOV_FROM_ITIR(reg) \ + movl reg = XSI_ITIR; \ + ;; \ + ld8 reg = [reg] + +#define MOV_FROM_ISR(reg) \ + movl reg = XSI_ISR; \ + ;; \ + ld8 reg = [reg] + +#define MOV_FROM_IHA(reg) \ + movl reg = XSI_IHA; \ + ;; \ + ld8 reg = [reg] + +#define MOV_FROM_IPSR(pred, reg) \ +(pred) movl reg = XSI_IPSR; \ + ;; \ +(pred) ld8 reg = [reg] + +#define MOV_FROM_IIM(reg) \ + movl reg = XSI_IIM; \ + ;; \ + ld8 reg = [reg] + +#define MOV_FROM_IIP(reg) \ + movl reg = XSI_IIP; \ + ;; \ + ld8 reg = [reg] + +.macro __MOV_FROM_IVR reg, clob + .ifc "\reg", "r8" + XEN_HYPER_GET_IVR + .exitm + .endif + .ifc "\clob", "r8" + XEN_HYPER_GET_IVR + ;; + mov \reg = r8 + .exitm + .endif + + mov \clob = r8 + ;; + XEN_HYPER_GET_IVR + ;; + mov \reg = r8 + ;; + mov r8 = \clob +.endm +#define MOV_FROM_IVR(reg, clob) __MOV_FROM_IVR reg, clob + +.macro __MOV_FROM_PSR pred, reg, clob + .ifc "\reg", "r8" + (\pred) XEN_HYPER_GET_PSR; + .exitm + .endif + .ifc "\clob", "r8" + (\pred) XEN_HYPER_GET_PSR + ;; + (\pred) mov \reg = r8 + .exitm + .endif + + (\pred) mov \clob = r8 + (\pred) XEN_HYPER_GET_PSR + ;; + (\pred) mov \reg = r8 + (\pred) mov r8 = \clob +.endm +#define MOV_FROM_PSR(pred, reg, clob) __MOV_FROM_PSR pred, reg, clob + + +#define MOV_TO_IFA(reg, clob) \ + movl clob = XSI_IFA; \ + ;; \ + st8 [clob] = reg \ + +#define MOV_TO_ITIR(pred, reg, clob) \ +(pred) movl clob = XSI_ITIR; \ + ;; \ +(pred) st8 [clob] = reg + +#define MOV_TO_IHA(pred, reg, clob) \ +(pred) movl clob = XSI_IHA; \ + ;; \ +(pred) st8 [clob] = reg + +#define MOV_TO_IPSR(pred, reg, clob) \ +(pred) movl clob = XSI_IPSR; \ + ;; \ +(pred) st8 [clob] = reg; \ + ;; + +#define MOV_TO_IFS(pred, reg, clob) \ +(pred) movl clob = XSI_IFS; \ + ;; \ +(pred) st8 [clob] = reg; \ + ;; + +#define MOV_TO_IIP(reg, clob) \ + movl clob = XSI_IIP; \ + ;; \ + st8 [clob] = reg + +.macro ____MOV_TO_KR kr, reg, clob0, clob1 + .ifc "\clob0", "r9" + .error "clob0 \clob0 must not be r9" + .endif + .ifc "\clob1", "r8" + .error "clob1 \clob1 must not be r8" + .endif + + .ifnc "\reg", "r9" + .ifnc "\clob1", "r9" + mov \clob1 = r9 + .endif + mov r9 = \reg + .endif + .ifnc "\clob0", "r8" + mov \clob0 = r8 + .endif + mov r8 = \kr + ;; + XEN_HYPER_SET_KR + + .ifnc "\reg", "r9" + .ifnc "\clob1", "r9" + mov r9 = \clob1 + .endif + .endif + .ifnc "\clob0", "r8" + mov r8 = \clob0 + .endif +.endm + +.macro __MOV_TO_KR kr, reg, clob0, clob1 + .ifc "\clob0", "r9" + ____MOV_TO_KR \kr, \reg, \clob1, \clob0 + .exitm + .endif + .ifc "\clob1", "r8" + ____MOV_TO_KR \kr, \reg, \clob1, \clob0 + .exitm + .endif + + ____MOV_TO_KR \kr, \reg, \clob0, \clob1 +.endm + +#define MOV_TO_KR(kr, reg, clob0, clob1) \ + __MOV_TO_KR IA64_KR_ ## kr, reg, clob0, clob1 + + +.macro __ITC_I pred, reg, clob + .ifc "\reg", "r8" + (\pred) XEN_HYPER_ITC_I + .exitm + .endif + .ifc "\clob", "r8" + (\pred) mov r8 = \reg + ;; + (\pred) XEN_HYPER_ITC_I + .exitm + .endif + + (\pred) mov \clob = r8 + (\pred) mov r8 = \reg + ;; + (\pred) XEN_HYPER_ITC_I + ;; + (\pred) mov r8 = \clob + ;; +.endm +#define ITC_I(pred, reg, clob) __ITC_I pred, reg, clob + +.macro __ITC_D pred, reg, clob + .ifc "\reg", "r8" + (\pred) XEN_HYPER_ITC_D + ;; + .exitm + .endif + .ifc "\clob", "r8" + (\pred) mov r8 = \reg + ;; + (\pred) XEN_HYPER_ITC_D + ;; + .exitm + .endif + + (\pred) mov \clob = r8 + (\pred) mov r8 = \reg + ;; + (\pred) XEN_HYPER_ITC_D + ;; + (\pred) mov r8 = \clob + ;; +.endm +#define ITC_D(pred, reg, clob) __ITC_D pred, reg, clob + +.macro __ITC_I_AND_D pred_i, pred_d, reg, clob + .ifc "\reg", "r8" + (\pred_i)XEN_HYPER_ITC_I + ;; + (\pred_d)XEN_HYPER_ITC_D + ;; + .exitm + .endif + .ifc "\clob", "r8" + mov r8 = \reg + ;; + (\pred_i)XEN_HYPER_ITC_I + ;; + (\pred_d)XEN_HYPER_ITC_D + ;; + .exitm + .endif + + mov \clob = r8 + mov r8 = \reg + ;; + (\pred_i)XEN_HYPER_ITC_I + ;; + (\pred_d)XEN_HYPER_ITC_D + ;; + mov r8 = \clob + ;; +.endm +#define ITC_I_AND_D(pred_i, pred_d, reg, clob) \ + __ITC_I_AND_D pred_i, pred_d, reg, clob + +.macro __THASH pred, reg0, reg1, clob + .ifc "\reg0", "r8" + (\pred) mov r8 = \reg1 + (\pred) XEN_HYPER_THASH + .exitm + .endc + .ifc "\reg1", "r8" + (\pred) XEN_HYPER_THASH + ;; + (\pred) mov \reg0 = r8 + ;; + .exitm + .endif + .ifc "\clob", "r8" + (\pred) mov r8 = \reg1 + (\pred) XEN_HYPER_THASH + ;; + (\pred) mov \reg0 = r8 + ;; + .exitm + .endif + + (\pred) mov \clob = r8 + (\pred) mov r8 = \reg1 + (\pred) XEN_HYPER_THASH + ;; + (\pred) mov \reg0 = r8 + (\pred) mov r8 = \clob + ;; +.endm +#define THASH(pred, reg0, reg1, clob) __THASH pred, reg0, reg1, clob + +#define SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(clob0, clob1) \ + mov clob0 = 1; \ + movl clob1 = XSI_PSR_IC; \ + ;; \ + st4 [clob1] = clob0 \ + ;; + +#define SSM_PSR_IC_AND_SRLZ_D(clob0, clob1) \ + ;; \ + srlz.d; \ + mov clob1 = 1; \ + movl clob0 = XSI_PSR_IC; \ + ;; \ + st4 [clob0] = clob1 + +#define RSM_PSR_IC(clob) \ + movl clob = XSI_PSR_IC; \ + ;; \ + st4 [clob] = r0; \ + ;; + +/* pred will be clobbered */ +#define MASK_TO_PEND_OFS (-1) +#define SSM_PSR_I(pred, pred_clob, clob) \ +(pred) movl clob = XSI_PSR_I_ADDR \ + ;; \ +(pred) ld8 clob = [clob] \ + ;; \ + /* if (pred) vpsr.i = 1 */ \ + /* if (pred) (vcpu->vcpu_info->evtchn_upcall_mask)=0 */ \ +(pred) st1 [clob] = r0, MASK_TO_PEND_OFS \ + ;; \ + /* if (vcpu->vcpu_info->evtchn_upcall_pending) */ \ +(pred) ld1 clob = [clob] \ + ;; \ +(pred) cmp.ne.unc pred_clob, p0 = clob, r0 \ + ;; \ +(pred_clob)XEN_HYPER_SSM_I /* do areal ssm psr.i */ + +#define RSM_PSR_I(pred, clob0, clob1) \ + movl clob0 = XSI_PSR_I_ADDR; \ + mov clob1 = 1; \ + ;; \ + ld8 clob0 = [clob0]; \ + ;; \ +(pred) st1 [clob0] = clob1 + +#define RSM_PSR_I_IC(clob0, clob1, clob2) \ + movl clob0 = XSI_PSR_I_ADDR; \ + movl clob1 = XSI_PSR_IC; \ + ;; \ + ld8 clob0 = [clob0]; \ + mov clob2 = 1; \ + ;; \ + /* note: clears both vpsr.i and vpsr.ic! */ \ + st1 [clob0] = clob2; \ + st4 [clob1] = r0; \ + ;; + +#define RSM_PSR_DT \ + XEN_HYPER_RSM_PSR_DT + +#define SSM_PSR_DT_AND_SRLZ_I \ + XEN_HYPER_SSM_PSR_DT + +#define BSW_0(clob0, clob1, clob2) \ + ;; \ + /* r16-r31 all now hold bank1 values */ \ + mov clob2 = ar.unat; \ + movl clob0 = XSI_BANK1_R16; \ + movl clob1 = XSI_BANK1_R16 + 8; \ + ;; \ +.mem.offset 0, 0; st8.spill [clob0] = r16, 16; \ +.mem.offset 8, 0; st8.spill [clob1] = r17, 16; \ + ;; \ +.mem.offset 0, 0; st8.spill [clob0] = r18, 16; \ +.mem.offset 8, 0; st8.spill [clob1] = r19, 16; \ + ;; \ +.mem.offset 0, 0; st8.spill [clob0] = r20, 16; \ +.mem.offset 8, 0; st8.spill [clob1] = r21, 16; \ + ;; \ +.mem.offset 0, 0; st8.spill [clob0] = r22, 16; \ +.mem.offset 8, 0; st8.spill [clob1] = r23, 16; \ + ;; \ +.mem.offset 0, 0; st8.spill [clob0] = r24, 16; \ +.mem.offset 8, 0; st8.spill [clob1] = r25, 16; \ + ;; \ +.mem.offset 0, 0; st8.spill [clob0] = r26, 16; \ +.mem.offset 8, 0; st8.spill [clob1] = r27, 16; \ + ;; \ +.mem.offset 0, 0; st8.spill [clob0] = r28, 16; \ +.mem.offset 8, 0; st8.spill [clob1] = r29, 16; \ + ;; \ +.mem.offset 0, 0; st8.spill [clob0] = r30, 16; \ +.mem.offset 8, 0; st8.spill [clob1] = r31, 16; \ + ;; \ + mov clob1 = ar.unat; \ + movl clob0 = XSI_B1NAT; \ + ;; \ + st8 [clob0] = clob1; \ + mov ar.unat = clob2; \ + movl clob0 = XSI_BANKNUM; \ + ;; \ + st4 [clob0] = r0 + + + /* FIXME: THIS CODE IS NOT NaT SAFE! */ +#define XEN_BSW_1(clob) \ + mov clob = ar.unat; \ + movl r30 = XSI_B1NAT; \ + ;; \ + ld8 r30 = [r30]; \ + mov r31 = 1; \ + ;; \ + mov ar.unat = r30; \ + movl r30 = XSI_BANKNUM; \ + ;; \ + st4 [r30] = r31; \ + movl r30 = XSI_BANK1_R16; \ + movl r31 = XSI_BANK1_R16+8; \ + ;; \ + ld8.fill r16 = [r30], 16; \ + ld8.fill r17 = [r31], 16; \ + ;; \ + ld8.fill r18 = [r30], 16; \ + ld8.fill r19 = [r31], 16; \ + ;; \ + ld8.fill r20 = [r30], 16; \ + ld8.fill r21 = [r31], 16; \ + ;; \ + ld8.fill r22 = [r30], 16; \ + ld8.fill r23 = [r31], 16; \ + ;; \ + ld8.fill r24 = [r30], 16; \ + ld8.fill r25 = [r31], 16; \ + ;; \ + ld8.fill r26 = [r30], 16; \ + ld8.fill r27 = [r31], 16; \ + ;; \ + ld8.fill r28 = [r30], 16; \ + ld8.fill r29 = [r31], 16; \ + ;; \ + ld8.fill r30 = [r30]; \ + ld8.fill r31 = [r31]; \ + ;; \ + mov ar.unat = clob + +#define BSW_1(clob0, clob1) XEN_BSW_1(clob1) + + +#define COVER \ + XEN_HYPER_COVER + +#define RFI \ + XEN_HYPER_RFI; \ + dv_serialize_data diff --git a/arch/ia64/include/asm/xen/interface.h b/arch/ia64/include/asm/xen/interface.h new file mode 100644 index 00000000000..f00fab40854 --- /dev/null +++ b/arch/ia64/include/asm/xen/interface.h @@ -0,0 +1,346 @@ +/****************************************************************************** + * arch-ia64/hypervisor-if.h + * + * Guest OS interface to IA64 Xen. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright by those who contributed. (in alphabetical order) + * + * Anthony Xu <anthony.xu@intel.com> + * Eddie Dong <eddie.dong@intel.com> + * Fred Yang <fred.yang@intel.com> + * Kevin Tian <kevin.tian@intel.com> + * Alex Williamson <alex.williamson@hp.com> + * Chris Wright <chrisw@sous-sol.org> + * Christian Limpach <Christian.Limpach@cl.cam.ac.uk> + * Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com> + * Hollis Blanchard <hollisb@us.ibm.com> + * Isaku Yamahata <yamahata@valinux.co.jp> + * Jan Beulich <jbeulich@novell.com> + * John Levon <john.levon@sun.com> + * Kazuhiro Suzuki <kaz@jp.fujitsu.com> + * Keir Fraser <keir.fraser@citrix.com> + * Kouya Shimura <kouya@jp.fujitsu.com> + * Masaki Kanno <kanno.masaki@jp.fujitsu.com> + * Matt Chapman <matthewc@hp.com> + * Matthew Chapman <matthewc@hp.com> + * Samuel Thibault <samuel.thibault@eu.citrix.com> + * Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com> + * Tristan Gingold <tgingold@free.fr> + * Tsunehisa Doi <Doi.Tsunehisa@jp.fujitsu.com> + * Yutaka Ezaki <yutaka.ezaki@jp.fujitsu.com> + * Zhang Xin <xing.z.zhang@intel.com> + * Zhang xiantao <xiantao.zhang@intel.com> + * dan.magenheimer@hp.com + * ian.pratt@cl.cam.ac.uk + * michael.fetterman@cl.cam.ac.uk + */ + +#ifndef _ASM_IA64_XEN_INTERFACE_H +#define _ASM_IA64_XEN_INTERFACE_H + +#define __DEFINE_GUEST_HANDLE(name, type) \ + typedef struct { type *p; } __guest_handle_ ## name + +#define DEFINE_GUEST_HANDLE_STRUCT(name) \ + __DEFINE_GUEST_HANDLE(name, struct name) +#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name) +#define GUEST_HANDLE(name) __guest_handle_ ## name +#define GUEST_HANDLE_64(name) GUEST_HANDLE(name) +#define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0) + +#ifndef __ASSEMBLY__ +/* Guest handles for primitive C types. */ +__DEFINE_GUEST_HANDLE(uchar, unsigned char); +__DEFINE_GUEST_HANDLE(uint, unsigned int); +__DEFINE_GUEST_HANDLE(ulong, unsigned long); +__DEFINE_GUEST_HANDLE(u64, unsigned long); +DEFINE_GUEST_HANDLE(char); +DEFINE_GUEST_HANDLE(int); +DEFINE_GUEST_HANDLE(long); +DEFINE_GUEST_HANDLE(void); + +typedef unsigned long xen_pfn_t; +DEFINE_GUEST_HANDLE(xen_pfn_t); +#define PRI_xen_pfn "lx" +#endif + +/* Arch specific VIRQs definition */ +#define VIRQ_ITC VIRQ_ARCH_0 /* V. Virtual itc timer */ +#define VIRQ_MCA_CMC VIRQ_ARCH_1 /* MCA cmc interrupt */ +#define VIRQ_MCA_CPE VIRQ_ARCH_2 /* MCA cpe interrupt */ + +/* Maximum number of virtual CPUs in multi-processor guests. */ +/* keep sizeof(struct shared_page) <= PAGE_SIZE. + * this is checked in arch/ia64/xen/hypervisor.c. */ +#define MAX_VIRT_CPUS 64 + +#ifndef __ASSEMBLY__ + +#define INVALID_MFN (~0UL) + +union vac { + unsigned long value; + struct { + int a_int:1; + int a_from_int_cr:1; + int a_to_int_cr:1; + int a_from_psr:1; + int a_from_cpuid:1; + int a_cover:1; + int a_bsw:1; + long reserved:57; + }; +}; + +union vdc { + unsigned long value; + struct { + int d_vmsw:1; + int d_extint:1; + int d_ibr_dbr:1; + int d_pmc:1; + int d_to_pmd:1; + int d_itm:1; + long reserved:58; + }; +}; + +struct mapped_regs { + union vac vac; + union vdc vdc; + unsigned long virt_env_vaddr; + unsigned long reserved1[29]; + unsigned long vhpi; + unsigned long reserved2[95]; + union { + unsigned long vgr[16]; + unsigned long bank1_regs[16]; /* bank1 regs (r16-r31) + when bank0 active */ + }; + union { + unsigned long vbgr[16]; + unsigned long bank0_regs[16]; /* bank0 regs (r16-r31) + when bank1 active */ + }; + unsigned long vnat; + unsigned long vbnat; + unsigned long vcpuid[5]; + unsigned long reserved3[11]; + unsigned long vpsr; + unsigned long vpr; + unsigned long reserved4[76]; + union { + unsigned long vcr[128]; + struct { + unsigned long dcr; /* CR0 */ + unsigned long itm; + unsigned long iva; + unsigned long rsv1[5]; + unsigned long pta; /* CR8 */ + unsigned long rsv2[7]; + unsigned long ipsr; /* CR16 */ + unsigned long isr; + unsigned long rsv3; + unsigned long iip; + unsigned long ifa; + unsigned long itir; + unsigned long iipa; + unsigned long ifs; + unsigned long iim; /* CR24 */ + unsigned long iha; + unsigned long rsv4[38]; + unsigned long lid; /* CR64 */ + unsigned long ivr; + unsigned long tpr; + unsigned long eoi; + unsigned long irr[4]; + unsigned long itv; /* CR72 */ + unsigned long pmv; + unsigned long cmcv; + unsigned long rsv5[5]; + unsigned long lrr0; /* CR80 */ + unsigned long lrr1; + unsigned long rsv6[46]; + }; + }; + union { + unsigned long reserved5[128]; + struct { + unsigned long precover_ifs; + unsigned long unat; /* not sure if this is needed + until NaT arch is done */ + int interrupt_collection_enabled; /* virtual psr.ic */ + + /* virtual interrupt deliverable flag is + * evtchn_upcall_mask in shared info area now. + * interrupt_mask_addr is the address + * of evtchn_upcall_mask for current vcpu + */ + unsigned char *interrupt_mask_addr; + int pending_interruption; + unsigned char vpsr_pp; + unsigned char vpsr_dfh; + unsigned char hpsr_dfh; + unsigned char hpsr_mfh; + unsigned long reserved5_1[4]; + int metaphysical_mode; /* 1 = use metaphys mapping + 0 = use virtual */ + int banknum; /* 0 or 1, which virtual + register bank is active */ + unsigned long rrs[8]; /* region registers */ + unsigned long krs[8]; /* kernel registers */ + unsigned long tmp[16]; /* temp registers + (e.g. for hyperprivops) */ + }; + }; +}; + +struct arch_vcpu_info { + /* nothing */ +}; + +/* + * This structure is used for magic page in domain pseudo physical address + * space and the result of XENMEM_machine_memory_map. + * As the XENMEM_machine_memory_map result, + * xen_memory_map::nr_entries indicates the size in bytes + * including struct xen_ia64_memmap_info. Not the number of entries. + */ +struct xen_ia64_memmap_info { + uint64_t efi_memmap_size; /* size of EFI memory map */ + uint64_t efi_memdesc_size; /* size of an EFI memory map + * descriptor */ + uint32_t efi_memdesc_version; /* memory descriptor version */ + void *memdesc[0]; /* array of efi_memory_desc_t */ +}; + +struct arch_shared_info { + /* PFN of the start_info page. */ + unsigned long start_info_pfn; + + /* Interrupt vector for event channel. */ + int evtchn_vector; + + /* PFN of memmap_info page */ + unsigned int memmap_info_num_pages; /* currently only = 1 case is + supported. */ + unsigned long memmap_info_pfn; + + uint64_t pad[31]; +}; + +struct xen_callback { + unsigned long ip; +}; +typedef struct xen_callback xen_callback_t; + +#endif /* !__ASSEMBLY__ */ + +/* Size of the shared_info area (this is not related to page size). */ +#define XSI_SHIFT 14 +#define XSI_SIZE (1 << XSI_SHIFT) +/* Log size of mapped_regs area (64 KB - only 4KB is used). */ +#define XMAPPEDREGS_SHIFT 12 +#define XMAPPEDREGS_SIZE (1 << XMAPPEDREGS_SHIFT) +/* Offset of XASI (Xen arch shared info) wrt XSI_BASE. */ +#define XMAPPEDREGS_OFS XSI_SIZE + +/* Hyperprivops. */ +#define HYPERPRIVOP_START 0x1 +#define HYPERPRIVOP_RFI (HYPERPRIVOP_START + 0x0) +#define HYPERPRIVOP_RSM_DT (HYPERPRIVOP_START + 0x1) +#define HYPERPRIVOP_SSM_DT (HYPERPRIVOP_START + 0x2) +#define HYPERPRIVOP_COVER (HYPERPRIVOP_START + 0x3) +#define HYPERPRIVOP_ITC_D (HYPERPRIVOP_START + 0x4) +#define HYPERPRIVOP_ITC_I (HYPERPRIVOP_START + 0x5) +#define HYPERPRIVOP_SSM_I (HYPERPRIVOP_START + 0x6) +#define HYPERPRIVOP_GET_IVR (HYPERPRIVOP_START + 0x7) +#define HYPERPRIVOP_GET_TPR (HYPERPRIVOP_START + 0x8) +#define HYPERPRIVOP_SET_TPR (HYPERPRIVOP_START + 0x9) +#define HYPERPRIVOP_EOI (HYPERPRIVOP_START + 0xa) +#define HYPERPRIVOP_SET_ITM (HYPERPRIVOP_START + 0xb) +#define HYPERPRIVOP_THASH (HYPERPRIVOP_START + 0xc) +#define HYPERPRIVOP_PTC_GA (HYPERPRIVOP_START + 0xd) +#define HYPERPRIVOP_ITR_D (HYPERPRIVOP_START + 0xe) +#define HYPERPRIVOP_GET_RR (HYPERPRIVOP_START + 0xf) +#define HYPERPRIVOP_SET_RR (HYPERPRIVOP_START + 0x10) +#define HYPERPRIVOP_SET_KR (HYPERPRIVOP_START + 0x11) +#define HYPERPRIVOP_FC (HYPERPRIVOP_START + 0x12) +#define HYPERPRIVOP_GET_CPUID (HYPERPRIVOP_START + 0x13) +#define HYPERPRIVOP_GET_PMD (HYPERPRIVOP_START + 0x14) +#define HYPERPRIVOP_GET_EFLAG (HYPERPRIVOP_START + 0x15) +#define HYPERPRIVOP_SET_EFLAG (HYPERPRIVOP_START + 0x16) +#define HYPERPRIVOP_RSM_BE (HYPERPRIVOP_START + 0x17) +#define HYPERPRIVOP_GET_PSR (HYPERPRIVOP_START + 0x18) +#define HYPERPRIVOP_SET_RR0_TO_RR4 (HYPERPRIVOP_START + 0x19) +#define HYPERPRIVOP_MAX (0x1a) + +/* Fast and light hypercalls. */ +#define __HYPERVISOR_ia64_fast_eoi __HYPERVISOR_arch_1 + +/* Xencomm macros. */ +#define XENCOMM_INLINE_MASK 0xf800000000000000UL +#define XENCOMM_INLINE_FLAG 0x8000000000000000UL + +#ifndef __ASSEMBLY__ + +/* + * Optimization features. + * The hypervisor may do some special optimizations for guests. This hypercall + * can be used to switch on/of these special optimizations. + */ +#define __HYPERVISOR_opt_feature 0x700UL + +#define XEN_IA64_OPTF_OFF 0x0 +#define XEN_IA64_OPTF_ON 0x1 + +/* + * If this feature is switched on, the hypervisor inserts the + * tlb entries without calling the guests traphandler. + * This is useful in guests using region 7 for identity mapping + * like the linux kernel does. + */ +#define XEN_IA64_OPTF_IDENT_MAP_REG7 1 + +/* Identity mapping of region 4 addresses in HVM. */ +#define XEN_IA64_OPTF_IDENT_MAP_REG4 2 + +/* Identity mapping of region 5 addresses in HVM. */ +#define XEN_IA64_OPTF_IDENT_MAP_REG5 3 + +#define XEN_IA64_OPTF_IDENT_MAP_NOT_SET (0) + +struct xen_ia64_opt_feature { + unsigned long cmd; /* Which feature */ + unsigned char on; /* Switch feature on/off */ + union { + struct { + /* The page protection bit mask of the pte. + * This will be or'ed with the pte. */ + unsigned long pgprot; + unsigned long key; /* A protection key for itir.*/ + }; + }; +}; + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_IA64_XEN_INTERFACE_H */ diff --git a/arch/ia64/include/asm/xen/irq.h b/arch/ia64/include/asm/xen/irq.h new file mode 100644 index 00000000000..a9045098300 --- /dev/null +++ b/arch/ia64/include/asm/xen/irq.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * arch/ia64/include/asm/xen/irq.h + * + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _ASM_IA64_XEN_IRQ_H +#define _ASM_IA64_XEN_IRQ_H + +/* + * The flat IRQ space is divided into two regions: + * 1. A one-to-one mapping of real physical IRQs. This space is only used + * if we have physical device-access privilege. This region is at the + * start of the IRQ space so that existing device drivers do not need + * to be modified to translate physical IRQ numbers into our IRQ space. + * 3. A dynamic mapping of inter-domain and Xen-sourced virtual IRQs. These + * are bound using the provided bind/unbind functions. + */ + +#define XEN_PIRQ_BASE 0 +#define XEN_NR_PIRQS 256 + +#define XEN_DYNIRQ_BASE (XEN_PIRQ_BASE + XEN_NR_PIRQS) +#define XEN_NR_DYNIRQS (NR_CPUS * 8) + +#define XEN_NR_IRQS (XEN_NR_PIRQS + XEN_NR_DYNIRQS) + +#endif /* _ASM_IA64_XEN_IRQ_H */ diff --git a/arch/ia64/include/asm/xen/minstate.h b/arch/ia64/include/asm/xen/minstate.h new file mode 100644 index 00000000000..4d92d9bbda7 --- /dev/null +++ b/arch/ia64/include/asm/xen/minstate.h @@ -0,0 +1,134 @@ +/* + * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves + * the minimum state necessary that allows us to turn psr.ic back + * on. + * + * Assumed state upon entry: + * psr.ic: off + * r31: contains saved predicates (pr) + * + * Upon exit, the state is as follows: + * psr.ic: off + * r2 = points to &pt_regs.r16 + * r8 = contents of ar.ccv + * r9 = contents of ar.csd + * r10 = contents of ar.ssd + * r11 = FPSR_DEFAULT + * r12 = kernel sp (kernel virtual address) + * r13 = points to current task_struct (kernel virtual address) + * p15 = TRUE if psr.i is set in cr.ipsr + * predicate registers (other than p2, p3, and p15), b6, r3, r14, r15: + * preserved + * CONFIG_XEN note: p6/p7 are not preserved + * + * Note that psr.ic is NOT turned on by this macro. This is so that + * we can pass interruption state as arguments to a handler. + */ +#define XEN_DO_SAVE_MIN(__COVER,SAVE_IFS,EXTRA,WORKAROUND) \ + mov r16=IA64_KR(CURRENT); /* M */ \ + mov r27=ar.rsc; /* M */ \ + mov r20=r1; /* A */ \ + mov r25=ar.unat; /* M */ \ + MOV_FROM_IPSR(p0,r29); /* M */ \ + MOV_FROM_IIP(r28); /* M */ \ + mov r21=ar.fpsr; /* M */ \ + mov r26=ar.pfs; /* I */ \ + __COVER; /* B;; (or nothing) */ \ + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16; \ + ;; \ + ld1 r17=[r16]; /* load current->thread.on_ustack flag */ \ + st1 [r16]=r0; /* clear current->thread.on_ustack flag */ \ + adds r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 \ + /* switch from user to kernel RBS: */ \ + ;; \ + invala; /* M */ \ + /* SAVE_IFS;*/ /* see xen special handling below */ \ + cmp.eq pKStk,pUStk=r0,r17; /* are we in kernel mode already? */ \ + ;; \ +(pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ + ;; \ +(pUStk) mov.m r24=ar.rnat; \ +(pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of RBS */ \ +(pKStk) mov r1=sp; /* get sp */ \ + ;; \ +(pUStk) lfetch.fault.excl.nt1 [r22]; \ +(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \ +(pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \ + ;; \ +(pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \ +(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ + ;; \ +(pUStk) mov r18=ar.bsp; \ +(pUStk) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \ + adds r17=2*L1_CACHE_BYTES,r1; /* really: biggest cache-line size */ \ + adds r16=PT(CR_IPSR),r1; \ + ;; \ + lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES; \ + st8 [r16]=r29; /* save cr.ipsr */ \ + ;; \ + lfetch.fault.excl.nt1 [r17]; \ + tbit.nz p15,p0=r29,IA64_PSR_I_BIT; \ + mov r29=b0 \ + ;; \ + WORKAROUND; \ + adds r16=PT(R8),r1; /* initialize first base pointer */ \ + adds r17=PT(R9),r1; /* initialize second base pointer */ \ +(pKStk) mov r18=r0; /* make sure r18 isn't NaT */ \ + ;; \ +.mem.offset 0,0; st8.spill [r16]=r8,16; \ +.mem.offset 8,0; st8.spill [r17]=r9,16; \ + ;; \ +.mem.offset 0,0; st8.spill [r16]=r10,24; \ + movl r8=XSI_PRECOVER_IFS; \ +.mem.offset 8,0; st8.spill [r17]=r11,24; \ + ;; \ + /* xen special handling for possibly lazy cover */ \ + /* SAVE_MIN case in dispatch_ia32_handler: mov r30=r0 */ \ + ld8 r30=[r8]; \ +(pUStk) sub r18=r18,r22; /* r18=RSE.ndirty*8 */ \ + st8 [r16]=r28,16; /* save cr.iip */ \ + ;; \ + st8 [r17]=r30,16; /* save cr.ifs */ \ + mov r8=ar.ccv; \ + mov r9=ar.csd; \ + mov r10=ar.ssd; \ + movl r11=FPSR_DEFAULT; /* L-unit */ \ + ;; \ + st8 [r16]=r25,16; /* save ar.unat */ \ + st8 [r17]=r26,16; /* save ar.pfs */ \ + shl r18=r18,16; /* compute ar.rsc to be used for "loadrs" */ \ + ;; \ + st8 [r16]=r27,16; /* save ar.rsc */ \ +(pUStk) st8 [r17]=r24,16; /* save ar.rnat */ \ +(pKStk) adds r17=16,r17; /* skip over ar_rnat field */ \ + ;; /* avoid RAW on r16 & r17 */ \ +(pUStk) st8 [r16]=r23,16; /* save ar.bspstore */ \ + st8 [r17]=r31,16; /* save predicates */ \ +(pKStk) adds r16=16,r16; /* skip over ar_bspstore field */ \ + ;; \ + st8 [r16]=r29,16; /* save b0 */ \ + st8 [r17]=r18,16; /* save ar.rsc value for "loadrs" */ \ + cmp.eq pNonSys,pSys=r0,r0 /* initialize pSys=0, pNonSys=1 */ \ + ;; \ +.mem.offset 0,0; st8.spill [r16]=r20,16; /* save original r1 */ \ +.mem.offset 8,0; st8.spill [r17]=r12,16; \ + adds r12=-16,r1; /* switch to kernel memory stack (with 16 bytes of scratch) */ \ + ;; \ +.mem.offset 0,0; st8.spill [r16]=r13,16; \ +.mem.offset 8,0; st8.spill [r17]=r21,16; /* save ar.fpsr */ \ + mov r13=IA64_KR(CURRENT); /* establish `current' */ \ + ;; \ +.mem.offset 0,0; st8.spill [r16]=r15,16; \ +.mem.offset 8,0; st8.spill [r17]=r14,16; \ + ;; \ +.mem.offset 0,0; st8.spill [r16]=r2,16; \ +.mem.offset 8,0; st8.spill [r17]=r3,16; \ + ACCOUNT_GET_STAMP \ + adds r2=IA64_PT_REGS_R16_OFFSET,r1; \ + ;; \ + EXTRA; \ + movl r1=__gp; /* establish kernel global pointer */ \ + ;; \ + ACCOUNT_SYS_ENTER \ + BSW_1(r3,r14); /* switch back to bank 1 (must be last in insn group) */ \ + ;; diff --git a/arch/ia64/include/asm/xen/page.h b/arch/ia64/include/asm/xen/page.h new file mode 100644 index 00000000000..03441a780b5 --- /dev/null +++ b/arch/ia64/include/asm/xen/page.h @@ -0,0 +1,65 @@ +/****************************************************************************** + * arch/ia64/include/asm/xen/page.h + * + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _ASM_IA64_XEN_PAGE_H +#define _ASM_IA64_XEN_PAGE_H + +#define INVALID_P2M_ENTRY (~0UL) + +static inline unsigned long mfn_to_pfn(unsigned long mfn) +{ + return mfn; +} + +static inline unsigned long pfn_to_mfn(unsigned long pfn) +{ + return pfn; +} + +#define phys_to_machine_mapping_valid(_x) (1) + +static inline void *mfn_to_virt(unsigned long mfn) +{ + return __va(mfn << PAGE_SHIFT); +} + +static inline unsigned long virt_to_mfn(void *virt) +{ + return __pa(virt) >> PAGE_SHIFT; +} + +/* for tpmfront.c */ +static inline unsigned long virt_to_machine(void *virt) +{ + return __pa(virt); +} + +static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn) +{ + /* nothing */ +} + +#define pte_mfn(_x) pte_pfn(_x) +#define mfn_pte(_x, _y) __pte_ma(0) /* unmodified use */ +#define __pte_ma(_x) ((pte_t) {(_x)}) /* unmodified use */ + +#endif /* _ASM_IA64_XEN_PAGE_H */ diff --git a/arch/ia64/include/asm/xen/privop.h b/arch/ia64/include/asm/xen/privop.h new file mode 100644 index 00000000000..71ec7546e10 --- /dev/null +++ b/arch/ia64/include/asm/xen/privop.h @@ -0,0 +1,129 @@ +#ifndef _ASM_IA64_XEN_PRIVOP_H +#define _ASM_IA64_XEN_PRIVOP_H + +/* + * Copyright (C) 2005 Hewlett-Packard Co + * Dan Magenheimer <dan.magenheimer@hp.com> + * + * Paravirtualizations of privileged operations for Xen/ia64 + * + * + * inline privop and paravirt_alt support + * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + */ + +#ifndef __ASSEMBLY__ +#include <linux/types.h> /* arch-ia64.h requires uint64_t */ +#endif +#include <asm/xen/interface.h> + +/* At 1 MB, before per-cpu space but still addressable using addl instead + of movl. */ +#define XSI_BASE 0xfffffffffff00000 + +/* Address of mapped regs. */ +#define XMAPPEDREGS_BASE (XSI_BASE + XSI_SIZE) + +#ifdef __ASSEMBLY__ +#define XEN_HYPER_RFI break HYPERPRIVOP_RFI +#define XEN_HYPER_RSM_PSR_DT break HYPERPRIVOP_RSM_DT +#define XEN_HYPER_SSM_PSR_DT break HYPERPRIVOP_SSM_DT +#define XEN_HYPER_COVER break HYPERPRIVOP_COVER +#define XEN_HYPER_ITC_D break HYPERPRIVOP_ITC_D +#define XEN_HYPER_ITC_I break HYPERPRIVOP_ITC_I +#define XEN_HYPER_SSM_I break HYPERPRIVOP_SSM_I +#define XEN_HYPER_GET_IVR break HYPERPRIVOP_GET_IVR +#define XEN_HYPER_THASH break HYPERPRIVOP_THASH +#define XEN_HYPER_ITR_D break HYPERPRIVOP_ITR_D +#define XEN_HYPER_SET_KR break HYPERPRIVOP_SET_KR +#define XEN_HYPER_GET_PSR break HYPERPRIVOP_GET_PSR +#define XEN_HYPER_SET_RR0_TO_RR4 break HYPERPRIVOP_SET_RR0_TO_RR4 + +#define XSI_IFS (XSI_BASE + XSI_IFS_OFS) +#define XSI_PRECOVER_IFS (XSI_BASE + XSI_PRECOVER_IFS_OFS) +#define XSI_IFA (XSI_BASE + XSI_IFA_OFS) +#define XSI_ISR (XSI_BASE + XSI_ISR_OFS) +#define XSI_IIM (XSI_BASE + XSI_IIM_OFS) +#define XSI_ITIR (XSI_BASE + XSI_ITIR_OFS) +#define XSI_PSR_I_ADDR (XSI_BASE + XSI_PSR_I_ADDR_OFS) +#define XSI_PSR_IC (XSI_BASE + XSI_PSR_IC_OFS) +#define XSI_IPSR (XSI_BASE + XSI_IPSR_OFS) +#define XSI_IIP (XSI_BASE + XSI_IIP_OFS) +#define XSI_B1NAT (XSI_BASE + XSI_B1NATS_OFS) +#define XSI_BANK1_R16 (XSI_BASE + XSI_BANK1_R16_OFS) +#define XSI_BANKNUM (XSI_BASE + XSI_BANKNUM_OFS) +#define XSI_IHA (XSI_BASE + XSI_IHA_OFS) +#endif + +#ifndef __ASSEMBLY__ + +/************************************************/ +/* Instructions paravirtualized for correctness */ +/************************************************/ + +/* "fc" and "thash" are privilege-sensitive instructions, meaning they + * may have different semantics depending on whether they are executed + * at PL0 vs PL!=0. When paravirtualized, these instructions mustn't + * be allowed to execute directly, lest incorrect semantics result. */ +extern void xen_fc(unsigned long addr); +extern unsigned long xen_thash(unsigned long addr); + +/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag" + * is not currently used (though it may be in a long-format VHPT system!) + * and the semantics of cover only change if psr.ic is off which is very + * rare (and currently non-existent outside of assembly code */ + +/* There are also privilege-sensitive registers. These registers are + * readable at any privilege level but only writable at PL0. */ +extern unsigned long xen_get_cpuid(int index); +extern unsigned long xen_get_pmd(int index); + +extern unsigned long xen_get_eflag(void); /* see xen_ia64_getreg */ +extern void xen_set_eflag(unsigned long); /* see xen_ia64_setreg */ + +/************************************************/ +/* Instructions paravirtualized for performance */ +/************************************************/ + +/* Xen uses memory-mapped virtual privileged registers for access to many + * performance-sensitive privileged registers. Some, like the processor + * status register (psr), are broken up into multiple memory locations. + * Others, like "pend", are abstractions based on privileged registers. + * "Pend" is guaranteed to be set if reading cr.ivr would return a + * (non-spurious) interrupt. */ +#define XEN_MAPPEDREGS ((struct mapped_regs *)XMAPPEDREGS_BASE) + +#define XSI_PSR_I \ + (*XEN_MAPPEDREGS->interrupt_mask_addr) +#define xen_get_virtual_psr_i() \ + (!XSI_PSR_I) +#define xen_set_virtual_psr_i(_val) \ + ({ XSI_PSR_I = (uint8_t)(_val) ? 0 : 1; }) +#define xen_set_virtual_psr_ic(_val) \ + ({ XEN_MAPPEDREGS->interrupt_collection_enabled = _val ? 1 : 0; }) +#define xen_get_virtual_pend() \ + (*(((uint8_t *)XEN_MAPPEDREGS->interrupt_mask_addr) - 1)) + +/* Although all privileged operations can be left to trap and will + * be properly handled by Xen, some are frequent enough that we use + * hyperprivops for performance. */ +extern unsigned long xen_get_psr(void); +extern unsigned long xen_get_ivr(void); +extern unsigned long xen_get_tpr(void); +extern void xen_hyper_ssm_i(void); +extern void xen_set_itm(unsigned long); +extern void xen_set_tpr(unsigned long); +extern void xen_eoi(unsigned long); +extern unsigned long xen_get_rr(unsigned long index); +extern void xen_set_rr(unsigned long index, unsigned long val); +extern void xen_set_rr0_to_rr4(unsigned long val0, unsigned long val1, + unsigned long val2, unsigned long val3, + unsigned long val4); +extern void xen_set_kr(unsigned long index, unsigned long val); +extern void xen_ptcga(unsigned long addr, unsigned long size); + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_IA64_XEN_PRIVOP_H */ diff --git a/arch/ia64/include/asm/xen/xcom_hcall.h b/arch/ia64/include/asm/xen/xcom_hcall.h new file mode 100644 index 00000000000..20b2950c71b --- /dev/null +++ b/arch/ia64/include/asm/xen/xcom_hcall.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2006 Tristan Gingold <tristan.gingold@bull.net>, Bull SAS + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _ASM_IA64_XEN_XCOM_HCALL_H +#define _ASM_IA64_XEN_XCOM_HCALL_H + +/* These function creates inline or mini descriptor for the parameters and + calls the corresponding xencomm_arch_hypercall_X. + Architectures should defines HYPERVISOR_xxx as xencomm_hypercall_xxx unless + they want to use their own wrapper. */ +extern int xencomm_hypercall_console_io(int cmd, int count, char *str); + +extern int xencomm_hypercall_event_channel_op(int cmd, void *op); + +extern int xencomm_hypercall_xen_version(int cmd, void *arg); + +extern int xencomm_hypercall_physdev_op(int cmd, void *op); + +extern int xencomm_hypercall_grant_table_op(unsigned int cmd, void *op, + unsigned int count); + +extern int xencomm_hypercall_sched_op(int cmd, void *arg); + +extern int xencomm_hypercall_multicall(void *call_list, int nr_calls); + +extern int xencomm_hypercall_callback_op(int cmd, void *arg); + +extern int xencomm_hypercall_memory_op(unsigned int cmd, void *arg); + +extern int xencomm_hypercall_suspend(unsigned long srec); + +extern long xencomm_hypercall_vcpu_op(int cmd, int cpu, void *arg); + +extern long xencomm_hypercall_opt_feature(void *arg); + +#endif /* _ASM_IA64_XEN_XCOM_HCALL_H */ diff --git a/arch/ia64/include/asm/xen/xencomm.h b/arch/ia64/include/asm/xen/xencomm.h new file mode 100644 index 00000000000..cded677bebf --- /dev/null +++ b/arch/ia64/include/asm/xen/xencomm.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2006 Hollis Blanchard <hollisb@us.ibm.com>, IBM Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _ASM_IA64_XEN_XENCOMM_H +#define _ASM_IA64_XEN_XENCOMM_H + +#include <xen/xencomm.h> +#include <asm/pgtable.h> + +/* Must be called before any hypercall. */ +extern void xencomm_initialize(void); +extern int xencomm_is_initialized(void); + +/* Check if virtual contiguity means physical contiguity + * where the passed address is a pointer value in virtual address. + * On ia64, identity mapping area in region 7 or the piece of region 5 + * that is mapped by itr[IA64_TR_KERNEL]/dtr[IA64_TR_KERNEL] + */ +static inline int xencomm_is_phys_contiguous(unsigned long addr) +{ + return (PAGE_OFFSET <= addr && + addr < (PAGE_OFFSET + (1UL << IA64_MAX_PHYS_BITS))) || + (KERNEL_START <= addr && + addr < KERNEL_START + KERNEL_TR_PAGE_SIZE); +} + +#endif /* _ASM_IA64_XEN_XENCOMM_H */ diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 87fea11aecb..c381ea95489 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -42,6 +42,10 @@ obj-$(CONFIG_IA64_ESI) += esi.o ifneq ($(CONFIG_IA64_ESI),) obj-y += esi_stub.o # must be in kernel proper endif +obj-$(CONFIG_DMAR) += pci-dma.o +ifeq ($(CONFIG_DMAR), y) +obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o +endif # The gate DSO image is built using a special linker script. targets += gate.so gate-syms.o @@ -112,5 +116,23 @@ clean-files += $(objtree)/include/asm-ia64/nr-irqs.h ASM_PARAVIRT_OBJS = ivt.o entry.o define paravirtualized_native AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE +AFLAGS_pvchk-sed-$(1) += -D__IA64_ASM_PARAVIRTUALIZED_PVCHECK +extra-y += pvchk-$(1) endef $(foreach obj,$(ASM_PARAVIRT_OBJS),$(eval $(call paravirtualized_native,$(obj)))) + +# +# Checker for paravirtualizations of privileged operations. +# +quiet_cmd_pv_check_sed = PVCHK $@ +define cmd_pv_check_sed + sed -f $(srctree)/arch/$(SRCARCH)/scripts/pvcheck.sed $< > $@ +endef + +$(obj)/pvchk-sed-%.s: $(src)/%.S $(srctree)/arch/$(SRCARCH)/scripts/pvcheck.sed FORCE + $(call if_changed_dep,as_s_S) +$(obj)/pvchk-%.s: $(obj)/pvchk-sed-%.s FORCE + $(call if_changed,pv_check_sed) +$(obj)/pvchk-%.o: $(obj)/pvchk-%.s FORCE + $(call if_changed,as_o_S) +.PRECIOUS: $(obj)/pvchk-sed-%.s $(obj)/pvchk-%.s $(obj)/pvchk-%.o diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 5d1eb7ee2bf..0635015d0aa 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -52,6 +52,7 @@ #include <asm/numa.h> #include <asm/sal.h> #include <asm/cyclone.h> +#include <asm/xen/hypervisor.h> #define BAD_MADT_ENTRY(entry, end) ( \ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ @@ -91,6 +92,9 @@ acpi_get_sysname(void) struct acpi_table_rsdp *rsdp; struct acpi_table_xsdt *xsdt; struct acpi_table_header *hdr; +#ifdef CONFIG_DMAR + u64 i, nentries; +#endif rsdp_phys = acpi_find_rsdp(); if (!rsdp_phys) { @@ -121,7 +125,21 @@ acpi_get_sysname(void) return "uv"; else return "sn2"; + } else if (xen_pv_domain() && !strcmp(hdr->oem_id, "XEN")) { + return "xen"; + } + +#ifdef CONFIG_DMAR + /* Look for Intel IOMMU */ + nentries = (hdr->length - sizeof(*hdr)) / + sizeof(xsdt->table_offset_entry[0]); + for (i = 0; i < nentries; i++) { + hdr = __va(xsdt->table_offset_entry[i]); + if (strncmp(hdr->signature, ACPI_SIG_DMAR, + sizeof(ACPI_SIG_DMAR) - 1) == 0) + return "dig_vtd"; } +#endif return "dig"; #else @@ -137,6 +155,10 @@ acpi_get_sysname(void) return "uv"; # elif defined (CONFIG_IA64_DIG) return "dig"; +# elif defined (CONFIG_IA64_XEN_GUEST) + return "xen"; +# elif defined(CONFIG_IA64_DIG_VTD) + return "dig_vtd"; # else # error Unknown platform. Fix acpi.c. # endif diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c index 94c44b1ccfd..742dbb1d5a4 100644 --- a/arch/ia64/kernel/asm-offsets.c +++ b/arch/ia64/kernel/asm-offsets.c @@ -16,6 +16,9 @@ #include <asm/sigcontext.h> #include <asm/mca.h> +#include <asm/xen/interface.h> +#include <asm/xen/hypervisor.h> + #include "../kernel/sigframe.h" #include "../kernel/fsyscall_gtod_data.h" @@ -286,4 +289,32 @@ void foo(void) offsetof (struct itc_jitter_data_t, itc_jitter)); DEFINE(IA64_ITC_LASTCYCLE_OFFSET, offsetof (struct itc_jitter_data_t, itc_lastcycle)); + +#ifdef CONFIG_XEN + BLANK(); + + DEFINE(XEN_NATIVE_ASM, XEN_NATIVE); + DEFINE(XEN_PV_DOMAIN_ASM, XEN_PV_DOMAIN); + +#define DEFINE_MAPPED_REG_OFS(sym, field) \ + DEFINE(sym, (XMAPPEDREGS_OFS + offsetof(struct mapped_regs, field))) + + DEFINE_MAPPED_REG_OFS(XSI_PSR_I_ADDR_OFS, interrupt_mask_addr); + DEFINE_MAPPED_REG_OFS(XSI_IPSR_OFS, ipsr); + DEFINE_MAPPED_REG_OFS(XSI_IIP_OFS, iip); + DEFINE_MAPPED_REG_OFS(XSI_IFS_OFS, ifs); + DEFINE_MAPPED_REG_OFS(XSI_PRECOVER_IFS_OFS, precover_ifs); + DEFINE_MAPPED_REG_OFS(XSI_ISR_OFS, isr); + DEFINE_MAPPED_REG_OFS(XSI_IFA_OFS, ifa); + DEFINE_MAPPED_REG_OFS(XSI_IIPA_OFS, iipa); + DEFINE_MAPPED_REG_OFS(XSI_IIM_OFS, iim); + DEFINE_MAPPED_REG_OFS(XSI_IHA_OFS, iha); + DEFINE_MAPPED_REG_OFS(XSI_ITIR_OFS, itir); + DEFINE_MAPPED_REG_OFS(XSI_PSR_IC_OFS, interrupt_collection_enabled); + DEFINE_MAPPED_REG_OFS(XSI_BANKNUM_OFS, banknum); + DEFINE_MAPPED_REG_OFS(XSI_BANK0_R16_OFS, bank0_regs[0]); + DEFINE_MAPPED_REG_OFS(XSI_BANK1_R16_OFS, bank1_regs[0]); + DEFINE_MAPPED_REG_OFS(XSI_B0NATS_OFS, vbnat); + DEFINE_MAPPED_REG_OFS(XSI_B1NATS_OFS, vnat); +#endif /* CONFIG_XEN */ } diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 0dd6c1419d8..7ef0c594f5e 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -534,6 +534,11 @@ GLOBAL_ENTRY(ia64_trace_syscall) stf.spill [r16]=f10 stf.spill [r17]=f11 br.call.sptk.many rp=syscall_trace_enter // give parent a chance to catch syscall args + cmp.lt p6,p0=r8,r0 // check tracehook + adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8 + adds r3=PT(R10)+16,sp // r3 = &pt_regs.r10 + mov r10=0 +(p6) br.cond.sptk strace_error // syscall failed -> adds r16=PT(F6)+16,sp adds r17=PT(F7)+16,sp ;; diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index 416a952b19b..f675d8e3385 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -580,7 +580,7 @@ ENTRY(dirty_bit) mov b0=r29 // restore b0 ;; st8 [r17]=r18 // store back updated PTE - itc.d r18 // install updated PTE + ITC_D(p0, r18, r16) // install updated PTE #endif mov pr=r31,-1 // restore pr RFI @@ -646,7 +646,7 @@ ENTRY(iaccess_bit) mov b0=r29 // restore b0 ;; st8 [r17]=r18 // store back updated PTE - itc.i r18 // install updated PTE + ITC_I(p0, r18, r16) // install updated PTE #endif /* !CONFIG_SMP */ mov pr=r31,-1 RFI @@ -698,7 +698,7 @@ ENTRY(daccess_bit) or r18=_PAGE_A,r18 // set the accessed bit ;; st8 [r17]=r18 // store back updated PTE - itc.d r18 // install updated PTE + ITC_D(p0, r18, r16) // install updated PTE #endif mov b0=r29 // restore b0 mov pr=r31,-1 diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c index 60c6ef67ebb..702a09c1323 100644 --- a/arch/ia64/kernel/msi_ia64.c +++ b/arch/ia64/kernel/msi_ia64.c @@ -5,6 +5,7 @@ #include <linux/pci.h> #include <linux/irq.h> #include <linux/msi.h> +#include <linux/dmar.h> #include <asm/smp.h> /* @@ -162,3 +163,82 @@ void arch_teardown_msi_irq(unsigned int irq) return ia64_teardown_msi_irq(irq); } + +#ifdef CONFIG_DMAR +#ifdef CONFIG_SMP +static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask) +{ + struct irq_cfg *cfg = irq_cfg + irq; + struct msi_msg msg; + int cpu = first_cpu(mask); + + + if (!cpu_online(cpu)) + return; + + if (irq_prepare_move(irq, cpu)) + return; + + dmar_msi_read(irq, &msg); + + msg.data &= ~MSI_DATA_VECTOR_MASK; + msg.data |= MSI_DATA_VECTOR(cfg->vector); + msg.address_lo &= ~MSI_ADDR_DESTID_MASK; + msg.address_lo |= MSI_ADDR_DESTID_CPU(cpu_physical_id(cpu)); + + dmar_msi_write(irq, &msg); + irq_desc[irq].affinity = mask; +} +#endif /* CONFIG_SMP */ + +struct irq_chip dmar_msi_type = { + .name = "DMAR_MSI", + .unmask = dmar_msi_unmask, + .mask = dmar_msi_mask, + .ack = ia64_ack_msi_irq, +#ifdef CONFIG_SMP + .set_affinity = dmar_msi_set_affinity, +#endif + .retrigger = ia64_msi_retrigger_irq, +}; + +static int +msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg) +{ + struct irq_cfg *cfg = irq_cfg + irq; + unsigned dest; + cpumask_t mask; + + cpus_and(mask, irq_to_domain(irq), cpu_online_map); + dest = cpu_physical_id(first_cpu(mask)); + + msg->address_hi = 0; + msg->address_lo = + MSI_ADDR_HEADER | + MSI_ADDR_DESTMODE_PHYS | + MSI_ADDR_REDIRECTION_CPU | + MSI_ADDR_DESTID_CPU(dest); + + msg->data = + MSI_DATA_TRIGGER_EDGE | + MSI_DATA_LEVEL_ASSERT | + MSI_DATA_DELIVERY_FIXED | + MSI_DATA_VECTOR(cfg->vector); + return 0; +} + +int arch_setup_dmar_msi(unsigned int irq) +{ + int ret; + struct msi_msg msg; + + ret = msi_compose_msg(NULL, irq, &msg); + if (ret < 0) + return ret; + dmar_msi_write(irq, &msg); + set_irq_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq, + "edge"); + return 0; +} +#endif /* CONFIG_DMAR */ + diff --git a/arch/ia64/kernel/nr-irqs.c b/arch/ia64/kernel/nr-irqs.c index 8273afc32db..ee564575148 100644 --- a/arch/ia64/kernel/nr-irqs.c +++ b/arch/ia64/kernel/nr-irqs.c @@ -10,6 +10,7 @@ #include <linux/kbuild.h> #include <linux/threads.h> #include <asm/native/irq.h> +#include <asm/xen/irq.h> void foo(void) { diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c index afaf5b9a2cf..de35d8e8b7d 100644 --- a/arch/ia64/kernel/paravirt.c +++ b/arch/ia64/kernel/paravirt.c @@ -332,7 +332,7 @@ ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val) struct pv_iosapic_ops pv_iosapic_ops = { .pcat_compat_init = ia64_native_iosapic_pcat_compat_init, - .get_irq_chip = ia64_native_iosapic_get_irq_chip, + .__get_irq_chip = ia64_native_iosapic_get_irq_chip, .__read = ia64_native_iosapic_read, .__write = ia64_native_iosapic_write, diff --git a/arch/ia64/kernel/paravirt_inst.h b/arch/ia64/kernel/paravirt_inst.h index 5cad6fb2ed1..64d6d810c64 100644 --- a/arch/ia64/kernel/paravirt_inst.h +++ b/arch/ia64/kernel/paravirt_inst.h @@ -20,7 +20,9 @@ * */ -#ifdef __IA64_ASM_PARAVIRTUALIZED_XEN +#ifdef __IA64_ASM_PARAVIRTUALIZED_PVCHECK +#include <asm/native/pvchk_inst.h> +#elif defined(__IA64_ASM_PARAVIRTUALIZED_XEN) #include <asm/xen/inst.h> #include <asm/xen/minstate.h> #else diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c new file mode 100644 index 00000000000..10a75b55765 --- /dev/null +++ b/arch/ia64/kernel/pci-dma.c @@ -0,0 +1,129 @@ +/* + * Dynamic DMA mapping support. + */ + +#include <linux/types.h> +#include <linux/mm.h> +#include <linux/string.h> +#include <linux/pci.h> +#include <linux/module.h> +#include <linux/dmar.h> +#include <asm/iommu.h> +#include <asm/machvec.h> +#include <linux/dma-mapping.h> + +#include <asm/machvec.h> +#include <asm/system.h> + +#ifdef CONFIG_DMAR + +#include <linux/kernel.h> +#include <linux/string.h> + +#include <asm/page.h> +#include <asm/iommu.h> + +dma_addr_t bad_dma_address __read_mostly; +EXPORT_SYMBOL(bad_dma_address); + +static int iommu_sac_force __read_mostly; + +int no_iommu __read_mostly; +#ifdef CONFIG_IOMMU_DEBUG +int force_iommu __read_mostly = 1; +#else +int force_iommu __read_mostly; +#endif + +/* Set this to 1 if there is a HW IOMMU in the system */ +int iommu_detected __read_mostly; + +/* Dummy device used for NULL arguments (normally ISA). Better would + be probably a smaller DMA mask, but this is bug-to-bug compatible + to i386. */ +struct device fallback_dev = { + .bus_id = "fallback device", + .coherent_dma_mask = DMA_32BIT_MASK, + .dma_mask = &fallback_dev.coherent_dma_mask, +}; + +void __init pci_iommu_alloc(void) +{ + /* + * The order of these functions is important for + * fall-back/fail-over reasons + */ + detect_intel_iommu(); + +#ifdef CONFIG_SWIOTLB + pci_swiotlb_init(); +#endif +} + +static int __init pci_iommu_init(void) +{ + if (iommu_detected) + intel_iommu_init(); + + return 0; +} + +/* Must execute after PCI subsystem */ +fs_initcall(pci_iommu_init); + +void pci_iommu_shutdown(void) +{ + return; +} + +void __init +iommu_dma_init(void) +{ + return; +} + +struct dma_mapping_ops *dma_ops; +EXPORT_SYMBOL(dma_ops); + +int iommu_dma_supported(struct device *dev, u64 mask) +{ + struct dma_mapping_ops *ops = get_dma_ops(dev); + +#ifdef CONFIG_PCI + if (mask > 0xffffffff && forbid_dac > 0) { + dev_info(dev, "Disallowing DAC for device\n"); + return 0; + } +#endif + + if (ops->dma_supported_op) + return ops->dma_supported_op(dev, mask); + + /* Copied from i386. Doesn't make much sense, because it will + only work for pci_alloc_coherent. + The caller just has to use GFP_DMA in this case. */ + if (mask < DMA_24BIT_MASK) + return 0; + + /* Tell the device to use SAC when IOMMU force is on. This + allows the driver to use cheaper accesses in some cases. + + Problem with this is that if we overflow the IOMMU area and + return DAC as fallback address the device may not handle it + correctly. + + As a special case some controllers have a 39bit address + mode that is as efficient as 32bit (aic79xx). Don't force + SAC for these. Assume all masks <= 40 bits are of this + type. Normally this doesn't make any difference, but gives + more gentle handling of IOMMU overflow. */ + if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) { + dev_info(dev, "Force SAC with mask %lx\n", mask); + return 0; + } + + return 1; +} +EXPORT_SYMBOL(iommu_dma_supported); + +#endif diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c new file mode 100644 index 00000000000..16c50516dbc --- /dev/null +++ b/arch/ia64/kernel/pci-swiotlb.c @@ -0,0 +1,46 @@ +/* Glue code to lib/swiotlb.c */ + +#include <linux/pci.h> +#include <linux/cache.h> +#include <linux/module.h> +#include <linux/dma-mapping.h> + +#include <asm/swiotlb.h> +#include <asm/dma.h> +#include <asm/iommu.h> +#include <asm/machvec.h> + +int swiotlb __read_mostly; +EXPORT_SYMBOL(swiotlb); + +struct dma_mapping_ops swiotlb_dma_ops = { + .mapping_error = swiotlb_dma_mapping_error, + .alloc_coherent = swiotlb_alloc_coherent, + .free_coherent = swiotlb_free_coherent, + .map_single = swiotlb_map_single, + .unmap_single = swiotlb_unmap_single, + .sync_single_for_cpu = swiotlb_sync_single_for_cpu, + .sync_single_for_device = swiotlb_sync_single_for_device, + .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu, + .sync_single_range_for_device = swiotlb_sync_single_range_for_device, + .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, + .sync_sg_for_device = swiotlb_sync_sg_for_device, + .map_sg = swiotlb_map_sg, + .unmap_sg = swiotlb_unmap_sg, + .dma_supported_op = swiotlb_dma_supported, +}; + +void __init pci_swiotlb_init(void) +{ + if (!iommu_detected) { +#ifdef CONFIG_IA64_GENERIC + swiotlb = 1; + printk(KERN_INFO "PCI-DMA: Re-initialize machine vector.\n"); + machvec_init("dig"); + swiotlb_init(); + dma_ops = &swiotlb_dma_ops; +#else + panic("Unable to find Intel IOMMU"); +#endif + } +} diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index fc8f3509df2..ada4605d122 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -40,6 +40,7 @@ #include <linux/capability.h> #include <linux/rcupdate.h> #include <linux/completion.h> +#include <linux/tracehook.h> #include <asm/errno.h> #include <asm/intrinsics.h> @@ -3684,7 +3685,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) PFM_SET_WORK_PENDING(task, 1); - tsk_set_notify_resume(task); + set_notify_resume(task); /* * XXX: send reschedule if task runs on another CPU @@ -5044,8 +5045,6 @@ pfm_handle_work(void) PFM_SET_WORK_PENDING(current, 0); - tsk_clear_notify_resume(current); - regs = task_pt_regs(current); /* @@ -5414,7 +5413,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str * when coming from ctxsw, current still points to the * previous task, therefore we must work with task and not current. */ - tsk_set_notify_resume(task); + set_notify_resume(task); } /* * defer until state is changed (shorten spin window). the context is locked diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 3ab8373103e..c5716270514 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -28,6 +28,7 @@ #include <linux/delay.h> #include <linux/kdebug.h> #include <linux/utsname.h> +#include <linux/tracehook.h> #include <asm/cpu.h> #include <asm/delay.h> @@ -160,21 +161,6 @@ show_regs (struct pt_regs *regs) show_stack(NULL, NULL); } -void tsk_clear_notify_resume(struct task_struct *tsk) -{ -#ifdef CONFIG_PERFMON - if (tsk->thread.pfm_needs_checking) - return; -#endif - if (test_ti_thread_flag(task_thread_info(tsk), TIF_RESTORE_RSE)) - return; - clear_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME); -} - -/* - * do_notify_resume_user(): - * Called from notify_resume_user at entry.S, with interrupts disabled. - */ void do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall) { @@ -203,6 +189,11 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall) ia64_do_signal(scr, in_syscall); } + if (test_thread_flag(TIF_NOTIFY_RESUME)) { + clear_thread_flag(TIF_NOTIFY_RESUME); + tracehook_notify_resume(&scr->pt); + } + /* copy user rbs to kernel rbs */ if (unlikely(test_thread_flag(TIF_RESTORE_RSE))) { local_irq_enable(); /* force interrupt enable */ @@ -251,7 +242,6 @@ default_idle (void) /* We don't actually take CPU down, just spin without interrupts. */ static inline void play_dead(void) { - extern void ia64_cpu_local_tick (void); unsigned int this_cpu = smp_processor_id(); /* Ack it */ diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 2a9943b5947..92c9689b7d9 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -22,6 +22,7 @@ #include <linux/signal.h> #include <linux/regset.h> #include <linux/elf.h> +#include <linux/tracehook.h> #include <asm/pgtable.h> #include <asm/processor.h> @@ -603,7 +604,7 @@ void ia64_ptrace_stop(void) { if (test_and_set_tsk_thread_flag(current, TIF_RESTORE_RSE)) return; - tsk_set_notify_resume(current); + set_notify_resume(current); unw_init_running(do_sync_rbs, ia64_sync_user_rbs); } @@ -613,7 +614,6 @@ void ia64_ptrace_stop(void) void ia64_sync_krbs(void) { clear_tsk_thread_flag(current, TIF_RESTORE_RSE); - tsk_clear_notify_resume(current); unw_init_running(do_sync_rbs, ia64_sync_kernel_rbs); } @@ -644,7 +644,7 @@ ptrace_attach_sync_user_rbs (struct task_struct *child) spin_lock_irq(&child->sighand->siglock); if (child->state == TASK_STOPPED && !test_and_set_tsk_thread_flag(child, TIF_RESTORE_RSE)) { - tsk_set_notify_resume(child); + set_notify_resume(child); child->state = TASK_TRACED; stopped = 1; @@ -1232,37 +1232,16 @@ arch_ptrace (struct task_struct *child, long request, long addr, long data) } -static void -syscall_trace (void) -{ - /* - * The 0x80 provides a way for the tracing parent to - * distinguish between a syscall stop and SIGTRAP delivery. - */ - ptrace_notify(SIGTRAP - | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); - - /* - * This isn't the same as continuing with a signal, but it - * will do for normal use. strace only continues with a - * signal if the stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } -} - /* "asmlinkage" so the input arguments are preserved... */ -asmlinkage void +asmlinkage long syscall_trace_enter (long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, struct pt_regs regs) { - if (test_thread_flag(TIF_SYSCALL_TRACE) - && (current->ptrace & PT_PTRACED)) - syscall_trace(); + if (test_thread_flag(TIF_SYSCALL_TRACE)) + if (tracehook_report_syscall_entry(®s)) + return -ENOSYS; /* copy user rbs to kernel rbs */ if (test_thread_flag(TIF_RESTORE_RSE)) @@ -1283,6 +1262,7 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3, audit_syscall_entry(arch, syscall, arg0, arg1, arg2, arg3); } + return 0; } /* "asmlinkage" so the input arguments are preserved... */ @@ -1292,6 +1272,8 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6, long arg7, struct pt_regs regs) { + int step; + if (unlikely(current->audit_context)) { int success = AUDITSC_RESULT(regs.r10); long result = regs.r8; @@ -1301,10 +1283,9 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3, audit_syscall_exit(success, result); } - if ((test_thread_flag(TIF_SYSCALL_TRACE) - || test_thread_flag(TIF_SINGLESTEP)) - && (current->ptrace & PT_PTRACED)) - syscall_trace(); + step = test_thread_flag(TIF_SINGLESTEP); + if (step || test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(®s, step); /* copy user rbs to kernel rbs */ if (test_thread_flag(TIF_RESTORE_RSE)) @@ -1940,7 +1921,7 @@ gpregs_writeback(struct task_struct *target, { if (test_and_set_tsk_thread_flag(target, TIF_RESTORE_RSE)) return 0; - tsk_set_notify_resume(target); + set_notify_resume(target); return do_regset_call(do_gpregs_writeback, target, regset, 0, 0, NULL, NULL); } @@ -2199,3 +2180,68 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *tsk) #endif return &user_ia64_view; } + +struct syscall_get_set_args { + unsigned int i; + unsigned int n; + unsigned long *args; + struct pt_regs *regs; + int rw; +}; + +static void syscall_get_set_args_cb(struct unw_frame_info *info, void *data) +{ + struct syscall_get_set_args *args = data; + struct pt_regs *pt = args->regs; + unsigned long *krbs, cfm, ndirty; + int i, count; + + if (unw_unwind_to_user(info) < 0) + return; + + cfm = pt->cr_ifs; + krbs = (unsigned long *)info->task + IA64_RBS_OFFSET/8; + ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19)); + + count = 0; + if (in_syscall(pt)) + count = min_t(int, args->n, cfm & 0x7f); + + for (i = 0; i < count; i++) { + if (args->rw) + *ia64_rse_skip_regs(krbs, ndirty + i + args->i) = + args->args[i]; + else + args->args[i] = *ia64_rse_skip_regs(krbs, + ndirty + i + args->i); + } + + if (!args->rw) { + while (i < args->n) { + args->args[i] = 0; + i++; + } + } +} + +void ia64_syscall_get_set_arguments(struct task_struct *task, + struct pt_regs *regs, unsigned int i, unsigned int n, + unsigned long *args, int rw) +{ + struct syscall_get_set_args data = { + .i = i, + .n = n, + .args = args, + .regs = regs, + .rw = rw, + }; + + if (task == current) + unw_init_running(syscall_get_set_args_cb, &data); + else { + struct unw_frame_info ufi; + memset(&ufi, 0, sizeof(ufi)); + unw_init_from_blocked_task(&ufi, task); + syscall_get_set_args_cb(&ufi, &data); + } +} diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 916ba898237..ae7911702bf 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -116,6 +116,13 @@ unsigned int num_io_spaces; */ #define I_CACHE_STRIDE_SHIFT 5 /* Safest way to go: 32 bytes by 32 bytes */ unsigned long ia64_i_cache_stride_shift = ~0; +/* + * "clflush_cache_range()" needs to know what processor dependent stride size to + * use when it flushes cache lines including both d-cache and i-cache. + */ +/* Safest way to go: 32 bytes by 32 bytes */ +#define CACHE_STRIDE_SHIFT 5 +unsigned long ia64_cache_stride_shift = ~0; /* * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1). This @@ -852,13 +859,14 @@ setup_per_cpu_areas (void) } /* - * Calculate the max. cache line size. + * Do the following calculations: * - * In addition, the minimum of the i-cache stride sizes is calculated for - * "flush_icache_range()". + * 1. the max. cache line size. + * 2. the minimum of the i-cache stride sizes for "flush_icache_range()". + * 3. the minimum of the cache stride sizes for "clflush_cache_range()". */ static void __cpuinit -get_max_cacheline_size (void) +get_cache_info(void) { unsigned long line_size, max = 1; u64 l, levels, unique_caches; @@ -872,12 +880,14 @@ get_max_cacheline_size (void) max = SMP_CACHE_BYTES; /* Safest setup for "flush_icache_range()" */ ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT; + /* Safest setup for "clflush_cache_range()" */ + ia64_cache_stride_shift = CACHE_STRIDE_SHIFT; goto out; } for (l = 0; l < levels; ++l) { - status = ia64_pal_cache_config_info(l, /* cache_type (data_or_unified)= */ 2, - &cci); + /* cache_type (data_or_unified)=2 */ + status = ia64_pal_cache_config_info(l, 2, &cci); if (status != 0) { printk(KERN_ERR "%s: ia64_pal_cache_config_info(l=%lu, 2) failed (status=%ld)\n", @@ -885,15 +895,21 @@ get_max_cacheline_size (void) max = SMP_CACHE_BYTES; /* The safest setup for "flush_icache_range()" */ cci.pcci_stride = I_CACHE_STRIDE_SHIFT; + /* The safest setup for "clflush_cache_range()" */ + ia64_cache_stride_shift = CACHE_STRIDE_SHIFT; cci.pcci_unified = 1; + } else { + if (cci.pcci_stride < ia64_cache_stride_shift) + ia64_cache_stride_shift = cci.pcci_stride; + + line_size = 1 << cci.pcci_line_size; + if (line_size > max) + max = line_size; } - line_size = 1 << cci.pcci_line_size; - if (line_size > max) - max = line_size; + if (!cci.pcci_unified) { - status = ia64_pal_cache_config_info(l, - /* cache_type (instruction)= */ 1, - &cci); + /* cache_type (instruction)=1*/ + status = ia64_pal_cache_config_info(l, 1, &cci); if (status != 0) { printk(KERN_ERR "%s: ia64_pal_cache_config_info(l=%lu, 1) failed (status=%ld)\n", @@ -947,7 +963,7 @@ cpu_init (void) } #endif - get_max_cacheline_size(); + get_cache_info(); /* * We can't pass "local_cpu_data" to identify_cpu() because we haven't called diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 19c5a78636f..e12500a9c44 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/mm.h> #include <linux/ptrace.h> +#include <linux/tracehook.h> #include <linux/sched.h> #include <linux/signal.h> #include <linux/smp.h> @@ -439,6 +440,13 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse sigaddset(¤t->blocked, sig); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + + /* + * Let tracing know that we've done the handler setup. + */ + tracehook_signal_handler(sig, info, ka, &scr->pt, + test_thread_flag(TIF_SINGLESTEP)); + return 1; } diff --git a/arch/ia64/lib/flush.S b/arch/ia64/lib/flush.S index 2a0d27f2f21..1d8c8886006 100644 --- a/arch/ia64/lib/flush.S +++ b/arch/ia64/lib/flush.S @@ -60,3 +60,58 @@ GLOBAL_ENTRY(flush_icache_range) mov ar.lc=r3 // restore ar.lc br.ret.sptk.many rp END(flush_icache_range) + + /* + * clflush_cache_range(start,size) + * + * Flush cache lines from start to start+size-1. + * + * Must deal with range from start to start+size-1 but nothing else + * (need to be careful not to touch addresses that may be + * unmapped). + * + * Note: "in0" and "in1" are preserved for debugging purposes. + */ + .section .kprobes.text,"ax" +GLOBAL_ENTRY(clflush_cache_range) + + .prologue + alloc r2=ar.pfs,2,0,0,0 + movl r3=ia64_cache_stride_shift + mov r21=1 + add r22=in1,in0 + ;; + ld8 r20=[r3] // r20: stride shift + sub r22=r22,r0,1 // last byte address + ;; + shr.u r23=in0,r20 // start / (stride size) + shr.u r22=r22,r20 // (last byte address) / (stride size) + shl r21=r21,r20 // r21: stride size of the i-cache(s) + ;; + sub r8=r22,r23 // number of strides - 1 + shl r24=r23,r20 // r24: addresses for "fc" = + // "start" rounded down to stride + // boundary + .save ar.lc,r3 + mov r3=ar.lc // save ar.lc + ;; + + .body + mov ar.lc=r8 + ;; + /* + * 32 byte aligned loop, even number of (actually 2) bundles + */ +.Loop_fc: + fc r24 // issuable on M0 only + add r24=r21,r24 // we flush "stride size" bytes per iteration + nop.i 0 + br.cloop.sptk.few .Loop_fc + ;; + sync.i + ;; + srlz.i + ;; + mov ar.lc=r3 // restore ar.lc + br.ret.sptk.many rp +END(clflush_cache_range) diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index 8caf42471f0..bd9818a36b4 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c @@ -362,9 +362,13 @@ ia64_tlb_init (void) per_cpu(ia64_tr_num, cpu) = vm_info_1.pal_vm_info_1_s.max_dtr_entry+1; if (per_cpu(ia64_tr_num, cpu) > IA64_TR_ALLOC_MAX) { + static int justonce = 1; per_cpu(ia64_tr_num, cpu) = IA64_TR_ALLOC_MAX; - printk(KERN_DEBUG "TR register number exceeds IA64_TR_ALLOC_MAX!" - "IA64_TR_ALLOC_MAX should be extended\n"); + if (justonce) { + justonce = 0; + printk(KERN_DEBUG "TR register number exceeds " + "IA64_TR_ALLOC_MAX!\n"); + } } } diff --git a/arch/ia64/scripts/pvcheck.sed b/arch/ia64/scripts/pvcheck.sed new file mode 100644 index 00000000000..ba66ac2e4c6 --- /dev/null +++ b/arch/ia64/scripts/pvcheck.sed @@ -0,0 +1,32 @@ +# +# Checker for paravirtualizations of privileged operations. +# +s/ssm.*psr\.ic.*/.warning \"ssm psr.ic should not be used directly\"/g +s/rsm.*psr\.ic.*/.warning \"rsm psr.ic should not be used directly\"/g +s/ssm.*psr\.i.*/.warning \"ssm psr.i should not be used directly\"/g +s/rsm.*psr\.i.*/.warning \"rsm psr.i should not be used directly\"/g +s/ssm.*psr\.dt.*/.warning \"ssm psr.dt should not be used directly\"/g +s/rsm.*psr\.dt.*/.warning \"rsm psr.dt should not be used directly\"/g +s/mov.*=.*cr\.ifa/.warning \"cr.ifa should not used directly\"/g +s/mov.*=.*cr\.itir/.warning \"cr.itir should not used directly\"/g +s/mov.*=.*cr\.isr/.warning \"cr.isr should not used directly\"/g +s/mov.*=.*cr\.iha/.warning \"cr.iha should not used directly\"/g +s/mov.*=.*cr\.ipsr/.warning \"cr.ipsr should not used directly\"/g +s/mov.*=.*cr\.iim/.warning \"cr.iim should not used directly\"/g +s/mov.*=.*cr\.iip/.warning \"cr.iip should not used directly\"/g +s/mov.*=.*cr\.ivr/.warning \"cr.ivr should not used directly\"/g +s/mov.*=[^\.]*psr/.warning \"psr should not used directly\"/g # avoid ar.fpsr +s/mov.*=.*ar\.eflags/.warning \"ar.eflags should not used directly\"/g +s/mov.*cr\.ifa.*=.*/.warning \"cr.ifa should not used directly\"/g +s/mov.*cr\.itir.*=.*/.warning \"cr.itir should not used directly\"/g +s/mov.*cr\.iha.*=.*/.warning \"cr.iha should not used directly\"/g +s/mov.*cr\.ipsr.*=.*/.warning \"cr.ipsr should not used directly\"/g +s/mov.*cr\.ifs.*=.*/.warning \"cr.ifs should not used directly\"/g +s/mov.*cr\.iip.*=.*/.warning \"cr.iip should not used directly\"/g +s/mov.*cr\.kr.*=.*/.warning \"cr.kr should not used directly\"/g +s/mov.*ar\.eflags.*=.*/.warning \"ar.eflags should not used directly\"/g +s/itc\.i.*/.warning \"itc.i should not be used directly.\"/g +s/itc\.d.*/.warning \"itc.d should not be used directly.\"/g +s/bsw\.0/.warning \"bsw.0 should not be used directly.\"/g +s/bsw\.1/.warning \"bsw.1 should not be used directly.\"/g +s/ptc\.ga.*/.warning \"ptc.ga should not be used directly.\"/g diff --git a/arch/ia64/xen/Kconfig b/arch/ia64/xen/Kconfig new file mode 100644 index 00000000000..f1683a20275 --- /dev/null +++ b/arch/ia64/xen/Kconfig @@ -0,0 +1,26 @@ +# +# This Kconfig describes xen/ia64 options +# + +config XEN + bool "Xen hypervisor support" + default y + depends on PARAVIRT && MCKINLEY && IA64_PAGE_SIZE_16KB && EXPERIMENTAL + select XEN_XENCOMM + select NO_IDLE_HZ + + # those are required to save/restore. + select ARCH_SUSPEND_POSSIBLE + select SUSPEND + select PM_SLEEP + help + Enable Xen hypervisor support. Resulting kernel runs + both as a guest OS on Xen and natively on hardware. + +config XEN_XENCOMM + depends on XEN + bool + +config NO_IDLE_HZ + depends on XEN + bool diff --git a/arch/ia64/xen/Makefile b/arch/ia64/xen/Makefile new file mode 100644 index 00000000000..0ad0224693d --- /dev/null +++ b/arch/ia64/xen/Makefile @@ -0,0 +1,22 @@ +# +# Makefile for Xen components +# + +obj-y := hypercall.o xenivt.o xensetup.o xen_pv_ops.o irq_xen.o \ + hypervisor.o xencomm.o xcom_hcall.o grant-table.o time.o suspend.o + +obj-$(CONFIG_IA64_GENERIC) += machvec.o + +AFLAGS_xenivt.o += -D__IA64_ASM_PARAVIRTUALIZED_XEN + +# xen multi compile +ASM_PARAVIRT_MULTI_COMPILE_SRCS = ivt.S entry.S +ASM_PARAVIRT_OBJS = $(addprefix xen-,$(ASM_PARAVIRT_MULTI_COMPILE_SRCS:.S=.o)) +obj-y += $(ASM_PARAVIRT_OBJS) +define paravirtualized_xen +AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_XEN +endef +$(foreach o,$(ASM_PARAVIRT_OBJS),$(eval $(call paravirtualized_xen,$(o)))) + +$(obj)/xen-%.o: $(src)/../kernel/%.S FORCE + $(call if_changed_dep,as_o_S) diff --git a/arch/ia64/xen/grant-table.c b/arch/ia64/xen/grant-table.c new file mode 100644 index 00000000000..777dd9a9108 --- /dev/null +++ b/arch/ia64/xen/grant-table.c @@ -0,0 +1,155 @@ +/****************************************************************************** + * arch/ia64/xen/grant-table.c + * + * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <linux/module.h> +#include <linux/vmalloc.h> +#include <linux/mm.h> + +#include <xen/interface/xen.h> +#include <xen/interface/memory.h> +#include <xen/grant_table.h> + +#include <asm/xen/hypervisor.h> + +struct vm_struct *xen_alloc_vm_area(unsigned long size) +{ + int order; + unsigned long virt; + unsigned long nr_pages; + struct vm_struct *area; + + order = get_order(size); + virt = __get_free_pages(GFP_KERNEL, order); + if (virt == 0) + goto err0; + nr_pages = 1 << order; + scrub_pages(virt, nr_pages); + + area = kmalloc(sizeof(*area), GFP_KERNEL); + if (area == NULL) + goto err1; + + area->flags = VM_IOREMAP; + area->addr = (void *)virt; + area->size = size; + area->pages = NULL; + area->nr_pages = nr_pages; + area->phys_addr = 0; /* xenbus_map_ring_valloc uses this field! */ + + return area; + +err1: + free_pages(virt, order); +err0: + return NULL; +} +EXPORT_SYMBOL_GPL(xen_alloc_vm_area); + +void xen_free_vm_area(struct vm_struct *area) +{ + unsigned int order = get_order(area->size); + unsigned long i; + unsigned long phys_addr = __pa(area->addr); + + /* This area is used for foreign page mappping. + * So underlying machine page may not be assigned. */ + for (i = 0; i < (1 << order); i++) { + unsigned long ret; + unsigned long gpfn = (phys_addr >> PAGE_SHIFT) + i; + struct xen_memory_reservation reservation = { + .nr_extents = 1, + .address_bits = 0, + .extent_order = 0, + .domid = DOMID_SELF + }; + set_xen_guest_handle(reservation.extent_start, &gpfn); + ret = HYPERVISOR_memory_op(XENMEM_populate_physmap, + &reservation); + BUG_ON(ret != 1); + } + free_pages((unsigned long)area->addr, order); + kfree(area); +} +EXPORT_SYMBOL_GPL(xen_free_vm_area); + + +/**************************************************************************** + * grant table hack + * cmd: GNTTABOP_xxx + */ + +int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes, + unsigned long max_nr_gframes, + struct grant_entry **__shared) +{ + *__shared = __va(frames[0] << PAGE_SHIFT); + return 0; +} + +void arch_gnttab_unmap_shared(struct grant_entry *shared, + unsigned long nr_gframes) +{ + /* nothing */ +} + +static void +gnttab_map_grant_ref_pre(struct gnttab_map_grant_ref *uop) +{ + uint32_t flags; + + flags = uop->flags; + + if (flags & GNTMAP_host_map) { + if (flags & GNTMAP_application_map) { + printk(KERN_DEBUG + "GNTMAP_application_map is not supported yet: " + "flags 0x%x\n", flags); + BUG(); + } + if (flags & GNTMAP_contains_pte) { + printk(KERN_DEBUG + "GNTMAP_contains_pte is not supported yet: " + "flags 0x%x\n", flags); + BUG(); + } + } else if (flags & GNTMAP_device_map) { + printk("GNTMAP_device_map is not supported yet 0x%x\n", flags); + BUG(); /* not yet. actually this flag is not used. */ + } else { + BUG(); + } +} + +int +HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count) +{ + if (cmd == GNTTABOP_map_grant_ref) { + unsigned int i; + for (i = 0; i < count; i++) { + gnttab_map_grant_ref_pre( + (struct gnttab_map_grant_ref *)uop + i); + } + } + return xencomm_hypercall_grant_table_op(cmd, uop, count); +} + +EXPORT_SYMBOL(HYPERVISOR_grant_table_op); diff --git a/arch/ia64/xen/hypercall.S b/arch/ia64/xen/hypercall.S new file mode 100644 index 00000000000..d4ff0b9e79f --- /dev/null +++ b/arch/ia64/xen/hypercall.S @@ -0,0 +1,91 @@ +/* + * Support routines for Xen hypercalls + * + * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@hp.com> + * Copyright (C) 2008 Yaozu (Eddie) Dong <eddie.dong@intel.com> + */ + +#include <asm/asmmacro.h> +#include <asm/intrinsics.h> +#include <asm/xen/privop.h> + +/* + * Hypercalls without parameter. + */ +#define __HCALL0(name,hcall) \ + GLOBAL_ENTRY(name); \ + break hcall; \ + br.ret.sptk.many rp; \ + END(name) + +/* + * Hypercalls with 1 parameter. + */ +#define __HCALL1(name,hcall) \ + GLOBAL_ENTRY(name); \ + mov r8=r32; \ + break hcall; \ + br.ret.sptk.many rp; \ + END(name) + +/* + * Hypercalls with 2 parameters. + */ +#define __HCALL2(name,hcall) \ + GLOBAL_ENTRY(name); \ + mov r8=r32; \ + mov r9=r33; \ + break hcall; \ + br.ret.sptk.many rp; \ + END(name) + +__HCALL0(xen_get_psr, HYPERPRIVOP_GET_PSR) +__HCALL0(xen_get_ivr, HYPERPRIVOP_GET_IVR) +__HCALL0(xen_get_tpr, HYPERPRIVOP_GET_TPR) +__HCALL0(xen_hyper_ssm_i, HYPERPRIVOP_SSM_I) + +__HCALL1(xen_set_tpr, HYPERPRIVOP_SET_TPR) +__HCALL1(xen_eoi, HYPERPRIVOP_EOI) +__HCALL1(xen_thash, HYPERPRIVOP_THASH) +__HCALL1(xen_set_itm, HYPERPRIVOP_SET_ITM) +__HCALL1(xen_get_rr, HYPERPRIVOP_GET_RR) +__HCALL1(xen_fc, HYPERPRIVOP_FC) +__HCALL1(xen_get_cpuid, HYPERPRIVOP_GET_CPUID) +__HCALL1(xen_get_pmd, HYPERPRIVOP_GET_PMD) + +__HCALL2(xen_ptcga, HYPERPRIVOP_PTC_GA) +__HCALL2(xen_set_rr, HYPERPRIVOP_SET_RR) +__HCALL2(xen_set_kr, HYPERPRIVOP_SET_KR) + +#ifdef CONFIG_IA32_SUPPORT +__HCALL1(xen_get_eflag, HYPERPRIVOP_GET_EFLAG) +__HCALL1(xen_set_eflag, HYPERPRIVOP_SET_EFLAG) // refer SDM vol1 3.1.8 +#endif /* CONFIG_IA32_SUPPORT */ + +GLOBAL_ENTRY(xen_set_rr0_to_rr4) + mov r8=r32 + mov r9=r33 + mov r10=r34 + mov r11=r35 + mov r14=r36 + XEN_HYPER_SET_RR0_TO_RR4 + br.ret.sptk.many rp + ;; +END(xen_set_rr0_to_rr4) + +GLOBAL_ENTRY(xen_send_ipi) + mov r14=r32 + mov r15=r33 + mov r2=0x400 + break 0x1000 + ;; + br.ret.sptk.many rp + ;; +END(xen_send_ipi) + +GLOBAL_ENTRY(__hypercall) + mov r2=r37 + break 0x1000 + br.ret.sptk.many b0 + ;; +END(__hypercall) diff --git a/arch/ia64/xen/hypervisor.c b/arch/ia64/xen/hypervisor.c new file mode 100644 index 00000000000..cac4d97c0b5 --- /dev/null +++ b/arch/ia64/xen/hypervisor.c @@ -0,0 +1,96 @@ +/****************************************************************************** + * arch/ia64/xen/hypervisor.c + * + * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <linux/efi.h> +#include <asm/xen/hypervisor.h> +#include <asm/xen/privop.h> + +#include "irq_xen.h" + +struct shared_info *HYPERVISOR_shared_info __read_mostly = + (struct shared_info *)XSI_BASE; +EXPORT_SYMBOL(HYPERVISOR_shared_info); + +DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); + +struct start_info *xen_start_info; +EXPORT_SYMBOL(xen_start_info); + +EXPORT_SYMBOL(xen_domain_type); + +EXPORT_SYMBOL(__hypercall); + +/* Stolen from arch/x86/xen/enlighten.c */ +/* + * Flag to determine whether vcpu info placement is available on all + * VCPUs. We assume it is to start with, and then set it to zero on + * the first failure. This is because it can succeed on some VCPUs + * and not others, since it can involve hypervisor memory allocation, + * or because the guest failed to guarantee all the appropriate + * constraints on all VCPUs (ie buffer can't cross a page boundary). + * + * Note that any particular CPU may be using a placed vcpu structure, + * but we can only optimise if the all are. + * + * 0: not available, 1: available + */ + +static void __init xen_vcpu_setup(int cpu) +{ + /* + * WARNING: + * before changing MAX_VIRT_CPUS, + * check that shared_info fits on a page + */ + BUILD_BUG_ON(sizeof(struct shared_info) > PAGE_SIZE); + per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; +} + +void __init xen_setup_vcpu_info_placement(void) +{ + int cpu; + + for_each_possible_cpu(cpu) + xen_vcpu_setup(cpu); +} + +void __cpuinit +xen_cpu_init(void) +{ + xen_smp_intr_init(); +} + +/************************************************************************** + * opt feature + */ +void +xen_ia64_enable_opt_feature(void) +{ + /* Enable region 7 identity map optimizations in Xen */ + struct xen_ia64_opt_feature optf; + + optf.cmd = XEN_IA64_OPTF_IDENT_MAP_REG7; + optf.on = XEN_IA64_OPTF_ON; + optf.pgprot = pgprot_val(PAGE_KERNEL); + optf.key = 0; /* No key on linux. */ + HYPERVISOR_opt_feature(&optf); +} diff --git a/arch/ia64/xen/irq_xen.c b/arch/ia64/xen/irq_xen.c new file mode 100644 index 00000000000..af93aadb68b --- /dev/null +++ b/arch/ia64/xen/irq_xen.c @@ -0,0 +1,435 @@ +/****************************************************************************** + * arch/ia64/xen/irq_xen.c + * + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <linux/cpu.h> + +#include <xen/interface/xen.h> +#include <xen/interface/callback.h> +#include <xen/events.h> + +#include <asm/xen/privop.h> + +#include "irq_xen.h" + +/*************************************************************************** + * pv_irq_ops + * irq operations + */ + +static int +xen_assign_irq_vector(int irq) +{ + struct physdev_irq irq_op; + + irq_op.irq = irq; + if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op)) + return -ENOSPC; + + return irq_op.vector; +} + +static void +xen_free_irq_vector(int vector) +{ + struct physdev_irq irq_op; + + if (vector < IA64_FIRST_DEVICE_VECTOR || + vector > IA64_LAST_DEVICE_VECTOR) + return; + + irq_op.vector = vector; + if (HYPERVISOR_physdev_op(PHYSDEVOP_free_irq_vector, &irq_op)) + printk(KERN_WARNING "%s: xen_free_irq_vecotr fail vector=%d\n", + __func__, vector); +} + + +static DEFINE_PER_CPU(int, timer_irq) = -1; +static DEFINE_PER_CPU(int, ipi_irq) = -1; +static DEFINE_PER_CPU(int, resched_irq) = -1; +static DEFINE_PER_CPU(int, cmc_irq) = -1; +static DEFINE_PER_CPU(int, cmcp_irq) = -1; +static DEFINE_PER_CPU(int, cpep_irq) = -1; +#define NAME_SIZE 15 +static DEFINE_PER_CPU(char[NAME_SIZE], timer_name); +static DEFINE_PER_CPU(char[NAME_SIZE], ipi_name); +static DEFINE_PER_CPU(char[NAME_SIZE], resched_name); +static DEFINE_PER_CPU(char[NAME_SIZE], cmc_name); +static DEFINE_PER_CPU(char[NAME_SIZE], cmcp_name); +static DEFINE_PER_CPU(char[NAME_SIZE], cpep_name); +#undef NAME_SIZE + +struct saved_irq { + unsigned int irq; + struct irqaction *action; +}; +/* 16 should be far optimistic value, since only several percpu irqs + * are registered early. + */ +#define MAX_LATE_IRQ 16 +static struct saved_irq saved_percpu_irqs[MAX_LATE_IRQ]; +static unsigned short late_irq_cnt; +static unsigned short saved_irq_cnt; +static int xen_slab_ready; + +#ifdef CONFIG_SMP +/* Dummy stub. Though we may check XEN_RESCHEDULE_VECTOR before __do_IRQ, + * it ends up to issue several memory accesses upon percpu data and + * thus adds unnecessary traffic to other paths. + */ +static irqreturn_t +xen_dummy_handler(int irq, void *dev_id) +{ + + return IRQ_HANDLED; +} + +static struct irqaction xen_ipi_irqaction = { + .handler = handle_IPI, + .flags = IRQF_DISABLED, + .name = "IPI" +}; + +static struct irqaction xen_resched_irqaction = { + .handler = xen_dummy_handler, + .flags = IRQF_DISABLED, + .name = "resched" +}; + +static struct irqaction xen_tlb_irqaction = { + .handler = xen_dummy_handler, + .flags = IRQF_DISABLED, + .name = "tlb_flush" +}; +#endif + +/* + * This is xen version percpu irq registration, which needs bind + * to xen specific evtchn sub-system. One trick here is that xen + * evtchn binding interface depends on kmalloc because related + * port needs to be freed at device/cpu down. So we cache the + * registration on BSP before slab is ready and then deal them + * at later point. For rest instances happening after slab ready, + * we hook them to xen evtchn immediately. + * + * FIXME: MCA is not supported by far, and thus "nomca" boot param is + * required. + */ +static void +__xen_register_percpu_irq(unsigned int cpu, unsigned int vec, + struct irqaction *action, int save) +{ + irq_desc_t *desc; + int irq = 0; + + if (xen_slab_ready) { + switch (vec) { + case IA64_TIMER_VECTOR: + snprintf(per_cpu(timer_name, cpu), + sizeof(per_cpu(timer_name, cpu)), + "%s%d", action->name, cpu); + irq = bind_virq_to_irqhandler(VIRQ_ITC, cpu, + action->handler, action->flags, + per_cpu(timer_name, cpu), action->dev_id); + per_cpu(timer_irq, cpu) = irq; + break; + case IA64_IPI_RESCHEDULE: + snprintf(per_cpu(resched_name, cpu), + sizeof(per_cpu(resched_name, cpu)), + "%s%d", action->name, cpu); + irq = bind_ipi_to_irqhandler(XEN_RESCHEDULE_VECTOR, cpu, + action->handler, action->flags, + per_cpu(resched_name, cpu), action->dev_id); + per_cpu(resched_irq, cpu) = irq; + break; + case IA64_IPI_VECTOR: + snprintf(per_cpu(ipi_name, cpu), + sizeof(per_cpu(ipi_name, cpu)), + "%s%d", action->name, cpu); + irq = bind_ipi_to_irqhandler(XEN_IPI_VECTOR, cpu, + action->handler, action->flags, + per_cpu(ipi_name, cpu), action->dev_id); + per_cpu(ipi_irq, cpu) = irq; + break; + case IA64_CMC_VECTOR: + snprintf(per_cpu(cmc_name, cpu), + sizeof(per_cpu(cmc_name, cpu)), + "%s%d", action->name, cpu); + irq = bind_virq_to_irqhandler(VIRQ_MCA_CMC, cpu, + action->handler, + action->flags, + per_cpu(cmc_name, cpu), + action->dev_id); + per_cpu(cmc_irq, cpu) = irq; + break; + case IA64_CMCP_VECTOR: + snprintf(per_cpu(cmcp_name, cpu), + sizeof(per_cpu(cmcp_name, cpu)), + "%s%d", action->name, cpu); + irq = bind_ipi_to_irqhandler(XEN_CMCP_VECTOR, cpu, + action->handler, + action->flags, + per_cpu(cmcp_name, cpu), + action->dev_id); + per_cpu(cmcp_irq, cpu) = irq; + break; + case IA64_CPEP_VECTOR: + snprintf(per_cpu(cpep_name, cpu), + sizeof(per_cpu(cpep_name, cpu)), + "%s%d", action->name, cpu); + irq = bind_ipi_to_irqhandler(XEN_CPEP_VECTOR, cpu, + action->handler, + action->flags, + per_cpu(cpep_name, cpu), + action->dev_id); + per_cpu(cpep_irq, cpu) = irq; + break; + case IA64_CPE_VECTOR: + case IA64_MCA_RENDEZ_VECTOR: + case IA64_PERFMON_VECTOR: + case IA64_MCA_WAKEUP_VECTOR: + case IA64_SPURIOUS_INT_VECTOR: + /* No need to complain, these aren't supported. */ + break; + default: + printk(KERN_WARNING "Percpu irq %d is unsupported " + "by xen!\n", vec); + break; + } + BUG_ON(irq < 0); + + if (irq > 0) { + /* + * Mark percpu. Without this, migrate_irqs() will + * mark the interrupt for migrations and trigger it + * on cpu hotplug. + */ + desc = irq_desc + irq; + desc->status |= IRQ_PER_CPU; + } + } + + /* For BSP, we cache registered percpu irqs, and then re-walk + * them when initializing APs + */ + if (!cpu && save) { + BUG_ON(saved_irq_cnt == MAX_LATE_IRQ); + saved_percpu_irqs[saved_irq_cnt].irq = vec; + saved_percpu_irqs[saved_irq_cnt].action = action; + saved_irq_cnt++; + if (!xen_slab_ready) + late_irq_cnt++; + } +} + +static void +xen_register_percpu_irq(ia64_vector vec, struct irqaction *action) +{ + __xen_register_percpu_irq(smp_processor_id(), vec, action, 1); +} + +static void +xen_bind_early_percpu_irq(void) +{ + int i; + + xen_slab_ready = 1; + /* There's no race when accessing this cached array, since only + * BSP will face with such step shortly + */ + for (i = 0; i < late_irq_cnt; i++) + __xen_register_percpu_irq(smp_processor_id(), + saved_percpu_irqs[i].irq, + saved_percpu_irqs[i].action, 0); +} + +/* FIXME: There's no obvious point to check whether slab is ready. So + * a hack is used here by utilizing a late time hook. + */ + +#ifdef CONFIG_HOTPLUG_CPU +static int __devinit +unbind_evtchn_callback(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + + if (action == CPU_DEAD) { + /* Unregister evtchn. */ + if (per_cpu(cpep_irq, cpu) >= 0) { + unbind_from_irqhandler(per_cpu(cpep_irq, cpu), NULL); + per_cpu(cpep_irq, cpu) = -1; + } + if (per_cpu(cmcp_irq, cpu) >= 0) { + unbind_from_irqhandler(per_cpu(cmcp_irq, cpu), NULL); + per_cpu(cmcp_irq, cpu) = -1; + } + if (per_cpu(cmc_irq, cpu) >= 0) { + unbind_from_irqhandler(per_cpu(cmc_irq, cpu), NULL); + per_cpu(cmc_irq, cpu) = -1; + } + if (per_cpu(ipi_irq, cpu) >= 0) { + unbind_from_irqhandler(per_cpu(ipi_irq, cpu), NULL); + per_cpu(ipi_irq, cpu) = -1; + } + if (per_cpu(resched_irq, cpu) >= 0) { + unbind_from_irqhandler(per_cpu(resched_irq, cpu), + NULL); + per_cpu(resched_irq, cpu) = -1; + } + if (per_cpu(timer_irq, cpu) >= 0) { + unbind_from_irqhandler(per_cpu(timer_irq, cpu), NULL); + per_cpu(timer_irq, cpu) = -1; + } + } + return NOTIFY_OK; +} + +static struct notifier_block unbind_evtchn_notifier = { + .notifier_call = unbind_evtchn_callback, + .priority = 0 +}; +#endif + +void xen_smp_intr_init_early(unsigned int cpu) +{ +#ifdef CONFIG_SMP + unsigned int i; + + for (i = 0; i < saved_irq_cnt; i++) + __xen_register_percpu_irq(cpu, saved_percpu_irqs[i].irq, + saved_percpu_irqs[i].action, 0); +#endif +} + +void xen_smp_intr_init(void) +{ +#ifdef CONFIG_SMP + unsigned int cpu = smp_processor_id(); + struct callback_register event = { + .type = CALLBACKTYPE_event, + .address = { .ip = (unsigned long)&xen_event_callback }, + }; + + if (cpu == 0) { + /* Initialization was already done for boot cpu. */ +#ifdef CONFIG_HOTPLUG_CPU + /* Register the notifier only once. */ + register_cpu_notifier(&unbind_evtchn_notifier); +#endif + return; + } + + /* This should be piggyback when setup vcpu guest context */ + BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event)); +#endif /* CONFIG_SMP */ +} + +void __init +xen_irq_init(void) +{ + struct callback_register event = { + .type = CALLBACKTYPE_event, + .address = { .ip = (unsigned long)&xen_event_callback }, + }; + + xen_init_IRQ(); + BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event)); + late_time_init = xen_bind_early_percpu_irq; +} + +void +xen_platform_send_ipi(int cpu, int vector, int delivery_mode, int redirect) +{ +#ifdef CONFIG_SMP + /* TODO: we need to call vcpu_up here */ + if (unlikely(vector == ap_wakeup_vector)) { + /* XXX + * This should be in __cpu_up(cpu) in ia64 smpboot.c + * like x86. But don't want to modify it, + * keep it untouched. + */ + xen_smp_intr_init_early(cpu); + + xen_send_ipi(cpu, vector); + /* vcpu_prepare_and_up(cpu); */ + return; + } +#endif + + switch (vector) { + case IA64_IPI_VECTOR: + xen_send_IPI_one(cpu, XEN_IPI_VECTOR); + break; + case IA64_IPI_RESCHEDULE: + xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR); + break; + case IA64_CMCP_VECTOR: + xen_send_IPI_one(cpu, XEN_CMCP_VECTOR); + break; + case IA64_CPEP_VECTOR: + xen_send_IPI_one(cpu, XEN_CPEP_VECTOR); + break; + case IA64_TIMER_VECTOR: { + /* this is used only once by check_sal_cache_flush() + at boot time */ + static int used = 0; + if (!used) { + xen_send_ipi(cpu, IA64_TIMER_VECTOR); + used = 1; + break; + } + /* fallthrough */ + } + default: + printk(KERN_WARNING "Unsupported IPI type 0x%x\n", + vector); + notify_remote_via_irq(0); /* defaults to 0 irq */ + break; + } +} + +static void __init +xen_register_ipi(void) +{ +#ifdef CONFIG_SMP + register_percpu_irq(IA64_IPI_VECTOR, &xen_ipi_irqaction); + register_percpu_irq(IA64_IPI_RESCHEDULE, &xen_resched_irqaction); + register_percpu_irq(IA64_IPI_LOCAL_TLB_FLUSH, &xen_tlb_irqaction); +#endif +} + +static void +xen_resend_irq(unsigned int vector) +{ + (void)resend_irq_on_evtchn(vector); +} + +const struct pv_irq_ops xen_irq_ops __initdata = { + .register_ipi = xen_register_ipi, + + .assign_irq_vector = xen_assign_irq_vector, + .free_irq_vector = xen_free_irq_vector, + .register_percpu_irq = xen_register_percpu_irq, + + .resend_irq = xen_resend_irq, +}; diff --git a/arch/ia64/xen/irq_xen.h b/arch/ia64/xen/irq_xen.h new file mode 100644 index 00000000000..26110f330c8 --- /dev/null +++ b/arch/ia64/xen/irq_xen.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * arch/ia64/xen/irq_xen.h + * + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef IRQ_XEN_H +#define IRQ_XEN_H + +extern void (*late_time_init)(void); +extern char xen_event_callback; +void __init xen_init_IRQ(void); + +extern const struct pv_irq_ops xen_irq_ops __initdata; +extern void xen_smp_intr_init(void); +extern void xen_send_ipi(int cpu, int vec); + +#endif /* IRQ_XEN_H */ diff --git a/arch/ia64/xen/machvec.c b/arch/ia64/xen/machvec.c new file mode 100644 index 00000000000..4ad588a7c27 --- /dev/null +++ b/arch/ia64/xen/machvec.c @@ -0,0 +1,4 @@ +#define MACHVEC_PLATFORM_NAME xen +#define MACHVEC_PLATFORM_HEADER <asm/machvec_xen.h> +#include <asm/machvec_init.h> + diff --git a/arch/ia64/xen/suspend.c b/arch/ia64/xen/suspend.c new file mode 100644 index 00000000000..fd66b048c6f --- /dev/null +++ b/arch/ia64/xen/suspend.c @@ -0,0 +1,64 @@ +/****************************************************************************** + * arch/ia64/xen/suspend.c + * + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * suspend/resume + */ + +#include <xen/xen-ops.h> +#include <asm/xen/hypervisor.h> +#include "time.h" + +void +xen_mm_pin_all(void) +{ + /* nothing */ +} + +void +xen_mm_unpin_all(void) +{ + /* nothing */ +} + +void xen_pre_device_suspend(void) +{ + /* nothing */ +} + +void +xen_pre_suspend() +{ + /* nothing */ +} + +void +xen_post_suspend(int suspend_cancelled) +{ + if (suspend_cancelled) + return; + + xen_ia64_enable_opt_feature(); + /* add more if necessary */ +} + +void xen_arch_resume(void) +{ + xen_timer_resume_on_aps(); +} diff --git a/arch/ia64/xen/time.c b/arch/ia64/xen/time.c new file mode 100644 index 00000000000..d15a94c330f --- /dev/null +++ b/arch/ia64/xen/time.c @@ -0,0 +1,213 @@ +/****************************************************************************** + * arch/ia64/xen/time.c + * + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <linux/delay.h> +#include <linux/kernel_stat.h> +#include <linux/posix-timers.h> +#include <linux/irq.h> +#include <linux/clocksource.h> + +#include <asm/timex.h> + +#include <asm/xen/hypervisor.h> + +#include <xen/interface/vcpu.h> + +#include "../kernel/fsyscall_gtod_data.h" + +DEFINE_PER_CPU(struct vcpu_runstate_info, runstate); +DEFINE_PER_CPU(unsigned long, processed_stolen_time); +DEFINE_PER_CPU(unsigned long, processed_blocked_time); + +/* taken from i386/kernel/time-xen.c */ +static void xen_init_missing_ticks_accounting(int cpu) +{ + struct vcpu_register_runstate_memory_area area; + struct vcpu_runstate_info *runstate = &per_cpu(runstate, cpu); + int rc; + + memset(runstate, 0, sizeof(*runstate)); + + area.addr.v = runstate; + rc = HYPERVISOR_vcpu_op(VCPUOP_register_runstate_memory_area, cpu, + &area); + WARN_ON(rc && rc != -ENOSYS); + + per_cpu(processed_blocked_time, cpu) = runstate->time[RUNSTATE_blocked]; + per_cpu(processed_stolen_time, cpu) = runstate->time[RUNSTATE_runnable] + + runstate->time[RUNSTATE_offline]; +} + +/* + * Runstate accounting + */ +/* stolen from arch/x86/xen/time.c */ +static void get_runstate_snapshot(struct vcpu_runstate_info *res) +{ + u64 state_time; + struct vcpu_runstate_info *state; + + BUG_ON(preemptible()); + + state = &__get_cpu_var(runstate); + + /* + * The runstate info is always updated by the hypervisor on + * the current CPU, so there's no need to use anything + * stronger than a compiler barrier when fetching it. + */ + do { + state_time = state->state_entry_time; + rmb(); + *res = *state; + rmb(); + } while (state->state_entry_time != state_time); +} + +#define NS_PER_TICK (1000000000LL/HZ) + +static unsigned long +consider_steal_time(unsigned long new_itm) +{ + unsigned long stolen, blocked; + unsigned long delta_itm = 0, stolentick = 0; + int cpu = smp_processor_id(); + struct vcpu_runstate_info runstate; + struct task_struct *p = current; + + get_runstate_snapshot(&runstate); + + /* + * Check for vcpu migration effect + * In this case, itc value is reversed. + * This causes huge stolen value. + * This function just checks and reject this effect. + */ + if (!time_after_eq(runstate.time[RUNSTATE_blocked], + per_cpu(processed_blocked_time, cpu))) + blocked = 0; + + if (!time_after_eq(runstate.time[RUNSTATE_runnable] + + runstate.time[RUNSTATE_offline], + per_cpu(processed_stolen_time, cpu))) + stolen = 0; + + if (!time_after(delta_itm + new_itm, ia64_get_itc())) + stolentick = ia64_get_itc() - new_itm; + + do_div(stolentick, NS_PER_TICK); + stolentick++; + + do_div(stolen, NS_PER_TICK); + + if (stolen > stolentick) + stolen = stolentick; + + stolentick -= stolen; + do_div(blocked, NS_PER_TICK); + + if (blocked > stolentick) + blocked = stolentick; + + if (stolen > 0 || blocked > 0) { + account_steal_time(NULL, jiffies_to_cputime(stolen)); + account_steal_time(idle_task(cpu), jiffies_to_cputime(blocked)); + run_local_timers(); + + if (rcu_pending(cpu)) + rcu_check_callbacks(cpu, user_mode(get_irq_regs())); + + scheduler_tick(); + run_posix_cpu_timers(p); + delta_itm += local_cpu_data->itm_delta * (stolen + blocked); + + if (cpu == time_keeper_id) { + write_seqlock(&xtime_lock); + do_timer(stolen + blocked); + local_cpu_data->itm_next = delta_itm + new_itm; + write_sequnlock(&xtime_lock); + } else { + local_cpu_data->itm_next = delta_itm + new_itm; + } + per_cpu(processed_stolen_time, cpu) += NS_PER_TICK * stolen; + per_cpu(processed_blocked_time, cpu) += NS_PER_TICK * blocked; + } + return delta_itm; +} + +static int xen_do_steal_accounting(unsigned long *new_itm) +{ + unsigned long delta_itm; + delta_itm = consider_steal_time(*new_itm); + *new_itm += delta_itm; + if (time_after(*new_itm, ia64_get_itc()) && delta_itm) + return 1; + + return 0; +} + +static void xen_itc_jitter_data_reset(void) +{ + u64 lcycle, ret; + + do { + lcycle = itc_jitter_data.itc_lastcycle; + ret = cmpxchg(&itc_jitter_data.itc_lastcycle, lcycle, 0); + } while (unlikely(ret != lcycle)); +} + +struct pv_time_ops xen_time_ops __initdata = { + .init_missing_ticks_accounting = xen_init_missing_ticks_accounting, + .do_steal_accounting = xen_do_steal_accounting, + .clocksource_resume = xen_itc_jitter_data_reset, +}; + +/* Called after suspend, to resume time. */ +static void xen_local_tick_resume(void) +{ + /* Just trigger a tick. */ + ia64_cpu_local_tick(); + touch_softlockup_watchdog(); +} + +void +xen_timer_resume(void) +{ + unsigned int cpu; + + xen_local_tick_resume(); + + for_each_online_cpu(cpu) + xen_init_missing_ticks_accounting(cpu); +} + +static void ia64_cpu_local_tick_fn(void *unused) +{ + xen_local_tick_resume(); + xen_init_missing_ticks_accounting(smp_processor_id()); +} + +void +xen_timer_resume_on_aps(void) +{ + smp_call_function(&ia64_cpu_local_tick_fn, NULL, 1); +} diff --git a/arch/ia64/xen/time.h b/arch/ia64/xen/time.h new file mode 100644 index 00000000000..f98d7e1a42f --- /dev/null +++ b/arch/ia64/xen/time.h @@ -0,0 +1,24 @@ +/****************************************************************************** + * arch/ia64/xen/time.h + * + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +extern struct pv_time_ops xen_time_ops __initdata; +void xen_timer_resume_on_aps(void); diff --git a/arch/ia64/xen/xcom_hcall.c b/arch/ia64/xen/xcom_hcall.c new file mode 100644 index 00000000000..ccaf7431f7c --- /dev/null +++ b/arch/ia64/xen/xcom_hcall.c @@ -0,0 +1,441 @@ +/* + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Tristan Gingold <tristan.gingold@bull.net> + * + * Copyright (c) 2007 + * Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * consolidate mini and inline version. + */ + +#include <linux/module.h> +#include <xen/interface/xen.h> +#include <xen/interface/memory.h> +#include <xen/interface/grant_table.h> +#include <xen/interface/callback.h> +#include <xen/interface/vcpu.h> +#include <asm/xen/hypervisor.h> +#include <asm/xen/xencomm.h> + +/* Xencomm notes: + * This file defines hypercalls to be used by xencomm. The hypercalls simply + * create inlines or mini descriptors for pointers and then call the raw arch + * hypercall xencomm_arch_hypercall_XXX + * + * If the arch wants to directly use these hypercalls, simply define macros + * in asm/xen/hypercall.h, eg: + * #define HYPERVISOR_sched_op xencomm_hypercall_sched_op + * + * The arch may also define HYPERVISOR_xxx as a function and do more operations + * before/after doing the hypercall. + * + * Note: because only inline or mini descriptors are created these functions + * must only be called with in kernel memory parameters. + */ + +int +xencomm_hypercall_console_io(int cmd, int count, char *str) +{ + /* xen early printk uses console io hypercall before + * xencomm initialization. In that case, we just ignore it. + */ + if (!xencomm_is_initialized()) + return 0; + + return xencomm_arch_hypercall_console_io + (cmd, count, xencomm_map_no_alloc(str, count)); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_console_io); + +int +xencomm_hypercall_event_channel_op(int cmd, void *op) +{ + struct xencomm_handle *desc; + desc = xencomm_map_no_alloc(op, sizeof(struct evtchn_op)); + if (desc == NULL) + return -EINVAL; + + return xencomm_arch_hypercall_event_channel_op(cmd, desc); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_event_channel_op); + +int +xencomm_hypercall_xen_version(int cmd, void *arg) +{ + struct xencomm_handle *desc; + unsigned int argsize; + + switch (cmd) { + case XENVER_version: + /* do not actually pass an argument */ + return xencomm_arch_hypercall_xen_version(cmd, 0); + case XENVER_extraversion: + argsize = sizeof(struct xen_extraversion); + break; + case XENVER_compile_info: + argsize = sizeof(struct xen_compile_info); + break; + case XENVER_capabilities: + argsize = sizeof(struct xen_capabilities_info); + break; + case XENVER_changeset: + argsize = sizeof(struct xen_changeset_info); + break; + case XENVER_platform_parameters: + argsize = sizeof(struct xen_platform_parameters); + break; + case XENVER_get_features: + argsize = (arg == NULL) ? 0 : sizeof(struct xen_feature_info); + break; + + default: + printk(KERN_DEBUG + "%s: unknown version op %d\n", __func__, cmd); + return -ENOSYS; + } + + desc = xencomm_map_no_alloc(arg, argsize); + if (desc == NULL) + return -EINVAL; + + return xencomm_arch_hypercall_xen_version(cmd, desc); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_xen_version); + +int +xencomm_hypercall_physdev_op(int cmd, void *op) +{ + unsigned int argsize; + + switch (cmd) { + case PHYSDEVOP_apic_read: + case PHYSDEVOP_apic_write: + argsize = sizeof(struct physdev_apic); + break; + case PHYSDEVOP_alloc_irq_vector: + case PHYSDEVOP_free_irq_vector: + argsize = sizeof(struct physdev_irq); + break; + case PHYSDEVOP_irq_status_query: + argsize = sizeof(struct physdev_irq_status_query); + break; + + default: + printk(KERN_DEBUG + "%s: unknown physdev op %d\n", __func__, cmd); + return -ENOSYS; + } + + return xencomm_arch_hypercall_physdev_op + (cmd, xencomm_map_no_alloc(op, argsize)); +} + +static int +xencommize_grant_table_op(struct xencomm_mini **xc_area, + unsigned int cmd, void *op, unsigned int count, + struct xencomm_handle **desc) +{ + struct xencomm_handle *desc1; + unsigned int argsize; + + switch (cmd) { + case GNTTABOP_map_grant_ref: + argsize = sizeof(struct gnttab_map_grant_ref); + break; + case GNTTABOP_unmap_grant_ref: + argsize = sizeof(struct gnttab_unmap_grant_ref); + break; + case GNTTABOP_setup_table: + { + struct gnttab_setup_table *setup = op; + + argsize = sizeof(*setup); + + if (count != 1) + return -EINVAL; + desc1 = __xencomm_map_no_alloc + (xen_guest_handle(setup->frame_list), + setup->nr_frames * + sizeof(*xen_guest_handle(setup->frame_list)), + *xc_area); + if (desc1 == NULL) + return -EINVAL; + (*xc_area)++; + set_xen_guest_handle(setup->frame_list, (void *)desc1); + break; + } + case GNTTABOP_dump_table: + argsize = sizeof(struct gnttab_dump_table); + break; + case GNTTABOP_transfer: + argsize = sizeof(struct gnttab_transfer); + break; + case GNTTABOP_copy: + argsize = sizeof(struct gnttab_copy); + break; + case GNTTABOP_query_size: + argsize = sizeof(struct gnttab_query_size); + break; + default: + printk(KERN_DEBUG "%s: unknown hypercall grant table op %d\n", + __func__, cmd); + BUG(); + } + + *desc = __xencomm_map_no_alloc(op, count * argsize, *xc_area); + if (*desc == NULL) + return -EINVAL; + (*xc_area)++; + + return 0; +} + +int +xencomm_hypercall_grant_table_op(unsigned int cmd, void *op, + unsigned int count) +{ + int rc; + struct xencomm_handle *desc; + XENCOMM_MINI_ALIGNED(xc_area, 2); + + rc = xencommize_grant_table_op(&xc_area, cmd, op, count, &desc); + if (rc) + return rc; + + return xencomm_arch_hypercall_grant_table_op(cmd, desc, count); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_grant_table_op); + +int +xencomm_hypercall_sched_op(int cmd, void *arg) +{ + struct xencomm_handle *desc; + unsigned int argsize; + + switch (cmd) { + case SCHEDOP_yield: + case SCHEDOP_block: + argsize = 0; + break; + case SCHEDOP_shutdown: + argsize = sizeof(struct sched_shutdown); + break; + case SCHEDOP_poll: + { + struct sched_poll *poll = arg; + struct xencomm_handle *ports; + + argsize = sizeof(struct sched_poll); + ports = xencomm_map_no_alloc(xen_guest_handle(poll->ports), + sizeof(*xen_guest_handle(poll->ports))); + + set_xen_guest_handle(poll->ports, (void *)ports); + break; + } + default: + printk(KERN_DEBUG "%s: unknown sched op %d\n", __func__, cmd); + return -ENOSYS; + } + + desc = xencomm_map_no_alloc(arg, argsize); + if (desc == NULL) + return -EINVAL; + + return xencomm_arch_hypercall_sched_op(cmd, desc); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_sched_op); + +int +xencomm_hypercall_multicall(void *call_list, int nr_calls) +{ + int rc; + int i; + struct multicall_entry *mce; + struct xencomm_handle *desc; + XENCOMM_MINI_ALIGNED(xc_area, nr_calls * 2); + + for (i = 0; i < nr_calls; i++) { + mce = (struct multicall_entry *)call_list + i; + + switch (mce->op) { + case __HYPERVISOR_update_va_mapping: + case __HYPERVISOR_mmu_update: + /* No-op on ia64. */ + break; + case __HYPERVISOR_grant_table_op: + rc = xencommize_grant_table_op + (&xc_area, + mce->args[0], (void *)mce->args[1], + mce->args[2], &desc); + if (rc) + return rc; + mce->args[1] = (unsigned long)desc; + break; + case __HYPERVISOR_memory_op: + default: + printk(KERN_DEBUG + "%s: unhandled multicall op entry op %lu\n", + __func__, mce->op); + return -ENOSYS; + } + } + + desc = xencomm_map_no_alloc(call_list, + nr_calls * sizeof(struct multicall_entry)); + if (desc == NULL) + return -EINVAL; + + return xencomm_arch_hypercall_multicall(desc, nr_calls); +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_multicall); + +int +xencomm_hypercall_callback_op(int cmd, void *arg) +{ + unsigned int argsize; + switch (cmd) { + case CALLBACKOP_register: + argsize = sizeof(struct callback_register); + break; + case CALLBACKOP_unregister: + argsize = sizeof(struct callback_unregister); + break; + default: + printk(KERN_DEBUG + "%s: unknown callback op %d\n", __func__, cmd); + return -ENOSYS; + } + + return xencomm_arch_hypercall_callback_op + (cmd, xencomm_map_no_alloc(arg, argsize)); +} + +static int +xencommize_memory_reservation(struct xencomm_mini *xc_area, + struct xen_memory_reservation *mop) +{ + struct xencomm_handle *desc; + + desc = __xencomm_map_no_alloc(xen_guest_handle(mop->extent_start), + mop->nr_extents * + sizeof(*xen_guest_handle(mop->extent_start)), + xc_area); + if (desc == NULL) + return -EINVAL; + + set_xen_guest_handle(mop->extent_start, (void *)desc); + return 0; +} + +int +xencomm_hypercall_memory_op(unsigned int cmd, void *arg) +{ + GUEST_HANDLE(xen_pfn_t) extent_start_va[2] = { {NULL}, {NULL} }; + struct xen_memory_reservation *xmr = NULL; + int rc; + struct xencomm_handle *desc; + unsigned int argsize; + XENCOMM_MINI_ALIGNED(xc_area, 2); + + switch (cmd) { + case XENMEM_increase_reservation: + case XENMEM_decrease_reservation: + case XENMEM_populate_physmap: + xmr = (struct xen_memory_reservation *)arg; + set_xen_guest_handle(extent_start_va[0], + xen_guest_handle(xmr->extent_start)); + + argsize = sizeof(*xmr); + rc = xencommize_memory_reservation(xc_area, xmr); + if (rc) + return rc; + xc_area++; + break; + + case XENMEM_maximum_ram_page: + argsize = 0; + break; + + case XENMEM_add_to_physmap: + argsize = sizeof(struct xen_add_to_physmap); + break; + + default: + printk(KERN_DEBUG "%s: unknown memory op %d\n", __func__, cmd); + return -ENOSYS; + } + + desc = xencomm_map_no_alloc(arg, argsize); + if (desc == NULL) + return -EINVAL; + + rc = xencomm_arch_hypercall_memory_op(cmd, desc); + + switch (cmd) { + case XENMEM_increase_reservation: + case XENMEM_decrease_reservation: + case XENMEM_populate_physmap: + set_xen_guest_handle(xmr->extent_start, + xen_guest_handle(extent_start_va[0])); + break; + } + + return rc; +} +EXPORT_SYMBOL_GPL(xencomm_hypercall_memory_op); + +int +xencomm_hypercall_suspend(unsigned long srec) +{ + struct sched_shutdown arg; + + arg.reason = SHUTDOWN_suspend; + + return xencomm_arch_hypercall_sched_op( + SCHEDOP_shutdown, xencomm_map_no_alloc(&arg, sizeof(arg))); +} + +long +xencomm_hypercall_vcpu_op(int cmd, int cpu, void *arg) +{ + unsigned int argsize; + switch (cmd) { + case VCPUOP_register_runstate_memory_area: { + struct vcpu_register_runstate_memory_area *area = + (struct vcpu_register_runstate_memory_area *)arg; + argsize = sizeof(*arg); + set_xen_guest_handle(area->addr.h, + (void *)xencomm_map_no_alloc(area->addr.v, + sizeof(area->addr.v))); + break; + } + + default: + printk(KERN_DEBUG "%s: unknown vcpu op %d\n", __func__, cmd); + return -ENOSYS; + } + + return xencomm_arch_hypercall_vcpu_op(cmd, cpu, + xencomm_map_no_alloc(arg, argsize)); +} + +long +xencomm_hypercall_opt_feature(void *arg) +{ + return xencomm_arch_hypercall_opt_feature( + xencomm_map_no_alloc(arg, + sizeof(struct xen_ia64_opt_feature))); +} diff --git a/arch/ia64/xen/xen_pv_ops.c b/arch/ia64/xen/xen_pv_ops.c new file mode 100644 index 00000000000..04cd1235045 --- /dev/null +++ b/arch/ia64/xen/xen_pv_ops.c @@ -0,0 +1,364 @@ +/****************************************************************************** + * arch/ia64/xen/xen_pv_ops.c + * + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <linux/console.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/pm.h> + +#include <asm/xen/hypervisor.h> +#include <asm/xen/xencomm.h> +#include <asm/xen/privop.h> + +#include "irq_xen.h" +#include "time.h" + +/*************************************************************************** + * general info + */ +static struct pv_info xen_info __initdata = { + .kernel_rpl = 2, /* or 1: determin at runtime */ + .paravirt_enabled = 1, + .name = "Xen/ia64", +}; + +#define IA64_RSC_PL_SHIFT 2 +#define IA64_RSC_PL_BIT_SIZE 2 +#define IA64_RSC_PL_MASK \ + (((1UL << IA64_RSC_PL_BIT_SIZE) - 1) << IA64_RSC_PL_SHIFT) + +static void __init +xen_info_init(void) +{ + /* Xenified Linux/ia64 may run on pl = 1 or 2. + * determin at run time. */ + unsigned long rsc = ia64_getreg(_IA64_REG_AR_RSC); + unsigned int rpl = (rsc & IA64_RSC_PL_MASK) >> IA64_RSC_PL_SHIFT; + xen_info.kernel_rpl = rpl; +} + +/*************************************************************************** + * pv_init_ops + * initialization hooks. + */ + +static void +xen_panic_hypercall(struct unw_frame_info *info, void *arg) +{ + current->thread.ksp = (__u64)info->sw - 16; + HYPERVISOR_shutdown(SHUTDOWN_crash); + /* we're never actually going to get here... */ +} + +static int +xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr) +{ + unw_init_running(xen_panic_hypercall, NULL); + /* we're never actually going to get here... */ + return NOTIFY_DONE; +} + +static struct notifier_block xen_panic_block = { + xen_panic_event, NULL, 0 /* try to go last */ +}; + +static void xen_pm_power_off(void) +{ + local_irq_disable(); + HYPERVISOR_shutdown(SHUTDOWN_poweroff); +} + +static void __init +xen_banner(void) +{ + printk(KERN_INFO + "Running on Xen! pl = %d start_info_pfn=0x%lx nr_pages=%ld " + "flags=0x%x\n", + xen_info.kernel_rpl, + HYPERVISOR_shared_info->arch.start_info_pfn, + xen_start_info->nr_pages, xen_start_info->flags); +} + +static int __init +xen_reserve_memory(struct rsvd_region *region) +{ + region->start = (unsigned long)__va( + (HYPERVISOR_shared_info->arch.start_info_pfn << PAGE_SHIFT)); + region->end = region->start + PAGE_SIZE; + return 1; +} + +static void __init +xen_arch_setup_early(void) +{ + struct shared_info *s; + BUG_ON(!xen_pv_domain()); + + s = HYPERVISOR_shared_info; + xen_start_info = __va(s->arch.start_info_pfn << PAGE_SHIFT); + + /* Must be done before any hypercall. */ + xencomm_initialize(); + + xen_setup_features(); + /* Register a call for panic conditions. */ + atomic_notifier_chain_register(&panic_notifier_list, + &xen_panic_block); + pm_power_off = xen_pm_power_off; + + xen_ia64_enable_opt_feature(); +} + +static void __init +xen_arch_setup_console(char **cmdline_p) +{ + add_preferred_console("xenboot", 0, NULL); + add_preferred_console("tty", 0, NULL); + /* use hvc_xen */ + add_preferred_console("hvc", 0, NULL); + +#if !defined(CONFIG_VT) || !defined(CONFIG_DUMMY_CONSOLE) + conswitchp = NULL; +#endif +} + +static int __init +xen_arch_setup_nomca(void) +{ + return 1; +} + +static void __init +xen_post_smp_prepare_boot_cpu(void) +{ + xen_setup_vcpu_info_placement(); +} + +static const struct pv_init_ops xen_init_ops __initdata = { + .banner = xen_banner, + + .reserve_memory = xen_reserve_memory, + + .arch_setup_early = xen_arch_setup_early, + .arch_setup_console = xen_arch_setup_console, + .arch_setup_nomca = xen_arch_setup_nomca, + + .post_smp_prepare_boot_cpu = xen_post_smp_prepare_boot_cpu, +}; + +/*************************************************************************** + * pv_cpu_ops + * intrinsics hooks. + */ + +static void xen_setreg(int regnum, unsigned long val) +{ + switch (regnum) { + case _IA64_REG_AR_KR0 ... _IA64_REG_AR_KR7: + xen_set_kr(regnum - _IA64_REG_AR_KR0, val); + break; +#ifdef CONFIG_IA32_SUPPORT + case _IA64_REG_AR_EFLAG: + xen_set_eflag(val); + break; +#endif + case _IA64_REG_CR_TPR: + xen_set_tpr(val); + break; + case _IA64_REG_CR_ITM: + xen_set_itm(val); + break; + case _IA64_REG_CR_EOI: + xen_eoi(val); + break; + default: + ia64_native_setreg_func(regnum, val); + break; + } +} + +static unsigned long xen_getreg(int regnum) +{ + unsigned long res; + + switch (regnum) { + case _IA64_REG_PSR: + res = xen_get_psr(); + break; +#ifdef CONFIG_IA32_SUPPORT + case _IA64_REG_AR_EFLAG: + res = xen_get_eflag(); + break; +#endif + case _IA64_REG_CR_IVR: + res = xen_get_ivr(); + break; + case _IA64_REG_CR_TPR: + res = xen_get_tpr(); + break; + default: + res = ia64_native_getreg_func(regnum); + break; + } + return res; +} + +/* turning on interrupts is a bit more complicated.. write to the + * memory-mapped virtual psr.i bit first (to avoid race condition), + * then if any interrupts were pending, we have to execute a hyperprivop + * to ensure the pending interrupt gets delivered; else we're done! */ +static void +xen_ssm_i(void) +{ + int old = xen_get_virtual_psr_i(); + xen_set_virtual_psr_i(1); + barrier(); + if (!old && xen_get_virtual_pend()) + xen_hyper_ssm_i(); +} + +/* turning off interrupts can be paravirtualized simply by writing + * to a memory-mapped virtual psr.i bit (implemented as a 16-bit bool) */ +static void +xen_rsm_i(void) +{ + xen_set_virtual_psr_i(0); + barrier(); +} + +static unsigned long +xen_get_psr_i(void) +{ + return xen_get_virtual_psr_i() ? IA64_PSR_I : 0; +} + +static void +xen_intrin_local_irq_restore(unsigned long mask) +{ + if (mask & IA64_PSR_I) + xen_ssm_i(); + else + xen_rsm_i(); +} + +static const struct pv_cpu_ops xen_cpu_ops __initdata = { + .fc = xen_fc, + .thash = xen_thash, + .get_cpuid = xen_get_cpuid, + .get_pmd = xen_get_pmd, + .getreg = xen_getreg, + .setreg = xen_setreg, + .ptcga = xen_ptcga, + .get_rr = xen_get_rr, + .set_rr = xen_set_rr, + .set_rr0_to_rr4 = xen_set_rr0_to_rr4, + .ssm_i = xen_ssm_i, + .rsm_i = xen_rsm_i, + .get_psr_i = xen_get_psr_i, + .intrin_local_irq_restore + = xen_intrin_local_irq_restore, +}; + +/****************************************************************************** + * replacement of hand written assembly codes. + */ + +extern char xen_switch_to; +extern char xen_leave_syscall; +extern char xen_work_processed_syscall; +extern char xen_leave_kernel; + +const struct pv_cpu_asm_switch xen_cpu_asm_switch = { + .switch_to = (unsigned long)&xen_switch_to, + .leave_syscall = (unsigned long)&xen_leave_syscall, + .work_processed_syscall = (unsigned long)&xen_work_processed_syscall, + .leave_kernel = (unsigned long)&xen_leave_kernel, +}; + +/*************************************************************************** + * pv_iosapic_ops + * iosapic read/write hooks. + */ +static void +xen_pcat_compat_init(void) +{ + /* nothing */ +} + +static struct irq_chip* +xen_iosapic_get_irq_chip(unsigned long trigger) +{ + return NULL; +} + +static unsigned int +xen_iosapic_read(char __iomem *iosapic, unsigned int reg) +{ + struct physdev_apic apic_op; + int ret; + + apic_op.apic_physbase = (unsigned long)iosapic - + __IA64_UNCACHED_OFFSET; + apic_op.reg = reg; + ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op); + if (ret) + return ret; + return apic_op.value; +} + +static void +xen_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val) +{ + struct physdev_apic apic_op; + + apic_op.apic_physbase = (unsigned long)iosapic - + __IA64_UNCACHED_OFFSET; + apic_op.reg = reg; + apic_op.value = val; + HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op); +} + +static const struct pv_iosapic_ops xen_iosapic_ops __initdata = { + .pcat_compat_init = xen_pcat_compat_init, + .__get_irq_chip = xen_iosapic_get_irq_chip, + + .__read = xen_iosapic_read, + .__write = xen_iosapic_write, +}; + +/*************************************************************************** + * pv_ops initialization + */ + +void __init +xen_setup_pv_ops(void) +{ + xen_info_init(); + pv_info = xen_info; + pv_init_ops = xen_init_ops; + pv_cpu_ops = xen_cpu_ops; + pv_iosapic_ops = xen_iosapic_ops; + pv_irq_ops = xen_irq_ops; + pv_time_ops = xen_time_ops; + + paravirt_cpu_asm_init(&xen_cpu_asm_switch); +} diff --git a/arch/ia64/xen/xencomm.c b/arch/ia64/xen/xencomm.c new file mode 100644 index 00000000000..1f5d7ac82e9 --- /dev/null +++ b/arch/ia64/xen/xencomm.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2006 Hollis Blanchard <hollisb@us.ibm.com>, IBM Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/mm.h> + +static unsigned long kernel_virtual_offset; +static int is_xencomm_initialized; + +/* for xen early printk. It uses console io hypercall which uses xencomm. + * However early printk may use it before xencomm initialization. + */ +int +xencomm_is_initialized(void) +{ + return is_xencomm_initialized; +} + +void +xencomm_initialize(void) +{ + kernel_virtual_offset = KERNEL_START - ia64_tpa(KERNEL_START); + is_xencomm_initialized = 1; +} + +/* Translate virtual address to physical address. */ +unsigned long +xencomm_vtop(unsigned long vaddr) +{ + struct page *page; + struct vm_area_struct *vma; + + if (vaddr == 0) + return 0UL; + + if (REGION_NUMBER(vaddr) == 5) { + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *ptep; + + /* On ia64, TASK_SIZE refers to current. It is not initialized + during boot. + Furthermore the kernel is relocatable and __pa() doesn't + work on addresses. */ + if (vaddr >= KERNEL_START + && vaddr < (KERNEL_START + KERNEL_TR_PAGE_SIZE)) + return vaddr - kernel_virtual_offset; + + /* In kernel area -- virtually mapped. */ + pgd = pgd_offset_k(vaddr); + if (pgd_none(*pgd) || pgd_bad(*pgd)) + return ~0UL; + + pud = pud_offset(pgd, vaddr); + if (pud_none(*pud) || pud_bad(*pud)) + return ~0UL; + + pmd = pmd_offset(pud, vaddr); + if (pmd_none(*pmd) || pmd_bad(*pmd)) + return ~0UL; + + ptep = pte_offset_kernel(pmd, vaddr); + if (!ptep) + return ~0UL; + + return (pte_val(*ptep) & _PFN_MASK) | (vaddr & ~PAGE_MASK); + } + + if (vaddr > TASK_SIZE) { + /* percpu variables */ + if (REGION_NUMBER(vaddr) == 7 && + REGION_OFFSET(vaddr) >= (1ULL << IA64_MAX_PHYS_BITS)) + ia64_tpa(vaddr); + + /* kernel address */ + return __pa(vaddr); + } + + /* XXX double-check (lack of) locking */ + vma = find_extend_vma(current->mm, vaddr); + if (!vma) + return ~0UL; + + /* We assume the page is modified. */ + page = follow_page(vma, vaddr, FOLL_WRITE | FOLL_TOUCH); + if (!page) + return ~0UL; + + return (page_to_pfn(page) << PAGE_SHIFT) | (vaddr & ~PAGE_MASK); +} diff --git a/arch/ia64/xen/xenivt.S b/arch/ia64/xen/xenivt.S new file mode 100644 index 00000000000..3e71d50584d --- /dev/null +++ b/arch/ia64/xen/xenivt.S @@ -0,0 +1,52 @@ +/* + * arch/ia64/xen/ivt.S + * + * Copyright (C) 2005 Hewlett-Packard Co + * Dan Magenheimer <dan.magenheimer@hp.com> + * + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * pv_ops. + */ + +#include <asm/asmmacro.h> +#include <asm/kregs.h> +#include <asm/pgtable.h> + +#include "../kernel/minstate.h" + + .section .text,"ax" +GLOBAL_ENTRY(xen_event_callback) + mov r31=pr // prepare to save predicates + ;; + SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3 + ;; + movl r3=XSI_PSR_IC + mov r14=1 + ;; + st4 [r3]=r14 + ;; + adds r3=8,r2 // set up second base pointer for SAVE_REST + srlz.i // ensure everybody knows psr.ic is back on + ;; + SAVE_REST + ;; +1: + alloc r14=ar.pfs,0,0,1,0 // must be first in an insn group + add out0=16,sp // pass pointer to pt_regs as first arg + ;; + br.call.sptk.many b0=xen_evtchn_do_upcall + ;; + movl r20=XSI_PSR_I_ADDR + ;; + ld8 r20=[r20] + ;; + adds r20=-1,r20 // vcpu_info->evtchn_upcall_pending + ;; + ld1 r20=[r20] + ;; + cmp.ne p6,p0=r20,r0 // if there are pending events, + (p6) br.spnt.few 1b // call evtchn_do_upcall again. + br.sptk.many xen_leave_kernel // we know ia64_leave_kernel is + // paravirtualized as xen_leave_kernel +END(xen_event_callback) diff --git a/arch/ia64/xen/xensetup.S b/arch/ia64/xen/xensetup.S new file mode 100644 index 00000000000..28fed1fcc07 --- /dev/null +++ b/arch/ia64/xen/xensetup.S @@ -0,0 +1,83 @@ +/* + * Support routines for Xen + * + * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@hp.com> + */ + +#include <asm/processor.h> +#include <asm/asmmacro.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/paravirt.h> +#include <asm/xen/privop.h> +#include <linux/elfnote.h> +#include <linux/init.h> +#include <xen/interface/elfnote.h> + + .section .data.read_mostly + .align 8 + .global xen_domain_type +xen_domain_type: + data4 XEN_NATIVE_ASM + .previous + + __INIT +ENTRY(startup_xen) + // Calculate load offset. + // The constant, LOAD_OFFSET, can't be used because the boot + // loader doesn't always load to the LMA specified by the vmlinux.lds. + mov r9=ip // must be the first instruction to make sure + // that r9 = the physical address of startup_xen. + // Usually r9 = startup_xen - LOAD_OFFSET + movl r8=startup_xen + ;; + sub r9=r9,r8 // Usually r9 = -LOAD_OFFSET. + + mov r10=PARAVIRT_HYPERVISOR_TYPE_XEN + movl r11=_start + ;; + add r11=r11,r9 + movl r8=hypervisor_type + ;; + add r8=r8,r9 + mov b0=r11 + ;; + st8 [r8]=r10 + br.cond.sptk.many b0 + ;; +END(startup_xen) + + ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux") + ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6") + ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0") + ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, data8.ua startup_xen - LOAD_OFFSET) + +#define isBP p3 // are we the Bootstrap Processor? + + .text + +GLOBAL_ENTRY(xen_setup_hook) + mov r8=XEN_PV_DOMAIN_ASM +(isBP) movl r9=xen_domain_type;; +(isBP) st4 [r9]=r8 + movl r10=xen_ivt;; + + mov cr.iva=r10 + + /* Set xsi base. */ +#define FW_HYPERCALL_SET_SHARED_INFO_VA 0x600 +(isBP) mov r2=FW_HYPERCALL_SET_SHARED_INFO_VA +(isBP) movl r28=XSI_BASE;; +(isBP) break 0x1000;; + + /* setup pv_ops */ +(isBP) mov r4=rp + ;; +(isBP) br.call.sptk.many rp=xen_setup_pv_ops + ;; +(isBP) mov rp=r4 + ;; + + br.ret.sptk.many rp + ;; +END(xen_setup_hook) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 9391199d9e7..5b1527883fc 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -19,9 +19,6 @@ config WORD_SIZE default 64 if PPC64 default 32 if !PPC64 -config PPC_MERGE - def_bool y - config ARCH_PHYS_ADDR_T_64BIT def_bool PPC64 || PHYS_64BIT @@ -326,13 +323,11 @@ config KEXEC config CRASH_DUMP bool "Build a kdump crash kernel" - depends on PPC_MULTIPLATFORM && PPC64 + depends on PPC_MULTIPLATFORM && PPC64 && RELOCATABLE help Build a kernel suitable for use as a kdump capture kernel. - The kernel will be linked at a different address than normal, and - so can only be used for Kdump. - - Don't change this unless you know what you are doing. + The same kernel binary can be used as production kernel and dump + capture kernel. config PHYP_DUMP bool "Hypervisor-assisted dump (EXPERIMENTAL)" @@ -832,11 +827,9 @@ config PAGE_OFFSET default "0xc000000000000000" config KERNEL_START hex - default "0xc000000002000000" if CRASH_DUMP default "0xc000000000000000" config PHYSICAL_START hex - default "0x02000000" if CRASH_DUMP default "0x00000000" endif diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index aac1406ccba..8fc6d72849a 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -68,7 +68,8 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c fixed-head.S ep88xc.c ep405.c cuboot-c2k.c \ cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \ cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \ - virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c + virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \ + cuboot-acadia.c src-boot := $(src-wlib) $(src-plat) empty.c src-boot := $(addprefix $(obj)/, $(src-boot)) @@ -211,6 +212,7 @@ image-$(CONFIG_DEFAULT_UIMAGE) += uImage # Board ports in arch/powerpc/platform/40x/Kconfig image-$(CONFIG_EP405) += dtbImage.ep405 image-$(CONFIG_WALNUT) += treeImage.walnut +image-$(CONFIG_ACADIA) += cuImage.acadia # Board ports in arch/powerpc/platform/44x/Kconfig image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony @@ -319,6 +321,9 @@ $(obj)/zImage.iseries: vmlinux $(obj)/uImage: vmlinux $(wrapperbits) $(call if_changed,wrap,uboot) +$(obj)/cuImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) + $(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) + $(obj)/cuImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) $(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb) diff --git a/arch/powerpc/boot/addnote.c b/arch/powerpc/boot/addnote.c index dcc9ab2ca82..3091d1d21ae 100644 --- a/arch/powerpc/boot/addnote.c +++ b/arch/powerpc/boot/addnote.c @@ -11,7 +11,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * Usage: addnote zImage [note.elf] + * Usage: addnote [-r realbase] zImage [note.elf] * * If note.elf is supplied, it is the name of an ELF file that contains * an RPA note to use instead of the built-in one. Alternatively, the @@ -153,18 +153,31 @@ unsigned char *read_rpanote(const char *fname, int *nnp) int main(int ac, char **av) { - int fd, n, i; + int fd, n, i, ai; int ph, ps, np; int nnote, nnote2, ns; unsigned char *rpap; - - if (ac != 2 && ac != 3) { - fprintf(stderr, "Usage: %s elf-file [rpanote.elf]\n", av[0]); + char *p, *endp; + + ai = 1; + if (ac >= ai + 2 && strcmp(av[ai], "-r") == 0) { + /* process -r realbase */ + p = av[ai + 1]; + descr[1] = strtol(p, &endp, 16); + if (endp == p || *endp != 0) { + fprintf(stderr, "Can't parse -r argument '%s' as hex\n", + p); + exit(1); + } + ai += 2; + } + if (ac != ai + 1 && ac != ai + 2) { + fprintf(stderr, "Usage: %s [-r realbase] elf-file [rpanote.elf]\n", av[0]); exit(1); } - fd = open(av[1], O_RDWR); + fd = open(av[ai], O_RDWR); if (fd < 0) { - perror(av[1]); + perror(av[ai]); exit(1); } @@ -184,12 +197,12 @@ main(int ac, char **av) if (buf[E_IDENT+EI_CLASS] != ELFCLASS32 || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) { fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", - av[1]); + av[ai]); exit(1); } - if (ac == 3) - rpap = read_rpanote(av[2], &nnote2); + if (ac == ai + 2) + rpap = read_rpanote(av[ai + 1], &nnote2); ph = GET_32BE(buf, E_PHOFF); ps = GET_16BE(buf, E_PHENTSIZE); @@ -202,7 +215,7 @@ main(int ac, char **av) for (i = 0; i < np; ++i) { if (GET_32BE(buf, ph + PH_TYPE) == PT_NOTE) { fprintf(stderr, "%s already has a note entry\n", - av[1]); + av[ai]); exit(0); } ph += ps; @@ -260,18 +273,18 @@ main(int ac, char **av) exit(1); } if (i < n) { - fprintf(stderr, "%s: write truncated\n", av[1]); + fprintf(stderr, "%s: write truncated\n", av[ai]); exit(1); } exit(0); notelf: - fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]); + fprintf(stderr, "%s does not appear to be an ELF file\n", av[ai]); exit(1); nospace: fprintf(stderr, "sorry, I can't find space in %s to put the note\n", - av[1]); + av[ai]); exit(1); } diff --git a/arch/powerpc/boot/cuboot-52xx.c b/arch/powerpc/boot/cuboot-52xx.c index a8611546a65..4c42ec8687b 100644 --- a/arch/powerpc/boot/cuboot-52xx.c +++ b/arch/powerpc/boot/cuboot-52xx.c @@ -37,6 +37,10 @@ static void platform_fixups(void) * this can do a simple path lookup. */ soc = find_node_by_devtype(NULL, "soc"); + if (!soc) + soc = find_node_by_compatible(NULL, "fsl,mpc5200-immr"); + if (!soc) + soc = find_node_by_compatible(NULL, "fsl,mpc5200b-immr"); if (soc) { setprop(soc, "bus-frequency", &bd.bi_ipbfreq, sizeof(bd.bi_ipbfreq)); diff --git a/arch/powerpc/boot/cuboot-acadia.c b/arch/powerpc/boot/cuboot-acadia.c new file mode 100644 index 00000000000..0634aba6348 --- /dev/null +++ b/arch/powerpc/boot/cuboot-acadia.c @@ -0,0 +1,174 @@ +/* + * Old U-boot compatibility for Acadia + * + * Author: Josh Boyer <jwboyer@linux.vnet.ibm.com> + * + * Copyright 2008 IBM Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include "ops.h" +#include "io.h" +#include "dcr.h" +#include "stdio.h" +#include "4xx.h" +#include "44x.h" +#include "cuboot.h" + +#define TARGET_4xx +#include "ppcboot.h" + +static bd_t bd; + +#define CPR_PERD0_SPIDV_MASK 0x000F0000 /* SPI Clock Divider */ + +#define PLLC_SRC_MASK 0x20000000 /* PLL feedback source */ + +#define PLLD_FBDV_MASK 0x1F000000 /* PLL feedback divider value */ +#define PLLD_FWDVA_MASK 0x000F0000 /* PLL forward divider A value */ +#define PLLD_FWDVB_MASK 0x00000700 /* PLL forward divider B value */ + +#define PRIMAD_CPUDV_MASK 0x0F000000 /* CPU Clock Divisor Mask */ +#define PRIMAD_PLBDV_MASK 0x000F0000 /* PLB Clock Divisor Mask */ +#define PRIMAD_OPBDV_MASK 0x00000F00 /* OPB Clock Divisor Mask */ +#define PRIMAD_EBCDV_MASK 0x0000000F /* EBC Clock Divisor Mask */ + +#define PERD0_PWMDV_MASK 0xFF000000 /* PWM Divider Mask */ +#define PERD0_SPIDV_MASK 0x000F0000 /* SPI Divider Mask */ +#define PERD0_U0DV_MASK 0x0000FF00 /* UART 0 Divider Mask */ +#define PERD0_U1DV_MASK 0x000000FF /* UART 1 Divider Mask */ + +static void get_clocks(void) +{ + unsigned long sysclk, cpr_plld, cpr_pllc, cpr_primad, plloutb, i; + unsigned long pllFwdDiv, pllFwdDivB, pllFbkDiv, pllPlbDiv, pllExtBusDiv; + unsigned long pllOpbDiv, freqEBC, freqUART, freqOPB; + unsigned long div; /* total divisor udiv * bdiv */ + unsigned long umin; /* minimum udiv */ + unsigned short diff; /* smallest diff */ + unsigned long udiv; /* best udiv */ + unsigned short idiff; /* current diff */ + unsigned short ibdiv; /* current bdiv */ + unsigned long est; /* current estimate */ + unsigned long baud; + void *np; + + /* read the sysclk value from the CPLD */ + sysclk = (in_8((unsigned char *)0x80000000) == 0xc) ? 66666666 : 33333000; + + /* + * Read PLL Mode registers + */ + cpr_plld = CPR0_READ(DCRN_CPR0_PLLD); + cpr_pllc = CPR0_READ(DCRN_CPR0_PLLC); + + /* + * Determine forward divider A + */ + pllFwdDiv = ((cpr_plld & PLLD_FWDVA_MASK) >> 16); + + /* + * Determine forward divider B + */ + pllFwdDivB = ((cpr_plld & PLLD_FWDVB_MASK) >> 8); + if (pllFwdDivB == 0) + pllFwdDivB = 8; + + /* + * Determine FBK_DIV. + */ + pllFbkDiv = ((cpr_plld & PLLD_FBDV_MASK) >> 24); + if (pllFbkDiv == 0) + pllFbkDiv = 256; + + /* + * Read CPR_PRIMAD register + */ + cpr_primad = CPR0_READ(DCRN_CPR0_PRIMAD); + + /* + * Determine PLB_DIV. + */ + pllPlbDiv = ((cpr_primad & PRIMAD_PLBDV_MASK) >> 16); + if (pllPlbDiv == 0) + pllPlbDiv = 16; + + /* + * Determine EXTBUS_DIV. + */ + pllExtBusDiv = (cpr_primad & PRIMAD_EBCDV_MASK); + if (pllExtBusDiv == 0) + pllExtBusDiv = 16; + + /* + * Determine OPB_DIV. + */ + pllOpbDiv = ((cpr_primad & PRIMAD_OPBDV_MASK) >> 8); + if (pllOpbDiv == 0) + pllOpbDiv = 16; + + /* There is a bug in U-Boot that prevents us from using + * bd.bi_opbfreq because U-Boot doesn't populate it for + * 405EZ. We get to calculate it, yay! + */ + freqOPB = (sysclk *pllFbkDiv) /pllOpbDiv; + + freqEBC = (sysclk * pllFbkDiv) / pllExtBusDiv; + + plloutb = ((sysclk * ((cpr_pllc & PLLC_SRC_MASK) ? + pllFwdDivB : pllFwdDiv) * + pllFbkDiv) / pllFwdDivB); + + np = find_node_by_alias("serial0"); + if (getprop(np, "current-speed", &baud, sizeof(baud)) != sizeof(baud)) + fatal("no current-speed property\n\r"); + + udiv = 256; /* Assume lowest possible serial clk */ + div = plloutb / (16 * baud); /* total divisor */ + umin = (plloutb / freqOPB) << 1; /* 2 x OPB divisor */ + diff = 256; /* highest possible */ + + /* i is the test udiv value -- start with the largest + * possible (256) to minimize serial clock and constrain + * search to umin. + */ + for (i = 256; i > umin; i--) { + ibdiv = div / i; + est = i * ibdiv; + idiff = (est > div) ? (est-div) : (div-est); + if (idiff == 0) { + udiv = i; + break; /* can't do better */ + } else if (idiff < diff) { + udiv = i; /* best so far */ + diff = idiff; /* update lowest diff*/ + } + } + freqUART = plloutb / udiv; + + dt_fixup_cpu_clocks(bd.bi_procfreq, bd.bi_intfreq, bd.bi_plb_busfreq); + dt_fixup_clock("/plb/ebc", freqEBC); + dt_fixup_clock("/plb/opb", freqOPB); + dt_fixup_clock("/plb/opb/serial@ef600300", freqUART); + dt_fixup_clock("/plb/opb/serial@ef600400", freqUART); +} + +static void acadia_fixups(void) +{ + dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); + get_clocks(); + dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr); +} + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + CUBOOT_INIT(); + platform_ops.fixups = acadia_fixups; + platform_ops.exit = ibm40x_dbcr_reset; + fdt_init(_dtb_start); + serial_console_init(); +} diff --git a/arch/powerpc/boot/dts/acadia.dts b/arch/powerpc/boot/dts/acadia.dts new file mode 100644 index 00000000000..57291f61ffe --- /dev/null +++ b/arch/powerpc/boot/dts/acadia.dts @@ -0,0 +1,224 @@ +/* + * Device Tree Source for AMCC Acadia (405EZ) + * + * Copyright IBM Corp. 2008 + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "amcc,acadia"; + compatible = "amcc,acadia"; + dcr-parent = <&{/cpus/cpu@0}>; + + aliases { + ethernet0 = &EMAC0; + serial0 = &UART0; + serial1 = &UART1; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + model = "PowerPC,405EZ"; + reg = <0x0>; + clock-frequency = <0>; /* Filled in by wrapper */ + timebase-frequency = <0>; /* Filled in by wrapper */ + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <16384>; + d-cache-size = <16384>; + dcr-controller; + dcr-access-method = "native"; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x0>; /* Filled in by wrapper */ + }; + + UIC0: interrupt-controller { + compatible = "ibm,uic-405ez", "ibm,uic"; + interrupt-controller; + dcr-reg = <0x0c0 0x009>; + cell-index = <0>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + }; + + plb { + compatible = "ibm,plb-405ez", "ibm,plb3"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + clock-frequency = <0>; /* Filled in by wrapper */ + + MAL0: mcmal { + compatible = "ibm,mcmal-405ez", "ibm,mcmal"; + dcr-reg = <0x380 0x62>; + num-tx-chans = <1>; + num-rx-chans = <1>; + interrupt-parent = <&UIC0>; + /* 405EZ has only 3 interrupts to the UIC, as + * SERR, TXDE, and RXDE are or'd together into + * one UIC bit + */ + interrupts = < + 0x13 0x4 /* TXEOB */ + 0x15 0x4 /* RXEOB */ + 0x12 0x4 /* SERR, TXDE, RXDE */>; + }; + + POB0: opb { + compatible = "ibm,opb-405ez", "ibm,opb"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + dcr-reg = <0x0a 0x05>; + clock-frequency = <0>; /* Filled in by wrapper */ + + UART0: serial@ef600300 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600300 0x8>; + virtual-reg = <0xef600300>; + clock-frequency = <0>; /* Filled in by wrapper */ + current-speed = <115200>; + interrupt-parent = <&UIC0>; + interrupts = <0x5 0x4>; + }; + + UART1: serial@ef600400 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600400 0x8>; + clock-frequency = <0>; /* Filled in by wrapper */ + current-speed = <115200>; + interrupt-parent = <&UIC0>; + interrupts = <0x6 0x4>; + }; + + IIC: i2c@ef600500 { + compatible = "ibm,iic-405ez", "ibm,iic"; + reg = <0xef600500 0x11>; + interrupt-parent = <&UIC0>; + interrupts = <0xa 0x4>; + }; + + GPIO0: gpio@ef600700 { + compatible = "ibm,gpio-405ez"; + reg = <0xef600700 0x20>; + }; + + GPIO1: gpio@ef600800 { + compatible = "ibm,gpio-405ez"; + reg = <0xef600800 0x20>; + }; + + EMAC0: ethernet@ef600900 { + device_type = "network"; + compatible = "ibm,emac-405ez", "ibm,emac"; + interrupt-parent = <&UIC0>; + interrupts = < + 0x10 0x4 /* Ethernet */ + 0x11 0x4 /* Ethernet Wake up */>; + local-mac-address = [000000000000]; /* Filled in by wrapper */ + reg = <0xef600900 0x70>; + mal-device = <&MAL0>; + mal-tx-channel = <0>; + mal-rx-channel = <0>; + cell-index = <0>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; + phy-mode = "mii"; + phy-map = <0x0>; + }; + + CAN0: can@ef601000 { + compatible = "amcc,can-405ez"; + reg = <0xef601000 0x620>; + interrupt-parent = <&UIC0>; + interrupts = <0x7 0x4>; + }; + + CAN1: can@ef601800 { + compatible = "amcc,can-405ez"; + reg = <0xef601800 0x620>; + interrupt-parent = <&UIC0>; + interrupts = <0x8 0x4>; + }; + + cameleon@ef602000 { + compatible = "amcc,cameleon-405ez"; + reg = <0xef602000 0x800>; + interrupt-parent = <&UIC0>; + interrupts = <0xb 0x4 0xc 0x4>; + }; + + ieee1588@ef602800 { + compatible = "amcc,ieee1588-405ez"; + reg = <0xef602800 0x60>; + interrupt-parent = <&UIC0>; + interrupts = <0x4 0x4>; + /* This thing is a bit weird. It has it's own UIC + * that it uses to generate snapshot triggers. We + * don't really support this device yet, and it needs + * work to figure this out. + */ + dcr-reg = <0xe0 0x9>; + }; + + usb@ef603000 { + compatible = "ohci-be"; + reg = <0xef603000 0x80>; + interrupts-parent = <&UIC0>; + interrupts = <0xd 0x4 0xe 0x4>; + }; + + dac@ef603300 { + compatible = "amcc,dac-405ez"; + reg = <0xef603300 0x40>; + interrupt-parent = <&UIC0>; + interrupts = <0x18 0x4>; + }; + + adc@ef603400 { + compatible = "amcc,adc-405ez"; + reg = <0xef603400 0x40>; + interrupt-parent = <&UIC0>; + interrupts = <0x17 0x4>; + }; + + spi@ef603500 { + compatible = "amcc,spi-405ez"; + reg = <0xef603500 0x100>; + interrupt-parent = <&UIC0>; + interrupts = <0x9 0x4>; + }; + }; + + EBC0: ebc { + compatible = "ibm,ebc-405ez", "ibm,ebc"; + dcr-reg = <0x12 0x2>; + #address-cells = <2>; + #size-cells = <1>; + clock-frequency = <0>; /* Filled in by wrapper */ + }; + }; + + chosen { + linux,stdout-path = "/plb/opb/serial@ef600300"; + }; +}; diff --git a/arch/powerpc/boot/dts/hcu4.dts b/arch/powerpc/boot/dts/hcu4.dts new file mode 100644 index 00000000000..7988598da4c --- /dev/null +++ b/arch/powerpc/boot/dts/hcu4.dts @@ -0,0 +1,168 @@ +/* +* Device Tree Source for Netstal Maschinen HCU4 +* based on the IBM Walnut +* +* Copyright 2008 +* Niklaus Giger <niklaus.giger@member.fsf.org> +* +* Copyright 2007 IBM Corp. +* Josh Boyer <jwboyer@linux.vnet.ibm.com> +* +* This file is licensed under the terms of the GNU General Public +* License version 2. This program is licensed "as is" without +* any warranty of any kind, whether express or implied. +*/ + +/dts-v1/; + +/ { + #address-cells = <0x1>; + #size-cells = <0x1>; + model = "netstal,hcu4"; + compatible = "netstal,hcu4"; + dcr-parent = <0x1>; + + aliases { + ethernet0 = "/plb/opb/ethernet@ef600800"; + serial0 = "/plb/opb/serial@ef600300"; + }; + + cpus { + #address-cells = <0x1>; + #size-cells = <0x0>; + + cpu@0 { + device_type = "cpu"; + model = "PowerPC,405GPr"; + reg = <0x0>; + clock-frequency = <0>; /* Filled in by U-Boot */ + timebase-frequency = <0x0>; /* Filled in by U-Boot */ + i-cache-line-size = <0x20>; + d-cache-line-size = <0x20>; + i-cache-size = <0x4000>; + d-cache-size = <0x4000>; + dcr-controller; + dcr-access-method = "native"; + linux,phandle = <0x1>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x0>; /* Filled in by U-Boot */ + }; + + UIC0: interrupt-controller { + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <0x0>; + dcr-reg = <0xc0 0x9>; + #address-cells = <0x0>; + #size-cells = <0x0>; + #interrupt-cells = <0x2>; + linux,phandle = <0x2>; + }; + + plb { + compatible = "ibm,plb3"; + #address-cells = <0x1>; + #size-cells = <0x1>; + ranges; + clock-frequency = <0x0>; /* Filled in by U-Boot */ + + SDRAM0: memory-controller { + compatible = "ibm,sdram-405gp"; + dcr-reg = <0x10 0x2>; + }; + + MAL: mcmal { + compatible = "ibm,mcmal-405gp", "ibm,mcmal"; + dcr-reg = <0x180 0x62>; + num-tx-chans = <0x1>; + num-rx-chans = <0x1>; + interrupt-parent = <0x2>; + interrupts = <0xb 0x4 0xc 0x4 0xa 0x4 0xd 0x4 0xe 0x4>; + linux,phandle = <0x3>; + }; + + POB0: opb { + compatible = "ibm,opb-405gp", "ibm,opb"; + #address-cells = <0x1>; + #size-cells = <0x1>; + ranges = <0xef600000 0xef600000 0xa00000>; + dcr-reg = <0xa0 0x5>; + clock-frequency = <0x0>; /* Filled in by U-Boot */ + + UART0: serial@ef600300 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600300 0x8>; + virtual-reg = <0xef600300>; + clock-frequency = <0x0>;/* Filled in by U-Boot */ + current-speed = <0>; /* Filled in by U-Boot */ + interrupt-parent = <0x2>; + interrupts = <0x0 0x4>; + }; + + IIC: i2c@ef600500 { + compatible = "ibm,iic-405gp", "ibm,iic"; + reg = <0xef600500 0x11>; + interrupt-parent = <0x2>; + interrupts = <0x2 0x4>; + }; + + GPIO: gpio@ef600700 { + compatible = "ibm,gpio-405gp"; + reg = <0xef600700 0x20>; + }; + + EMAC: ethernet@ef600800 { + device_type = "network"; + compatible = "ibm,emac-405gp", "ibm,emac"; + interrupt-parent = <0x2>; + interrupts = <0xf 0x4 0x9 0x4>; + local-mac-address = [00 00 00 00 00 00]; + reg = <0xef600800 0x70>; + mal-device = <0x3>; + mal-tx-channel = <0x0>; + mal-rx-channel = <0x0>; + cell-index = <0x0>; + max-frame-size = <0x5dc>; + rx-fifo-size = <0x1000>; + tx-fifo-size = <0x800>; + phy-mode = "rmii"; + phy-map = <0x1>; + }; + }; + + EBC0: ebc { + compatible = "ibm,ebc-405gp", "ibm,ebc"; + dcr-reg = <0x12 0x2>; + #address-cells = <0x2>; + #size-cells = <0x1>; + clock-frequency = <0x0>; /* Filled in by U-Boot */ + + sram@0,0 { + reg = <0x0 0x0 0x80000>; + }; + + flash@0,80000 { + compatible = "jedec-flash"; + bank-width = <0x1>; + reg = <0x0 0x80000 0x80000>; + #address-cells = <0x1>; + #size-cells = <0x1>; + + partition@0 { + label = "OpenBIOS"; + reg = <0x0 0x80000>; + read-only; + }; + }; + }; + }; + + chosen { + linux,stdout-path = "/plb/opb/serial@ef600300"; + }; +}; diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index 7449e54c1a9..6b850670de1 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -121,6 +121,14 @@ compatible = "dallas,ds1339"; reg = <0x68>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8315erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; spi@7000 { diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts index e4cc1768f24..57c595bf107 100644 --- a/arch/powerpc/boot/dts/mpc832x_mds.dts +++ b/arch/powerpc/boot/dts/mpc832x_mds.dts @@ -60,7 +60,7 @@ }; bcsr@f8000000 { - device_type = "board-control"; + compatible = "fsl,mpc8323mds-bcsr"; reg = <0xf8000000 0x8000>; }; diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index 5cedf373a1d..2c9d54a35bc 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -83,6 +83,14 @@ interrupts = <15 0x8>; interrupt-parent = <&ipic>; dfsrr; + + rtc@68 { + device_type = "rtc"; + compatible = "dallas,ds1339"; + reg = <0x68>; + interrupts = <18 0x8>; + interrupt-parent = <&ipic>; + }; }; spi@7000 { @@ -131,6 +139,14 @@ interrupt-parent = <&ipic>; interrupts = <71 8>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8349emitx", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; usb@22000 { diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts index 81ae1d3e944..fa40647ee62 100644 --- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts +++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts @@ -81,6 +81,14 @@ interrupts = <15 0x8>; interrupt-parent = <&ipic>; dfsrr; + + rtc@68 { + device_type = "rtc"; + compatible = "dallas,ds1339"; + reg = <0x68>; + interrupts = <18 0x8>; + interrupt-parent = <&ipic>; + }; }; spi@7000 { diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts index 04bfde3ea60..c986c541e9b 100644 --- a/arch/powerpc/boot/dts/mpc834x_mds.dts +++ b/arch/powerpc/boot/dts/mpc834x_mds.dts @@ -49,7 +49,7 @@ }; bcsr@e2400000 { - device_type = "board-control"; + compatible = "fsl,mpc8349mds-bcsr"; reg = <0xe2400000 0x8000>; }; diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts index 66a12d2631f..14534d04e4d 100644 --- a/arch/powerpc/boot/dts/mpc836x_mds.dts +++ b/arch/powerpc/boot/dts/mpc836x_mds.dts @@ -69,7 +69,7 @@ }; bcsr@1,0 { - device_type = "board-control"; + compatible = "fsl,mpc8360mds-bcsr"; reg = <1 0 0x8000>; }; }; diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts index 53191ba67aa..435ef3dd022 100644 --- a/arch/powerpc/boot/dts/mpc8377_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts @@ -121,6 +121,14 @@ compatible = "dallas,ds1339"; reg = <0x68>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8377erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; i2c@3100 { diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts index 4a09153d160..b11e68f56a0 100644 --- a/arch/powerpc/boot/dts/mpc8378_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts @@ -121,6 +121,14 @@ compatible = "dallas,ds1339"; reg = <0x68>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8378erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; i2c@3100 { diff --git a/arch/powerpc/boot/dts/mpc8379_rdb.dts b/arch/powerpc/boot/dts/mpc8379_rdb.dts index bbd884ac9dc..337af6ea26d 100644 --- a/arch/powerpc/boot/dts/mpc8379_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8379_rdb.dts @@ -121,6 +121,14 @@ compatible = "dallas,ds1339"; reg = <0x68>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8379erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; i2c@3100 { diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts index 93fdd99901b..35db1e5440c 100644 --- a/arch/powerpc/boot/dts/mpc8536ds.dts +++ b/arch/powerpc/boot/dts/mpc8536ds.dts @@ -109,7 +109,7 @@ reg = <0x0 0x80>; cell-index = <0>; interrupt-parent = <&mpic>; - interrupts = <14 0x2>; + interrupts = <20 2>; }; dma-channel@80 { compatible = "fsl,mpc8536-dma-channel", @@ -117,7 +117,7 @@ reg = <0x80 0x80>; cell-index = <1>; interrupt-parent = <&mpic>; - interrupts = <15 0x2>; + interrupts = <21 2>; }; dma-channel@100 { compatible = "fsl,mpc8536-dma-channel", @@ -125,7 +125,7 @@ reg = <0x100 0x80>; cell-index = <2>; interrupt-parent = <&mpic>; - interrupts = <16 0x2>; + interrupts = <22 2>; }; dma-channel@180 { compatible = "fsl,mpc8536-dma-channel", @@ -133,7 +133,7 @@ reg = <0x180 0x80>; cell-index = <3>; interrupt-parent = <&mpic>; - interrupts = <17 0x2>; + interrupts = <23 2>; }; }; @@ -180,7 +180,7 @@ enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; - model = "TSEC"; + model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; @@ -193,7 +193,7 @@ enet1: ethernet@26000 { cell-index = <1>; device_type = "network"; - model = "TSEC"; + model = "eTSEC"; compatible = "gianfar"; reg = <0x26000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts index a15f10343f5..c80158f7741 100644 --- a/arch/powerpc/boot/dts/mpc8568mds.dts +++ b/arch/powerpc/boot/dts/mpc8568mds.dts @@ -52,7 +52,7 @@ }; bcsr@f8000000 { - device_type = "board-control"; + compatible = "fsl,mpc8568mds-bcsr"; reg = <0xf8000000 0x8000>; }; diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts index e124dd18fb5..cadd4652a69 100644 --- a/arch/powerpc/boot/dts/mpc8572ds.dts +++ b/arch/powerpc/boot/dts/mpc8572ds.dts @@ -13,8 +13,8 @@ / { model = "fsl,MPC8572DS"; compatible = "fsl,MPC8572DS"; - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; aliases { ethernet0 = &enet0; @@ -61,7 +61,6 @@ memory { device_type = "memory"; - reg = <0x0 0x0>; // Filled by U-Boot }; soc8572@ffe00000 { @@ -69,8 +68,8 @@ #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 + ranges = <0x0 0 0xffe00000 0x100000>; + reg = <0 0xffe00000 0 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed bus-frequency = <0>; // Filled out by uboot. memory-controller@2000 { @@ -351,10 +350,10 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xffe08000 0x1000>; + reg = <0 0xffe08000 0 0x1000>; bus-range = <0 255>; - ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000 - 0x1000000 0x0 0x0 0xffc00000 0x0 0x10000>; + ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x00010000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <24 2>; @@ -561,10 +560,10 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xffe09000 0x1000>; + reg = <0 0xffe09000 0 0x1000>; bus-range = <0 255>; - ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000 - 0x1000000 0x0 0x0 0xffc10000 0x0 0x10000>; + ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x00010000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <26 2>; @@ -598,10 +597,10 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xffe0a000 0x1000>; + reg = <0 0xffe0a000 0 0x1000>; bus-range = <0 255>; - ranges = <0x2000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000 - 0x1000000 0x0 0x0 0xffc20000 0x0 0x10000>; + ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x00010000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <27 2>; diff --git a/arch/powerpc/boot/libfdt-wrapper.c b/arch/powerpc/boot/libfdt-wrapper.c index c541fd8a95d..9276327bc2b 100644 --- a/arch/powerpc/boot/libfdt-wrapper.c +++ b/arch/powerpc/boot/libfdt-wrapper.c @@ -105,6 +105,11 @@ static int fdt_wrapper_setprop(const void *devp, const char *name, return check_err(rc); } +static int fdt_wrapper_del_node(const void *devp) +{ + return fdt_del_node(fdt, devp_offset(devp)); +} + static void *fdt_wrapper_get_parent(const void *devp) { return offset_devp(fdt_parent_offset(fdt, devp_offset(devp))); @@ -165,6 +170,7 @@ static unsigned long fdt_wrapper_finalize(void) void fdt_init(void *blob) { int err; + int bufsize; dt_ops.finddevice = fdt_wrapper_finddevice; dt_ops.getprop = fdt_wrapper_getprop; @@ -173,21 +179,21 @@ void fdt_init(void *blob) dt_ops.create_node = fdt_wrapper_create_node; dt_ops.find_node_by_prop_value = fdt_wrapper_find_node_by_prop_value; dt_ops.find_node_by_compatible = fdt_wrapper_find_node_by_compatible; + dt_ops.del_node = fdt_wrapper_del_node; dt_ops.get_path = fdt_wrapper_get_path; dt_ops.finalize = fdt_wrapper_finalize; /* Make sure the dt blob is the right version and so forth */ fdt = blob; - err = fdt_open_into(fdt, fdt, fdt_totalsize(blob)); - if (err == -FDT_ERR_NOSPACE) { - int bufsize = fdt_totalsize(fdt) + 4; - buf = malloc(bufsize); - err = fdt_open_into(fdt, buf, bufsize); - } + bufsize = fdt_totalsize(fdt) + 4; + buf = malloc(bufsize); + if(!buf) + fatal("malloc failed. can't relocate the device tree\n\r"); + + err = fdt_open_into(fdt, buf, bufsize); if (err != 0) fatal("fdt_init(): %s\n\r", fdt_strerror(err)); - if (buf) - fdt = buf; + fdt = buf; } diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index 9e7f3ddd991..ae32801ebd6 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c @@ -56,9 +56,19 @@ static struct addr_range prep_kernel(void) if (platform_ops.vmlinux_alloc) { addr = platform_ops.vmlinux_alloc(ei.memsize); } else { - if ((unsigned long)_start < ei.memsize) + /* + * Check if the kernel image (without bss) would overwrite the + * bootwrapper. The device tree has been moved in fdt_init() + * to an area allocated with malloc() (somewhere past _end). + */ + if ((unsigned long)_start < ei.loadsize) fatal("Insufficient memory for kernel at address 0!" - " (_start=%p)\n\r", _start); + " (_start=%p, uncomressed size=%08x)\n\r", + _start, ei.loadsize); + + if ((unsigned long)_end < ei.memsize) + fatal("The final kernel image would overwrite the " + "device tree\n\r"); } /* Finally, gunzip the kernel */ diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index 321e2f5afe7..b3218ce451b 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h @@ -40,6 +40,7 @@ struct dt_ops { const int buflen); int (*setprop)(const void *phandle, const char *name, const void *buf, const int buflen); + int (*del_node)(const void *phandle); void *(*get_parent)(const void *phandle); /* The node must not already exist. */ void *(*create_node)(const void *parent, const char *name); @@ -126,6 +127,11 @@ static inline int setprop_str(void *devp, const char *name, const char *buf) return -1; } +static inline int del_node(const void *devp) +{ + return dt_ops.del_node ? dt_ops.del_node(devp) : -1; +} + static inline void *get_parent(const char *devp) { return dt_ops.get_parent ? dt_ops.get_parent(devp) : NULL; diff --git a/arch/powerpc/boot/string.S b/arch/powerpc/boot/string.S index 643e4cb2f11..acc9428f278 100644 --- a/arch/powerpc/boot/string.S +++ b/arch/powerpc/boot/string.S @@ -235,7 +235,7 @@ memchr: .globl memcmp memcmp: cmpwi 0,r5,0 - blelr + ble 2f mtctr r5 addi r6,r3,-1 addi r4,r4,-1 @@ -244,6 +244,8 @@ memcmp: subf. r3,r0,r3 bdnzt 2,1b blr +2: li r3,0 + blr /* diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index ee0dc41d7c5..f39073511a4 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -306,11 +306,14 @@ fi # post-processing needed for some platforms case "$platform" in -pseries|chrp) +pseries) ${CROSS}objcopy -O binary -j .fakeelf "$kernel" "$ofile".rpanote $objbin/addnote "$ofile" "$ofile".rpanote rm -r "$ofile".rpanote ;; +chrp) + $objbin/addnote -r c00000 "$ofile" + ;; coff) ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile" $objbin/hack-coff "$ofile" diff --git a/arch/powerpc/configs/40x/acadia_defconfig b/arch/powerpc/configs/40x/acadia_defconfig new file mode 100644 index 00000000000..39bd9eb453f --- /dev/null +++ b/arch/powerpc/configs/40x/acadia_defconfig @@ -0,0 +1,921 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.27-rc5 +# Mon Oct 13 13:47:16 2008 +# +# CONFIG_PPC64 is not set + +# +# Processor support +# +# CONFIG_6xx is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_8xx is not set +CONFIG_40x=y +# CONFIG_44x is not set +# CONFIG_E200 is not set +CONFIG_4xx=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_NOT_COHERENT_CACHE=y +CONFIG_PPC32=y +CONFIG_WORD_SIZE=32 +CONFIG_PPC_MERGE=y +CONFIG_MMU=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set +CONFIG_IRQ_PER_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_OF=y +CONFIG_PPC_UDBG_16550=y +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +# CONFIG_DEFAULT_UIMAGE is not set +CONFIG_PPC_DCR_NATIVE=y +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_PPC_DCR=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y +# CONFIG_FAIR_GROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +# CONFIG_HAVE_DMA_ATTRS is not set +# CONFIG_USE_GENERIC_SMP_HELPERS is not set +# CONFIG_HAVE_CLK is not set +CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PPC4xx_PCI_EXPRESS is not set + +# +# Platform support +# +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set +CONFIG_ACADIA=y +# CONFIG_EP405 is not set +# CONFIG_KILAUEA is not set +# CONFIG_MAKALU is not set +# CONFIG_WALNUT is not set +# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set +CONFIG_PPC40x_SIMPLE=y +CONFIG_405EZ=y +# CONFIG_IPIC is not set +# CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_FSL_ULI1575 is not set + +# +# Kernel options +# +# CONFIG_HIGHMEM is not set +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_IOMMU_HELPER is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_MIGRATION=y +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +CONFIG_EXTRA_TARGETS="" +# CONFIG_PM is not set +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_ZONE_DMA=y +CONFIG_PPC_INDIRECT_PCI=y +CONFIG_4xx_SOC=y +CONFIG_PPC_PCI_CHOICE=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +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_DEBUG is not set +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HAS_RAPIDIO is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_PAGE_OFFSET=0xc0000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_PHYSICAL_START=0x00000000 +CONFIG_TASK_SIZE=0xc0000000 +CONFIG_CONSISTENT_START=0xff100000 +CONFIG_CONSISTENT_SIZE=0x00200000 +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +CONFIG_OF_DEVICE=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=35000 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_XILINX_SYSACE is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# Enable only one of the two stacks, unless you know what you are doing +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_IBM_NEW_EMAC=y +CONFIG_IBM_NEW_EMAC_RXB=256 +CONFIG_IBM_NEW_EMAC_TXB=256 +CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 +CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 +CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 +CONFIG_IBM_NEW_EMAC_DEBUG=y +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL=y +CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT=y +CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR=y +# CONFIG_NET_PCI is not set +# CONFIG_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_I2C is not set +# CONFIG_SPI is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +# CONFIG_GPIOLIB is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_THERMAL=y +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_SOUND is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +# CONFIG_EDAC is not set +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_HAVE_LMB=y + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_HAVE_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +# CONFIG_FTRACE is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_CODE_PATCHING_SELFTEST is not set +# CONFIG_FTR_FIXUP_SELFTEST is not set +# CONFIG_MSI_BITMAP_SELFTEST is not set +# CONFIG_XMON is not set +# CONFIG_IRQSTACKS is not set +# CONFIG_VIRQ_DEBUG is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_PPC_EARLY_DEBUG is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=y +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_PPC_CLOCK is not set +# CONFIG_VIRTUALIZATION is not set diff --git a/arch/powerpc/configs/40x/hcu4_defconfig b/arch/powerpc/configs/40x/hcu4_defconfig new file mode 100644 index 00000000000..682fce02c73 --- /dev/null +++ b/arch/powerpc/configs/40x/hcu4_defconfig @@ -0,0 +1,929 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26.5 +# Tue Sep 16 00:44:33 2008 +# +# CONFIG_PPC64 is not set + +# +# Processor support +# +# CONFIG_6xx is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_8xx is not set +CONFIG_40x=y +# CONFIG_44x is not set +# CONFIG_E200 is not set +CONFIG_4xx=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_NOT_COHERENT_CACHE=y +CONFIG_PPC32=y +CONFIG_WORD_SIZE=32 +CONFIG_PPC_MERGE=y +CONFIG_MMU=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set +CONFIG_IRQ_PER_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_OF=y +CONFIG_PPC_UDBG_16550=y +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +# CONFIG_DEFAULT_UIMAGE is not set +CONFIG_PPC_DCR_NATIVE=y +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_PPC_DCR=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +# CONFIG_LOGBUFFER is not set +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +# CONFIG_HAVE_DMA_ATTRS is not set +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PPC4xx_PCI_EXPRESS is not set + +# +# Platform support +# +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set +# CONFIG_EP405 is not set +CONFIG_HCU4=y +# CONFIG_KILAUEA is not set +# CONFIG_MAKALU is not set +# CONFIG_WALNUT is not set +# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set +# CONFIG_IPIC is not set +# CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_FSL_ULI1575 is not set + +# +# Kernel options +# +# CONFIG_HIGHMEM is not set +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_IOMMU_HELPER is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_RESOURCES_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_PM is not set +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_ZONE_DMA=y +CONFIG_PPC_INDIRECT_PCI=y +CONFIG_4xx_SOC=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_SYSCALL=y +# CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set +# CONFIG_PCI_LEGACY is not set +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HAS_RAPIDIO is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_PAGE_OFFSET=0xc0000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_PHYSICAL_START=0x00000000 +CONFIG_TASK_SIZE=0xc0000000 +CONFIG_CONSISTENT_START=0xff100000 +CONFIG_CONSISTENT_SIZE=0x00200000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +CONFIG_OF_DEVICE=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=35000 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_XILINX_SYSACE is not set +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# Enable only one of the two stacks, unless you know what you are doing +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_IBM_NEW_EMAC=y +CONFIG_IBM_NEW_EMAC_RXB=128 +CONFIG_IBM_NEW_EMAC_TXB=64 +CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 +CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 +CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 +# CONFIG_IBM_NEW_EMAC_DEBUG is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_NET_PCI is not set +# CONFIG_B44 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_E1000E_ENABLED is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NIU is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set +# CONFIG_SFC is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_I2C is not set +# CONFIG_SPI is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +# CONFIG_EDAC is not set +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_YAFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_HAVE_LMB=y + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUGGER is not set +# CONFIG_IRQSTACKS is not set +# CONFIG_VIRQ_DEBUG is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_PPC_EARLY_DEBUG is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=y +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_PPC_CLOCK is not set +# CONFIG_VIRTUALIZATION is not set diff --git a/arch/powerpc/include/asm/kdump.h b/arch/powerpc/include/asm/kdump.h index f6c93c71689..a503da9d56f 100644 --- a/arch/powerpc/include/asm/kdump.h +++ b/arch/powerpc/include/asm/kdump.h @@ -9,6 +9,12 @@ * Reserve to the end of the FWNMI area, see head_64.S */ #define KDUMP_RESERVE_LIMIT 0x10000 /* 64K */ +/* + * Used to differentiate between relocatable kdump kernel and other + * kernels + */ +#define KDUMP_SIGNATURE 0xfeed1234 + #ifdef CONFIG_CRASH_DUMP #define KDUMP_TRAMPOLINE_START 0x0100 @@ -19,17 +25,18 @@ #endif /* CONFIG_CRASH_DUMP */ #ifndef __ASSEMBLY__ -#ifdef CONFIG_CRASH_DUMP +extern unsigned long __kdump_flag; + +#if defined(CONFIG_CRASH_DUMP) && !defined(CONFIG_RELOCATABLE) extern void reserve_kdump_trampoline(void); extern void setup_kdump_trampoline(void); - -#else /* !CONFIG_CRASH_DUMP */ - +#else +/* !CRASH_DUMP || RELOCATABLE */ static inline void reserve_kdump_trampoline(void) { ; } static inline void setup_kdump_trampoline(void) { ; } +#endif -#endif /* CONFIG_CRASH_DUMP */ #endif /* __ASSEMBLY__ */ #endif /* __PPC64_KDUMP_H */ diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index 5ac51e6efc1..c0b8d4a29a9 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -77,6 +77,7 @@ #if defined(CONFIG_RELOCATABLE) #ifndef __ASSEMBLY__ + extern phys_addr_t memstart_addr; extern phys_addr_t kernstart_addr; #endif diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index e70d0483fb4..b1eb834bc0f 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1277,6 +1277,19 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_4xx, .platform = "ppc405", }, + { + /* 405EZ */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x41510000, + .cpu_name = "405EZ", + .cpu_features = CPU_FTRS_40X, + .cpu_user_features = PPC_FEATURE_32 | + PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, + .icache_bsize = 32, + .dcache_bsize = 32, + .machine_check = machine_check_4xx, + .platform = "ppc405", + }, { /* default match */ .pvr_mask = 0x00000000, .pvr_value = 0x00000000, diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 97e05637972..19671aca659 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c @@ -30,6 +30,7 @@ /* Stores the physical address of elf header of crash image. */ unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; +#ifndef CONFIG_RELOCATABLE void __init reserve_kdump_trampoline(void) { lmb_reserve(0, KDUMP_RESERVE_LIMIT); @@ -68,6 +69,7 @@ void __init setup_kdump_trampoline(void) DBG(" <- setup_kdump_trampoline()\n"); } +#endif /* CONFIG_RELOCATABLE */ /* * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 84856bee33a..69489bd3210 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -97,6 +97,12 @@ __secondary_hold_spinloop: __secondary_hold_acknowledge: .llong 0x0 + /* This flag is set by purgatory if we should be a kdump kernel. */ + /* Do not move this variable as purgatory knows about it. */ + .globl __kdump_flag +__kdump_flag: + .llong 0x0 + #ifdef CONFIG_PPC_ISERIES /* * At offset 0x20, there is a pointer to iSeries LPAR data. @@ -1384,7 +1390,13 @@ _STATIC(__after_prom_start) /* process relocations for the final address of the kernel */ lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */ sldi r25,r25,32 - mr r3,r25 +#ifdef CONFIG_CRASH_DUMP + ld r7,__kdump_flag-_stext(r26) + cmpldi cr0,r7,1 /* kdump kernel ? - stay where we are */ + bne 1f + add r25,r25,r26 +#endif +1: mr r3,r25 bl .relocate #endif @@ -1398,11 +1410,26 @@ _STATIC(__after_prom_start) li r3,0 /* target addr */ mr. r4,r26 /* In some cases the loader may */ beq 9f /* have already put us at zero */ - lis r5,(copy_to_here - _stext)@ha - addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */ li r6,0x100 /* Start offset, the first 0x100 */ /* bytes were copied earlier. */ +#ifdef CONFIG_CRASH_DUMP +/* + * Check if the kernel has to be running as relocatable kernel based on the + * variable __kdump_flag, if it is set the kernel is treated as relocatable + * kernel, otherwise it will be moved to PHYSICAL_START + */ + ld r7,__kdump_flag-_stext(r26) + cmpldi cr0,r7,1 + bne 3f + + li r5,__end_interrupts - _stext /* just copy interrupts */ + b 5f +3: +#endif + lis r5,(copy_to_here - _stext)@ha + addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */ + bl .copy_and_flush /* copy the first n bytes */ /* this includes the code being */ /* executed here. */ @@ -1411,15 +1438,15 @@ _STATIC(__after_prom_start) mtctr r8 bctr +p_end: .llong _end - _stext + 4: /* Now copy the rest of the kernel up to _end */ addis r5,r26,(p_end - _stext)@ha ld r5,(p_end - _stext)@l(r5) /* get _end */ - bl .copy_and_flush /* copy the rest */ +5: bl .copy_and_flush /* copy the rest */ 9: b .start_here_multiplatform -p_end: .llong _end - _stext - /* * Copy routine used to copy the kernel to start at physical address 0 * and flush and invalidate the caches as needed. diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index ea1ba89f9c9..3857d7e2af0 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -458,6 +458,42 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, spin_unlock_irqrestore(&(tbl->it_lock), flags); } +static void iommu_table_clear(struct iommu_table *tbl) +{ + if (!__kdump_flag) { + /* Clear the table in case firmware left allocations in it */ + ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); + return; + } + +#ifdef CONFIG_CRASH_DUMP + if (ppc_md.tce_get) { + unsigned long index, tceval, tcecount = 0; + + /* Reserve the existing mappings left by the first kernel. */ + for (index = 0; index < tbl->it_size; index++) { + tceval = ppc_md.tce_get(tbl, index + tbl->it_offset); + /* + * Freed TCE entry contains 0x7fffffffffffffff on JS20 + */ + if (tceval && (tceval != 0x7fffffffffffffffUL)) { + __set_bit(index, tbl->it_map); + tcecount++; + } + } + + if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) { + printk(KERN_WARNING "TCE table is full; freeing "); + printk(KERN_WARNING "%d entries for the kdump boot\n", + KDUMP_MIN_TCE_ENTRIES); + for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES; + index < tbl->it_size; index++) + __clear_bit(index, tbl->it_map); + } + } +#endif +} + /* * Build a iommu_table structure. This contains a bit map which * is used to manage allocation of the tce space. @@ -484,38 +520,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) tbl->it_largehint = tbl->it_halfpoint; spin_lock_init(&tbl->it_lock); -#ifdef CONFIG_CRASH_DUMP - if (ppc_md.tce_get) { - unsigned long index; - unsigned long tceval; - unsigned long tcecount = 0; - - /* - * Reserve the existing mappings left by the first kernel. - */ - for (index = 0; index < tbl->it_size; index++) { - tceval = ppc_md.tce_get(tbl, index + tbl->it_offset); - /* - * Freed TCE entry contains 0x7fffffffffffffff on JS20 - */ - if (tceval && (tceval != 0x7fffffffffffffffUL)) { - __set_bit(index, tbl->it_map); - tcecount++; - } - } - if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) { - printk(KERN_WARNING "TCE table is full; "); - printk(KERN_WARNING "freeing %d entries for the kdump boot\n", - KDUMP_MIN_TCE_ENTRIES); - for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES; - index < tbl->it_size; index++) - __clear_bit(index, tbl->it_map); - } - } -#else - /* Clear the hardware table in case firmware left allocations in it */ - ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); -#endif + iommu_table_clear(tbl); if (!welcomed) { printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index aab76887a84..ac2a21f45c7 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -88,11 +88,13 @@ void __init reserve_crashkernel(void) crash_size = crashk_res.end - crashk_res.start + 1; +#ifndef CONFIG_RELOCATABLE if (crashk_res.start != KDUMP_KERNELBASE) printk("Crash kernel location must be 0x%x\n", KDUMP_KERNELBASE); crashk_res.start = KDUMP_KERNELBASE; +#endif crash_size = PAGE_ALIGN(crash_size); crashk_res.end = crashk_res.start + crash_size - 1; diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index a168514d860..e6efec788c4 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c @@ -255,11 +255,14 @@ static union thread_union kexec_stack /* Our assembly helper, in kexec_stub.S */ extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start, void *image, void *control, - void (*clear_all)(void)) ATTRIB_NORET; + void (*clear_all)(void), + unsigned long kdump_flag) ATTRIB_NORET; /* too late to fail here */ void default_machine_kexec(struct kimage *image) { + unsigned long kdump_flag = 0; + /* prepare control code if any */ /* @@ -270,8 +273,10 @@ void default_machine_kexec(struct kimage *image) * using debugger IPI. */ - if (crashing_cpu == -1) - kexec_prepare_cpus(); + if (crashing_cpu == -1) + kexec_prepare_cpus(); + else + kdump_flag = KDUMP_SIGNATURE; /* switch to a staticly allocated stack. Based on irq stack code. * XXX: the task struct will likely be invalid once we do the copy! @@ -284,7 +289,7 @@ void default_machine_kexec(struct kimage *image) */ kexec_sequence(&kexec_stack, image->start, image, page_address(image->control_code_page), - ppc_md.hpte_clear_all); + ppc_md.hpte_clear_all, kdump_flag); /* NOTREACHED */ } @@ -312,11 +317,24 @@ static struct property kernel_end_prop = { static void __init export_htab_values(void) { struct device_node *node; + struct property *prop; node = of_find_node_by_path("/chosen"); if (!node) return; + /* 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); + prop = of_find_property(node, htab_size_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); diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 3053fe5c62f..a243fd072a7 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -611,10 +611,12 @@ real_mode: /* assume normal blr return */ /* - * kexec_sequence(newstack, start, image, control, clear_all()) + * kexec_sequence(newstack, start, image, control, clear_all(), kdump_flag) * * does the grungy work with stack switching and real mode switches * also does simple calls to other code + * + * kdump_flag says whether the next kernel should be a kdump kernel. */ _GLOBAL(kexec_sequence) @@ -647,7 +649,7 @@ _GLOBAL(kexec_sequence) mr r29,r5 /* image (virt) */ mr r28,r6 /* control, unused */ mr r27,r7 /* clear_all() fn desc */ - mr r26,r8 /* spare */ + mr r26,r8 /* kdump flag */ lhz r25,PACAHWCPUID(r13) /* get our phys cpu from paca */ /* disable interrupts, we are overwriting kernel data next */ @@ -709,5 +711,6 @@ _GLOBAL(kexec_sequence) mr r4,r30 # start, aka phys mem offset mtlr 4 li r5,0 - blr /* image->start(physid, image->start, 0); */ + mr r6,r26 /* kdump_flag */ + blr /* image->start(physid, image->start, 0, kdump_flag); */ #endif /* CONFIG_KEXEC */ diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 3815d84a1ef..1ec73938a00 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -610,7 +610,8 @@ 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 |= _PAGE_NO_CACHE | _PAGE_GUARDED; + vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) + | _PAGE_NO_CACHE | _PAGE_GUARDED); return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot); diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 2fdbc18ae94..23e0db20332 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -487,67 +487,6 @@ static int __init prom_setprop(phandle node, const char *nodename, return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd); } -/* We can't use the standard versions because of RELOC headaches. */ -#define isxdigit(c) (('0' <= (c) && (c) <= '9') \ - || ('a' <= (c) && (c) <= 'f') \ - || ('A' <= (c) && (c) <= 'F')) - -#define isdigit(c) ('0' <= (c) && (c) <= '9') -#define islower(c) ('a' <= (c) && (c) <= 'z') -#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c)) - -unsigned long prom_strtoul(const char *cp, const char **endp) -{ - unsigned long result = 0, base = 10, value; - - if (*cp == '0') { - base = 8; - cp++; - if (toupper(*cp) == 'X') { - cp++; - base = 16; - } - } - - while (isxdigit(*cp) && - (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) { - result = result * base + value; - cp++; - } - - if (endp) - *endp = cp; - - return result; -} - -unsigned long prom_memparse(const char *ptr, const char **retptr) -{ - unsigned long ret = prom_strtoul(ptr, retptr); - int shift = 0; - - /* - * We can't use a switch here because GCC *may* generate a - * jump table which won't work, because we're not running at - * the address we're linked at. - */ - if ('G' == **retptr || 'g' == **retptr) - shift = 30; - - if ('M' == **retptr || 'm' == **retptr) - shift = 20; - - if ('K' == **retptr || 'k' == **retptr) - shift = 10; - - if (shift) { - ret <<= shift; - (*retptr)++; - } - - return ret; -} - /* * Early parsing of the command line passed to the kernel, used for * "mem=x" and the options that affect the iommu diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh index 2c7e8e87f77..ea3a2ec03ff 100644 --- a/arch/powerpc/kernel/prom_init_check.sh +++ b/arch/powerpc/kernel/prom_init_check.sh @@ -20,7 +20,7 @@ WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush _end enter_prom memcpy memset reloc_offset __secondary_hold __secondary_hold_acknowledge __secondary_hold_spinloop __start strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224 -reloc_got2 kernstart_addr" +reloc_got2 kernstart_addr memstart_addr" NM="$1" OBJ="$2" diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 5ec56ff03e8..705fc4bf380 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -59,6 +59,7 @@ #include <asm/mmu.h> #include <asm/xmon.h> #include <asm/cputhreads.h> +#include <mm/mmu_decl.h> #include "setup.h" @@ -190,6 +191,12 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (ppc_md.show_cpuinfo != NULL) ppc_md.show_cpuinfo(m); +#ifdef CONFIG_PPC32 + /* Display the amount of memory */ + seq_printf(m, "Memory\t\t: %d MB\n", + (unsigned int)(total_memory / (1024 * 1024))); +#endif + return 0; } diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 65ad925c3a8..c6a8f2326b6 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -235,8 +235,6 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, else for (i = 0; i < 32 ; i++) current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; - -#else #endif return err; } diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c index cb01ebc5938..7b7da8cfd5e 100644 --- a/arch/powerpc/kernel/udbg_16550.c +++ b/arch/powerpc/kernel/udbg_16550.c @@ -142,7 +142,7 @@ unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock) speed = (clock / prescaler) / (divisor * 16); /* sanity check */ - if (speed < 0 || speed > (clock / 16)) + if (speed > (clock / 16)) speed = 9600; return speed; diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 5c64af17475..8d5b4758c13 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -382,8 +382,10 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node, printk(KERN_INFO "Huge page(16GB) memory: " "addr = 0x%lX size = 0x%lX pages = %d\n", phys_addr, block_size, expected_pages); - lmb_reserve(phys_addr, block_size * expected_pages); - add_gpage(phys_addr, block_size, expected_pages); + if (phys_addr + (16 * GB) <= lmb_end_of_DRAM()) { + lmb_reserve(phys_addr, block_size * expected_pages); + add_gpage(phys_addr, block_size, expected_pages); + } return 0; } #endif /* CONFIG_HUGETLB_PAGE */ diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 6cf5c71c431..eb505ad34a8 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -116,6 +116,7 @@ static int __init get_active_region_work_fn(unsigned long start_pfn, /* * get_node_active_region - Return active region containing start_pfn + * Active range returned is empty if none found. * @start_pfn: The page to return the region for. * @node_ar: Returned set to the active region containing start_pfn */ @@ -126,6 +127,7 @@ static void __init get_node_active_region(unsigned long start_pfn, node_ar->nid = nid; node_ar->start_pfn = start_pfn; + node_ar->end_pfn = start_pfn; work_with_active_regions(nid, get_active_region_work_fn, node_ar); } @@ -526,12 +528,10 @@ static unsigned long __init numa_enforce_memory_limit(unsigned long start, /* * We use lmb_end_of_DRAM() in here instead of memory_limit because * we've already adjusted it for the limit and it takes care of - * having memory holes below the limit. + * having memory holes below the limit. Also, in the case of + * iommu_is_off, memory_limit is not set but is implicitly enforced. */ - if (! memory_limit) - return size; - if (start + size <= lmb_end_of_DRAM()) return size; @@ -933,18 +933,20 @@ void __init do_init_bootmem(void) struct node_active_region node_ar; get_node_active_region(start_pfn, &node_ar); - while (start_pfn < end_pfn) { + while (start_pfn < end_pfn && + node_ar.start_pfn < node_ar.end_pfn) { + unsigned long reserve_size = size; /* * if reserved region extends past active region * then trim size to active region */ if (end_pfn > node_ar.end_pfn) - size = (node_ar.end_pfn << PAGE_SHIFT) + reserve_size = (node_ar.end_pfn << PAGE_SHIFT) - (start_pfn << PAGE_SHIFT); - dbg("reserve_bootmem %lx %lx nid=%d\n", physbase, size, - node_ar.nid); + dbg("reserve_bootmem %lx %lx nid=%d\n", physbase, + reserve_size, node_ar.nid); reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase, - size, BOOTMEM_DEFAULT); + reserve_size, BOOTMEM_DEFAULT); /* * if reserved region is contained in the active region * then done. @@ -959,6 +961,7 @@ void __init do_init_bootmem(void) */ start_pfn = node_ar.end_pfn; physbase = start_pfn << PAGE_SHIFT; + size = size - reserve_size; get_node_active_region(start_pfn, &node_ar); } diff --git a/arch/powerpc/oprofile/cell/pr_util.h b/arch/powerpc/oprofile/cell/pr_util.h index 22e4e8d4eb2..628009c0195 100644 --- a/arch/powerpc/oprofile/cell/pr_util.h +++ b/arch/powerpc/oprofile/cell/pr_util.h @@ -24,6 +24,11 @@ #define SKIP_GENERIC_SYNC 0 #define SYNC_START_ERROR -1 #define DO_GENERIC_SYNC 1 +#define SPUS_PER_NODE 8 +#define DEFAULT_TIMER_EXPIRE (HZ / 10) + +extern struct delayed_work spu_work; +extern int spu_prof_running; struct spu_overlay_info { /* map of sections within an SPU overlay */ unsigned int vma; /* SPU virtual memory address from elf */ @@ -62,6 +67,14 @@ struct vma_to_fileoffset_map { /* map of sections within an SPU program */ }; +struct spu_buffer { + int last_guard_val; + int ctx_sw_seen; + unsigned long *buff; + unsigned int head, tail; +}; + + /* The three functions below are for maintaining and accessing * the vma-to-fileoffset map. */ diff --git a/arch/powerpc/oprofile/cell/spu_profiler.c b/arch/powerpc/oprofile/cell/spu_profiler.c index 380d7e21753..6edaebd5099 100644 --- a/arch/powerpc/oprofile/cell/spu_profiler.c +++ b/arch/powerpc/oprofile/cell/spu_profiler.c @@ -23,12 +23,11 @@ static u32 *samples; -static int spu_prof_running; +int spu_prof_running; static unsigned int profiling_interval; #define NUM_SPU_BITS_TRBUF 16 #define SPUS_PER_TB_ENTRY 4 -#define SPUS_PER_NODE 8 #define SPU_PC_MASK 0xFFFF @@ -208,6 +207,7 @@ int start_spu_profiling(unsigned int cycles_reset) spu_prof_running = 1; hrtimer_start(&timer, kt, HRTIMER_MODE_REL); + schedule_delayed_work(&spu_work, DEFAULT_TIMER_EXPIRE); return 0; } diff --git a/arch/powerpc/oprofile/cell/spu_task_sync.c b/arch/powerpc/oprofile/cell/spu_task_sync.c index 2a9b4a04932..2949126d28d 100644 --- a/arch/powerpc/oprofile/cell/spu_task_sync.c +++ b/arch/powerpc/oprofile/cell/spu_task_sync.c @@ -35,7 +35,102 @@ static DEFINE_SPINLOCK(buffer_lock); static DEFINE_SPINLOCK(cache_lock); static int num_spu_nodes; int spu_prof_num_nodes; -int last_guard_val[MAX_NUMNODES * 8]; + +struct spu_buffer spu_buff[MAX_NUMNODES * SPUS_PER_NODE]; +struct delayed_work spu_work; +static unsigned max_spu_buff; + +static void spu_buff_add(unsigned long int value, int spu) +{ + /* spu buff is a circular buffer. Add entries to the + * head. Head is the index to store the next value. + * The buffer is full when there is one available entry + * in the queue, i.e. head and tail can't be equal. + * That way we can tell the difference between the + * buffer being full versus empty. + * + * ASSUPTION: the buffer_lock is held when this function + * is called to lock the buffer, head and tail. + */ + int full = 1; + + if (spu_buff[spu].head >= spu_buff[spu].tail) { + if ((spu_buff[spu].head - spu_buff[spu].tail) + < (max_spu_buff - 1)) + full = 0; + + } else if (spu_buff[spu].tail > spu_buff[spu].head) { + if ((spu_buff[spu].tail - spu_buff[spu].head) + > 1) + full = 0; + } + + if (!full) { + spu_buff[spu].buff[spu_buff[spu].head] = value; + spu_buff[spu].head++; + + if (spu_buff[spu].head >= max_spu_buff) + spu_buff[spu].head = 0; + } else { + /* From the user's perspective make the SPU buffer + * size management/overflow look like we are using + * per cpu buffers. The user uses the same + * per cpu parameter to adjust the SPU buffer size. + * Increment the sample_lost_overflow to inform + * the user the buffer size needs to be increased. + */ + oprofile_cpu_buffer_inc_smpl_lost(); + } +} + +/* This function copies the per SPU buffers to the + * OProfile kernel buffer. + */ +void sync_spu_buff(void) +{ + int spu; + unsigned long flags; + int curr_head; + + for (spu = 0; spu < num_spu_nodes; spu++) { + /* In case there was an issue and the buffer didn't + * get created skip it. + */ + if (spu_buff[spu].buff == NULL) + continue; + + /* Hold the lock to make sure the head/tail + * doesn't change while spu_buff_add() is + * deciding if the buffer is full or not. + * Being a little paranoid. + */ + spin_lock_irqsave(&buffer_lock, flags); + curr_head = spu_buff[spu].head; + spin_unlock_irqrestore(&buffer_lock, flags); + + /* Transfer the current contents to the kernel buffer. + * data can still be added to the head of the buffer. + */ + oprofile_put_buff(spu_buff[spu].buff, + spu_buff[spu].tail, + curr_head, max_spu_buff); + + spin_lock_irqsave(&buffer_lock, flags); + spu_buff[spu].tail = curr_head; + spin_unlock_irqrestore(&buffer_lock, flags); + } + +} + +static void wq_sync_spu_buff(struct work_struct *work) +{ + /* move data from spu buffers to kernel buffer */ + sync_spu_buff(); + + /* only reschedule if profiling is not done */ + if (spu_prof_running) + schedule_delayed_work(&spu_work, DEFAULT_TIMER_EXPIRE); +} /* Container for caching information about an active SPU task. */ struct cached_info { @@ -305,14 +400,21 @@ static int process_context_switch(struct spu *spu, unsigned long objectId) /* Record context info in event buffer */ spin_lock_irqsave(&buffer_lock, flags); - add_event_entry(ESCAPE_CODE); - add_event_entry(SPU_CTX_SWITCH_CODE); - add_event_entry(spu->number); - add_event_entry(spu->pid); - add_event_entry(spu->tgid); - add_event_entry(app_dcookie); - add_event_entry(spu_cookie); - add_event_entry(offset); + spu_buff_add(ESCAPE_CODE, spu->number); + spu_buff_add(SPU_CTX_SWITCH_CODE, spu->number); + spu_buff_add(spu->number, spu->number); + spu_buff_add(spu->pid, spu->number); + spu_buff_add(spu->tgid, spu->number); + spu_buff_add(app_dcookie, spu->number); + spu_buff_add(spu_cookie, spu->number); + spu_buff_add(offset, spu->number); + + /* Set flag to indicate SPU PC data can now be written out. If + * the SPU program counter data is seen before an SPU context + * record is seen, the postprocessing will fail. + */ + spu_buff[spu->number].ctx_sw_seen = 1; + spin_unlock_irqrestore(&buffer_lock, flags); smp_wmb(); /* insure spu event buffer updates are written */ /* don't want entries intermingled... */ @@ -360,6 +462,47 @@ static int number_of_online_nodes(void) return nodes; } +static int oprofile_spu_buff_create(void) +{ + int spu; + + max_spu_buff = oprofile_get_cpu_buffer_size(); + + for (spu = 0; spu < num_spu_nodes; spu++) { + /* create circular buffers to store the data in. + * use locks to manage accessing the buffers + */ + spu_buff[spu].head = 0; + spu_buff[spu].tail = 0; + + /* + * Create a buffer for each SPU. Can't reliably + * create a single buffer for all spus due to not + * enough contiguous kernel memory. + */ + + spu_buff[spu].buff = kzalloc((max_spu_buff + * sizeof(unsigned long)), + GFP_KERNEL); + + if (!spu_buff[spu].buff) { + printk(KERN_ERR "SPU_PROF: " + "%s, line %d: oprofile_spu_buff_create " + "failed to allocate spu buffer %d.\n", + __func__, __LINE__, spu); + + /* release the spu buffers that have been allocated */ + while (spu >= 0) { + kfree(spu_buff[spu].buff); + spu_buff[spu].buff = 0; + spu--; + } + return -ENOMEM; + } + } + return 0; +} + /* The main purpose of this function is to synchronize * OProfile with SPUFS by registering to be notified of * SPU task switches. @@ -372,20 +515,35 @@ static int number_of_online_nodes(void) */ int spu_sync_start(void) { - int k; + int spu; int ret = SKIP_GENERIC_SYNC; int register_ret; unsigned long flags = 0; spu_prof_num_nodes = number_of_online_nodes(); num_spu_nodes = spu_prof_num_nodes * 8; + INIT_DELAYED_WORK(&spu_work, wq_sync_spu_buff); + + /* create buffer for storing the SPU data to put in + * the kernel buffer. + */ + ret = oprofile_spu_buff_create(); + if (ret) + goto out; spin_lock_irqsave(&buffer_lock, flags); - add_event_entry(ESCAPE_CODE); - add_event_entry(SPU_PROFILING_CODE); - add_event_entry(num_spu_nodes); + for (spu = 0; spu < num_spu_nodes; spu++) { + spu_buff_add(ESCAPE_CODE, spu); + spu_buff_add(SPU_PROFILING_CODE, spu); + spu_buff_add(num_spu_nodes, spu); + } spin_unlock_irqrestore(&buffer_lock, flags); + for (spu = 0; spu < num_spu_nodes; spu++) { + spu_buff[spu].ctx_sw_seen = 0; + spu_buff[spu].last_guard_val = 0; + } + /* Register for SPU events */ register_ret = spu_switch_event_register(&spu_active); if (register_ret) { @@ -393,8 +551,6 @@ int spu_sync_start(void) goto out; } - for (k = 0; k < (MAX_NUMNODES * 8); k++) - last_guard_val[k] = 0; pr_debug("spu_sync_start -- running.\n"); out: return ret; @@ -446,13 +602,20 @@ void spu_sync_buffer(int spu_num, unsigned int *samples, * use. We need to discard samples taken during the time * period which an overlay occurs (i.e., guard value changes). */ - if (grd_val && grd_val != last_guard_val[spu_num]) { - last_guard_val[spu_num] = grd_val; + if (grd_val && grd_val != spu_buff[spu_num].last_guard_val) { + spu_buff[spu_num].last_guard_val = grd_val; /* Drop the rest of the samples. */ break; } - add_event_entry(file_offset | spu_num_shifted); + /* We must ensure that the SPU context switch has been written + * out before samples for the SPU. Otherwise, the SPU context + * information is not available and the postprocessing of the + * SPU PC will fail with no available anonymous map information. + */ + if (spu_buff[spu_num].ctx_sw_seen) + spu_buff_add((file_offset | spu_num_shifted), + spu_num); } spin_unlock(&buffer_lock); out: @@ -463,20 +626,41 @@ out: int spu_sync_stop(void) { unsigned long flags = 0; - int ret = spu_switch_event_unregister(&spu_active); - if (ret) { + int ret; + int k; + + ret = spu_switch_event_unregister(&spu_active); + + if (ret) printk(KERN_ERR "SPU_PROF: " - "%s, line %d: spu_switch_event_unregister returned %d\n", - __func__, __LINE__, ret); - goto out; - } + "%s, line %d: spu_switch_event_unregister " \ + "returned %d\n", + __func__, __LINE__, ret); + + /* flush any remaining data in the per SPU buffers */ + sync_spu_buff(); spin_lock_irqsave(&cache_lock, flags); ret = release_cached_info(RELEASE_ALL); spin_unlock_irqrestore(&cache_lock, flags); -out: + + /* remove scheduled work queue item rather then waiting + * for every queued entry to execute. Then flush pending + * system wide buffer to event buffer. + */ + cancel_delayed_work(&spu_work); + + for (k = 0; k < num_spu_nodes; k++) { + spu_buff[k].ctx_sw_seen = 0; + + /* + * spu_sys_buff will be null if there was a problem + * allocating the buffer. Only delete if it exists. + */ + kfree(spu_buff[k].buff); + spu_buff[k].buff = 0; + } pr_debug("spu_sync_stop -- done.\n"); return ret; } - diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig index a9260e21451..65730275e01 100644 --- a/arch/powerpc/platforms/40x/Kconfig +++ b/arch/powerpc/platforms/40x/Kconfig @@ -14,6 +14,15 @@ # help # This option enables support for the CPCI405 board. +config ACADIA + bool "Acadia" + depends on 40x + default n + select PPC40x_SIMPLE + select 405EZ + help + This option enables support for the AMCC 405EZ Acadia evaluation board. + config EP405 bool "EP405/EP405PC" depends on 40x @@ -23,6 +32,14 @@ config EP405 help This option enables support for the EP405/EP405PC boards. +config HCU4 + bool "Hcu4" + depends on 40x + default y + select 405GPR + help + This option enables support for the Nestal Maschinen HCU4 board. + config KILAUEA bool "Kilauea" depends on 40x @@ -93,6 +110,13 @@ config XILINX_VIRTEX_GENERIC_BOARD Most Virtex designs should use this unless it needs to do some special configuration at board probe time. +config PPC40x_SIMPLE + bool "Simple PowerPC 40x board support" + depends on 40x + default n + help + This option enables the simple PowerPC 40x platform support. + # 40x specific CPU modules, selected based on the board above. config NP405H bool @@ -118,6 +142,12 @@ config 405EX select IBM_NEW_EMAC_EMAC4 select IBM_NEW_EMAC_RGMII +config 405EZ + bool + select IBM_NEW_EMAC_NO_FLOW_CTRL + select IBM_NEW_EMAC_MAL_CLR_ICINTSTAT + select IBM_NEW_EMAC_MAL_COMMON_ERR + config 405GPR bool @@ -139,6 +169,14 @@ config STB03xxx select IBM405_ERR77 select IBM405_ERR51 +config PPC4xx_GPIO + bool "PPC4xx GPIO support" + depends on 40x + select ARCH_REQUIRE_GPIOLIB + select GENERIC_GPIO + help + Enable gpiolib support for ppc40x based boards + # 40x errata/workaround config symbols, selected by the CPU models above # All 405-based cores up until the 405GPR and 405EP have this errata. diff --git a/arch/powerpc/platforms/40x/Makefile b/arch/powerpc/platforms/40x/Makefile index 5533a5c8ce4..9bab76a652a 100644 --- a/arch/powerpc/platforms/40x/Makefile +++ b/arch/powerpc/platforms/40x/Makefile @@ -1,5 +1,7 @@ obj-$(CONFIG_KILAUEA) += kilauea.o +obj-$(CONFIG_HCU4) += hcu4.o obj-$(CONFIG_MAKALU) += makalu.o obj-$(CONFIG_WALNUT) += walnut.o obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD) += virtex.o obj-$(CONFIG_EP405) += ep405.o +obj-$(CONFIG_PPC40x_SIMPLE) += ppc40x_simple.o diff --git a/arch/powerpc/platforms/40x/hcu4.c b/arch/powerpc/platforms/40x/hcu4.c new file mode 100644 index 00000000000..60b2afecab7 --- /dev/null +++ b/arch/powerpc/platforms/40x/hcu4.c @@ -0,0 +1,61 @@ +/* + * Architecture- / platform-specific boot-time initialization code for + * IBM PowerPC 4xx based boards. Adapted from original + * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek + * <dan@net4x.com>. + * + * Copyright(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu> + * + * Rewritten and ported to the merged powerpc tree: + * Copyright 2007 IBM Corporation + * Josh Boyer <jwboyer@linux.vnet.ibm.com> + * + * 2002 (c) MontaVista, Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include <linux/init.h> +#include <linux/of_platform.h> + +#include <asm/machdep.h> +#include <asm/prom.h> +#include <asm/udbg.h> +#include <asm/time.h> +#include <asm/uic.h> +#include <asm/ppc4xx.h> + +static __initdata struct of_device_id hcu4_of_bus[] = { + { .compatible = "ibm,plb3", }, + { .compatible = "ibm,opb", }, + { .compatible = "ibm,ebc", }, + {}, +}; + +static int __init hcu4_device_probe(void) +{ + of_platform_bus_probe(NULL, hcu4_of_bus, NULL); + return 0; +} +machine_device_initcall(hcu4, hcu4_device_probe); + +static int __init hcu4_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "netstal,hcu4")) + return 0; + + return 1; +} + +define_machine(hcu4) { + .name = "HCU4", + .probe = hcu4_probe, + .progress = udbg_progress, + .init_IRQ = uic_init_tree, + .get_irq = uic_get_irq, + .restart = ppc4xx_reset_system, + .calibrate_decr = generic_calibrate_decr, +}; diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c new file mode 100644 index 00000000000..4498a86b46c --- /dev/null +++ b/arch/powerpc/platforms/40x/ppc40x_simple.c @@ -0,0 +1,80 @@ +/* + * Generic PowerPC 40x platform support + * + * Copyright 2008 IBM Corporation + * + * 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; version 2 of the License. + * + * This implements simple platform support for PowerPC 44x chips. This is + * mostly used for eval boards or other simple and "generic" 44x boards. If + * your board has custom functions or hardware, then you will likely want to + * implement your own board.c file to accommodate it. + */ + +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <asm/ppc4xx.h> +#include <asm/prom.h> +#include <asm/time.h> +#include <asm/udbg.h> +#include <asm/uic.h> + +#include <linux/init.h> +#include <linux/of_platform.h> + +static __initdata struct of_device_id ppc40x_of_bus[] = { + { .compatible = "ibm,plb3", }, + { .compatible = "ibm,plb4", }, + { .compatible = "ibm,opb", }, + { .compatible = "ibm,ebc", }, + { .compatible = "simple-bus", }, + {}, +}; + +static int __init ppc40x_device_probe(void) +{ + of_platform_bus_probe(NULL, ppc40x_of_bus, NULL); + + return 0; +} +machine_device_initcall(ppc40x_simple, ppc40x_device_probe); + +/* This is the list of boards that can be supported by this simple + * platform code. This does _not_ mean the boards are compatible, + * as they most certainly are not from a device tree perspective. + * However, their differences are handled by the device tree and the + * drivers and therefore they don't need custom board support files. + * + * Again, if your board needs to do things differently then create a + * board.c file for it rather than adding it to this list. + */ +static char *board[] __initdata = { + "amcc,acadia" +}; + +static int __init ppc40x_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + int i = 0; + + for (i = 0; i < ARRAY_SIZE(board); i++) { + if (of_flat_dt_is_compatible(root, board[i])) { + ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; + return 1; + } + } + + return 0; +} + +define_machine(ppc40x_simple) { + .name = "PowerPC 40x Platform", + .probe = ppc40x_probe, + .progress = udbg_progress, + .init_IRQ = uic_init_tree, + .get_irq = uic_get_irq, + .restart = ppc4xx_reset_system, + .calibrate_decr = generic_calibrate_decr, +}; diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 79c1154f88d..3496bc05058 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -167,6 +167,14 @@ config PPC44x_SIMPLE help This option enables the simple PowerPC 44x platform support. +config PPC4xx_GPIO + bool "PPC4xx GPIO support" + depends on 44x + select ARCH_REQUIRE_GPIOLIB + select GENERIC_GPIO + help + Enable gpiolib support for ppc440 based boards + # 44x specific CPU modules, selected based on the board above. config 440EP bool diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c index 044b4e6e874..ae7c34f37e1 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c @@ -99,11 +99,14 @@ mpc5200_setup_xlb_arbiter(void) out_be32(&xlb->master_pri_enable, 0xff); out_be32(&xlb->master_priority, 0x11111111); - /* Disable XLB pipelining + /* + * Disable XLB pipelining * (cfr errate 292. We could do this only just before ATA PIO * transaction and re-enable it afterwards ...) + * Not needed on MPC5200B. */ - out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS); + if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR) + out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS); iounmap(xlb); } diff --git a/arch/powerpc/platforms/85xx/ksi8560.c b/arch/powerpc/platforms/85xx/ksi8560.c index 8a3b117b6ce..81cee7bbf2d 100644 --- a/arch/powerpc/platforms/85xx/ksi8560.c +++ b/arch/powerpc/platforms/85xx/ksi8560.c @@ -193,7 +193,6 @@ static void __init ksi8560_setup_arch(void) static void ksi8560_show_cpuinfo(struct seq_file *m) { uint pvid, svid, phid1; - uint memsize = total_memory; pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); @@ -215,9 +214,6 @@ static void ksi8560_show_cpuinfo(struct seq_file *m) /* Display cpu Pll setting */ phid1 = mfspr(SPRN_HID1); seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } static struct of_device_id __initdata of_bus_ids[] = { diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 0293e3d3580..21f009023e2 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c @@ -207,7 +207,6 @@ static void __init mpc85xx_ads_setup_arch(void) static void mpc85xx_ads_show_cpuinfo(struct seq_file *m) { uint pvid, svid, phid1; - uint memsize = total_memory; pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); @@ -219,9 +218,6 @@ static void mpc85xx_ads_show_cpuinfo(struct seq_file *m) /* Display cpu Pll setting */ phid1 = mfspr(SPRN_HID1); seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } static struct of_device_id __initdata of_bus_ids[] = { diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 50d7ea8f922..aeb6a5bc552 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -307,7 +307,6 @@ static void __init mpc85xx_cds_setup_arch(void) static void mpc85xx_cds_show_cpuinfo(struct seq_file *m) { uint pvid, svid, phid1; - uint memsize = total_memory; pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); @@ -320,9 +319,6 @@ static void mpc85xx_cds_show_cpuinfo(struct seq_file *m) /* Display cpu Pll setting */ phid1 = mfspr(SPRN_HID1); seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } diff --git a/arch/powerpc/platforms/85xx/sbc8548.c b/arch/powerpc/platforms/85xx/sbc8548.c index b9246ea0928..7ec77ce12da 100644 --- a/arch/powerpc/platforms/85xx/sbc8548.c +++ b/arch/powerpc/platforms/85xx/sbc8548.c @@ -136,7 +136,6 @@ static void __init sbc8548_setup_arch(void) static void sbc8548_show_cpuinfo(struct seq_file *m) { uint pvid, svid, phid1; - uint memsize = total_memory; pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); @@ -149,9 +148,6 @@ static void sbc8548_show_cpuinfo(struct seq_file *m) /* Display cpu Pll setting */ phid1 = mfspr(SPRN_HID1); seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } static struct of_device_id __initdata of_bus_ids[] = { diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c index 0c9a856f66b..472f254a19d 100644 --- a/arch/powerpc/platforms/85xx/sbc8560.c +++ b/arch/powerpc/platforms/85xx/sbc8560.c @@ -194,7 +194,6 @@ static void __init sbc8560_setup_arch(void) static void sbc8560_show_cpuinfo(struct seq_file *m) { uint pvid, svid, phid1; - uint memsize = total_memory; pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); @@ -206,9 +205,6 @@ static void sbc8560_show_cpuinfo(struct seq_file *m) /* Display cpu Pll setting */ phid1 = mfspr(SPRN_HID1); seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } static struct of_device_id __initdata of_bus_ids[] = { diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c index 18499d7c9d9..0cca8f5cb27 100644 --- a/arch/powerpc/platforms/85xx/stx_gp3.c +++ b/arch/powerpc/platforms/85xx/stx_gp3.c @@ -130,7 +130,6 @@ static void __init stx_gp3_setup_arch(void) static void stx_gp3_show_cpuinfo(struct seq_file *m) { uint pvid, svid, phid1; - uint memsize = total_memory; pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); @@ -142,9 +141,6 @@ static void stx_gp3_show_cpuinfo(struct seq_file *m) /* Display cpu Pll setting */ phid1 = mfspr(SPRN_HID1); seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } static struct of_device_id __initdata of_bus_ids[] = { diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c index d850880d696..2933a8e827d 100644 --- a/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/arch/powerpc/platforms/85xx/tqm85xx.c @@ -138,7 +138,6 @@ static void __init tqm85xx_setup_arch(void) static void tqm85xx_show_cpuinfo(struct seq_file *m) { uint pvid, svid, phid1; - uint memsize = total_memory; pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); @@ -150,9 +149,6 @@ static void tqm85xx_show_cpuinfo(struct seq_file *m) /* Display cpu Pll setting */ phid1 = mfspr(SPRN_HID1); seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } static struct of_device_id __initdata of_bus_ids[] = { diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c index 821c45fac18..fb371f5ce13 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc610.c +++ b/arch/powerpc/platforms/86xx/gef_sbc610.c @@ -127,7 +127,6 @@ static unsigned int gef_sbc610_get_fpga_rev(void) static void gef_sbc610_show_cpuinfo(struct seq_file *m) { - uint memsize = total_memory; uint svid = mfspr(SPRN_SVR); seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n"); @@ -137,7 +136,6 @@ static void gef_sbc610_show_cpuinfo(struct seq_file *m) seq_printf(m, "FPGA Revision\t: %u\n", gef_sbc610_get_fpga_rev()); seq_printf(m, "SVR\t\t: 0x%x\n", svid); - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } static void __init gef_sbc610_nec_fixup(struct pci_dev *pdev) diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 2672829a71d..27e0e682d8e 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -101,13 +101,11 @@ mpc86xx_hpcn_setup_arch(void) static void mpc86xx_hpcn_show_cpuinfo(struct seq_file *m) { - uint memsize = total_memory; uint svid = mfspr(SPRN_SVR); seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); seq_printf(m, "SVR\t\t: 0x%x\n", svid); - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c index da677a74e2d..5fd7ed40986 100644 --- a/arch/powerpc/platforms/86xx/sbc8641d.c +++ b/arch/powerpc/platforms/86xx/sbc8641d.c @@ -63,13 +63,11 @@ sbc8641_setup_arch(void) static void sbc8641_show_cpuinfo(struct seq_file *m) { - uint memsize = total_memory; uint svid = mfspr(SPRN_SVR); seq_printf(m, "Vendor\t\t: Wind River Systems\n"); seq_printf(m, "SVR\t\t: 0x%x\n", svid); - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index 2a14b052abc..665af1c4195 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c @@ -21,6 +21,7 @@ #include <asm/machdep.h> #include <asm/rtas.h> #include <asm/cell-regs.h> +#include <asm/kdump.h> #include "ras.h" @@ -111,9 +112,8 @@ static int __init cbe_ptcal_enable_on_node(int nid, int order) int ret = -ENOMEM; unsigned long addr; -#ifdef CONFIG_CRASH_DUMP - rtas_call(ptcal_stop_tok, 1, 1, NULL, nid); -#endif + if (__kdump_flag) + rtas_call(ptcal_stop_tok, 1, 1, NULL, nid); area = kmalloc(sizeof(*area), GFP_KERNEL); if (!area) diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c index efb3964457b..c0d86e1f56e 100644 --- a/arch/powerpc/platforms/cell/smp.c +++ b/arch/powerpc/platforms/cell/smp.c @@ -54,8 +54,8 @@ #endif /* - * The primary thread of each non-boot processor is recorded here before - * smp init. + * The Primary thread of each non-boot processor was started from the OF client + * interface by prom_hold_cpus and is spinning on secondary_hold_spinloop. */ static cpumask_t of_spin_map; @@ -208,11 +208,7 @@ void __init smp_init_cell(void) /* Mark threads which are still spinning in hold loops. */ if (cpu_has_feature(CPU_FTR_SMT)) { for_each_present_cpu(i) { - if (i % 2 == 0) - /* - * Even-numbered logical cpus correspond to - * primary threads. - */ + if (cpu_thread_in_core(i) == 0) cpu_set(i, of_spin_map); } } else { diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 010a51f5979..b73c369cc6f 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -548,6 +548,11 @@ spufs_regs_read(struct file *file, char __user *buffer, int ret; struct spu_context *ctx = file->private_data; + /* pre-check for file position: if we'd return EOF, there's no point + * causing a deschedule */ + if (*pos >= sizeof(ctx->csa.lscsa->gprs)) + return 0; + ret = spu_acquire_saved(ctx); if (ret) return ret; @@ -2426,38 +2431,49 @@ static inline int spufs_switch_log_avail(struct spu_context *ctx) static int spufs_switch_log_open(struct inode *inode, struct file *file) { struct spu_context *ctx = SPUFS_I(inode)->i_ctx; + int rc; + + rc = spu_acquire(ctx); + if (rc) + return rc; - /* - * We (ab-)use the mapping_lock here because it serves the similar - * purpose for synchronizing open/close elsewhere. Maybe it should - * be renamed eventually. - */ - mutex_lock(&ctx->mapping_lock); if (ctx->switch_log) { - spin_lock(&ctx->switch_log->lock); - ctx->switch_log->head = 0; - ctx->switch_log->tail = 0; - spin_unlock(&ctx->switch_log->lock); - } else { - /* - * We allocate the switch log data structures on first open. - * They will never be free because we assume a context will - * be traced until it goes away. - */ - ctx->switch_log = kzalloc(sizeof(struct switch_log) + - SWITCH_LOG_BUFSIZE * sizeof(struct switch_log_entry), - GFP_KERNEL); - if (!ctx->switch_log) - goto out; - spin_lock_init(&ctx->switch_log->lock); - init_waitqueue_head(&ctx->switch_log->wait); + rc = -EBUSY; + goto out; } - mutex_unlock(&ctx->mapping_lock); + + ctx->switch_log = kmalloc(sizeof(struct switch_log) + + SWITCH_LOG_BUFSIZE * sizeof(struct switch_log_entry), + GFP_KERNEL); + + if (!ctx->switch_log) { + rc = -ENOMEM; + goto out; + } + + ctx->switch_log->head = ctx->switch_log->tail = 0; + init_waitqueue_head(&ctx->switch_log->wait); + rc = 0; + +out: + spu_release(ctx); + return rc; +} + +static int spufs_switch_log_release(struct inode *inode, struct file *file) +{ + struct spu_context *ctx = SPUFS_I(inode)->i_ctx; + int rc; + + rc = spu_acquire(ctx); + if (rc) + return rc; + + kfree(ctx->switch_log); + ctx->switch_log = NULL; + spu_release(ctx); return 0; - out: - mutex_unlock(&ctx->mapping_lock); - return -ENOMEM; } static int switch_log_sprint(struct spu_context *ctx, char *tbuf, int n) @@ -2485,42 +2501,54 @@ static ssize_t spufs_switch_log_read(struct file *file, char __user *buf, if (!buf || len < 0) return -EINVAL; + error = spu_acquire(ctx); + if (error) + return error; + while (cnt < len) { char tbuf[128]; int width; - if (file->f_flags & O_NONBLOCK) { - if (spufs_switch_log_used(ctx) <= 0) - return cnt ? cnt : -EAGAIN; - } else { - /* Wait for data in buffer */ - error = wait_event_interruptible(ctx->switch_log->wait, - spufs_switch_log_used(ctx) > 0); - if (error) + if (spufs_switch_log_used(ctx) == 0) { + if (cnt > 0) { + /* If there's data ready to go, we can + * just return straight away */ + break; + + } else if (file->f_flags & O_NONBLOCK) { + error = -EAGAIN; break; - } - spin_lock(&ctx->switch_log->lock); - if (ctx->switch_log->head == ctx->switch_log->tail) { - /* multiple readers race? */ - spin_unlock(&ctx->switch_log->lock); - continue; + } else { + /* spufs_wait will drop the mutex and + * re-acquire, but since we're in read(), the + * file cannot be _released (and so + * ctx->switch_log is stable). + */ + error = spufs_wait(ctx->switch_log->wait, + spufs_switch_log_used(ctx) > 0); + + /* On error, spufs_wait returns without the + * state mutex held */ + if (error) + return error; + + /* We may have had entries read from underneath + * us while we dropped the mutex in spufs_wait, + * so re-check */ + if (spufs_switch_log_used(ctx) == 0) + continue; + } } width = switch_log_sprint(ctx, tbuf, sizeof(tbuf)); - if (width < len) { + if (width < len) ctx->switch_log->tail = (ctx->switch_log->tail + 1) % SWITCH_LOG_BUFSIZE; - } - - spin_unlock(&ctx->switch_log->lock); - - /* - * If the record is greater than space available return - * partial buffer (so far) - */ - if (width >= len) + else + /* If the record is greater than space available return + * partial buffer (so far) */ break; error = copy_to_user(buf + cnt, tbuf, width); @@ -2529,6 +2557,8 @@ static ssize_t spufs_switch_log_read(struct file *file, char __user *buf, cnt += width; } + spu_release(ctx); + return cnt == 0 ? error : cnt; } @@ -2537,29 +2567,41 @@ static unsigned int spufs_switch_log_poll(struct file *file, poll_table *wait) struct inode *inode = file->f_path.dentry->d_inode; struct spu_context *ctx = SPUFS_I(inode)->i_ctx; unsigned int mask = 0; + int rc; poll_wait(file, &ctx->switch_log->wait, wait); + rc = spu_acquire(ctx); + if (rc) + return rc; + if (spufs_switch_log_used(ctx) > 0) mask |= POLLIN; + spu_release(ctx); + return mask; } static const struct file_operations spufs_switch_log_fops = { - .owner = THIS_MODULE, - .open = spufs_switch_log_open, - .read = spufs_switch_log_read, - .poll = spufs_switch_log_poll, + .owner = THIS_MODULE, + .open = spufs_switch_log_open, + .read = spufs_switch_log_read, + .poll = spufs_switch_log_poll, + .release = spufs_switch_log_release, }; +/** + * Log a context switch event to a switch log reader. + * + * Must be called with ctx->state_mutex held. + */ void spu_switch_log_notify(struct spu *spu, struct spu_context *ctx, u32 type, u32 val) { if (!ctx->switch_log) return; - spin_lock(&ctx->switch_log->lock); if (spufs_switch_log_avail(ctx) > 1) { struct switch_log_entry *p; @@ -2573,7 +2615,6 @@ void spu_switch_log_notify(struct spu *spu, struct spu_context *ctx, ctx->switch_log->head = (ctx->switch_log->head + 1) % SWITCH_LOG_BUFSIZE; } - spin_unlock(&ctx->switch_log->lock); wake_up(&ctx->switch_log->wait); } diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index c9bb7cfd3dc..c58bd36b0c5 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -249,6 +249,7 @@ static int spu_run_fini(struct spu_context *ctx, u32 *npc, spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); clear_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags); + spu_switch_log_notify(NULL, ctx, SWITCH_LOG_EXIT, *status); spu_release(ctx); if (signal_pending(current)) @@ -417,8 +418,6 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event) ret = spu_run_fini(ctx, npc, &status); spu_yield(ctx); - spu_switch_log_notify(NULL, ctx, SWITCH_LOG_EXIT, status); - if ((status & SPU_STATUS_STOPPED_BY_STOP) && (((status >> SPU_STOP_STATUS_SHIFT) & 0x3f00) == 0x2100)) ctx->stats.libassist++; diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 67595bc380d..2ad914c4749 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -312,6 +312,15 @@ static struct spu *aff_ref_location(struct spu_context *ctx, int mem_aff, */ node = cpu_to_node(raw_smp_processor_id()); for (n = 0; n < MAX_NUMNODES; n++, node++) { + /* + * "available_spus" counts how many spus are not potentially + * going to be used by other affinity gangs whose reference + * context is already in place. Although this code seeks to + * avoid having affinity gangs with a summed amount of + * contexts bigger than the amount of spus in the node, + * this may happen sporadically. In this case, available_spus + * becomes negative, which is harmless. + */ int available_spus; node = (node < MAX_NUMNODES) ? node : 0; @@ -321,12 +330,10 @@ static struct spu *aff_ref_location(struct spu_context *ctx, int mem_aff, available_spus = 0; mutex_lock(&cbe_spu_info[node].list_mutex); list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) { - if (spu->ctx && spu->ctx->gang - && spu->ctx->aff_offset == 0) - available_spus -= - (spu->ctx->gang->contexts - 1); - else - available_spus++; + if (spu->ctx && spu->ctx->gang && !spu->ctx->aff_offset + && spu->ctx->gang->aff_ref_spu) + available_spus -= spu->ctx->gang->contexts; + available_spus++; } if (available_spus < ctx->gang->contexts) { mutex_unlock(&cbe_spu_info[node].list_mutex); @@ -437,6 +444,11 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) atomic_dec(&cbe_spu_info[spu->node].reserved_spus); if (ctx->gang) + /* + * If ctx->gang->aff_sched_count is positive, SPU affinity is + * being considered in this gang. Using atomic_dec_if_positive + * allow us to skip an explicit check for affinity in this gang + */ atomic_dec_if_positive(&ctx->gang->aff_sched_count); spu_switch_notify(spu, NULL); diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 8ae8ef9dfc2..15c62d3ca12 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -65,7 +65,6 @@ enum { }; struct switch_log { - spinlock_t lock; wait_queue_head_t wait; unsigned long head; unsigned long tail; diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c index 2ece399f286..d0b1f3f4d9c 100644 --- a/arch/powerpc/platforms/cell/spufs/sputrace.c +++ b/arch/powerpc/platforms/cell/spufs/sputrace.c @@ -40,6 +40,7 @@ static DECLARE_WAIT_QUEUE_HEAD(sputrace_wait); static ktime_t sputrace_start; static unsigned long sputrace_head, sputrace_tail; static struct sputrace *sputrace_log; +static int sputrace_logging; static int sputrace_used(void) { @@ -79,6 +80,11 @@ static ssize_t sputrace_read(struct file *file, char __user *buf, char tbuf[128]; int width; + /* If we have data ready to return, don't block waiting + * for more */ + if (cnt > 0 && sputrace_used() == 0) + break; + error = wait_event_interruptible(sputrace_wait, sputrace_used() > 0); if (error) @@ -109,24 +115,49 @@ static ssize_t sputrace_read(struct file *file, char __user *buf, static int sputrace_open(struct inode *inode, struct file *file) { + int rc; + spin_lock(&sputrace_lock); + if (sputrace_logging) { + rc = -EBUSY; + goto out; + } + + sputrace_logging = 1; sputrace_head = sputrace_tail = 0; sputrace_start = ktime_get(); + rc = 0; + +out: spin_unlock(&sputrace_lock); + return rc; +} +static int sputrace_release(struct inode *inode, struct file *file) +{ + spin_lock(&sputrace_lock); + sputrace_logging = 0; + spin_unlock(&sputrace_lock); return 0; } static const struct file_operations sputrace_fops = { - .owner = THIS_MODULE, - .open = sputrace_open, - .read = sputrace_read, + .owner = THIS_MODULE, + .open = sputrace_open, + .read = sputrace_read, + .release = sputrace_release, }; static void sputrace_log_item(const char *name, struct spu_context *ctx, struct spu *spu) { spin_lock(&sputrace_lock); + + if (!sputrace_logging) { + spin_unlock(&sputrace_lock); + return; + } + if (sputrace_avail() > 1) { struct sputrace *t = sputrace_log + sputrace_head; diff --git a/arch/powerpc/platforms/embedded6xx/c2k.c b/arch/powerpc/platforms/embedded6xx/c2k.c index d0b25b8c39d..32ba0fa0ad0 100644 --- a/arch/powerpc/platforms/embedded6xx/c2k.c +++ b/arch/powerpc/platforms/embedded6xx/c2k.c @@ -116,10 +116,7 @@ static void c2k_restart(char *cmd) void c2k_show_cpuinfo(struct seq_file *m) { - uint memsize = total_memory; - seq_printf(m, "Vendor\t\t: GEFanuc\n"); - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); seq_printf(m, "coherency\t: %s\n", COHERENCY_SETTING); } diff --git a/arch/powerpc/platforms/embedded6xx/prpmc2800.c b/arch/powerpc/platforms/embedded6xx/prpmc2800.c index 5a19b9a1457..4c485e98423 100644 --- a/arch/powerpc/platforms/embedded6xx/prpmc2800.c +++ b/arch/powerpc/platforms/embedded6xx/prpmc2800.c @@ -119,10 +119,7 @@ static void prpmc2800_restart(char *cmd) void prpmc2800_show_cpuinfo(struct seq_file *m) { - uint memsize = total_memory; - seq_printf(m, "Vendor\t\t: Motorola\n"); - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); seq_printf(m, "coherency\t: %s\n", PPRPM2800_COHERENCY_SETTING); } diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 140d02a5232..a623ad256e9 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -22,6 +22,12 @@ static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size) int ret; start_pfn = base >> PAGE_SHIFT; + + if (!pfn_valid(start_pfn)) { + lmb_remove(base, lmb_size); + return 0; + } + zone = page_zone(pfn_to_page(start_pfn)); /* diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index a8c446697f9..d56491d182d 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -44,6 +44,7 @@ #include <asm/tce.h> #include <asm/ppc-pci.h> #include <asm/udbg.h> +#include <asm/kdump.h> #include "plpar_wrappers.h" @@ -291,9 +292,8 @@ static void iommu_table_setparms(struct pci_controller *phb, tbl->it_base = (unsigned long)__va(*basep); -#ifndef CONFIG_CRASH_DUMP - memset((void *)tbl->it_base, 0, *sizep); -#endif + if (!__kdump_flag) + memset((void *)tbl->it_base, 0, *sizep); tbl->it_busno = phb->bus->number; diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index e00f96baa38..1a231c389ba 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -52,8 +52,8 @@ /* - * The primary thread of each non-boot processor is recorded here before - * smp init. + * The Primary thread of each non-boot processor was started from the OF client + * interface by prom_hold_cpus and is spinning on secondary_hold_spinloop. */ static cpumask_t of_spin_map; @@ -161,8 +161,7 @@ static void __devinit smp_pSeries_kick_cpu(int nr) static int smp_pSeries_cpu_bootable(unsigned int nr) { /* Special case - we inhibit secondary thread startup - * during boot if the user requests it. Odd-numbered - * cpus are assumed to be secondary threads. + * during boot if the user requests it. */ if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT) && @@ -199,11 +198,7 @@ static void __init smp_init_pseries(void) /* Mark threads which are still spinning in hold loops. */ if (cpu_has_feature(CPU_FTR_SMT)) { for_each_present_cpu(i) { - if (i % 2 == 0) - /* - * Even-numbered logical cpus correspond to - * primary threads. - */ + if (cpu_thread_in_core(i) == 0) cpu_set(i, of_spin_map); } } else { diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index a44709a94f9..5afce115ab1 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_OF_RTC) += of_rtc.o ifeq ($(CONFIG_PCI),y) obj-$(CONFIG_4xx) += ppc4xx_pci.o endif +obj-$(CONFIG_PPC4xx_GPIO) += ppc4xx_gpio.o obj-$(CONFIG_CPM) += cpm_common.o obj-$(CONFIG_CPM2) += cpm2.o cpm2_pic.o diff --git a/arch/powerpc/sysdev/ppc4xx_gpio.c b/arch/powerpc/sysdev/ppc4xx_gpio.c new file mode 100644 index 00000000000..110efe2a54f --- /dev/null +++ b/arch/powerpc/sysdev/ppc4xx_gpio.c @@ -0,0 +1,217 @@ +/* + * PPC4xx gpio driver + * + * Copyright (c) 2008 Harris Corporation + * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix + * Copyright (c) MontaVista Software, Inc. 2008. + * + * Author: Steve Falco <sfalco@harris.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/spinlock.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_gpio.h> +#include <linux/gpio.h> +#include <linux/types.h> + +#define GPIO_MASK(gpio) (0x80000000 >> (gpio)) +#define GPIO_MASK2(gpio) (0xc0000000 >> ((gpio) * 2)) + +/* Physical GPIO register layout */ +struct ppc4xx_gpio { + __be32 or; + __be32 tcr; + __be32 osrl; + __be32 osrh; + __be32 tsrl; + __be32 tsrh; + __be32 odr; + __be32 ir; + __be32 rr1; + __be32 rr2; + __be32 rr3; + __be32 reserved1; + __be32 isr1l; + __be32 isr1h; + __be32 isr2l; + __be32 isr2h; + __be32 isr3l; + __be32 isr3h; +}; + +struct ppc4xx_gpio_chip { + struct of_mm_gpio_chip mm_gc; + spinlock_t lock; +}; + +/* + * GPIO LIB API implementation for GPIOs + * + * There are a maximum of 32 gpios in each gpio controller. + */ + +static inline struct ppc4xx_gpio_chip * +to_ppc4xx_gpiochip(struct of_mm_gpio_chip *mm_gc) +{ + return container_of(mm_gc, struct ppc4xx_gpio_chip, mm_gc); +} + +static int ppc4xx_gpio_get(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct ppc4xx_gpio __iomem *regs = mm_gc->regs; + + return in_be32(®s->ir) & GPIO_MASK(gpio); +} + +static inline void +__ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct ppc4xx_gpio __iomem *regs = mm_gc->regs; + + if (val) + setbits32(®s->or, GPIO_MASK(gpio)); + else + clrbits32(®s->or, GPIO_MASK(gpio)); +} + +static void +ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct ppc4xx_gpio_chip *chip = to_ppc4xx_gpiochip(mm_gc); + unsigned long flags; + + spin_lock_irqsave(&chip->lock, flags); + + __ppc4xx_gpio_set(gc, gpio, val); + + spin_unlock_irqrestore(&chip->lock, flags); + + pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); +} + +static int ppc4xx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct ppc4xx_gpio_chip *chip = to_ppc4xx_gpiochip(mm_gc); + struct ppc4xx_gpio __iomem *regs = mm_gc->regs; + unsigned long flags; + + spin_lock_irqsave(&chip->lock, flags); + + /* Disable open-drain function */ + clrbits32(®s->odr, GPIO_MASK(gpio)); + + /* Float the pin */ + clrbits32(®s->tcr, GPIO_MASK(gpio)); + + /* Bits 0-15 use TSRL/OSRL, bits 16-31 use TSRH/OSRH */ + if (gpio < 16) { + clrbits32(®s->osrl, GPIO_MASK2(gpio)); + clrbits32(®s->tsrl, GPIO_MASK2(gpio)); + } else { + clrbits32(®s->osrh, GPIO_MASK2(gpio)); + clrbits32(®s->tsrh, GPIO_MASK2(gpio)); + } + + spin_unlock_irqrestore(&chip->lock, flags); + + return 0; +} + +static int +ppc4xx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct ppc4xx_gpio_chip *chip = to_ppc4xx_gpiochip(mm_gc); + struct ppc4xx_gpio __iomem *regs = mm_gc->regs; + unsigned long flags; + + spin_lock_irqsave(&chip->lock, flags); + + /* First set initial value */ + __ppc4xx_gpio_set(gc, gpio, val); + + /* Disable open-drain function */ + clrbits32(®s->odr, GPIO_MASK(gpio)); + + /* Drive the pin */ + setbits32(®s->tcr, GPIO_MASK(gpio)); + + /* Bits 0-15 use TSRL, bits 16-31 use TSRH */ + if (gpio < 16) { + clrbits32(®s->osrl, GPIO_MASK2(gpio)); + clrbits32(®s->tsrl, GPIO_MASK2(gpio)); + } else { + clrbits32(®s->osrh, GPIO_MASK2(gpio)); + clrbits32(®s->tsrh, GPIO_MASK2(gpio)); + } + + spin_unlock_irqrestore(&chip->lock, flags); + + pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); + + return 0; +} + +static int __init ppc4xx_add_gpiochips(void) +{ + struct device_node *np; + + for_each_compatible_node(np, NULL, "ibm,ppc4xx-gpio") { + int ret; + struct ppc4xx_gpio_chip *ppc4xx_gc; + struct of_mm_gpio_chip *mm_gc; + struct of_gpio_chip *of_gc; + struct gpio_chip *gc; + + ppc4xx_gc = kzalloc(sizeof(*ppc4xx_gc), GFP_KERNEL); + if (!ppc4xx_gc) { + ret = -ENOMEM; + goto err; + } + + spin_lock_init(&ppc4xx_gc->lock); + + mm_gc = &ppc4xx_gc->mm_gc; + of_gc = &mm_gc->of_gc; + gc = &of_gc->gc; + + of_gc->gpio_cells = 2; + gc->ngpio = 32; + gc->direction_input = ppc4xx_gpio_dir_in; + gc->direction_output = ppc4xx_gpio_dir_out; + gc->get = ppc4xx_gpio_get; + gc->set = ppc4xx_gpio_set; + + ret = of_mm_gpiochip_add(np, mm_gc); + if (ret) + goto err; + continue; +err: + pr_err("%s: registration failed with status %d\n", + np->full_name, ret); + kfree(ppc4xx_gc); + /* try others anyway */ + } + return 0; +} +arch_initcall(ppc4xx_add_gpiochips); diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index ccf6c503fc3..d1d4dc52f64 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -36,7 +36,7 @@ void ack_bad_irq(unsigned int irq) } #ifdef CONFIG_X86_32 -# define irq_stats(x) (&per_cpu(irq_stat,x)) +# define irq_stats(x) (&per_cpu(irq_stat, x)) #else # define irq_stats(x) cpu_pda(x) #endif @@ -113,7 +113,7 @@ int show_interrupts(struct seq_file *p, void *v) if (i == 0) { seq_printf(p, " "); for_each_online_cpu(j) - seq_printf(p, "CPU%-8d",j); + seq_printf(p, "CPU%-8d", j); seq_putc(p, '\n'); } diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index a213260b51e..6c873dceb17 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -64,7 +64,12 @@ choice default XTENSA_VARIANT_FSF config XTENSA_VARIANT_FSF - bool "fsf" + bool "fsf - default (not generic) configuration" + +config XTENSA_VARIANT_DC232B + bool "dc232b - Diamond 232L Standard Core Rev.B (LE)" + help + This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE). endchoice config MMU diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 4bd1e14c6b9..015b6b2a26b 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -14,6 +14,7 @@ # (Use VAR=<xtensa_config> to use another default compiler.) variant-$(CONFIG_XTENSA_VARIANT_FSF) := fsf +variant-$(CONFIG_XTENSA_VARIANT_DC232B) := dc232b variant-$(CONFIG_XTENSA_VARIANT_LINUX_CUSTOM) := custom VARIANT = $(variant-y) diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index c9ea73b7031..5fbcde59a92 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c @@ -48,7 +48,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs) if (irq >= NR_IRQS) { printk(KERN_EMERG "%s: cannot handle IRQ %d\n", - __FUNCTION__, irq); + __func__, irq); } irq_enter(); diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c index a2e25221742..11a20adc140 100644 --- a/arch/xtensa/platforms/iss/network.c +++ b/arch/xtensa/platforms/iss/network.c @@ -640,7 +640,7 @@ static int iss_net_configure(int index, char *init) *lp = ((struct iss_net_private) { .device_list = LIST_HEAD_INIT(lp->device_list), .opened_list = LIST_HEAD_INIT(lp->opened_list), - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(lp.lock), .dev = dev, .index = index, //.fd = -1, |