diff options
Diffstat (limited to 'arch')
168 files changed, 3495 insertions, 3054 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index fb804043b320..be133f1f75a4 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -979,7 +979,7 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, long timeout; int ret = -EINVAL; struct fdtable *fdt; - int max_fdset; + int max_fds; timeout = MAX_SCHEDULE_TIMEOUT; if (tvp) { @@ -1003,9 +1003,9 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, rcu_read_lock(); fdt = files_fdtable(current->files); - max_fdset = fdt->max_fdset; + max_fds = fdt->max_fds; rcu_read_unlock(); - if (n < 0 || n > max_fdset) + if (n < 0 || n > max_fds) goto out_nofds; /* diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index cced73c58115..32b361f31c2c 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c @@ -7,20 +7,83 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include <linux/clk.h> +#include <linux/etherdevice.h> #include <linux/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/string.h> +#include <linux/types.h> +#include <asm/io.h> +#include <asm/setup.h> #include <asm/arch/board.h> #include <asm/arch/init.h> -struct eth_platform_data __initdata eth0_data = { - .valid = 1, - .mii_phy_addr = 0x10, - .is_rmii = 0, - .hw_addr = { 0x6a, 0x87, 0x71, 0x14, 0xcd, 0xcb }, +struct eth_addr { + u8 addr[6]; }; +static struct eth_addr __initdata hw_addr[2]; + +static struct eth_platform_data __initdata eth_data[2]; extern struct lcdc_platform_data atstk1000_fb0_data; +/* + * The next two functions should go away as the boot loader is + * supposed to initialize the macb address registers with a valid + * ethernet address. But we need to keep it around for a while until + * we can be reasonably sure the boot loader does this. + * + * The phy_id is ignored as the driver will probe for it. + */ +static int __init parse_tag_ethernet(struct tag *tag) +{ + int i; + + i = tag->u.ethernet.mac_index; + if (i < ARRAY_SIZE(hw_addr)) + memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address, + sizeof(hw_addr[i].addr)); + + return 0; +} +__tagtable(ATAG_ETHERNET, parse_tag_ethernet); + +static void __init set_hw_addr(struct platform_device *pdev) +{ + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + const u8 *addr; + void __iomem *regs; + struct clk *pclk; + + if (!res) + return; + if (pdev->id >= ARRAY_SIZE(hw_addr)) + return; + + addr = hw_addr[pdev->id].addr; + if (!is_valid_ether_addr(addr)) + return; + + /* + * Since this is board-specific code, we'll cheat and use the + * physical address directly as we happen to know that it's + * the same as the virtual address. + */ + regs = (void __iomem __force *)res->start; + pclk = clk_get(&pdev->dev, "pclk"); + if (!pclk) + return; + + clk_enable(pclk); + __raw_writel((addr[3] << 24) | (addr[2] << 16) + | (addr[1] << 8) | addr[0], regs + 0x98); + __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c); + clk_disable(pclk); + clk_put(pclk); +} + void __init setup_board(void) { at32_map_usart(1, 0); /* /dev/ttyS0 */ @@ -38,7 +101,8 @@ static int __init atstk1002_init(void) at32_add_device_usart(1); at32_add_device_usart(2); - at32_add_device_eth(0, ð0_data); + set_hw_addr(at32_add_device_eth(0, ð_data[0])); + at32_add_device_spi(0); at32_add_device_lcdc(0, &atstk1000_fb0_data); diff --git a/arch/avr32/kernel/avr32_ksyms.c b/arch/avr32/kernel/avr32_ksyms.c index 372e3f8b2417..7c4c76114bba 100644 --- a/arch/avr32/kernel/avr32_ksyms.c +++ b/arch/avr32/kernel/avr32_ksyms.c @@ -7,12 +7,12 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include <linux/delay.h> #include <linux/io.h> #include <linux/module.h> #include <asm/checksum.h> #include <asm/uaccess.h> -#include <asm/delay.h> /* * GCC functions diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index 317dc50945f2..0b4325946a41 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c @@ -38,6 +38,13 @@ void cpu_idle(void) void machine_halt(void) { + /* + * Enter Stop mode. The 32 kHz oscillator will keep running so + * the RTC will keep the time properly and the system will + * boot quickly. + */ + asm volatile("sleep 3\n\t" + "sub pc, -2"); } void machine_power_off(void) diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c index ea2d1ffee478..a34211601008 100644 --- a/arch/avr32/kernel/setup.c +++ b/arch/avr32/kernel/setup.c @@ -229,30 +229,6 @@ static int __init parse_tag_rsvd_mem(struct tag *tag) } __tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem); -static int __init parse_tag_ethernet(struct tag *tag) -{ -#if 0 - const struct platform_device *pdev; - - /* - * We really need a bus type that supports "classes"...this - * will do for now (until we must handle other kinds of - * ethernet controllers) - */ - pdev = platform_get_device("macb", tag->u.ethernet.mac_index); - if (pdev && pdev->dev.platform_data) { - struct eth_platform_data *data = pdev->dev.platform_data; - - data->valid = 1; - data->mii_phy_addr = tag->u.ethernet.mii_phy_addr; - memcpy(data->hw_addr, tag->u.ethernet.hw_address, - sizeof(data->hw_addr)); - } -#endif - return 0; -} -__tagtable(ATAG_ETHERNET, parse_tag_ethernet); - /* * Scan the tag table for this tag, and call its parse function. The * tag table is built by the linker from all the __tagtable diff --git a/arch/avr32/lib/delay.c b/arch/avr32/lib/delay.c index 462c8307b680..b3bc0b56e2c6 100644 --- a/arch/avr32/lib/delay.c +++ b/arch/avr32/lib/delay.c @@ -12,9 +12,9 @@ #include <linux/delay.h> #include <linux/module.h> +#include <linux/param.h> #include <linux/types.h> -#include <asm/delay.h> #include <asm/processor.h> #include <asm/sysreg.h> diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c index 7ff6ad8bab5f..48f4ef38c70e 100644 --- a/arch/avr32/mach-at32ap/at32ap7000.c +++ b/arch/avr32/mach-at32ap/at32ap7000.c @@ -11,6 +11,7 @@ #include <asm/io.h> +#include <asm/arch/at32ap7000.h> #include <asm/arch/board.h> #include <asm/arch/portmux.h> #include <asm/arch/sm.h> @@ -57,6 +58,9 @@ static struct platform_device _name##_id##_device = { \ .num_resources = ARRAY_SIZE(_name##_id##_resource), \ } +#define select_peripheral(pin, periph, flags) \ + at32_select_periph(GPIO_PIN_##pin, GPIO_##periph, flags) + #define DEV_CLK(_name, devname, bus, _index) \ static struct clk devname##_##_name = { \ .name = #_name, \ @@ -67,18 +71,6 @@ static struct clk devname##_##_name = { \ .index = _index, \ } -enum { - PIOA, - PIOB, - PIOC, - PIOD, -}; - -enum { - FUNC_A, - FUNC_B, -}; - unsigned long at32ap7000_osc_rates[3] = { [0] = 32768, /* FIXME: these are ATSTK1002-specific */ @@ -569,26 +561,26 @@ DEV_CLK(usart, atmel_usart3, pba, 6); static inline void configure_usart0_pins(void) { - portmux_set_func(PIOA, 8, FUNC_B); /* RXD */ - portmux_set_func(PIOA, 9, FUNC_B); /* TXD */ + select_peripheral(PA(8), PERIPH_B, 0); /* RXD */ + select_peripheral(PA(9), PERIPH_B, 0); /* TXD */ } static inline void configure_usart1_pins(void) { - portmux_set_func(PIOA, 17, FUNC_A); /* RXD */ - portmux_set_func(PIOA, 18, FUNC_A); /* TXD */ + select_peripheral(PA(17), PERIPH_A, 0); /* RXD */ + select_peripheral(PA(18), PERIPH_A, 0); /* TXD */ } static inline void configure_usart2_pins(void) { - portmux_set_func(PIOB, 26, FUNC_B); /* RXD */ - portmux_set_func(PIOB, 27, FUNC_B); /* TXD */ + select_peripheral(PB(26), PERIPH_B, 0); /* RXD */ + select_peripheral(PB(27), PERIPH_B, 0); /* TXD */ } static inline void configure_usart3_pins(void) { - portmux_set_func(PIOB, 18, FUNC_B); /* RXD */ - portmux_set_func(PIOB, 17, FUNC_B); /* TXD */ + select_peripheral(PB(18), PERIPH_B, 0); /* RXD */ + select_peripheral(PB(17), PERIPH_B, 0); /* TXD */ } static struct platform_device *at32_usarts[4]; @@ -654,6 +646,15 @@ DEFINE_DEV_DATA(macb, 0); DEV_CLK(hclk, macb0, hsb, 8); DEV_CLK(pclk, macb0, pbb, 6); +static struct eth_platform_data macb1_data; +static struct resource macb1_resource[] = { + PBMEM(0xfff01c00), + IRQ(26), +}; +DEFINE_DEV_DATA(macb, 1); +DEV_CLK(hclk, macb1, hsb, 9); +DEV_CLK(pclk, macb1, pbb, 7); + struct platform_device *__init at32_add_device_eth(unsigned int id, struct eth_platform_data *data) { @@ -663,27 +664,54 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data) case 0: pdev = &macb0_device; - portmux_set_func(PIOC, 3, FUNC_A); /* TXD0 */ - portmux_set_func(PIOC, 4, FUNC_A); /* TXD1 */ - portmux_set_func(PIOC, 7, FUNC_A); /* TXEN */ - portmux_set_func(PIOC, 8, FUNC_A); /* TXCK */ - portmux_set_func(PIOC, 9, FUNC_A); /* RXD0 */ - portmux_set_func(PIOC, 10, FUNC_A); /* RXD1 */ - portmux_set_func(PIOC, 13, FUNC_A); /* RXER */ - portmux_set_func(PIOC, 15, FUNC_A); /* RXDV */ - portmux_set_func(PIOC, 16, FUNC_A); /* MDC */ - portmux_set_func(PIOC, 17, FUNC_A); /* MDIO */ + select_peripheral(PC(3), PERIPH_A, 0); /* TXD0 */ + select_peripheral(PC(4), PERIPH_A, 0); /* TXD1 */ + select_peripheral(PC(7), PERIPH_A, 0); /* TXEN */ + select_peripheral(PC(8), PERIPH_A, 0); /* TXCK */ + select_peripheral(PC(9), PERIPH_A, 0); /* RXD0 */ + select_peripheral(PC(10), PERIPH_A, 0); /* RXD1 */ + select_peripheral(PC(13), PERIPH_A, 0); /* RXER */ + select_peripheral(PC(15), PERIPH_A, 0); /* RXDV */ + select_peripheral(PC(16), PERIPH_A, 0); /* MDC */ + select_peripheral(PC(17), PERIPH_A, 0); /* MDIO */ + + if (!data->is_rmii) { + select_peripheral(PC(0), PERIPH_A, 0); /* COL */ + select_peripheral(PC(1), PERIPH_A, 0); /* CRS */ + select_peripheral(PC(2), PERIPH_A, 0); /* TXER */ + select_peripheral(PC(5), PERIPH_A, 0); /* TXD2 */ + select_peripheral(PC(6), PERIPH_A, 0); /* TXD3 */ + select_peripheral(PC(11), PERIPH_A, 0); /* RXD2 */ + select_peripheral(PC(12), PERIPH_A, 0); /* RXD3 */ + select_peripheral(PC(14), PERIPH_A, 0); /* RXCK */ + select_peripheral(PC(18), PERIPH_A, 0); /* SPD */ + } + break; + + case 1: + pdev = &macb1_device; + + select_peripheral(PD(13), PERIPH_B, 0); /* TXD0 */ + select_peripheral(PD(14), PERIPH_B, 0); /* TXD1 */ + select_peripheral(PD(11), PERIPH_B, 0); /* TXEN */ + select_peripheral(PD(12), PERIPH_B, 0); /* TXCK */ + select_peripheral(PD(10), PERIPH_B, 0); /* RXD0 */ + select_peripheral(PD(6), PERIPH_B, 0); /* RXD1 */ + select_peripheral(PD(5), PERIPH_B, 0); /* RXER */ + select_peripheral(PD(4), PERIPH_B, 0); /* RXDV */ + select_peripheral(PD(3), PERIPH_B, 0); /* MDC */ + select_peripheral(PD(2), PERIPH_B, 0); /* MDIO */ if (!data->is_rmii) { - portmux_set_func(PIOC, 0, FUNC_A); /* COL */ - portmux_set_func(PIOC, 1, FUNC_A); /* CRS */ - portmux_set_func(PIOC, 2, FUNC_A); /* TXER */ - portmux_set_func(PIOC, 5, FUNC_A); /* TXD2 */ - portmux_set_func(PIOC, 6, FUNC_A); /* TXD3 */ - portmux_set_func(PIOC, 11, FUNC_A); /* RXD2 */ - portmux_set_func(PIOC, 12, FUNC_A); /* RXD3 */ - portmux_set_func(PIOC, 14, FUNC_A); /* RXCK */ - portmux_set_func(PIOC, 18, FUNC_A); /* SPD */ + select_peripheral(PC(19), PERIPH_B, 0); /* COL */ + select_peripheral(PC(23), PERIPH_B, 0); /* CRS */ + select_peripheral(PC(26), PERIPH_B, 0); /* TXER */ + select_peripheral(PC(27), PERIPH_B, 0); /* TXD2 */ + select_peripheral(PC(28), PERIPH_B, 0); /* TXD3 */ + select_peripheral(PC(29), PERIPH_B, 0); /* RXD2 */ + select_peripheral(PC(30), PERIPH_B, 0); /* RXD3 */ + select_peripheral(PC(24), PERIPH_B, 0); /* RXCK */ + select_peripheral(PD(15), PERIPH_B, 0); /* SPD */ } break; @@ -714,12 +742,12 @@ struct platform_device *__init at32_add_device_spi(unsigned int id) switch (id) { case 0: pdev = &spi0_device; - portmux_set_func(PIOA, 0, FUNC_A); /* MISO */ - portmux_set_func(PIOA, 1, FUNC_A); /* MOSI */ - portmux_set_func(PIOA, 2, FUNC_A); /* SCK */ - portmux_set_func(PIOA, 3, FUNC_A); /* NPCS0 */ - portmux_set_func(PIOA, 4, FUNC_A); /* NPCS1 */ - portmux_set_func(PIOA, 5, FUNC_A); /* NPCS2 */ + select_peripheral(PA(0), PERIPH_A, 0); /* MISO */ + select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */ + select_peripheral(PA(2), PERIPH_A, 0); /* SCK */ + select_peripheral(PA(3), PERIPH_A, 0); /* NPCS0 */ + select_peripheral(PA(4), PERIPH_A, 0); /* NPCS1 */ + select_peripheral(PA(5), PERIPH_A, 0); /* NPCS2 */ break; default: @@ -762,37 +790,37 @@ at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data) switch (id) { case 0: pdev = &lcdc0_device; - portmux_set_func(PIOC, 19, FUNC_A); /* CC */ - portmux_set_func(PIOC, 20, FUNC_A); /* HSYNC */ - portmux_set_func(PIOC, 21, FUNC_A); /* PCLK */ - portmux_set_func(PIOC, 22, FUNC_A); /* VSYNC */ - portmux_set_func(PIOC, 23, FUNC_A); /* DVAL */ - portmux_set_func(PIOC, 24, FUNC_A); /* MODE */ - portmux_set_func(PIOC, 25, FUNC_A); /* PWR */ - portmux_set_func(PIOC, 26, FUNC_A); /* DATA0 */ - portmux_set_func(PIOC, 27, FUNC_A); /* DATA1 */ - portmux_set_func(PIOC, 28, FUNC_A); /* DATA2 */ - portmux_set_func(PIOC, 29, FUNC_A); /* DATA3 */ - portmux_set_func(PIOC, 30, FUNC_A); /* DATA4 */ - portmux_set_func(PIOC, 31, FUNC_A); /* DATA5 */ - portmux_set_func(PIOD, 0, FUNC_A); /* DATA6 */ - portmux_set_func(PIOD, 1, FUNC_A); /* DATA7 */ - portmux_set_func(PIOD, 2, FUNC_A); /* DATA8 */ - portmux_set_func(PIOD, 3, FUNC_A); /* DATA9 */ - portmux_set_func(PIOD, 4, FUNC_A); /* DATA10 */ - portmux_set_func(PIOD, 5, FUNC_A); /* DATA11 */ - portmux_set_func(PIOD, 6, FUNC_A); /* DATA12 */ - portmux_set_func(PIOD, 7, FUNC_A); /* DATA13 */ - portmux_set_func(PIOD, 8, FUNC_A); /* DATA14 */ - portmux_set_func(PIOD, 9, FUNC_A); /* DATA15 */ - portmux_set_func(PIOD, 10, FUNC_A); /* DATA16 */ - portmux_set_func(PIOD, 11, FUNC_A); /* DATA17 */ - portmux_set_func(PIOD, 12, FUNC_A); /* DATA18 */ - portmux_set_func(PIOD, 13, FUNC_A); /* DATA19 */ - portmux_set_func(PIOD, 14, FUNC_A); /* DATA20 */ - portmux_set_func(PIOD, 15, FUNC_A); /* DATA21 */ - portmux_set_func(PIOD, 16, FUNC_A); /* DATA22 */ - portmux_set_func(PIOD, 17, FUNC_A); /* DATA23 */ + select_peripheral(PC(19), PERIPH_A, 0); /* CC */ + select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */ + select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */ + select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC */ + select_peripheral(PC(23), PERIPH_A, 0); /* DVAL */ + select_peripheral(PC(24), PERIPH_A, 0); /* MODE */ + select_peripheral(PC(25), PERIPH_A, 0); /* PWR */ + select_peripheral(PC(26), PERIPH_A, 0); /* DATA0 */ + select_peripheral(PC(27), PERIPH_A, 0); /* DATA1 */ + select_peripheral(PC(28), PERIPH_A, 0); /* DATA2 */ + select_peripheral(PC(29), PERIPH_A, 0); /* DATA3 */ + select_peripheral(PC(30), PERIPH_A, 0); /* DATA4 */ + select_peripheral(PC(31), PERIPH_A, 0); /* DATA5 */ + select_peripheral(PD(0), PERIPH_A, 0); /* DATA6 */ + select_peripheral(PD(1), PERIPH_A, 0); /* DATA7 */ + select_peripheral(PD(2), PERIPH_A, 0); /* DATA8 */ + select_peripheral(PD(3), PERIPH_A, 0); /* DATA9 */ + select_peripheral(PD(4), PERIPH_A, 0); /* DATA10 */ + select_peripheral(PD(5), PERIPH_A, 0); /* DATA11 */ + select_peripheral(PD(6), PERIPH_A, 0); /* DATA12 */ + select_peripheral(PD(7), PERIPH_A, 0); /* DATA13 */ + select_peripheral(PD(8), PERIPH_A, 0); /* DATA14 */ + select_peripheral(PD(9), PERIPH_A, 0); /* DATA15 */ + select_peripheral(PD(10), PERIPH_A, 0); /* DATA16 */ + select_peripheral(PD(11), PERIPH_A, 0); /* DATA17 */ + select_peripheral(PD(12), PERIPH_A, 0); /* DATA18 */ + select_peripheral(PD(13), PERIPH_A, 0); /* DATA19 */ + select_peripheral(PD(14), PERIPH_A, 0); /* DATA20 */ + select_peripheral(PD(15), PERIPH_A, 0); /* DATA21 */ + select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */ + select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */ clk_set_parent(&lcdc0_pixclk, &pll0); clk_set_rate(&lcdc0_pixclk, clk_get_rate(&pll0)); @@ -838,6 +866,8 @@ struct clk *at32_clock_list[] = { &atmel_usart3_usart, &macb0_hclk, &macb0_pclk, + &macb1_hclk, + &macb1_pclk, &spi0_mck, &lcdc0_hclk, &lcdc0_pixclk, diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c index 4dff1f988900..b59272e81b9a 100644 --- a/arch/avr32/mach-at32ap/extint.c +++ b/arch/avr32/mach-at32ap/extint.c @@ -49,12 +49,25 @@ static void eim_unmask_irq(unsigned int irq) static int eim_set_irq_type(unsigned int irq, unsigned int flow_type) { struct at32_sm *sm = get_irq_chip_data(irq); + struct irq_desc *desc; unsigned int i = irq - sm->eim_first_irq; u32 mode, edge, level; unsigned long flags; int ret = 0; - flow_type &= IRQ_TYPE_SENSE_MASK; + if (flow_type == IRQ_TYPE_NONE) + flow_type = IRQ_TYPE_LEVEL_LOW; + + desc = &irq_desc[irq]; + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; + + if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) { + desc->status |= IRQ_LEVEL; + set_irq_handler(irq, handle_level_irq); + } else { + set_irq_handler(irq, handle_edge_irq); + } spin_lock_irqsave(&sm->lock, flags); @@ -148,10 +161,15 @@ static int __init eim_init(void) pattern = sm_readl(sm, EIM_MODE); nr_irqs = fls(pattern); + /* Trigger on falling edge unless overridden by driver */ + sm_writel(sm, EIM_MODE, 0UL); + sm_writel(sm, EIM_EDGE, 0UL); + sm->eim_chip = &eim_chip; for (i = 0; i < nr_irqs; i++) { - set_irq_chip(sm->eim_first_irq + i, &eim_chip); + set_irq_chip_and_handler(sm->eim_first_irq + i, &eim_chip, + handle_edge_irq); set_irq_chip_data(sm->eim_first_irq + i, sm); } diff --git a/arch/avr32/mach-at32ap/intc.c b/arch/avr32/mach-at32ap/intc.c index eb87a18ad7b2..dd5c009cf224 100644 --- a/arch/avr32/mach-at32ap/intc.c +++ b/arch/avr32/mach-at32ap/intc.c @@ -136,3 +136,7 @@ fail: panic("Interrupt controller initialization failed!\n"); } +unsigned long intc_get_pending(int group) +{ + return intc_readl(&intc0, INTREQ0 + 4 * group); +} diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c index d3aabfca8598..f1280ed8ed6d 100644 --- a/arch/avr32/mach-at32ap/pio.c +++ b/arch/avr32/mach-at32ap/pio.c @@ -25,27 +25,98 @@ struct pio_device { void __iomem *regs; const struct platform_device *pdev; struct clk *clk; - u32 alloc_mask; + u32 pinmux_mask; char name[32]; }; static struct pio_device pio_dev[MAX_NR_PIO_DEVICES]; -void portmux_set_func(unsigned int portmux_id, unsigned int pin_id, - unsigned int function_id) +static struct pio_device *gpio_to_pio(unsigned int gpio) { struct pio_device *pio; - u32 mask = 1 << pin_id; + unsigned int index; - BUG_ON(portmux_id >= MAX_NR_PIO_DEVICES); + index = gpio >> 5; + if (index >= MAX_NR_PIO_DEVICES) + return NULL; + pio = &pio_dev[index]; + if (!pio->regs) + return NULL; - pio = &pio_dev[portmux_id]; + return pio; +} + +/* Pin multiplexing API */ + +void __init at32_select_periph(unsigned int pin, unsigned int periph, + unsigned long flags) +{ + struct pio_device *pio; + unsigned int pin_index = pin & 0x1f; + u32 mask = 1 << pin_index; + + pio = gpio_to_pio(pin); + if (unlikely(!pio)) { + printk("pio: invalid pin %u\n", pin); + goto fail; + } - if (function_id) + if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) { + printk("%s: pin %u is busy\n", pio->name, pin_index); + goto fail; + } + + pio_writel(pio, PUER, mask); + if (periph) pio_writel(pio, BSR, mask); else pio_writel(pio, ASR, mask); + pio_writel(pio, PDR, mask); + if (!(flags & AT32_GPIOF_PULLUP)) + pio_writel(pio, PUDR, mask); + + return; + +fail: + dump_stack(); +} + +void __init at32_select_gpio(unsigned int pin, unsigned long flags) +{ + struct pio_device *pio; + unsigned int pin_index = pin & 0x1f; + u32 mask = 1 << pin_index; + + pio = gpio_to_pio(pin); + if (unlikely(!pio)) { + printk("pio: invalid pin %u\n", pin); + goto fail; + } + + if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) { + printk("%s: pin %u is busy\n", pio->name, pin_index); + goto fail; + } + + pio_writel(pio, PUER, mask); + if (flags & AT32_GPIOF_HIGH) + pio_writel(pio, SODR, mask); + else + pio_writel(pio, CODR, mask); + if (flags & AT32_GPIOF_OUTPUT) + pio_writel(pio, OER, mask); + else + pio_writel(pio, ODR, mask); + + pio_writel(pio, PER, mask); + if (!(flags & AT32_GPIOF_PULLUP)) + pio_writel(pio, PUDR, mask); + + return; + +fail: + dump_stack(); } static int __init pio_probe(struct platform_device *pdev) diff --git a/arch/avr32/mach-at32ap/sm.c b/arch/avr32/mach-at32ap/sm.c deleted file mode 100644 index 03306eb0345e..000000000000 --- a/arch/avr32/mach-at32ap/sm.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * System Manager driver for AT32AP CPUs - * - * Copyright (C) 2006 Atmel 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 <linux/errno.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/random.h> -#include <linux/spinlock.h> - -#include <asm/intc.h> -#include <asm/io.h> -#include <asm/irq.h> - -#include <asm/arch/sm.h> - -#include "sm.h" - -#define SM_EIM_IRQ_RESOURCE 1 -#define SM_PM_IRQ_RESOURCE 2 -#define SM_RTC_IRQ_RESOURCE 3 - -#define to_eim(irqc) container_of(irqc, struct at32_sm, irqc) - -struct at32_sm system_manager; - -int __init at32_sm_init(void) -{ - struct resource *regs; - struct at32_sm *sm = &system_manager; - int ret = -ENXIO; - - regs = platform_get_resource(&at32_sm_device, IORESOURCE_MEM, 0); - if (!regs) - goto fail; - - spin_lock_init(&sm->lock); - sm->pdev = &at32_sm_device; - - ret = -ENOMEM; - sm->regs = ioremap(regs->start, regs->end - regs->start + 1); - if (!sm->regs) - goto fail; - - return 0; - -fail: - printk(KERN_ERR "Failed to initialize System Manager: %d\n", ret); - return ret; -} - -/* - * External Interrupt Module (EIM). - * - * EIM gets level- or edge-triggered interrupts of either polarity - * from the outside and converts it to active-high level-triggered - * interrupts that the internal interrupt controller can handle. EIM - * also provides masking/unmasking of interrupts, as well as - * acknowledging of edge-triggered interrupts. - */ - -static irqreturn_t spurious_eim_interrupt(int irq, void *dev_id, - struct pt_regs *regs) -{ - printk(KERN_WARNING "Spurious EIM interrupt %d\n", irq); - disable_irq(irq); - return IRQ_NONE; -} - -static struct irqaction eim_spurious_action = { - .handler = spurious_eim_interrupt, -}; - -static irqreturn_t eim_handle_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - struct irq_controller * irqc = dev_id; - struct at32_sm *sm = to_eim(irqc); - unsigned long pending; - - /* - * No need to disable interrupts globally. The interrupt - * level relevant to this group must be masked all the time, - * so we know that this particular EIM instance will not be - * re-entered. - */ - spin_lock(&sm->lock); - - pending = intc_get_pending(sm->irqc.irq_group); - if (unlikely(!pending)) { - printk(KERN_ERR "EIM (group %u): No interrupts pending!\n", - sm->irqc.irq_group); - goto unlock; - } - - do { - struct irqaction *action; - unsigned int i; - - i = fls(pending) - 1; - pending &= ~(1 << i); - action = sm->action[i]; - - /* Acknowledge the interrupt */ - sm_writel(sm, EIM_ICR, 1 << i); - - spin_unlock(&sm->lock); - - if (action->flags & SA_INTERRUPT) - local_irq_disable(); - action->handler(sm->irqc.first_irq + i, action->dev_id, regs); - local_irq_enable(); - spin_lock(&sm->lock); - if (action->flags & SA_SAMPLE_RANDOM) - add_interrupt_randomness(sm->irqc.first_irq + i); - } while (pending); - -unlock: - spin_unlock(&sm->lock); - return IRQ_HANDLED; -} - -static void eim_mask(struct irq_controller *irqc, unsigned int irq) -{ - struct at32_sm *sm = to_eim(irqc); - unsigned int i; - - i = irq - sm->irqc.first_irq; - sm_writel(sm, EIM_IDR, 1 << i); -} - -static void eim_unmask(struct irq_controller *irqc, unsigned int irq) -{ - struct at32_sm *sm = to_eim(irqc); - unsigned int i; - - i = irq - sm->irqc.first_irq; - sm_writel(sm, EIM_IER, 1 << i); -} - -static int eim_setup(struct irq_controller *irqc, unsigned int irq, - struct irqaction *action) -{ - struct at32_sm *sm = to_eim(irqc); - sm->action[irq - sm->irqc.first_irq] = action; - /* Acknowledge earlier interrupts */ - sm_writel(sm, EIM_ICR, (1<<(irq - sm->irqc.first_irq))); - eim_unmask(irqc, irq); - return 0; -} - -static void eim_free(struct irq_controller *irqc, unsigned int irq, - void *dev) -{ - struct at32_sm *sm = to_eim(irqc); - eim_mask(irqc, irq); - sm->action[irq - sm->irqc.first_irq] = &eim_spurious_action; -} - -static int eim_set_type(struct irq_controller *irqc, unsigned int irq, - unsigned int type) -{ - struct at32_sm *sm = to_eim(irqc); - unsigned long flags; - u32 value, pattern; - - spin_lock_irqsave(&sm->lock, flags); - - pattern = 1 << (irq - sm->irqc.first_irq); - - value = sm_readl(sm, EIM_MODE); - if (type & IRQ_TYPE_LEVEL) - value |= pattern; - else - value &= ~pattern; - sm_writel(sm, EIM_MODE, value); - value = sm_readl(sm, EIM_EDGE); - if (type & IRQ_EDGE_RISING) - value |= pattern; - else - value &= ~pattern; - sm_writel(sm, EIM_EDGE, value); - value = sm_readl(sm, EIM_LEVEL); - if (type & IRQ_LEVEL_HIGH) - value |= pattern; - else - value &= ~pattern; - sm_writel(sm, EIM_LEVEL, value); - - spin_unlock_irqrestore(&sm->lock, flags); - - return 0; -} - -static unsigned int eim_get_type(struct irq_controller *irqc, - unsigned int irq) -{ - struct at32_sm *sm = to_eim(irqc); - unsigned long flags; - unsigned int type = 0; - u32 mode, edge, level, pattern; - - pattern = 1 << (irq - sm->irqc.first_irq); - - spin_lock_irqsave(&sm->lock, flags); - mode = sm_readl(sm, EIM_MODE); - edge = sm_readl(sm, EIM_EDGE); - level = sm_readl(sm, EIM_LEVEL); - spin_unlock_irqrestore(&sm->lock, flags); - - if (mode & pattern) - type |= IRQ_TYPE_LEVEL; - if (edge & pattern) - type |= IRQ_EDGE_RISING; - if (level & pattern) - type |= IRQ_LEVEL_HIGH; - - return type; -} - -static struct irq_controller_class eim_irq_class = { - .typename = "EIM", - .handle = eim_handle_irq, - .setup = eim_setup, - .free = eim_free, - .mask = eim_mask, - .unmask = eim_unmask, - .set_type = eim_set_type, - .get_type = eim_get_type, -}; - -static int __init eim_init(void) -{ - struct at32_sm *sm = &system_manager; - unsigned int i; - u32 pattern; - int ret; - - /* - * The EIM is really the same module as SM, so register - * mapping, etc. has been taken care of already. - */ - - /* - * Find out how many interrupt lines that are actually - * implemented in hardware. - */ - sm_writel(sm, EIM_IDR, ~0UL); - sm_writel(sm, EIM_MODE, ~0UL); - pattern = sm_readl(sm, EIM_MODE); - sm->irqc.nr_irqs = fls(pattern); - - ret = -ENOMEM; - sm->action = kmalloc(sizeof(*sm->action) * sm->irqc.nr_irqs, - GFP_KERNEL); - if (!sm->action) - goto out; - - for (i = 0; i < sm->irqc.nr_irqs; i++) - sm->action[i] = &eim_spurious_action; - - spin_lock_init(&sm->lock); - sm->irqc.irq_group = sm->pdev->resource[SM_EIM_IRQ_RESOURCE].start; - sm->irqc.class = &eim_irq_class; - - ret = intc_register_controller(&sm->irqc); - if (ret < 0) - goto out_free_actions; - - printk("EIM: External Interrupt Module at 0x%p, IRQ group %u\n", - sm->regs, sm->irqc.irq_group); - printk("EIM: Handling %u external IRQs, starting with IRQ%u\n", - sm->irqc.nr_irqs, sm->irqc.first_irq); - - return 0; - -out_free_actions: - kfree(sm->action); -out: - return ret; -} -arch_initcall(eim_init); diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c index c1d9fc8f1a85..ee677ced7b68 100644 --- a/arch/frv/kernel/pm.c +++ b/arch/frv/kernel/pm.c @@ -223,7 +223,7 @@ static int cmode_procctl(ctl_table *ctl, int write, struct file *filp, static int cmode_sysctl(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen, void **context) + void __user *newval, size_t newlen) { if (oldval && oldlenp) { size_t oldlen; @@ -326,7 +326,7 @@ static int p0_procctl(ctl_table *ctl, int write, struct file *filp, static int p0_sysctl(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen, void **context) + void __user *newval, size_t newlen) { if (oldval && oldlenp) { size_t oldlen; @@ -370,7 +370,7 @@ static int cm_procctl(ctl_table *ctl, int write, struct file *filp, static int cm_sysctl(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen, void **context) + void __user *newval, size_t newlen) { if (oldval && oldlenp) { size_t oldlen; diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 1f9300f37f52..96e941084c04 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -644,7 +644,85 @@ CONFIG_CONNECTOR=m # # Memory Technology Devices (MTD) # -# CONFIG_MTD is not set +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 is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# 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 + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +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=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x0 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=0 +# 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 + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set # # Parallel port support diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index 2c82412b9efe..5929f883e46b 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c @@ -301,7 +301,7 @@ static void sp_cleanup(void) for (;;) { unsigned long set; i = j * __NFDBITS; - if (i >= fdt->max_fdset || i >= fdt->max_fds) + if (i >= fdt->max_fds) break; set = fdt->open_fds->fds_bits[j++]; while (set) { diff --git a/arch/mips/kernel/reset.c b/arch/mips/kernel/reset.c index 621037db2290..060563a712b6 100644 --- a/arch/mips/kernel/reset.c +++ b/arch/mips/kernel/reset.c @@ -23,6 +23,8 @@ void (*_machine_restart)(char *command); void (*_machine_halt)(void); void (*pm_power_off)(void); +EXPORT_SYMBOL(pm_power_off); + void machine_restart(char *command) { if (_machine_restart) diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 79f0317d84ac..cecff24cc972 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -112,6 +112,7 @@ SECTIONS /* .exit.text is discarded at runtime, not link time, to deal with references from .rodata */ .exit.text : { *(.exit.text) } + .exit.data : { *(.exit.data) } . = ALIGN(_PAGE_SIZE); __initramfs_start = .; .init.ramfs : { *(.init.ramfs) } @@ -139,7 +140,6 @@ SECTIONS /* Sections to be discarded */ /DISCARD/ : { - *(.exit.data) *(.exitcall.exit) /* ABI crap starts here */ diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c index da35d4555491..12878359f2c8 100644 --- a/arch/mips/lasat/sysctl.c +++ b/arch/mips/lasat/sysctl.c @@ -40,12 +40,12 @@ static DEFINE_MUTEX(lasat_info_mutex); /* Strategy function to write EEPROM after changing string entry */ int sysctl_lasatstring(ctl_table *table, int *name, int nlen, void *oldval, size_t *oldlenp, - void *newval, size_t newlen, void **context) + void *newval, size_t newlen) { int r; mutex_lock(&lasat_info_mutex); r = sysctl_string(table, name, - nlen, oldval, oldlenp, newval, newlen, context); + nlen, oldval, oldlenp, newval, newlen); if (r < 0) { mutex_unlock(&lasat_info_mutex); return r; @@ -119,11 +119,11 @@ int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, /* Sysctl for setting the IP addresses */ int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, void *oldval, size_t *oldlenp, - void *newval, size_t newlen, void **context) + void *newval, size_t newlen) { int r; mutex_lock(&lasat_info_mutex); - r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); if (r < 0) { mutex_unlock(&lasat_info_mutex); return r; @@ -139,14 +139,14 @@ int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, /* Same for RTC */ int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen, void *oldval, size_t *oldlenp, - void *newval, size_t newlen, void **context) + void *newval, size_t newlen) { int r; mutex_lock(&lasat_info_mutex); rtctmp = ds1603_read(); if (rtctmp < 0) rtctmp = 0; - r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); if (r < 0) { mutex_unlock(&lasat_info_mutex); return r; @@ -251,13 +251,12 @@ int proc_lasat_ip(ctl_table *table, int write, struct file *filp, static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen, void *oldval, size_t *oldlenp, - void *newval, size_t newlen, - void **context) + void *newval, size_t newlen) { int r; mutex_lock(&lasat_info_mutex); - r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); if (r < 0) { mutex_unlock(&lasat_info_mutex); return r; diff --git a/arch/mips/lib/csum_partial_copy.c b/arch/mips/lib/csum_partial_copy.c index 1720f2ceeeae..06771040a267 100644 --- a/arch/mips/lib/csum_partial_copy.c +++ b/arch/mips/lib/csum_partial_copy.c @@ -7,6 +7,7 @@ * Copyright (C) 1998, 1999 Ralf Baechle */ #include <linux/kernel.h> +#include <linux/module.h> #include <linux/types.h> #include <asm/byteorder.h> #include <asm/string.h> @@ -29,6 +30,8 @@ __wsum csum_partial_copy_nocheck(const void *src, return sum; } +EXPORT_SYMBOL(csum_partial_copy_nocheck); + /* * Copy from userspace and compute checksum. If we catch an exception * then zero the rest of the buffer. diff --git a/arch/mips/mips-boards/malta/Makefile b/arch/mips/mips-boards/malta/Makefile index 77ee5c6d33c1..b662c75fb28e 100644 --- a/arch/mips/mips-boards/malta/Makefile +++ b/arch/mips/mips-boards/malta/Makefile @@ -19,5 +19,5 @@ # under Linux. # -obj-y := malta_int.o malta_setup.o +obj-y := malta_int.o malta_mtd.o malta_setup.o obj-$(CONFIG_SMP) += malta_smp.o diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c index 282f3e52eea3..56ea76679cd4 100644 --- a/arch/mips/mips-boards/malta/malta_setup.c +++ b/arch/mips/mips-boards/malta/malta_setup.c @@ -21,13 +21,6 @@ #include <linux/pci.h> #include <linux/screen_info.h> -#ifdef CONFIG_MTD -#include <linux/mtd/partitions.h> -#include <linux/mtd/physmap.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/map.h> -#endif - #include <asm/cpu.h> #include <asm/bootinfo.h> #include <asm/irq.h> @@ -58,30 +51,6 @@ struct resource standard_io_resources[] = { { .name = "dma2", .start = 0xc0, .end = 0xdf, .flags = IORESOURCE_BUSY }, }; -#ifdef CONFIG_MTD -static struct mtd_partition malta_mtd_partitions[] = { - { - .name = "YAMON", - .offset = 0x0, - .size = 0x100000, - .mask_flags = MTD_WRITEABLE - }, - { - .name = "User FS", - .offset = 0x100000, - .size = 0x2e0000 - }, - { - .name = "Board Config", - .offset = 0x3e0000, - .size = 0x020000, - .mask_flags = MTD_WRITEABLE - } -}; - -#define number_partitions (sizeof(malta_mtd_partitions)/sizeof(struct mtd_partition)) -#endif - const char *get_system_type(void) { return "MIPS Malta"; @@ -211,14 +180,6 @@ void __init plat_mem_setup(void) #endif #endif -#ifdef CONFIG_MTD - /* - * Support for MTD on Malta. Use the generic physmap driver - */ - physmap_configure(0x1e000000, 0x400000, 4, NULL); - physmap_set_partitions(malta_mtd_partitions, number_partitions); -#endif - mips_reboot_setup(); board_time_init = mips_time_init; diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index caf807ded514..1f954a238a63 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -32,6 +32,7 @@ void (*local_flush_data_cache_page)(void * addr); void (*flush_data_cache_page)(unsigned long addr); void (*flush_icache_all)(void); +EXPORT_SYMBOL_GPL(local_flush_data_cache_page); EXPORT_SYMBOL(flush_data_cache_page); #ifdef CONFIG_DMA_NONCOHERENT diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 9e29ba9205f0..ea2d15370bb7 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -316,7 +316,7 @@ static int __init page_is_ram(unsigned long pagenr) void __init paging_init(void) { unsigned long zones_size[MAX_NR_ZONES] = { 0, }; - unsigned long max_dma, high, low; + unsigned long max_dma, low; #ifndef CONFIG_FLATMEM unsigned long zholes_size[MAX_NR_ZONES] = { 0, }; unsigned long i, j, pfn; @@ -331,7 +331,6 @@ void __init paging_init(void) max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; low = max_low_pfn; - high = highend_pfn; #ifdef CONFIG_ISA if (low < max_dma) @@ -344,13 +343,13 @@ void __init paging_init(void) zones_size[ZONE_DMA] = low; #endif #ifdef CONFIG_HIGHMEM - if (cpu_has_dc_aliases) { - printk(KERN_WARNING "This processor doesn't support highmem."); - if (high - low) - printk(" %ldk highmem ignored", high - low); - printk("\n"); - } else - zones_size[ZONE_HIGHMEM] = high - low; + zones_size[ZONE_HIGHMEM] = highend_pfn - highstart_pfn; + + if (cpu_has_dc_aliases && zones_size[ZONE_HIGHMEM]) { + printk(KERN_WARNING "This processor doesn't support highmem." + " %ldk highmem ignored\n", zones_size[ZONE_HIGHMEM]); + zones_size[ZONE_HIGHMEM] = 0; + } #endif #ifdef CONFIG_FLATMEM diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 56c3c4065eb0..8699dadcd096 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -107,6 +107,11 @@ config AUDIT_ARCH bool default y +config GENERIC_BUG + bool + default y + depends on BUG + config DEFAULT_UIMAGE bool help @@ -478,6 +483,7 @@ config PPC_MAPLE select PPC_UDBG_16550 select PPC_970_NAP select PPC_NATIVE + select PPC_RTAS default n help This option enables support for the Maple 970FX Evaluation Board. @@ -714,7 +720,7 @@ config FORCE_MAX_ZONEORDER config MATH_EMULATION bool "Math emulation" - depends on 4xx || 8xx || E200 || E500 + depends on 4xx || 8xx || E200 || PPC_83xx || E500 ---help--- Some PowerPC chips designed for embedded applications do not have a floating-point unit and therefore do not implement the diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig index f2d888e014a9..70ed61337f5c 100644 --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig @@ -157,6 +157,7 @@ CONFIG_SPU_BASE=y CONFIG_PS3_HTAB_SIZE=20 CONFIG_PS3_DYNAMIC_DMA=y CONFIG_PS3_USE_LPAR_ADDR=y +CONFIG_PS3_VUART=y # # Kernel options diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 4fe53d08ab81..d2ded19e4064 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -77,6 +77,7 @@ endif ifeq ($(CONFIG_PPC_ISERIES),y) extra-y += lparmap.s +$(obj)/head_64.o: $(obj)/lparmap.s AFLAGS_head_64.o += -I$(obj) endif diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 9d1614c3ce67..b742013bb9da 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -833,7 +833,7 @@ static struct cpu_spec cpu_specs[] = { .pvr_mask = 0x7fff0000, .pvr_value = 0x00840000, .cpu_name = "e300c2", - .cpu_features = CPU_FTRS_E300, + .cpu_features = CPU_FTRS_E300C2, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, @@ -1136,8 +1136,7 @@ static struct cpu_spec cpu_specs[] = { .pvr_mask = 0xff000fff, .pvr_value = 0x53000890, .cpu_name = "440SPe Rev. A", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_44X, .cpu_user_features = COMMON_USER_BOOKE, .icache_bsize = 32, .dcache_bsize = 32, diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index d88e182e40b3..9417cf5b4b7e 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -437,6 +437,13 @@ Alignment: /* Floating-point unavailable */ . = 0x800 FPUnavailable: +BEGIN_FTR_SECTION +/* + * Certain Freescale cores don't have a FPU and treat fp instructions + * as a FP Unavailable exception. Redirect to illegal/emulation handling. + */ + b ProgramCheck +END_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE) EXCEPTION_PROLOG bne load_up_fpu /* if from user, just load it up */ addi r3,r1,STACK_FRAME_OVERHEAD diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index e2c3c6a85f33..8339fd609de0 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c @@ -23,6 +23,7 @@ #include <linux/string.h> #include <linux/kernel.h> #include <linux/cache.h> +#include <linux/bug.h> #include "setup.h" @@ -290,23 +291,11 @@ int module_finalize(const Elf_Ehdr *hdr, struct module *me) { const Elf_Shdr *sect; + int err; - me->arch.bug_table = NULL; - me->arch.num_bugs = 0; - - /* Find the __bug_table section, if present */ - sect = find_section(hdr, sechdrs, "__bug_table"); - if (sect != NULL) { - me->arch.bug_table = (void *) sect->sh_addr; - me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry); - } - - /* - * Strictly speaking this should have a spinlock to protect against - * traversals, but since we only traverse on BUG()s, a spinlock - * could potentially lead to deadlock and thus be counter-productive. - */ - list_add(&me->arch.bug_list, &module_bug_list); + err = module_bug_finalize(hdr, sechdrs, me); + if (err) /* never true, currently */ + return err; /* Apply feature fixups */ sect = find_section(hdr, sechdrs, "__ftr_fixup"); @@ -320,7 +309,7 @@ int module_finalize(const Elf_Ehdr *hdr, void module_arch_cleanup(struct module *mod) { - list_del(&mod->arch.bug_list); + module_bug_cleanup(mod); } struct bug_entry *module_find_bug(unsigned long bugaddr) diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 8dd1f0aae5d6..75c7c4f19280 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -20,6 +20,7 @@ #include <linux/moduleloader.h> #include <linux/err.h> #include <linux/vmalloc.h> +#include <linux/bug.h> #include <asm/module.h> #include <asm/uaccess.h> #include <asm/firmware.h> @@ -439,23 +440,11 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { const Elf_Shdr *sect; + int err; - me->arch.bug_table = NULL; - me->arch.num_bugs = 0; - - /* Find the __bug_table section, if present */ - sect = find_section(hdr, sechdrs, "__bug_table"); - if (sect != NULL) { - me->arch.bug_table = (void *) sect->sh_addr; - me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry); - } - - /* - * Strictly speaking this should have a spinlock to protect against - * traversals, but since we only traverse on BUG()s, a spinlock - * could potentially lead to deadlock and thus be counter-productive. - */ - list_add(&me->arch.bug_list, &module_bug_list); + err = module_bug_finalize(hdr, sechdrs, me); + if (err) + return err; /* Apply feature fixups */ sect = find_section(hdr, sechdrs, "__ftr_fixup"); @@ -475,7 +464,7 @@ int module_finalize(const Elf_Ehdr *hdr, void module_arch_cleanup(struct module *mod) { - list_del(&mod->arch.bug_list); + module_bug_cleanup(mod); } struct bug_entry *module_find_bug(unsigned long bugaddr) diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 8a06724e029e..e921514e655b 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -109,9 +109,7 @@ int of_device_register(struct of_device *ofdev) if (rc) return rc; - device_create_file(&ofdev->dev, &dev_attr_devspec); - - return 0; + return device_create_file(&ofdev->dev, &dev_attr_devspec); } void of_device_unregister(struct of_device *ofdev) diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index b3189d0161b8..3002ea3a61a2 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -169,7 +169,7 @@ static void of_platform_make_bus_id(struct of_device *dev) char *name = dev->dev.bus_id; const u32 *reg; u64 addr; - long magic; + int magic; /* * If it's a DCR based device, use 'd' for native DCRs diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 2f54cd81dea5..8336deafc624 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -736,25 +736,51 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* return NULL; } -static int -scan_OF_pci_childs_iterator(struct device_node* node, void* data) +static struct device_node *scan_OF_for_pci_dev(struct device_node *parent, + unsigned int devfn) { - const unsigned int *reg; - u8* fdata = (u8*)data; - - reg = get_property(node, "reg", NULL); - if (reg && ((reg[0] >> 8) & 0xff) == fdata[1] - && ((reg[0] >> 16) & 0xff) == fdata[0]) - return 1; - return 0; + struct device_node *np = NULL; + const u32 *reg; + unsigned int psize; + + while ((np = of_get_next_child(parent, np)) != NULL) { + reg = get_property(np, "reg", &psize); + if (reg == NULL || psize < 4) + continue; + if (((reg[0] >> 8) & 0xff) == devfn) + return np; + } + return NULL; } -static struct device_node* -scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) + +static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus) { - u8 filter_data[2] = {bus, dev_fn}; + struct device_node *parent, *np; + + /* Are we a root bus ? */ + if (bus->self == NULL || bus->parent == NULL) { + struct pci_controller *hose = pci_bus_to_hose(bus->number); + if (hose == NULL) + return NULL; + return of_node_get(hose->arch_data); + } + + /* not a root bus, we need to get our parent */ + parent = scan_OF_for_pci_bus(bus->parent); + if (parent == NULL) + return NULL; + + /* now iterate for children for a match */ + np = scan_OF_for_pci_dev(parent, bus->self->devfn); + of_node_put(parent); - return scan_OF_pci_childs(node, scan_OF_pci_childs_iterator, filter_data); + /* sanity check */ + if (strcmp(np->type, "pci") != 0) + printk(KERN_WARNING "pci: wrong type \"%s\" for bridge %s\n", + np->type, np->full_name); + + return np; } /* @@ -763,43 +789,25 @@ scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) struct device_node * pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) { - struct pci_controller *hose; - struct device_node *node; - int busnr; + struct device_node *parent, *np; if (!have_of) return NULL; - - /* Lookup the hose */ - busnr = bus->number; - hose = pci_bus_to_hose(busnr); - if (!hose) - return NULL; - /* Check it has an OF node associated */ - node = (struct device_node *) hose->arch_data; - if (!node) + DBG("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn); + parent = scan_OF_for_pci_bus(bus); + if (parent == NULL) return NULL; - - /* Fixup bus number according to what OF think it is. */ -#ifdef CONFIG_PPC_PMAC - /* The G5 need a special case here. Basically, we don't remap all - * busses on it so we don't create the pci-OF-map. However, we do - * remap the AGP bus and so have to deal with it. A future better - * fix has to be done by making the remapping per-host and always - * filling the pci_to_OF map. --BenH + DBG(" parent is %s\n", parent ? parent->full_name : "<NULL>"); + np = scan_OF_for_pci_dev(parent, devfn); + of_node_put(parent); + DBG(" result is %s\n", np ? np->full_name : "<NULL>"); + + /* XXX most callers don't release the returned node + * mostly because ppc64 doesn't increase the refcount, + * we need to fix that. */ - if (machine_is(powermac) && busnr >= 0xf0) - busnr -= 0xf0; - else -#endif - if (pci_to_OF_bus_map) - busnr = pci_to_OF_bus_map[busnr]; - if (busnr == 0xff) - return NULL; - - /* Now, lookup childs of the hose */ - return scan_OF_childs_for_device(node->child, busnr, devfn); + return np; } EXPORT_SYMBOL(pci_busdev_to_OF_node); @@ -1544,7 +1552,7 @@ pci_resource_to_bus(struct pci_dev *pdev, struct resource *res) static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, - unsigned long *offset, + resource_size_t *offset, enum pci_mmap_state mmap_state) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); @@ -1556,7 +1564,9 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* If memory, add on the PCI bridge address offset */ if (mmap_state == pci_mmap_mem) { +#if 0 /* See comment in pci_resource_to_user() for why this is disabled */ *offset += hose->pci_mem_offset; +#endif res_bit = IORESOURCE_MEM; } else { io_offset = hose->io_base_virt - (void __iomem *)_IO_BASE; @@ -1624,9 +1634,6 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, else prot |= _PAGE_GUARDED; - printk("PCI map for %s:%llx, prot: %lx\n", pci_name(dev), - (unsigned long long)rp->start, prot); - return __pgprot(prot); } @@ -1695,7 +1702,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT; struct resource *rp; int ret; @@ -1808,22 +1815,42 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, resource_size_t *start, resource_size_t *end) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); - unsigned long offset = 0; + resource_size_t offset = 0; if (hose == NULL) return; if (rsrc->flags & IORESOURCE_IO) - offset = (void __iomem *)_IO_BASE - hose->io_base_virt - + hose->io_base_phys; + offset = (unsigned long)hose->io_base_virt - _IO_BASE; + + /* We pass a fully fixed up address to userland for MMIO instead of + * a BAR value because X is lame and expects to be able to use that + * to pass to /dev/mem ! + * + * That means that we'll have potentially 64 bits values where some + * userland apps only expect 32 (like X itself since it thinks only + * Sparc has 64 bits MMIO) but if we don't do that, we break it on + * 32 bits CHRPs :-( + * + * Hopefully, the sysfs insterface is immune to that gunk. Once X + * has been fixed (and the fix spread enough), we can re-enable the + * 2 lines below and pass down a BAR value to userland. In that case + * we'll also have to re-enable the matching code in + * __pci_mmap_make_offset(). + * + * BenH. + */ +#if 0 + else if (rsrc->flags & IORESOURCE_MEM) + offset = hose->pci_mem_offset; +#endif - *start = rsrc->start + offset; - *end = rsrc->end + offset; + *start = rsrc->start - offset; + *end = rsrc->end - offset; } -void __init -pci_init_resource(struct resource *res, unsigned long start, unsigned long end, - int flags, char *name) +void __init pci_init_resource(struct resource *res, resource_size_t start, + resource_size_t end, int flags, char *name) { res->start = start; res->end = end; diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 6fa9a0a5c8db..a6b7692c7269 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -682,7 +682,7 @@ int pci_proc_domain(struct pci_bus *bus) * Returns negative error code on failure, zero on success. */ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, - unsigned long *offset, + resource_size_t *offset, enum pci_mmap_state mmap_state) { struct pci_controller *hose = pci_bus_to_host(dev->bus); @@ -694,7 +694,9 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* If memory, add on the PCI bridge address offset */ if (mmap_state == pci_mmap_mem) { +#if 0 /* See comment in pci_resource_to_user() for why this is disabled */ *offset += hose->pci_mem_offset; +#endif res_bit = IORESOURCE_MEM; } else { io_offset = (unsigned long)hose->io_base_virt - pci_io_base; @@ -762,9 +764,6 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, else prot |= _PAGE_GUARDED; - printk(KERN_DEBUG "PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start, - prot); - return __pgprot(prot); } @@ -832,7 +831,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT; struct resource *rp; int ret; @@ -1333,20 +1332,41 @@ EXPORT_SYMBOL(pci_read_irq_line); void pci_resource_to_user(const struct pci_dev *dev, int bar, const struct resource *rsrc, - u64 *start, u64 *end) + resource_size_t *start, resource_size_t *end) { struct pci_controller *hose = pci_bus_to_host(dev->bus); - unsigned long offset = 0; + resource_size_t offset = 0; if (hose == NULL) return; if (rsrc->flags & IORESOURCE_IO) - offset = pci_io_base - (unsigned long)hose->io_base_virt + - hose->io_base_phys; + offset = (unsigned long)hose->io_base_virt - pci_io_base; + + /* We pass a fully fixed up address to userland for MMIO instead of + * a BAR value because X is lame and expects to be able to use that + * to pass to /dev/mem ! + * + * That means that we'll have potentially 64 bits values where some + * userland apps only expect 32 (like X itself since it thinks only + * Sparc has 64 bits MMIO) but if we don't do that, we break it on + * 32 bits CHRPs :-( + * + * Hopefully, the sysfs insterface is immune to that gunk. Once X + * has been fixed (and the fix spread enough), we can re-enable the + * 2 lines below and pass down a BAR value to userland. In that case + * we'll also have to re-enable the matching code in + * __pci_mmap_make_offset(). + * + * BenH. + */ +#if 0 + else if (rsrc->flags & IORESOURCE_MEM) + offset = hose->pci_mem_offset; +#endif - *start = rsrc->start + offset; - *end = rsrc->end + offset; + *start = rsrc->start - offset; + *end = rsrc->end - offset; } struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 9179f0739ea2..95776b6af4e2 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -208,7 +208,7 @@ EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */ extern long *intercept_table; EXPORT_SYMBOL(intercept_table); #endif /* CONFIG_PPC_STD_MMU_32 */ -#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) +#ifdef CONFIG_PPC_DCR_NATIVE EXPORT_SYMBOL(__mtdcr); EXPORT_SYMBOL(__mfdcr); #endif diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index c18dbe77fdc2..1fc732a552db 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -804,6 +804,56 @@ static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp) return of_read_ulong(p, s); } +#ifdef CONFIG_PPC_PSERIES +/* + * Interpret the ibm,dynamic-memory property in the + * /ibm,dynamic-reconfiguration-memory node. + * This contains a list of memory blocks along with NUMA affinity + * information. + */ +static int __init early_init_dt_scan_drconf_memory(unsigned long node) +{ + cell_t *dm, *ls; + unsigned long l, n; + unsigned long base, size, lmb_size, flags; + + ls = (cell_t *)of_get_flat_dt_prop(node, "ibm,lmb-size", &l); + if (ls == NULL || l < dt_root_size_cells * sizeof(cell_t)) + return 0; + lmb_size = dt_mem_next_cell(dt_root_size_cells, &ls); + + dm = (cell_t *)of_get_flat_dt_prop(node, "ibm,dynamic-memory", &l); + if (dm == NULL || l < sizeof(cell_t)) + return 0; + + n = *dm++; /* number of entries */ + if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(cell_t)) + return 0; + + for (; n != 0; --n) { + base = dt_mem_next_cell(dt_root_addr_cells, &dm); + flags = dm[3]; + /* skip DRC index, pad, assoc. list index, flags */ + dm += 4; + /* skip this block if the reserved bit is set in flags (0x80) + or if the block is not assigned to this partition (0x8) */ + if ((flags & 0x80) || !(flags & 0x8)) + continue; + size = lmb_size; + if (iommu_is_off) { + if (base >= 0x80000000ul) + continue; + if ((base + size) > 0x80000000ul) + size = 0x80000000ul - base; + } + lmb_add(base, size); + } + lmb_dump_all(); + return 0; +} +#else +#define early_init_dt_scan_drconf_memory(node) 0 +#endif /* CONFIG_PPC_PSERIES */ static int __init early_init_dt_scan_memory(unsigned long node, const char *uname, int depth, void *data) @@ -812,6 +862,11 @@ static int __init early_init_dt_scan_memory(unsigned long node, cell_t *reg, *endp; unsigned long l; + /* Look for the ibm,dynamic-reconfiguration-memory node */ + if (depth == 1 && + strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0) + return early_init_dt_scan_drconf_memory(node); + /* We are scanning "memory" nodes only */ if (type == NULL) { /* diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 46cf32670ddb..520ef42f642e 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -679,7 +679,7 @@ static unsigned char ibm_architecture_vec[] = { /* option vector 5: PAPR/OF options */ 3 - 2, /* length */ 0, /* don't ignore, don't halt */ - OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES, + OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY, }; /* Old method - ELF header with PT_NOTE sections */ diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 387ed0d9ad61..76b5d7ebdcc6 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -303,6 +303,12 @@ int rtas_token(const char *service) } EXPORT_SYMBOL(rtas_token); +int rtas_service_present(const char *service) +{ + return rtas_token(service) != RTAS_UNKNOWN_SERVICE; +} +EXPORT_SYMBOL(rtas_service_present); + #ifdef CONFIG_RTAS_ERROR_LOGGING /* * Return the firmware-specified size of the error log buffer @@ -810,32 +816,6 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) return 0; } -#ifdef CONFIG_HOTPLUG_CPU -/* This version can't take the spinlock, because it never returns */ -static struct rtas_args rtas_stop_self_args = { - /* The token is initialized for real in setup_system() */ - .token = RTAS_UNKNOWN_SERVICE, - .nargs = 0, - .nret = 1, - .rets = &rtas_stop_self_args.args[0], -}; - -void rtas_stop_self(void) -{ - struct rtas_args *rtas_args = &rtas_stop_self_args; - - local_irq_disable(); - - BUG_ON(rtas_args->token == RTAS_UNKNOWN_SERVICE); - - printk("cpu %u (hwid %u) Ready to die...\n", - smp_processor_id(), hard_smp_processor_id()); - enter_rtas(__pa(rtas_args)); - - panic("Alas, I survived.\n"); -} -#endif - /* * Call early during boot, before mem init or bootmem, to retrieve the RTAS * informations from the device-tree and allocate the RMO buffer for userland @@ -880,9 +860,6 @@ void __init rtas_initialize(void) #endif rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region); -#ifdef CONFIG_HOTPLUG_CPU - rtas_stop_self_args.token = rtas_token("stop-self"); -#endif /* CONFIG_HOTPLUG_CPU */ #ifdef CONFIG_RTAS_ERROR_LOGGING rtas_last_error_token = rtas_token("rtas-last-error"); #endif diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 63ed265b7f09..400ab2b946e7 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -181,6 +181,8 @@ SYSFS_PMCSETUP(pmc6, SPRN_PMC6); SYSFS_PMCSETUP(pmc7, SPRN_PMC7); SYSFS_PMCSETUP(pmc8, SPRN_PMC8); SYSFS_PMCSETUP(purr, SPRN_PURR); +SYSFS_PMCSETUP(spurr, SPRN_SPURR); +SYSFS_PMCSETUP(dscr, SPRN_DSCR); static SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0); static SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1); @@ -194,6 +196,8 @@ static SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6); static SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7); static SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8); static SYSDEV_ATTR(purr, 0600, show_purr, NULL); +static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL); +static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr); static void register_cpu_online(unsigned int cpu) { @@ -231,6 +235,12 @@ static void register_cpu_online(unsigned int cpu) if (cpu_has_feature(CPU_FTR_PURR)) sysdev_create_file(s, &attr_purr); + + if (cpu_has_feature(CPU_FTR_SPURR)) + sysdev_create_file(s, &attr_spurr); + + if (cpu_has_feature(CPU_FTR_DSCR)) + sysdev_create_file(s, &attr_dscr); } #ifdef CONFIG_HOTPLUG_CPU @@ -272,6 +282,12 @@ static void unregister_cpu_online(unsigned int cpu) if (cpu_has_feature(CPU_FTR_PURR)) sysdev_remove_file(s, &attr_purr); + + if (cpu_has_feature(CPU_FTR_SPURR)) + sysdev_remove_file(s, &attr_spurr); + + if (cpu_has_feature(CPU_FTR_DSCR)) + sysdev_remove_file(s, &attr_dscr); } #endif /* CONFIG_HOTPLUG_CPU */ diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 0d4e203fa7a0..535f50665647 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -32,6 +32,7 @@ #include <linux/kprobes.h> #include <linux/kexec.h> #include <linux/backlight.h> +#include <linux/bug.h> #include <asm/kdebug.h> #include <asm/pgtable.h> @@ -727,54 +728,9 @@ static int emulate_instruction(struct pt_regs *regs) return -EINVAL; } -/* - * Look through the list of trap instructions that are used for BUG(), - * BUG_ON() and WARN_ON() and see if we hit one. At this point we know - * that the exception was caused by a trap instruction of some kind. - * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0 - * otherwise. - */ -extern struct bug_entry __start___bug_table[], __stop___bug_table[]; - -#ifndef CONFIG_MODULES -#define module_find_bug(x) NULL -#endif - -struct bug_entry *find_bug(unsigned long bugaddr) +int is_valid_bugaddr(unsigned long addr) { - struct bug_entry *bug; - - for (bug = __start___bug_table; bug < __stop___bug_table; ++bug) - if (bugaddr == bug->bug_addr) - return bug; - return module_find_bug(bugaddr); -} - -static int check_bug_trap(struct pt_regs *regs) -{ - struct bug_entry *bug; - unsigned long addr; - - if (regs->msr & MSR_PR) - return 0; /* not in kernel */ - addr = regs->nip; /* address of trap instruction */ - if (addr < PAGE_OFFSET) - return 0; - bug = find_bug(regs->nip); - if (bug == NULL) - return 0; - if (bug->line & BUG_WARNING_TRAP) { - /* this is a WARN_ON rather than BUG/BUG_ON */ - printk(KERN_ERR "Badness in %s at %s:%ld\n", - bug->function, bug->file, - bug->line & ~BUG_WARNING_TRAP); - dump_stack(); - return 1; - } - printk(KERN_CRIT "kernel BUG in %s at %s:%ld!\n", - bug->function, bug->file, bug->line); - - return 0; + return is_kernel_addr(addr); } void __kprobes program_check_exception(struct pt_regs *regs) @@ -782,6 +738,8 @@ void __kprobes program_check_exception(struct pt_regs *regs) unsigned int reason = get_reason(regs); extern int do_mathemu(struct pt_regs *regs); + /* We can now get here via a FP Unavailable exception if the core + * has no FPU, in that case no reason flags will be set */ #ifdef CONFIG_MATH_EMULATION /* (reason & REASON_ILLEGAL) would be the obvious thing here, * but there seems to be a hardware bug on the 405GP (RevD) @@ -808,7 +766,9 @@ void __kprobes program_check_exception(struct pt_regs *regs) return; if (debugger_bpt(regs)) return; - if (check_bug_trap(regs)) { + + if (!(regs->msr & MSR_PR) && /* not user-mode */ + report_bug(regs->nip) == BUG_TRAP_TYPE_WARN) { regs->nip += 4; return; } diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 04b98671a060..04b8e71bf5b0 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -62,11 +62,7 @@ SECTIONS __stop___ex_table = .; } - __bug_table : { - __start___bug_table = .; - *(__bug_table) - __stop___bug_table = .; - } + BUG_TABLE /* * Init sections discarded at runtime diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 9da01dc8cfd9..262790910ff2 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -295,6 +295,63 @@ static unsigned long __init numa_enforce_memory_limit(unsigned long start, return lmb_end_of_DRAM() - start; } +/* + * Extract NUMA information from the ibm,dynamic-reconfiguration-memory + * node. This assumes n_mem_{addr,size}_cells have been set. + */ +static void __init parse_drconf_memory(struct device_node *memory) +{ + const unsigned int *lm, *dm, *aa; + unsigned int ls, ld, la; + unsigned int n, aam, aalen; + unsigned long lmb_size, size; + int nid, default_nid = 0; + unsigned int start, ai, flags; + + lm = get_property(memory, "ibm,lmb-size", &ls); + dm = get_property(memory, "ibm,dynamic-memory", &ld); + aa = get_property(memory, "ibm,associativity-lookup-arrays", &la); + if (!lm || !dm || !aa || + ls < sizeof(unsigned int) || ld < sizeof(unsigned int) || + la < 2 * sizeof(unsigned int)) + return; + + lmb_size = read_n_cells(n_mem_size_cells, &lm); + n = *dm++; /* number of LMBs */ + aam = *aa++; /* number of associativity lists */ + aalen = *aa++; /* length of each associativity list */ + if (ld < (n * (n_mem_addr_cells + 4) + 1) * sizeof(unsigned int) || + la < (aam * aalen + 2) * sizeof(unsigned int)) + return; + + for (; n != 0; --n) { + start = read_n_cells(n_mem_addr_cells, &dm); + ai = dm[2]; + flags = dm[3]; + dm += 4; + /* 0x80 == reserved, 0x8 = assigned to us */ + if ((flags & 0x80) || !(flags & 0x8)) + continue; + nid = default_nid; + /* flags & 0x40 means associativity index is invalid */ + if (min_common_depth > 0 && min_common_depth <= aalen && + (flags & 0x40) == 0 && ai < aam) { + /* this is like of_node_to_nid_single */ + nid = aa[ai * aalen + min_common_depth - 1]; + if (nid == 0xffff || nid >= MAX_NUMNODES) + nid = default_nid; + } + node_set_online(nid); + + size = numa_enforce_memory_limit(start, lmb_size); + if (!size) + continue; + + add_active_range(nid, start >> PAGE_SHIFT, + (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT)); + } +} + static int __init parse_numa_properties(void) { struct device_node *cpu = NULL; @@ -385,6 +442,14 @@ new_range: goto new_range; } + /* + * Now do the same thing for each LMB listed in the ibm,dynamic-memory + * property in the ibm,dynamic-reconfiguration-memory node. + */ + memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); + if (memory) + parse_drconf_memory(memory); + return 0; } diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c index a375c15b4315..eaff71e74fb0 100644 --- a/arch/powerpc/platforms/52xx/lite5200.c +++ b/arch/powerpc/platforms/52xx/lite5200.c @@ -40,8 +40,6 @@ #include <asm/prom.h> #include <asm/udbg.h> #include <sysdev/fsl_soc.h> -#include <asm/qe.h> -#include <asm/qe_ic.h> #include <asm/of_platform.h> #include <asm/mpc52xx.h> diff --git a/arch/powerpc/platforms/cell/cbe_thermal.c b/arch/powerpc/platforms/cell/cbe_thermal.c index 616a0a3fd0e2..70e0d968d30f 100644 --- a/arch/powerpc/platforms/cell/cbe_thermal.c +++ b/arch/powerpc/platforms/cell/cbe_thermal.c @@ -115,6 +115,7 @@ static struct sysdev_attribute attr_spu_temperature = { static struct attribute *spu_attributes[] = { &attr_spu_temperature.attr, + NULL, }; static struct attribute_group spu_attribute_group = { @@ -135,6 +136,7 @@ static struct sysdev_attribute attr_ppe_temperature1 = { static struct attribute *ppe_attributes[] = { &attr_ppe_temperature0.attr, &attr_ppe_temperature1.attr, + NULL, }; static struct attribute_group ppe_attribute_group = { diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c index 99c612025e8f..d04ae1671e6c 100644 --- a/arch/powerpc/platforms/cell/pmu.c +++ b/arch/powerpc/platforms/cell/pmu.c @@ -382,11 +382,14 @@ static irqreturn_t cbe_pm_irq(int irq, void *dev_id) return IRQ_HANDLED; } -int __init cbe_init_pm_irq(void) +static int __init cbe_init_pm_irq(void) { unsigned int irq; int rc, node; + if (!machine_is(cell)) + return 0; + for_each_node(node) { irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI | (node << IIC_IRQ_NODE_SHIFT)); diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c index 26945c491f6b..725e19561159 100644 --- a/arch/powerpc/platforms/cell/spufs/coredump.c +++ b/arch/powerpc/platforms/cell/spufs/coredump.c @@ -147,7 +147,7 @@ static int spufs_arch_notes_size(void) struct fdtable *fdt = files_fdtable(current->files); int size = 0, fd; - for (fd = 0; fd < fdt->max_fdset && fd < fdt->max_fds; fd++) { + for (fd = 0; fd < fdt->max_fds; fd++) { if (FD_ISSET(fd, fdt->open_fds)) { struct file *file = fcheck(fd); diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index 3a32deda765d..3f6a69f67195 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c @@ -562,7 +562,7 @@ void __init maple_pci_init(void) for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) { if (np->name == NULL) continue; - if (strcmp(np->name, "pci") == 0) { + if (!strcmp(np->name, "pci") || !strcmp(np->name, "pcie")) { if (add_bridge(np) == 0) of_node_get(np); } diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index 094989d50bab..f12d5c69e74d 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c @@ -60,6 +60,7 @@ #include <asm/of_device.h> #include <asm/lmb.h> #include <asm/mpic.h> +#include <asm/rtas.h> #include <asm/udbg.h> #include "maple.h" @@ -166,6 +167,16 @@ struct smp_ops_t maple_smp_ops = { }; #endif /* CONFIG_SMP */ +static void __init maple_use_rtas_reboot_and_halt_if_present(void) +{ + if (rtas_service_present("system-reboot") && + rtas_service_present("power-off")) { + ppc_md.restart = rtas_restart; + ppc_md.power_off = rtas_power_off; + ppc_md.halt = rtas_halt; + } +} + void __init maple_setup_arch(void) { /* init to some ~sane value until calibrate_delay() runs */ @@ -181,6 +192,7 @@ void __init maple_setup_arch(void) #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif + maple_use_rtas_reboot_and_halt_if_present(); printk(KERN_DEBUG "Using native/NAP idle loop\n"); } diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig index 451bfcd5502e..de52ec4e9e58 100644 --- a/arch/powerpc/platforms/ps3/Kconfig +++ b/arch/powerpc/platforms/ps3/Kconfig @@ -40,4 +40,15 @@ config PS3_USE_LPAR_ADDR If you have any doubt, choose the default y. +config PS3_VUART + depends on PPC_PS3 + bool "PS3 Virtual UART support" + default y + help + Include support for the PS3 Virtual UART. + + This support is required for several system services + including the System Manager and AV Settings. In + general, all users will say Y. + endmenu diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 997243a91be8..69590fbf83da 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -10,6 +10,8 @@ obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_SCANLOG) += scanlog.o obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o +obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o + obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_HVCS) += hvcserver.o obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 3c2d63ebf787..da6e5362e7cd 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c @@ -337,6 +337,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) printk (KERN_ERR "EEH: Device driver ignored %d bad reads, panicing\n", pdn->eeh_check_count); dump_stack(); + msleep(5000); /* re-read the slot reset state */ if (read_slot_reset_state(pdn, rets) != 0) diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c index c2bc9904f1cb..cbd6b0711ab4 100644 --- a/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/arch/powerpc/platforms/pseries/eeh_driver.c @@ -170,14 +170,19 @@ static void eeh_report_reset(struct pci_dev *dev, void *userdata) static void eeh_report_resume(struct pci_dev *dev, void *userdata) { struct pci_driver *driver = dev->driver; + struct device_node *dn = pci_device_to_OF_node(dev); dev->error_state = pci_channel_io_normal; if (!driver) return; - if (!driver->err_handler) - return; - if (!driver->err_handler->resume) + + if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) { + PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED; + enable_irq(dev->irq); + } + if (!driver->err_handler || + !driver->err_handler->resume) return; driver->err_handler->resume(dev); @@ -407,6 +412,8 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) if (rc) result = PCI_ERS_RESULT_NEED_RESET; + else + result = PCI_ERS_RESULT_RECOVERED; } /* If any device has a hard failure, then shut off everything. */ diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c new file mode 100644 index 000000000000..f460b9cbfd46 --- /dev/null +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -0,0 +1,275 @@ +/* + * pseries CPU Hotplug infrastructure. + * + * Split out from arch/powerpc/platforms/pseries/setup.c + * arch/powerpc/kernel/rtas.c, and arch/powerpc/platforms/pseries/smp.c + * + * Peter Bergner, IBM March 2001. + * Copyright (C) 2001 IBM. + * Dave Engebretsen, Peter Bergner, and + * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com + * Plus various changes from other IBM teams... + * + * Copyright (C) 2006 Michael Ellerman, 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. + */ + +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/cpu.h> +#include <asm/system.h> +#include <asm/prom.h> +#include <asm/rtas.h> +#include <asm/firmware.h> +#include <asm/machdep.h> +#include <asm/vdso_datapage.h> +#include <asm/pSeries_reconfig.h> +#include "xics.h" + +/* This version can't take the spinlock, because it never returns */ +static struct rtas_args rtas_stop_self_args = { + .token = RTAS_UNKNOWN_SERVICE, + .nargs = 0, + .nret = 1, + .rets = &rtas_stop_self_args.args[0], +}; + +static void rtas_stop_self(void) +{ + struct rtas_args *args = &rtas_stop_self_args; + + local_irq_disable(); + + BUG_ON(args->token == RTAS_UNKNOWN_SERVICE); + + printk("cpu %u (hwid %u) Ready to die...\n", + smp_processor_id(), hard_smp_processor_id()); + enter_rtas(__pa(args)); + + panic("Alas, I survived.\n"); +} + +static void pseries_mach_cpu_die(void) +{ + local_irq_disable(); + idle_task_exit(); + xics_teardown_cpu(0); + rtas_stop_self(); + /* Should never get here... */ + BUG(); + for(;;); +} + +static int qcss_tok; /* query-cpu-stopped-state token */ + +/* Get state of physical CPU. + * Return codes: + * 0 - The processor is in the RTAS stopped state + * 1 - stop-self is in progress + * 2 - The processor is not in the RTAS stopped state + * -1 - Hardware Error + * -2 - Hardware Busy, Try again later. + */ +static int query_cpu_stopped(unsigned int pcpu) +{ + int cpu_status, status; + + status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu); + if (status != 0) { + printk(KERN_ERR + "RTAS query-cpu-stopped-state failed: %i\n", status); + return status; + } + + return cpu_status; +} + +static int pseries_cpu_disable(void) +{ + int cpu = smp_processor_id(); + + cpu_clear(cpu, cpu_online_map); + vdso_data->processorCount--; + + /*fix boot_cpuid here*/ + if (cpu == boot_cpuid) + boot_cpuid = any_online_cpu(cpu_online_map); + + /* FIXME: abstract this to not be platform specific later on */ + xics_migrate_irqs_away(); + return 0; +} + +static void pseries_cpu_die(unsigned int cpu) +{ + int tries; + int cpu_status; + unsigned int pcpu = get_hard_smp_processor_id(cpu); + + for (tries = 0; tries < 25; tries++) { + cpu_status = query_cpu_stopped(pcpu); + if (cpu_status == 0 || cpu_status == -1) + break; + msleep(200); + } + if (cpu_status != 0) { + printk("Querying DEAD? cpu %i (%i) shows %i\n", + cpu, pcpu, cpu_status); + } + + /* Isolation and deallocation are definatly done by + * drslot_chrp_cpu. If they were not they would be + * done here. Change isolate state to Isolate and + * change allocation-state to Unusable. + */ + paca[cpu].cpu_start = 0; +} + +/* + * Update cpu_present_map and paca(s) for a new cpu node. The wrinkle + * here is that a cpu device node may represent up to two logical cpus + * in the SMT case. We must honor the assumption in other code that + * the logical ids for sibling SMT threads x and y are adjacent, such + * that x^1 == y and y^1 == x. + */ +static int pseries_add_processor(struct device_node *np) +{ + unsigned int cpu; + cpumask_t candidate_map, tmp = CPU_MASK_NONE; + int err = -ENOSPC, len, nthreads, i; + const u32 *intserv; + + intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); + if (!intserv) + return 0; + + nthreads = len / sizeof(u32); + for (i = 0; i < nthreads; i++) + cpu_set(i, tmp); + + lock_cpu_hotplug(); + + BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map)); + + /* Get a bitmap of unoccupied slots. */ + cpus_xor(candidate_map, cpu_possible_map, cpu_present_map); + if (cpus_empty(candidate_map)) { + /* If we get here, it most likely means that NR_CPUS is + * less than the partition's max processors setting. + */ + printk(KERN_ERR "Cannot add cpu %s; this system configuration" + " supports %d logical cpus.\n", np->full_name, + cpus_weight(cpu_possible_map)); + goto out_unlock; + } + + while (!cpus_empty(tmp)) + if (cpus_subset(tmp, candidate_map)) + /* Found a range where we can insert the new cpu(s) */ + break; + else + cpus_shift_left(tmp, tmp, nthreads); + + if (cpus_empty(tmp)) { + printk(KERN_ERR "Unable to find space in cpu_present_map for" + " processor %s with %d thread(s)\n", np->name, + nthreads); + goto out_unlock; + } + + for_each_cpu_mask(cpu, tmp) { + BUG_ON(cpu_isset(cpu, cpu_present_map)); + cpu_set(cpu, cpu_present_map); + set_hard_smp_processor_id(cpu, *intserv++); + } + err = 0; +out_unlock: + unlock_cpu_hotplug(); + return err; +} + +/* + * Update the present map for a cpu node which is going away, and set + * the hard id in the paca(s) to -1 to be consistent with boot time + * convention for non-present cpus. + */ +static void pseries_remove_processor(struct device_node *np) +{ + unsigned int cpu; + int len, nthreads, i; + const u32 *intserv; + + intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); + if (!intserv) + return; + + nthreads = len / sizeof(u32); + + lock_cpu_hotplug(); + for (i = 0; i < nthreads; i++) { + for_each_present_cpu(cpu) { + if (get_hard_smp_processor_id(cpu) != intserv[i]) + continue; + BUG_ON(cpu_online(cpu)); + cpu_clear(cpu, cpu_present_map); + set_hard_smp_processor_id(cpu, -1); + break; + } + if (cpu == NR_CPUS) + printk(KERN_WARNING "Could not find cpu to remove " + "with physical id 0x%x\n", intserv[i]); + } + unlock_cpu_hotplug(); +} + +static int pseries_smp_notifier(struct notifier_block *nb, + unsigned long action, void *node) +{ + int err = NOTIFY_OK; + + switch (action) { + case PSERIES_RECONFIG_ADD: + if (pseries_add_processor(node)) + err = NOTIFY_BAD; + break; + case PSERIES_RECONFIG_REMOVE: + pseries_remove_processor(node); + break; + default: + err = NOTIFY_DONE; + break; + } + return err; +} + +static struct notifier_block pseries_smp_nb = { + .notifier_call = pseries_smp_notifier, +}; + +static int __init pseries_cpu_hotplug_init(void) +{ + rtas_stop_self_args.token = rtas_token("stop-self"); + qcss_tok = rtas_token("query-cpu-stopped-state"); + + if (rtas_stop_self_args.token == RTAS_UNKNOWN_SERVICE || + qcss_tok == RTAS_UNKNOWN_SERVICE) { + printk(KERN_INFO "CPU Hotplug not supported by firmware " + "- disabling.\n"); + return 0; + } + + ppc_md.cpu_die = pseries_mach_cpu_die; + smp_ops->cpu_disable = pseries_cpu_disable; + smp_ops->cpu_die = pseries_cpu_die; + + /* Processors can be added/removed only on LPAR */ + if (firmware_has_feature(FW_FEATURE_LPAR)) + pSeries_reconfig_notifier_register(&pseries_smp_nb); + + return 0; +} +arch_initcall(pseries_cpu_hotplug_init); diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 0dc2548ca9bc..042ecae107ac 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -347,21 +347,6 @@ static int __init pSeries_init_panel(void) } arch_initcall(pSeries_init_panel); -#ifdef CONFIG_HOTPLUG_CPU -static void pSeries_mach_cpu_die(void) -{ - local_irq_disable(); - idle_task_exit(); - xics_teardown_cpu(0); - rtas_stop_self(); - /* Should never get here... */ - BUG(); - for(;;); -} -#else -#define pSeries_mach_cpu_die NULL -#endif - static int pseries_set_dabr(unsigned long dabr) { return plpar_hcall_norets(H_SET_DABR, dabr); @@ -437,19 +422,14 @@ static int __init pSeries_probe_hypertas(unsigned long node, if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) powerpc_firmware_features |= FW_FEATURE_LPAR; - if (firmware_has_feature(FW_FEATURE_LPAR)) - hpte_init_lpar(); - else - hpte_init_native(); - return 1; } static int __init pSeries_probe(void) { unsigned long root = of_get_flat_dt_root(); - char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(), - "device_type", NULL); + char *dtype = of_get_flat_dt_prop(root, "device_type", NULL); + if (dtype == NULL) return 0; if (strcmp(dtype, "chrp")) @@ -467,6 +447,11 @@ static int __init pSeries_probe(void) /* Now try to figure out if we are running on LPAR */ of_scan_flat_dt(pSeries_probe_hypertas, NULL); + if (firmware_has_feature(FW_FEATURE_LPAR)) + hpte_init_lpar(); + else + hpte_init_native(); + DBG("Machine is%s LPAR !\n", (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not"); @@ -561,7 +546,6 @@ define_machine(pseries) { .power_off = rtas_power_off, .halt = rtas_halt, .panic = rtas_os_term, - .cpu_die = pSeries_mach_cpu_die, .get_boot_time = rtas_get_boot_time, .get_rtc_time = rtas_get_rtc_time, .set_rtc_time = rtas_set_rtc_time, diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index c6624b8a0e77..4408518eaebe 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -64,197 +64,6 @@ static cpumask_t of_spin_map; extern void generic_secondary_smp_init(unsigned long); -#ifdef CONFIG_HOTPLUG_CPU - -/* Get state of physical CPU. - * Return codes: - * 0 - The processor is in the RTAS stopped state - * 1 - stop-self is in progress - * 2 - The processor is not in the RTAS stopped state - * -1 - Hardware Error - * -2 - Hardware Busy, Try again later. - */ -static int query_cpu_stopped(unsigned int pcpu) -{ - int cpu_status; - int status, qcss_tok; - - qcss_tok = rtas_token("query-cpu-stopped-state"); - if (qcss_tok == RTAS_UNKNOWN_SERVICE) - return -1; - status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu); - if (status != 0) { - printk(KERN_ERR - "RTAS query-cpu-stopped-state failed: %i\n", status); - return status; - } - - return cpu_status; -} - -static int pSeries_cpu_disable(void) -{ - int cpu = smp_processor_id(); - - cpu_clear(cpu, cpu_online_map); - vdso_data->processorCount--; - - /*fix boot_cpuid here*/ - if (cpu == boot_cpuid) - boot_cpuid = any_online_cpu(cpu_online_map); - - /* FIXME: abstract this to not be platform specific later on */ - xics_migrate_irqs_away(); - return 0; -} - -static void pSeries_cpu_die(unsigned int cpu) -{ - int tries; - int cpu_status; - unsigned int pcpu = get_hard_smp_processor_id(cpu); - - for (tries = 0; tries < 25; tries++) { - cpu_status = query_cpu_stopped(pcpu); - if (cpu_status == 0 || cpu_status == -1) - break; - msleep(200); - } - if (cpu_status != 0) { - printk("Querying DEAD? cpu %i (%i) shows %i\n", - cpu, pcpu, cpu_status); - } - - /* Isolation and deallocation are definatly done by - * drslot_chrp_cpu. If they were not they would be - * done here. Change isolate state to Isolate and - * change allocation-state to Unusable. - */ - paca[cpu].cpu_start = 0; -} - -/* - * Update cpu_present_map and paca(s) for a new cpu node. The wrinkle - * here is that a cpu device node may represent up to two logical cpus - * in the SMT case. We must honor the assumption in other code that - * the logical ids for sibling SMT threads x and y are adjacent, such - * that x^1 == y and y^1 == x. - */ -static int pSeries_add_processor(struct device_node *np) -{ - unsigned int cpu; - cpumask_t candidate_map, tmp = CPU_MASK_NONE; - int err = -ENOSPC, len, nthreads, i; - const u32 *intserv; - - intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); - if (!intserv) - return 0; - - nthreads = len / sizeof(u32); - for (i = 0; i < nthreads; i++) - cpu_set(i, tmp); - - lock_cpu_hotplug(); - - BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map)); - - /* Get a bitmap of unoccupied slots. */ - cpus_xor(candidate_map, cpu_possible_map, cpu_present_map); - if (cpus_empty(candidate_map)) { - /* If we get here, it most likely means that NR_CPUS is - * less than the partition's max processors setting. - */ - printk(KERN_ERR "Cannot add cpu %s; this system configuration" - " supports %d logical cpus.\n", np->full_name, - cpus_weight(cpu_possible_map)); - goto out_unlock; - } - - while (!cpus_empty(tmp)) - if (cpus_subset(tmp, candidate_map)) - /* Found a range where we can insert the new cpu(s) */ - break; - else - cpus_shift_left(tmp, tmp, nthreads); - - if (cpus_empty(tmp)) { - printk(KERN_ERR "Unable to find space in cpu_present_map for" - " processor %s with %d thread(s)\n", np->name, - nthreads); - goto out_unlock; - } - - for_each_cpu_mask(cpu, tmp) { - BUG_ON(cpu_isset(cpu, cpu_present_map)); - cpu_set(cpu, cpu_present_map); - set_hard_smp_processor_id(cpu, *intserv++); - } - err = 0; -out_unlock: - unlock_cpu_hotplug(); - return err; -} - -/* - * Update the present map for a cpu node which is going away, and set - * the hard id in the paca(s) to -1 to be consistent with boot time - * convention for non-present cpus. - */ -static void pSeries_remove_processor(struct device_node *np) -{ - unsigned int cpu; - int len, nthreads, i; - const u32 *intserv; - - intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); - if (!intserv) - return; - - nthreads = len / sizeof(u32); - - lock_cpu_hotplug(); - for (i = 0; i < nthreads; i++) { - for_each_present_cpu(cpu) { - if (get_hard_smp_processor_id(cpu) != intserv[i]) - continue; - BUG_ON(cpu_online(cpu)); - cpu_clear(cpu, cpu_present_map); - set_hard_smp_processor_id(cpu, -1); - break; - } - if (cpu == NR_CPUS) - printk(KERN_WARNING "Could not find cpu to remove " - "with physical id 0x%x\n", intserv[i]); - } - unlock_cpu_hotplug(); -} - -static int pSeries_smp_notifier(struct notifier_block *nb, unsigned long action, void *node) -{ - int err = NOTIFY_OK; - - switch (action) { - case PSERIES_RECONFIG_ADD: - if (pSeries_add_processor(node)) - err = NOTIFY_BAD; - break; - case PSERIES_RECONFIG_REMOVE: - pSeries_remove_processor(node); - break; - default: - err = NOTIFY_DONE; - break; - } - return err; -} - -static struct notifier_block pSeries_smp_nb = { - .notifier_call = pSeries_smp_notifier, -}; - -#endif /* CONFIG_HOTPLUG_CPU */ - /** * smp_startup_cpu() - start the given cpu * @@ -422,15 +231,6 @@ static void __init smp_init_pseries(void) DBG(" -> smp_init_pSeries()\n"); -#ifdef CONFIG_HOTPLUG_CPU - smp_ops->cpu_disable = pSeries_cpu_disable; - smp_ops->cpu_die = pSeries_cpu_die; - - /* Processors can be added/removed only on LPAR */ - if (firmware_has_feature(FW_FEATURE_LPAR)) - pSeries_reconfig_notifier_register(&pSeries_smp_nb); -#endif - /* Mark threads which are still spinning in hold loops. */ if (cpu_has_feature(CPU_FTR_SMT)) { for_each_present_cpu(i) { diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 6cc34597a620..04d4917eb303 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -5,7 +5,8 @@ endif obj-$(CONFIG_MPIC) += mpic.o obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o obj-$(CONFIG_PPC_MPC106) += grackle.o -obj-$(CONFIG_PPC_DCR) += dcr.o dcr-low.o +obj-$(CONFIG_PPC_DCR) += dcr.o +obj-$(CONFIG_PPC_DCR_NATIVE) += dcr-low.o obj-$(CONFIG_U3_DART) += dart_iommu.o obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o diff --git a/arch/powerpc/sysdev/dcr.S b/arch/powerpc/sysdev/dcr.S deleted file mode 100644 index 2078f39e2f17..000000000000 --- a/arch/powerpc/sysdev/dcr.S +++ /dev/null @@ -1,39 +0,0 @@ -/* - * "Indirect" DCR access - * - * Copyright (c) 2004 Eugene Surovegin <ebs@ebshome.net> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <asm/ppc_asm.h> -#include <asm/processor.h> - -#define DCR_ACCESS_PROLOG(table) \ - rlwinm r3,r3,4,18,27; \ - lis r5,table@h; \ - ori r5,r5,table@l; \ - add r3,r3,r5; \ - mtctr r3; \ - bctr - -_GLOBAL(__mfdcr) - DCR_ACCESS_PROLOG(__mfdcr_table) - -_GLOBAL(__mtdcr) - DCR_ACCESS_PROLOG(__mtdcr_table) - -__mfdcr_table: - mfdcr r3,0; blr -__mtdcr_table: - mtdcr 0,r4; blr - -dcr = 1 - .rept 1023 - mfdcr r3,dcr; blr - mtdcr dcr,r4; blr - dcr = dcr + 1 - .endr diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c index 6995f51b9488..74e48d94f27c 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c @@ -223,23 +223,15 @@ static void qe_ic_mask_irq(unsigned int virq) qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg, temp & ~qe_ic_info[src].mask); - spin_unlock_irqrestore(&qe_ic_lock, flags); -} - -static void qe_ic_mask_irq_and_ack(unsigned int virq) -{ - struct qe_ic *qe_ic = qe_ic_from_irq(virq); - unsigned int src = virq_to_hw(virq); - unsigned long flags; - u32 temp; - - spin_lock_irqsave(&qe_ic_lock, flags); - - temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg); - qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg, - temp & ~qe_ic_info[src].mask); - - /* There is nothing to do for ack here, ack is handled in ISR */ + /* Flush the above write before enabling interrupts; otherwise, + * spurious interrupts will sometimes happen. To be 100% sure + * that the write has reached the device before interrupts are + * enabled, the mask register would have to be read back; however, + * this is not required for correctness, only to avoid wasting + * time on a large number of spurious interrupts. In testing, + * a sync reduced the observed spurious interrupts to zero. + */ + mb(); spin_unlock_irqrestore(&qe_ic_lock, flags); } @@ -248,7 +240,7 @@ static struct irq_chip qe_ic_irq_chip = { .typename = " QEIC ", .unmask = qe_ic_unmask_irq, .mask = qe_ic_mask_irq, - .mask_ack = qe_ic_mask_irq_and_ack, + .mask_ack = qe_ic_mask_irq, }; static int qe_ic_host_match(struct irq_host *h, struct device_node *node) @@ -331,34 +323,22 @@ unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic) return irq_linear_revmap(qe_ic->irqhost, irq); } -/* FIXME: We mask all the QE Low interrupts while handling. We should - * let other interrupt come in, but BAD interrupts are generated */ void fastcall qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc) { struct qe_ic *qe_ic = desc->handler_data; - struct irq_chip *chip = irq_desc[irq].chip; - unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic); - chip->mask_ack(irq); if (cascade_irq != NO_IRQ) generic_handle_irq(cascade_irq); - chip->unmask(irq); } -/* FIXME: We mask all the QE High interrupts while handling. We should - * let other interrupt come in, but BAD interrupts are generated */ void fastcall qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc) { struct qe_ic *qe_ic = desc->handler_data; - struct irq_chip *chip = irq_desc[irq].chip; - unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic); - chip->mask_ack(irq); if (cascade_irq != NO_IRQ) generic_handle_irq(cascade_irq); - chip->unmask(irq); } void __init qe_ic_init(struct device_node *node, unsigned int flags) diff --git a/arch/powerpc/sysdev/rom.c b/arch/powerpc/sysdev/rom.c index bf5b3f10e6c6..c855a3b298a3 100644 --- a/arch/powerpc/sysdev/rom.c +++ b/arch/powerpc/sysdev/rom.c @@ -9,6 +9,7 @@ #include <linux/kernel.h> #include <asm/of_device.h> +#include <asm/of_platform.h> static int __init powerpc_flash_init(void) { diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index a34ed49e0356..77540a2f7704 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -22,6 +22,7 @@ #include <linux/sysrq.h> #include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/bug.h> #include <asm/ptrace.h> #include <asm/string.h> @@ -35,7 +36,6 @@ #include <asm/cputable.h> #include <asm/rtas.h> #include <asm/sstep.h> -#include <asm/bug.h> #include <asm/irq_regs.h> #include <asm/spu.h> #include <asm/spu_priv1.h> @@ -1346,7 +1346,7 @@ static void backtrace(struct pt_regs *excp) static void print_bug_trap(struct pt_regs *regs) { - struct bug_entry *bug; + const struct bug_entry *bug; unsigned long addr; if (regs->msr & MSR_PR) @@ -1357,11 +1357,11 @@ static void print_bug_trap(struct pt_regs *regs) bug = find_bug(regs->nip); if (bug == NULL) return; - if (bug->line & BUG_WARNING_TRAP) + if (is_warning_bug(bug)) return; - printf("kernel BUG in %s at %s:%d!\n", - bug->function, bug->file, (unsigned int)bug->line); + printf("kernel BUG at %s:%u!\n", + bug->file, bug->line); } void excprint(struct pt_regs *fp) diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 63808e01cb0b..5e723c4c2571 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -879,7 +879,7 @@ pci_resource_to_bus(struct pci_dev *pdev, struct resource *res) static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, - unsigned long *offset, + resource_size_t *offset, enum pci_mmap_state mmap_state) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); @@ -891,7 +891,9 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* If memory, add on the PCI bridge address offset */ if (mmap_state == pci_mmap_mem) { +#if 0 /* See comment in pci_resource_to_user() for why this is disabled */ *offset += hose->pci_mem_offset; +#endif res_bit = IORESOURCE_MEM; } else { io_offset = hose->io_base_virt - ___IO_BASE; @@ -1030,7 +1032,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT; struct resource *rp; int ret; @@ -1132,21 +1134,42 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, resource_size_t *start, resource_size_t *end) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); - unsigned long offset = 0; + resource_size_t offset = 0; if (hose == NULL) return; if (rsrc->flags & IORESOURCE_IO) - offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys; + offset = (unsigned long)hose->io_base_virt - _IO_BASE; + + /* We pass a fully fixed up address to userland for MMIO instead of + * a BAR value because X is lame and expects to be able to use that + * to pass to /dev/mem ! + * + * That means that we'll have potentially 64 bits values where some + * userland apps only expect 32 (like X itself since it thinks only + * Sparc has 64 bits MMIO) but if we don't do that, we break it on + * 32 bits CHRPs :-( + * + * Hopefully, the sysfs insterface is immune to that gunk. Once X + * has been fixed (and the fix spread enough), we can re-enable the + * 2 lines below and pass down a BAR value to userland. In that case + * we'll also have to re-enable the matching code in + * __pci_mmap_make_offset(). + * + * BenH. + */ +#if 0 + else if (rsrc->flags & IORESOURCE_MEM) + offset = hose->pci_mem_offset; +#endif - *start = rsrc->start + offset; - *end = rsrc->end + offset; + *start = rsrc->start - offset; + *end = rsrc->end - offset; } -void __init -pci_init_resource(struct resource *res, unsigned long start, unsigned long end, - int flags, char *name) +void __init pci_init_resource(struct resource *res, resource_size_t start, + resource_size_t end, int flags, char *name) { res->start = start; res->end = end; diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 8e24c40662e3..3aa3b885ab36 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -479,7 +479,7 @@ config SH_CLK_MD int "CPU Mode Pin Setting" depends on CPU_SUBTYPE_SH7619 || CPU_SUBTYPE_SH7206 help - MD2 - MD0 Setting. + MD2 - MD0 pin setting. menu "CPU Frequency scaling" @@ -580,18 +580,6 @@ config NR_CPUS source "kernel/Kconfig.preempt" -config CPU_HAS_SR_RB - bool "CPU has SR.RB" - depends on CPU_SH3 || CPU_SH4 - default y - help - This will enable the use of SR.RB register bank usage. Processors - that are lacking this bit must have another method in place for - accomplishing what is taken care of by the banked registers. - - See <file:Documentation/sh/register-banks.txt> for further - information on SR.RB and register banking in the kernel in general. - config NODES_SHIFT int default "1" diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 66a25ef4ef1b..87902e0298e2 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -31,7 +31,8 @@ config EARLY_SCIF_CONSOLE_PORT hex "SCIF port for early console" depends on EARLY_SCIF_CONSOLE default "0xffe00000" if CPU_SUBTYPE_SH7780 - default "0xfffe9800" if CPU_SUBTYPE_SH72060 + default "0xfffe9800" if CPU_SUBTYPE_SH7206 + default "0xf8420000" if CPU_SUBTYPE_SH7619 default "0xffe80000" if CPU_SH4 config EARLY_PRINTK diff --git a/arch/sh/Makefile b/arch/sh/Makefile index d10bba5e1074..c1dbef212634 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -179,7 +179,7 @@ maketools: include/linux/version.h FORCE all: zImage -zImage: vmlinux +zImage uImage uImage.srec vmlinux.srec: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ compressed: zImage @@ -190,5 +190,8 @@ archclean: CLEAN_FILES += include/asm-sh/machtypes.h define archhelp - @echo ' zImage - Compressed kernel image (arch/sh/boot/zImage)' + @echo '* zImage - Compressed kernel image' + @echo ' vmlinux.srec - Create an ELF S-record' + @echo ' uImage - Create a bootable image for U-Boot' + @echo ' uImage.srec - Create an S-record for U-Boot' endef diff --git a/arch/sh/boards/landisk/irq.c b/arch/sh/boards/landisk/irq.c index 8f2e1c68b90f..3eba6d086d7f 100644 --- a/arch/sh/boards/landisk/irq.c +++ b/arch/sh/boards/landisk/irq.c @@ -16,8 +16,8 @@ */ #include <linux/init.h> #include <linux/irq.h> -#include <asm/io.h> -#include <asm/irq.h> +#include <linux/interrupt.h> +#include <linux/io.h> #include <asm/landisk/iodata_landisk.h> static void enable_landisk_irq(unsigned int irq); diff --git a/arch/sh/boards/se/7206/irq.c b/arch/sh/boards/se/7206/irq.c index 3fb0c5f5b23a..27da88486f73 100644 --- a/arch/sh/boards/se/7206/irq.c +++ b/arch/sh/boards/se/7206/irq.c @@ -10,6 +10,7 @@ #include <linux/irq.h> #include <linux/io.h> #include <linux/irq.h> +#include <linux/interrupt.h> #include <asm/se7206.h> #define INTSTS0 0x31800000 @@ -18,6 +19,13 @@ #define INTMSK1 0x31800006 #define INTSEL 0x31800008 +#define IRQ0_IRQ 64 +#define IRQ1_IRQ 65 +#define IRQ3_IRQ 67 + +#define INTC_IPR01 0xfffe0818 +#define INTC_ICR1 0xfffe0802 + static void disable_se7206_irq(unsigned int irq) { unsigned short val; @@ -39,7 +47,7 @@ static void disable_se7206_irq(unsigned int irq) case IRQ1_IRQ: msk0 |= 0x000f; break; - case IRQ2_IRQ: + case IRQ3_IRQ: msk0 |= 0x0f00; msk1 |= 0x00ff; break; @@ -70,7 +78,7 @@ static void enable_se7206_irq(unsigned int irq) case IRQ1_IRQ: msk0 &= ~0x000f; break; - case IRQ2_IRQ: + case IRQ3_IRQ: msk0 &= ~0x0f00; msk1 &= ~0x00ff; break; @@ -96,7 +104,7 @@ static void eoi_se7206_irq(unsigned int irq) case IRQ1_IRQ: sts0 &= ~0x000f; break; - case IRQ2_IRQ: + case IRQ3_IRQ: sts0 &= ~0x0f00; sts1 &= ~0x00ff; break; @@ -106,7 +114,7 @@ static void eoi_se7206_irq(unsigned int irq) } static struct irq_chip se7206_irq_chip __read_mostly = { - .name = "SE7206-FPGA-IRQ", + .name = "SE7206-FPGA", .mask = disable_se7206_irq, .unmask = enable_se7206_irq, .mask_ack = disable_se7206_irq, diff --git a/arch/sh/boards/se/7619/Makefile b/arch/sh/boards/se/7619/Makefile index 3666eca8a658..d21775c28cda 100644 --- a/arch/sh/boards/se/7619/Makefile +++ b/arch/sh/boards/se/7619/Makefile @@ -2,4 +2,4 @@ # Makefile for the 7619 SolutionEngine specific parts of the kernel # -obj-y := setup.o io.o +obj-y := setup.o diff --git a/arch/sh/boards/se/7619/io.c b/arch/sh/boards/se/7619/io.c deleted file mode 100644 index 176f1f39cd9d..000000000000 --- a/arch/sh/boards/se/7619/io.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * linux/arch/sh/boards/se/7619/io.c - * - * Copyright (C) 2006 Yoshinori Sato - * - * I/O routine for Hitachi 7619 SolutionEngine. - * - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <asm/io.h> -#include <asm/se7619.h> -#include <asm/irq.h> - -/* FIXME: M3A-ZAB7 Compact Flash Slot support */ - -static inline void delay(void) -{ - ctrl_inw(0xa0000000); /* Uncached ROM area (P2) */ -} - -#define badio(name,port) \ - printk("bad I/O operation (%s) for port 0x%lx at 0x%08x\n", \ - #name, (port), (__u32) __builtin_return_address(0)) - -unsigned char se7619___inb(unsigned long port) -{ - badio(inb, port); - return 0; -} - -unsigned char se7619___inb_p(unsigned long port) -{ - badio(inb_p, port); - delay(); - return 0; -} - -unsigned short se7619___inw(unsigned long port) -{ - badio(inw, port); - return 0; -} - -unsigned int se7619___inl(unsigned long port) -{ - badio(inl, port); - return 0; -} - -void se7619___outb(unsigned char value, unsigned long port) -{ - badio(outb, port); -} - -void se7619___outb_p(unsigned char value, unsigned long port) -{ - badio(outb_p, port); - delay(); -} - -void se7619___outw(unsigned short value, unsigned long port) -{ - badio(outw, port); -} - -void se7619___outl(unsigned int value, unsigned long port) -{ - badio(outl, port); -} - -void se7619___insb(unsigned long port, void *addr, unsigned long count) -{ - badio(inw, port); -} - -void se7619___insw(unsigned long port, void *addr, unsigned long count) -{ - badio(inw, port); -} - -void se7619___insl(unsigned long port, void *addr, unsigned long count) -{ - badio(insl, port); -} - -void se7619___outsb(unsigned long port, const void *addr, unsigned long count) -{ - badio(insl, port); -} - -void se7619___outsw(unsigned long port, const void *addr, unsigned long count) -{ - badio(insl, port); -} - -void se7619___outsl(unsigned long port, const void *addr, unsigned long count) -{ - badio(outsw, port); -} diff --git a/arch/sh/boards/se/7619/setup.c b/arch/sh/boards/se/7619/setup.c index e627b26de0d0..52d2c4d5d2fa 100644 --- a/arch/sh/boards/se/7619/setup.c +++ b/arch/sh/boards/se/7619/setup.c @@ -9,7 +9,6 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <asm/io.h> -#include <asm/se7619.h> #include <asm/machvec.h> /* @@ -19,25 +18,5 @@ struct sh_machine_vector mv_se __initmv = { .mv_name = "SolutionEngine", .mv_nr_irqs = 108, - .mv_inb = se7619___inb, - .mv_inw = se7619___inw, - .mv_inl = se7619___inl, - .mv_outb = se7619___outb, - .mv_outw = se7619___outw, - .mv_outl = se7619___outl, - - .mv_inb_p = se7619___inb_p, - .mv_inw_p = se7619___inw, - .mv_inl_p = se7619___inl, - .mv_outb_p = se7619___outb_p, - .mv_outw_p = se7619___outw, - .mv_outl_p = se7619___outl, - - .mv_insb = se7619___insb, - .mv_insw = se7619___insw, - .mv_insl = se7619___insl, - .mv_outsb = se7619___outsb, - .mv_outsw = se7619___outsw, - .mv_outsl = se7619___outsl, }; ALIAS_MV(se) diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile index 60797b31089c..11dc272c618e 100644 --- a/arch/sh/boot/Makefile +++ b/arch/sh/boot/Makefile @@ -8,13 +8,49 @@ # Copyright (C) 1999 Stuart Menefy # -targets := zImage +MKIMAGE := $(srctree)/scripts/mkuboot.sh + +# +# Assign safe dummy values if these variables are not defined, +# in order to suppress error message. +# +CONFIG_PAGE_OFFSET ?= 0x80000000 +CONFIG_MEMORY_START ?= 0x0c000000 +CONFIG_BOOT_LINK_OFFSET ?= 0x00800000 +CONFIG_ZERO_PAGE_OFFSET ?= 0x00001000 + +export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \ + CONFIG_ZERO_PAGE_OFFSET + +targets := zImage vmlinux.srec uImage uImage.srec subdir- := compressed $(obj)/zImage: $(obj)/compressed/vmlinux FORCE $(call if_changed,objcopy) - @echo 'Kernel: $@ is ready' + @echo ' Kernel: $@ is ready' $(obj)/compressed/vmlinux: FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed $@ +KERNEL_LOAD := $(shell printf "0x%8x" $$[$(CONFIG_PAGE_OFFSET) + \ + $(CONFIG_MEMORY_START) + \ + $(CONFIG_ZERO_PAGE_OFFSET)+0x1000]) + +quiet_cmd_uimage = UIMAGE $@ + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sh -O linux -T kernel \ + -C gzip -a $(KERNEL_LOAD) -e $(KERNEL_LOAD) \ + -n 'Linux-$(KERNELRELEASE)' -d $< $@ + +$(obj)/uImage: $(obj)/zImage FORCE + $(call if_changed,uimage) + @echo ' Image $@ is ready' + +OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec +$(obj)/vmlinux.srec: $(obj)/compressed/vmlinux + $(call if_changed,objcopy) + +OBJCOPYFLAGS_uImage.srec := -I binary -O srec +$(obj)/uImage.srec: $(obj)/uImage + $(call if_changed,objcopy) + +clean-files += uImage uImage.srec vmlinux.srec diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index e5f443790079..d9512416f885 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -15,13 +15,7 @@ endif # # IMAGE_OFFSET is the load offset of the compression loader -# Assign dummy values if these 2 variables are not defined, -# in order to suppress error message. # -CONFIG_PAGE_OFFSET ?= 0x80000000 -CONFIG_MEMORY_START ?= 0x0c000000 -CONFIG_BOOT_LINK_OFFSET ?= 0x00800000 - IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_PAGE_OFFSET) + \ $(CONFIG_MEMORY_START) + \ $(CONFIG_BOOT_LINK_OFFSET)]) diff --git a/arch/sh/boot/compressed/head.S b/arch/sh/boot/compressed/head.S index 4c26a192277d..a8399b013729 100644 --- a/arch/sh/boot/compressed/head.S +++ b/arch/sh/boot/compressed/head.S @@ -8,6 +8,7 @@ .text #include <linux/linkage.h> +#include <asm/page.h> .global startup startup: @@ -97,7 +98,7 @@ init_stack_addr: decompress_kernel_addr: .long decompress_kernel kernel_start_addr: - .long _text+0x1000 + .long _text+PAGE_SIZE .align 9 fake_headers_as_bzImage: diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c index 35452d85b7f7..df65e305acf7 100644 --- a/arch/sh/boot/compressed/misc.c +++ b/arch/sh/boot/compressed/misc.c @@ -13,6 +13,7 @@ #include <asm/uaccess.h> #include <asm/addrspace.h> +#include <asm/page.h> #ifdef CONFIG_SH_STANDARD_BIOS #include <asm/sh_bios.h> #endif @@ -229,7 +230,7 @@ long* stack_start = &user_stack[STACK_SIZE]; void decompress_kernel(void) { output_data = 0; - output_ptr = P2SEGADDR((unsigned long)&_text+0x1000); + output_ptr = P2SEGADDR((unsigned long)&_text+PAGE_SIZE); free_mem_ptr = (unsigned long)&_end; free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig index 238c0f109907..e7f8ddb0ada4 100644 --- a/arch/sh/configs/landisk_defconfig +++ b/arch/sh/configs/landisk_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Tue Oct 3 11:14:13 2006 +# Linux kernel version: 2.6.19 +# Thu Dec 7 17:13:04 2006 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -10,6 +10,9 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME is not set +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -33,6 +36,7 @@ CONFIG_SYSVIPC=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -114,6 +118,8 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_SH_LANDISK=y # CONFIG_SH_TITAN is not set # CONFIG_SH_SHMIN is not set +# CONFIG_SH_7206_SOLUTION_ENGINE is not set +# CONFIG_SH_7619_SOLUTION_ENGINE is not set # CONFIG_SH_UNKNOWN is not set # @@ -125,6 +131,12 @@ CONFIG_CPU_SH4=y # SH-2 Processor Support # # CONFIG_CPU_SUBTYPE_SH7604 is not set +# CONFIG_CPU_SUBTYPE_SH7619 is not set + +# +# SH-2A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7206 is not set # # SH-3 Processor Support @@ -160,6 +172,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set # # SH4AL-DSP Processor Support @@ -175,6 +188,9 @@ CONFIG_PAGE_OFFSET=0x80000000 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_VSYSCALL=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -196,16 +212,21 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # Processor features # CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set CONFIG_SH_FPU=y # CONFIG_SH_DSP is not set # CONFIG_SH_STORE_QUEUES is not set CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_IPR_IRQ=y CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_PTEA=y # # Timer support # CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=16 +# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=33333333 # @@ -216,9 +237,7 @@ CONFIG_SH_PCLK_FREQ=33333333 # # DMA support # -CONFIG_SH_DMA=y -CONFIG_NR_ONCHIP_DMA_CHANNELS=4 -# CONFIG_NR_DMA_CHANNELS_BOOL is not set +# CONFIG_SH_DMA is not set # # Companion Chips @@ -227,6 +246,11 @@ CONFIG_NR_ONCHIP_DMA_CHANNELS=4 CONFIG_HEARTBEAT=y # +# Additional SuperH Device Drivers +# +# CONFIG_PUSH_SWITCH is not set + +# # Kernel features # # CONFIG_HZ_100 is not set @@ -340,11 +364,13 @@ CONFIG_IP_PNP=y # CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y 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 # # IP: Virtual Server Configuration @@ -361,24 +387,12 @@ CONFIG_NETFILTER=y # Core Netfilter Configuration # # CONFIG_NETFILTER_NETLINK is not set +# CONFIG_NF_CONNTRACK_ENABLED is not set # CONFIG_NETFILTER_XTABLES is not set # # IP: Netfilter Configuration # -CONFIG_IP_NF_CONNTRACK=m -CONFIG_IP_NF_CT_ACCT=y -CONFIG_IP_NF_CONNTRACK_MARK=y -# CONFIG_IP_NF_CONNTRACK_EVENTS is not set -# CONFIG_IP_NF_CT_PROTO_SCTP is not set -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_IRC=m -# CONFIG_IP_NF_NETBIOS_NS is not set -CONFIG_IP_NF_TFTP=m -CONFIG_IP_NF_AMANDA=m -# CONFIG_IP_NF_PPTP is not set -# CONFIG_IP_NF_H323 is not set -# CONFIG_IP_NF_SIP is not set CONFIG_IP_NF_QUEUE=m # @@ -477,6 +491,12 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_ATA_OVER_ETH is not set # +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + +# # ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y @@ -519,6 +539,7 @@ CONFIG_BLK_DEV_AEC62XX=y # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set # CONFIG_BLK_DEV_IT821X is not set @@ -542,6 +563,7 @@ CONFIG_IDEDMA_AUTO=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -561,6 +583,7 @@ CONFIG_BLK_DEV_SD=y CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set # # SCSI Transports @@ -602,12 +625,12 @@ CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC395x is not set @@ -615,6 +638,7 @@ CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set # # PCMCIA SCSI adapter support @@ -757,6 +781,7 @@ CONFIG_8139CP=y # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set # # Token Ring devices @@ -871,10 +896,6 @@ CONFIG_HW_RANDOM=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# # CONFIG_DRM is not set # @@ -889,7 +910,6 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support @@ -905,6 +925,7 @@ CONFIG_HW_RANDOM=y # # Dallas's 1-wire bus # +# CONFIG_W1 is not set # # Hardware Monitoring support @@ -917,10 +938,6 @@ CONFIG_HWMON=y # CONFIG_HWMON_DEBUG_CHIP is not set # -# Misc devices -# - -# # Multimedia devices # CONFIG_VIDEO_DEV=m @@ -1037,6 +1054,7 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_MULTITHREAD_PROBE is not set # CONFIG_USB_OTG is not set # @@ -1106,7 +1124,6 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_TRANCEVIBRATOR is not set # # USB Imaging devices @@ -1121,6 +1138,7 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_KAWETH is not set CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m +# CONFIG_USB_USBNET_MII is not set # CONFIG_USB_USBNET is not set CONFIG_USB_MON=y @@ -1156,6 +1174,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=m # CONFIG_USB_SERIAL_KLSI is not set # CONFIG_USB_SERIAL_KOBIL_SCT is not set # CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set # CONFIG_USB_SERIAL_MOS7840 is not set # CONFIG_USB_SERIAL_NAVMAN is not set CONFIG_USB_SERIAL_PL2303=m @@ -1167,6 +1186,7 @@ CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_SERIAL_XIRCOM is not set # CONFIG_USB_SERIAL_OPTION is not set # CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_DEBUG is not set # # USB Miscellaneous drivers @@ -1188,6 +1208,7 @@ CONFIG_USB_EMI26=m CONFIG_USB_SISUSBVGA=m CONFIG_USB_SISUSBVGA_CON=y # CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_TEST is not set # @@ -1254,6 +1275,7 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1264,6 +1286,7 @@ CONFIG_REISERFS_FS=y # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y @@ -1414,6 +1437,7 @@ CONFIG_NLS_CODEPAGE_932=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set @@ -1422,6 +1446,7 @@ CONFIG_ENABLE_MUST_CHECK=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set CONFIG_SH_STANDARD_BIOS=y # CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_EARLY_PRINTK is not set @@ -1445,6 +1470,4 @@ CONFIG_SH_STANDARD_BIOS=y # CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m CONFIG_PLIST=y diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig index 36cec0b6e7c1..87ab9080fd1d 100644 --- a/arch/sh/configs/se7206_defconfig +++ b/arch/sh/configs/se7206_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc4 -# Sun Nov 5 16:20:10 2006 +# Linux kernel version: 2.6.19 +# Wed Dec 6 14:40:15 2006 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -11,6 +11,8 @@ CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y # CONFIG_GENERIC_TIME is not set +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -34,24 +36,23 @@ CONFIG_LOCALVERSION="" # CONFIG_IKCONFIG is not set # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_EMBEDDED=y -CONFIG_UID16=y +# CONFIG_UID16 is not set # CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_KALLSYMS is not set # CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y +# CONFIG_ELF_CORE is not set +# CONFIG_BASE_FULL is not set # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_VM_EVENT_COUNTERS is not set CONFIG_TINY_SHMEM=y -CONFIG_BASE_SMALL=0 +CONFIG_BASE_SMALL=1 # CONFIG_SLOB is not set # @@ -160,6 +161,7 @@ CONFIG_CPU_SUBTYPE_SH7206=y # # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set # # SH4AL-DSP Processor Support @@ -172,7 +174,10 @@ CONFIG_CPU_SUBTYPE_SH7206=y # CONFIG_PAGE_OFFSET=0x00000000 CONFIG_MEMORY_START=0x0c000000 -CONFIG_MEMORY_SIZE=0x02000000 +CONFIG_MEMORY_SIZE=0x04000000 +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -194,6 +199,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # Processor features # # CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_CPU_BIG_ENDIAN=y # CONFIG_SH_FPU is not set # CONFIG_SH_FPU_EMU is not set # CONFIG_SH_DSP is not set @@ -203,6 +209,8 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_SH_CMT=y # CONFIG_SH_MTU2 is not set +CONFIG_SH_TIMER_IRQ=140 +# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_MD=6 @@ -222,6 +230,11 @@ CONFIG_SH_CLK_MD=6 # CONFIG_HD6446X_SERIES is not set # +# Additional SuperH Device Drivers +# +# CONFIG_PUSH_SWITCH is not set + +# # Kernel features # CONFIG_HZ_100=y @@ -279,9 +292,6 @@ CONFIG_NET=y # CONFIG_NETDEBUG is not set # CONFIG_PACKET is not set # CONFIG_UNIX is not set -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -297,9 +307,9 @@ CONFIG_IP_FIB_HASH=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y +# 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_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y @@ -371,7 +381,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_CONCAT=y CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 @@ -422,7 +432,7 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y CONFIG_MTD_PHYSMAP_START=0x20000000 -CONFIG_MTD_PHYSMAP_LEN=0x1000000 +CONFIG_MTD_PHYSMAP_LEN=0x01000000 CONFIG_MTD_PHYSMAP_BANKWIDTH=4 # CONFIG_MTD_SOLUTIONENGINE is not set # CONFIG_MTD_UCLINUX is not set @@ -468,10 +478,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4 # 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_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -519,7 +526,50 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # Network device support # -# CONFIG_NETDEVICES is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_STNIC is not set +CONFIG_SMC91X=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -536,7 +586,26 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # Input device support # -# CONFIG_INPUT is not set +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Hardware I/O ports @@ -564,8 +633,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_UNIX98_PTYS is not set -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_LEGACY_PTYS is not set # # IPMI @@ -576,7 +644,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM is not set # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -610,12 +678,8 @@ CONFIG_HW_RANDOM=y # # Hardware Monitoring support # -CONFIG_HWMON=y +# CONFIG_HWMON is not set # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_HWMON_DEBUG_CHIP is not set # # Multimedia devices @@ -630,7 +694,7 @@ CONFIG_HWMON=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_FIRMWARE_EDID is not set # CONFIG_FB is not set # @@ -701,8 +765,7 @@ CONFIG_FIRMWARE_EDID=y # # File systems # -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4DEV_FS is not set # CONFIG_REISERFS_FS is not set @@ -755,7 +818,7 @@ CONFIG_RAMFS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y +# CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set @@ -793,8 +856,9 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_ENABLE_MUST_CHECK is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_KERNEL is not set @@ -819,7 +883,7 @@ CONFIG_LOG_BUF_SHIFT=14 # # Library routines # -CONFIG_CRC_CCITT=y +# CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set diff --git a/arch/sh/configs/se7619_defconfig b/arch/sh/configs/se7619_defconfig new file mode 100644 index 000000000000..20ac7f4c53fb --- /dev/null +++ b/arch/sh/configs/se7619_defconfig @@ -0,0 +1,744 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.19 +# Wed Dec 6 16:35:36 2006 +# +CONFIG_SUPERH=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME is not set +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SYSVIPC is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_UTS_NS is not set +# CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +# CONFIG_UID16 is not set +# CONFIG_SYSCTL_SYSCALL is not set +# CONFIG_KALLSYMS is not set +# CONFIG_HOTPLUG is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +# CONFIG_BASE_FULL is not set +# CONFIG_FUTEX is not set +# CONFIG_EPOLL is not set +CONFIG_SLAB=y +# CONFIG_VM_EVENT_COUNTERS is not set +CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=1 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" + +# +# System type +# +# CONFIG_SH_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SOLUTION_ENGINE is not set +# CONFIG_SH_7300_SOLUTION_ENGINE is not set +# CONFIG_SH_7343_SOLUTION_ENGINE is not set +# CONFIG_SH_73180_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_HP6XX is not set +# CONFIG_SH_EC3104 is not set +# CONFIG_SH_SATURN is not set +# CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_BIGSUR is not set +# CONFIG_SH_MPC1211 is not set +# CONFIG_SH_SH03 is not set +# CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set +# CONFIG_SH_7710VOIPGW is not set +# CONFIG_SH_RTS7751R2D is not set +# CONFIG_SH_R7780RP is not set +# CONFIG_SH_EDOSK7705 is not set +# CONFIG_SH_SH4202_MICRODEV is not set +# CONFIG_SH_LANDISK is not set +# CONFIG_SH_TITAN is not set +# CONFIG_SH_SHMIN is not set +# CONFIG_SH_7206_SOLUTION_ENGINE is not set +CONFIG_SH_7619_SOLUTION_ENGINE=y +# CONFIG_SH_UNKNOWN is not set + +# +# Processor selection +# +CONFIG_CPU_SH2=y + +# +# SH-2 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7604 is not set +CONFIG_CPU_SUBTYPE_SH7619=y + +# +# SH-2A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7206 is not set + +# +# SH-3 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7706 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7710 is not set + +# +# SH-4 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7091 is not set +# CONFIG_CPU_SUBTYPE_SH7750R is not set +# CONFIG_CPU_SUBTYPE_SH7750S is not set +# CONFIG_CPU_SUBTYPE_SH7751 is not set +# CONFIG_CPU_SUBTYPE_SH7751R is not set +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_SH4_202 is not set + +# +# ST40 Processor Support +# +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set + +# +# SH-4A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7770 is not set +# CONFIG_CPU_SUBTYPE_SH7780 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set + +# +# SH4AL-DSP Processor Support +# +# CONFIG_CPU_SUBTYPE_SH73180 is not set +# CONFIG_CPU_SUBTYPE_SH7343 is not set + +# +# Memory management options +# +CONFIG_PAGE_OFFSET=0x00000000 +CONFIG_MEMORY_START=0x0c000000 +CONFIG_MEMORY_SIZE=0x04000000 +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +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_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set + +# +# Cache configuration +# +# CONFIG_SH_DIRECT_MAPPED is not set +CONFIG_SH_WRITETHROUGH=y +# CONFIG_SH_OCRAM is not set + +# +# Processor features +# +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_CPU_BIG_ENDIAN=y +# CONFIG_SH_FPU is not set +# CONFIG_SH_FPU_EMU is not set +# CONFIG_SH_DSP is not set + +# +# Timer support +# +CONFIG_SH_CMT=y +CONFIG_SH_TIMER_IRQ=86 +# CONFIG_NO_IDLE_HZ is not set +CONFIG_SH_PCLK_FREQ=31250000 +CONFIG_SH_CLK_MD=5 + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# DMA support +# +# CONFIG_SH_DMA is not set + +# +# Companion Chips +# +# CONFIG_HD6446X_SERIES is not set + +# +# Additional SuperH Device Drivers +# +# CONFIG_PUSH_SWITCH is not set + +# +# Kernel features +# +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=100 +# CONFIG_KEXEC is not set +# CONFIG_SMP is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +# CONFIG_UBC_WAKEUP is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Bus options +# +# CONFIG_PCI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# + +# +# PCI Hotplug Support +# + +# +# Executable file formats +# +CONFIG_BINFMT_FLAT=y +CONFIG_BINFMT_ZFLAT=y +# CONFIG_BINFMT_SHARED_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options (EXPERIMENTAL) +# +# CONFIG_PM is not set + +# +# Networking +# +# CONFIG_NET is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# 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 + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +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 +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xa0000000 +CONFIG_MTD_PHYSMAP_LEN=0x01000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_SOLUTIONENGINE is not set +# CONFIG_MTD_UCLINUX is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# 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 + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CDROM_PKTCDVD is not set + +# +# Misc devices +# +# CONFIG_TIFM_CORE is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_NETLINK is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# ISDN subsystem +# + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC 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_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=3 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_UNIX98_PTYS is not set +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# + +# +# Graphics support +# +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +# CONFIG_EXT2_FS 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_GFS2_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY 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_SYSCTL=y +# CONFIG_SYSFS is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# 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_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_UNWIND_INFO is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_SH_STANDARD_BIOS is not set +# CONFIG_EARLY_SCIF_CONSOLE is not set +# CONFIG_KGDB is not set + +# +# Security options +# +# CONFIG_KEYS is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y diff --git a/arch/sh/drivers/push-switch.c b/arch/sh/drivers/push-switch.c index f2b9157c314f..b3d20c0e021f 100644 --- a/arch/sh/drivers/push-switch.c +++ b/arch/sh/drivers/push-switch.c @@ -14,7 +14,7 @@ #include <asm/push-switch.h> #define DRV_NAME "push-switch" -#define DRV_VERSION "0.1.0" +#define DRV_VERSION "0.1.1" static ssize_t switch_show(struct device *dev, struct device_attribute *attr, @@ -32,10 +32,10 @@ static void switch_timer(unsigned long data) schedule_work(&psw->work); } -static void switch_work_handler(void *data) +static void switch_work_handler(struct work_struct *work) { - struct platform_device *pdev = data; - struct push_switch *psw = platform_get_drvdata(pdev); + struct push_switch *psw = container_of(work, struct push_switch, work); + struct platform_device *pdev = psw->pdev; psw->state = 0; @@ -76,12 +76,15 @@ static int switch_drv_probe(struct platform_device *pdev) } } - INIT_WORK(&psw->work, switch_work_handler, pdev); + INIT_WORK(&psw->work, switch_work_handler); init_timer(&psw->debounce); psw->debounce.function = switch_timer; psw->debounce.data = (unsigned long)psw; + /* Workqueue API brain-damage */ + psw->pdev = pdev; + platform_set_drvdata(pdev, psw); return 0; diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index 0582e6712b79..d055a3ea6b4b 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_CPU_SH2) = sh2/ obj-$(CONFIG_CPU_SH2A) = sh2a/ obj-$(CONFIG_CPU_SH3) = sh3/ obj-$(CONFIG_CPU_SH4) = sh4/ +obj-$(CONFIG_CPU_SH4A) += sh4a/ obj-$(CONFIG_UBC_WAKEUP) += ubc.o obj-$(CONFIG_SH_ADC) += adc.o diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S index 34d51b3745ea..d51fa5e9904a 100644 --- a/arch/sh/kernel/cpu/sh2/entry.S +++ b/arch/sh/kernel/cpu/sh2/entry.S @@ -177,15 +177,21 @@ interrupt_entry: 7: .long do_IRQ 8: .long do_exception_error -trap_entry: - add #-0x10,r9 +trap_entry: + /* verbose BUG trapa entry check */ + mov #0x3e,r8 + cmp/ge r8,r9 + bf/s 1f + add #-0x10,r9 + add #0x10,r9 +1: shll2 r9 ! TRA mov #OFF_TRA,r8 add r15,r8 mov.l r9,@r8 mov r9,r8 #ifdef CONFIG_TRACE_IRQFLAGS - mov.l 5f, r9 + mov.l 2f, r9 jsr @r9 nop #endif @@ -194,12 +200,8 @@ trap_entry: nop .align 2 -1: .long syscall_exit -2: .long break_point_trap_software -3: .long NR_syscalls -4: .long sys_call_table #ifdef CONFIG_TRACE_IRQFLAGS -5: .long trace_hardirqs_on +2: .long trace_hardirqs_on #endif #if defined(CONFIG_SH_STANDARD_BIOS) @@ -264,7 +266,7 @@ ENTRY(address_error_handler) restore_all: cli #ifdef CONFIG_TRACE_IRQFLAGS - mov.l 3f, r0 + mov.l 1f, r0 jsr @r0 nop #endif @@ -309,20 +311,14 @@ restore_all: mov.l @r15,r15 rte nop -2: - mov.l 1f,r8 - mov.l 2f,r9 - jmp @r9 - lds r8,pr - .align 2 +#ifdef CONFIG_TRACE_IRQFLAGS +1: .long trace_hardirqs_off +#endif $current_thread_info: .long __current_thread_info $cpu_mode: .long __cpu_mode -#ifdef CONFIG_TRACE_IRQFLAGS -3: .long trace_hardirqs_off -#endif ! common exception handler #include "../../entry-common.S" diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index 82c2d905152f..79283e6c1d8f 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -51,3 +51,44 @@ static int __init sh7619_devices_setup(void) ARRAY_SIZE(sh7619_devices)); } __initcall(sh7619_devices_setup); + +#define INTC_IPRC 0xf8080000UL +#define INTC_IPRD 0xf8080002UL + +#define CMI0_IRQ 86 + +#define SCIF0_ERI_IRQ 88 +#define SCIF0_RXI_IRQ 89 +#define SCIF0_BRI_IRQ 90 +#define SCIF0_TXI_IRQ 91 + +#define SCIF1_ERI_IRQ 92 +#define SCIF1_RXI_IRQ 93 +#define SCIF1_BRI_IRQ 94 +#define SCIF1_TXI_IRQ 95 + +#define SCIF2_BRI_IRQ 96 +#define SCIF2_ERI_IRQ 97 +#define SCIF2_RXI_IRQ 98 +#define SCIF2_TXI_IRQ 99 + +static struct ipr_data sh7619_ipr_map[] = { + { CMI0_IRQ, INTC_IPRC, 1, 2 }, + { SCIF0_ERI_IRQ, INTC_IPRD, 3, 3 }, + { SCIF0_RXI_IRQ, INTC_IPRD, 3, 3 }, + { SCIF0_BRI_IRQ, INTC_IPRD, 3, 3 }, + { SCIF0_TXI_IRQ, INTC_IPRD, 3, 3 }, + { SCIF1_ERI_IRQ, INTC_IPRD, 2, 3 }, + { SCIF1_RXI_IRQ, INTC_IPRD, 2, 3 }, + { SCIF1_BRI_IRQ, INTC_IPRD, 2, 3 }, + { SCIF1_TXI_IRQ, INTC_IPRD, 2, 3 }, + { SCIF2_ERI_IRQ, INTC_IPRD, 1, 3 }, + { SCIF2_RXI_IRQ, INTC_IPRD, 1, 3 }, + { SCIF2_BRI_IRQ, INTC_IPRD, 1, 3 }, + { SCIF2_TXI_IRQ, INTC_IPRD, 1, 3 }, +}; + +void __init init_IRQ_ipr(void) +{ + make_ipr_irq(sh7619_ipr_map, ARRAY_SIZE(sh7619_ipr_map)); +} diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index cdfeef49e62e..4b60fcc7d667 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -17,22 +17,22 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xfffe8000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 240, 241, 242, 243}, + .irqs = { 241, 242, 243, 240}, }, { .mapbase = 0xfffe8800, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 244, 245, 246, 247}, + .irqs = { 247, 244, 245, 246}, }, { .mapbase = 0xfffe9000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 248, 249, 250, 251}, + .irqs = { 249, 250, 251, 248}, }, { .mapbase = 0xfffe9800, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 252, 253, 254, 255}, + .irqs = { 253, 254, 255, 252}, }, { .flags = 0, } @@ -56,3 +56,57 @@ static int __init sh7206_devices_setup(void) ARRAY_SIZE(sh7206_devices)); } __initcall(sh7206_devices_setup); + +#define INTC_IPR08 0xfffe0c04UL +#define INTC_IPR09 0xfffe0c06UL +#define INTC_IPR14 0xfffe0c10UL + +#define CMI0_IRQ 140 + +#define MTU1_TGI1A 164 + +#define SCIF0_BRI_IRQ 240 +#define SCIF0_ERI_IRQ 241 +#define SCIF0_RXI_IRQ 242 +#define SCIF0_TXI_IRQ 243 + +#define SCIF1_BRI_IRQ 244 +#define SCIF1_ERI_IRQ 245 +#define SCIF1_RXI_IRQ 246 +#define SCIF1_TXI_IRQ 247 + +#define SCIF2_BRI_IRQ 248 +#define SCIF2_ERI_IRQ 249 +#define SCIF2_RXI_IRQ 250 +#define SCIF2_TXI_IRQ 251 + +#define SCIF3_BRI_IRQ 252 +#define SCIF3_ERI_IRQ 253 +#define SCIF3_RXI_IRQ 254 +#define SCIF3_TXI_IRQ 255 + +static struct ipr_data sh7206_ipr_map[] = { + { CMI0_IRQ, INTC_IPR08, 3, 2 }, + { MTU2_TGI1A, INTC_IPR09, 1, 2 }, + { SCIF0_ERI_IRQ, INTC_IPR14, 3, 3 }, + { SCIF0_RXI_IRQ, INTC_IPR14, 3, 3 }, + { SCIF0_BRI_IRQ, INTC_IPR14, 3, 3 }, + { SCIF0_TXI_IRQ, INTC_IPR14, 3, 3 }, + { SCIF1_ERI_IRQ, INTC_IPR14, 2, 3 }, + { SCIF1_RXI_IRQ, INTC_IPR14, 2, 3 }, + { SCIF1_BRI_IRQ, INTC_IPR14, 2, 3 }, + { SCIF1_TXI_IRQ, INTC_IPR14, 2, 3 }, + { SCIF2_ERI_IRQ, INTC_IPR14, 1, 3 }, + { SCIF2_RXI_IRQ, INTC_IPR14, 1, 3 }, + { SCIF2_BRI_IRQ, INTC_IPR14, 1, 3 }, + { SCIF2_TXI_IRQ, INTC_IPR14, 1, 3 }, + { SCIF3_ERI_IRQ, INTC_IPR14, 0, 3 }, + { SCIF3_RXI_IRQ, INTC_IPR14, 0, 3 }, + { SCIF3_BRI_IRQ, INTC_IPR14, 0, 3 }, + { SCIF3_TXI_IRQ, INTC_IPR14, 0, 3 }, +}; + +void __init init_IRQ_ipr(void) +{ + make_ipr_irq(sh7206_ipr_map, ARRAY_SIZE(sh7206_ipr_map)); +} diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile index 6e415baf04b4..19ca68c71884 100644 --- a/arch/sh/kernel/cpu/sh4/Makefile +++ b/arch/sh/kernel/cpu/sh4/Makefile @@ -12,17 +12,12 @@ obj-$(CONFIG_SH_STORE_QUEUES) += sq.o obj-$(CONFIG_CPU_SUBTYPE_SH7750) += setup-sh7750.o obj-$(CONFIG_CPU_SUBTYPE_SH7751) += setup-sh7750.o obj-$(CONFIG_CPU_SUBTYPE_SH7760) += setup-sh7760.o -obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o -obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o -obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o -obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o obj-$(CONFIG_CPU_SUBTYPE_SH4_202) += setup-sh4-202.o # Primary on-chip clocks (common) +ifndef CONFIG_CPU_SH4A clock-$(CONFIG_CPU_SH4) := clock-sh4.o -clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o -clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o -clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o +endif # Additional clocks by subtype clock-$(CONFIG_CPU_SUBTYPE_SH4_202) += clock-sh4-202.o diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index afe0f1b1c030..9031a22a2ce7 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -119,11 +119,20 @@ int __init detect_cpu_and_cache_system(void) break; case 0x3000: case 0x3003: + case 0x3009: cpu_data->type = CPU_SH7343; cpu_data->icache.ways = 4; cpu_data->dcache.ways = 4; cpu_data->flags |= CPU_HAS_LLSC; break; + case 0x3008: + if (prr == 0xa0) { + cpu_data->type = CPU_SH7722; + cpu_data->icache.ways = 4; + cpu_data->dcache.ways = 4; + cpu_data->flags |= CPU_HAS_LLSC; + } + break; case 0x8000: cpu_data->type = CPU_ST40RA; cpu_data->flags |= CPU_HAS_FPU; diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index bbcb06f18b04..cbac27634c0b 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -14,6 +14,36 @@ #include <linux/io.h> #include <asm/sci.h> +static struct resource rtc_resources[] = { + [0] = { + .start = 0xffc80000, + .end = 0xffc80000 + 0x58 - 1, + .flags = IORESOURCE_IO, + }, + [1] = { + /* Period IRQ */ + .start = 21, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* Carry IRQ */ + .start = 22, + .flags = IORESOURCE_IRQ, + }, + [3] = { + /* Alarm IRQ */ + .start = 20, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device rtc_device = { + .name = "sh-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, +}; + static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xffe00000, @@ -39,6 +69,7 @@ static struct platform_device sci_device = { }; static struct platform_device *sh7750_devices[] __initdata = { + &rtc_device, &sci_device, }; diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c index 0c9ea38d2caa..d7fff752e569 100644 --- a/arch/sh/kernel/cpu/sh4/sq.c +++ b/arch/sh/kernel/cpu/sh4/sq.c @@ -111,8 +111,9 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags) vma->phys_addr = map->addr; - if (remap_area_pages((unsigned long)vma->addr, vma->phys_addr, - map->size, flags)) { + if (ioremap_page_range((unsigned long)vma->addr, + (unsigned long)vma->addr + map->size, + vma->phys_addr, __pgprot(flags))) { vunmap(vma->addr); return -EAGAIN; } @@ -176,7 +177,7 @@ unsigned long sq_remap(unsigned long phys, unsigned int size, map->sq_addr = P4SEG_STORE_QUE + (page << PAGE_SHIFT); - ret = __sq_remap(map, flags); + ret = __sq_remap(map, pgprot_val(PAGE_KERNEL_NOCACHE) | flags); if (unlikely(ret != 0)) goto out; diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile new file mode 100644 index 000000000000..a8f493f2f21f --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -0,0 +1,19 @@ +# +# Makefile for the Linux/SuperH SH-4 backends. +# + +# CPU subtype setup +obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o +obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o +obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o +obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o +obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o + +# Primary on-chip clocks (common) +clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o +clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o +clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o +clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o +clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7343.o + +obj-y += $(clock-y) diff --git a/arch/sh/kernel/cpu/sh4/clock-sh73180.c b/arch/sh/kernel/cpu/sh4a/clock-sh73180.c index 2fa5cb2ae68d..2fa5cb2ae68d 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh73180.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh73180.c diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c new file mode 100644 index 000000000000..1707a213f0cf --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -0,0 +1,99 @@ +/* + * arch/sh/kernel/cpu/sh4/clock-sh7343.c + * + * SH7343/SH7722 support for the clock framework + * + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/io.h> +#include <asm/clock.h> +#include <asm/freq.h> + +/* + * SH7343/SH7722 uses a common set of multipliers and divisors, so this + * is quite simple.. + */ +static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; +static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 }; + +#define pll_calc() (((ctrl_inl(FRQCR) >> 24) & 0x1f) + 1) + +static void master_clk_init(struct clk *clk) +{ + clk->parent = clk_get(NULL, "cpu_clk"); +} + +static void master_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) & 0x000f); + clk->rate *= clk->parent->rate * multipliers[idx] / divisors[idx]; +} + +static struct clk_ops sh7343_master_clk_ops = { + .init = master_clk_init, + .recalc = master_clk_recalc, +}; + +static void module_clk_init(struct clk *clk) +{ + clk->parent = NULL; + clk->rate = CONFIG_SH_PCLK_FREQ; +} + +static struct clk_ops sh7343_module_clk_ops = { + .init = module_clk_init, +}; + +static void bus_clk_init(struct clk *clk) +{ + clk->parent = clk_get(NULL, "cpu_clk"); +} + +static void bus_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) >> 8) & 0x000f; + clk->rate = clk->parent->rate * multipliers[idx] / divisors[idx]; +} + +static struct clk_ops sh7343_bus_clk_ops = { + .init = bus_clk_init, + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_init(struct clk *clk) +{ + clk->parent = clk_get(NULL, "module_clk"); + clk->flags |= CLK_RATE_PROPAGATES; + clk_set_rate(clk, clk_get_rate(clk)); +} + +static void cpu_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) >> 20) & 0x000f; + clk->rate = clk->parent->rate * pll_calc() * + multipliers[idx] / divisors[idx]; +} + +static struct clk_ops sh7343_cpu_clk_ops = { + .init = cpu_clk_init, + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh7343_clk_ops[] = { + &sh7343_master_clk_ops, + &sh7343_module_clk_ops, + &sh7343_bus_clk_ops, + &sh7343_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh7343_clk_ops)) + *ops = sh7343_clk_ops[idx]; +} diff --git a/arch/sh/kernel/cpu/sh4/clock-sh7770.c b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c index c8694bac6477..c8694bac6477 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c diff --git a/arch/sh/kernel/cpu/sh4/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c index 9e6a216750c8..9e6a216750c8 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c diff --git a/arch/sh/kernel/cpu/sh4/setup-sh73180.c b/arch/sh/kernel/cpu/sh4a/setup-sh73180.c index cc9ea1e2e5df..cc9ea1e2e5df 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh73180.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh73180.c diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index 91d61cf91ba1..91d61cf91ba1 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c new file mode 100644 index 000000000000..1143fbf65faf --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -0,0 +1,80 @@ +/* + * SH7722 Setup + * + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/platform_device.h> +#include <linux/init.h> +#include <linux/serial.h> +#include <asm/sci.h> + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 81, 83, 82 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7722_devices[] __initdata = { + &sci_device, +}; + +static int __init sh7722_devices_setup(void) +{ + return platform_add_devices(sh7722_devices, + ARRAY_SIZE(sh7722_devices)); +} +__initcall(sh7722_devices_setup); + +static struct ipr_data sh7722_ipr_map[] = { + /* IRQ, IPR-idx, shift, prio */ + { 16, 0, 12, 2 }, /* TMU0 */ + { 17, 0, 8, 2 }, /* TMU1 */ + { 80, 6, 12, 3 }, /* SCIF ERI */ + { 81, 6, 12, 3 }, /* SCIF RXI */ + { 82, 6, 12, 3 }, /* SCIF BRI */ + { 83, 6, 12, 3 }, /* SCIF TXI */ +}; + +static unsigned long ipr_offsets[] = { + 0xa4080000, /* 0: IPRA */ + 0xa4080004, /* 1: IPRB */ + 0xa4080008, /* 2: IPRC */ + 0xa408000c, /* 3: IPRD */ + 0xa4080010, /* 4: IPRE */ + 0xa4080014, /* 5: IPRF */ + 0xa4080018, /* 6: IPRG */ + 0xa408001c, /* 7: IPRH */ + 0xa4080020, /* 8: IPRI */ + 0xa4080024, /* 9: IPRJ */ + 0xa4080028, /* 10: IPRK */ + 0xa408002c, /* 11: IPRL */ +}; + +unsigned int map_ipridx_to_addr(int idx) +{ + if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) + return 0; + return ipr_offsets[idx]; +} + +void __init init_IRQ_ipr(void) +{ + make_ipr_irq(sh7722_ipr_map, ARRAY_SIZE(sh7722_ipr_map)); +} diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index 6a04cc5f5aca..6a04cc5f5aca 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 9aeaa2ddaa28..9aeaa2ddaa28 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c index 60340823798a..560b91cdd15c 100644 --- a/arch/sh/kernel/early_printk.c +++ b/arch/sh/kernel/early_printk.c @@ -144,16 +144,16 @@ static struct console *early_console = ; static int __initdata keep_early; +static int early_console_initialized; -int __init setup_early_printk(char *opt) +int __init setup_early_printk(char *buf) { - char *space; - char buf[256]; + if (!buf) + return 0; - strlcpy(buf, opt, sizeof(buf)); - space = strchr(buf, ' '); - if (space) - *space = 0; + if (early_console_initialized) + return 0; + early_console_initialized = 1; if (strstr(buf, "keep")) keep_early = 1; @@ -175,12 +175,14 @@ int __init setup_early_printk(char *opt) if (likely(early_console)) register_console(early_console); - return 1; + return 0; } -__setup("earlyprintk=", setup_early_printk); +early_param("earlyprintk", setup_early_printk); void __init disable_early_printk(void) { + if (!early_console_initialized || !early_console) + return; if (!keep_early) { printk("disabling early console\n"); unregister_console(early_console); diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index 29136a35d7c7..fc279aeb73ab 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -79,18 +79,29 @@ debug_kernel_sw: .align 2 3: .long kgdb_handle_exception #endif /* CONFIG_SH_KGDB */ - +#ifdef CONFIG_SH_STANDARD_BIOS + bra debug_kernel_fw + nop +#endif #endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ - .align 2 debug_trap: #if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) + mov r8, r0 + shlr2 r0 + cmp/eq #0x3f, r0 ! sh_bios() trap + bf 1f +#ifdef CONFIG_SH_KGDB + cmp/eq #0xff, r0 ! XXX: KGDB trap, fix for SH-2. + bf 1f +#endif mov #OFF_SR, r0 mov.l @(r0,r15), r0 ! get status register shll r0 shll r0 ! kernel space? bt/s debug_kernel +1: #endif mov.l @r15, r0 ! Restore R0 value mov.l 1f, r8 diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S index 6aca4bc6ec5d..71a3ad7d283e 100644 --- a/arch/sh/kernel/head.S +++ b/arch/sh/kernel/head.S @@ -33,7 +33,8 @@ ENTRY(empty_zero_page) .long 0x00360000 /* INITRD_START */ .long 0x000a0000 /* INITRD_SIZE */ .long 0 - .balign PAGE_SIZE,0,PAGE_SIZE +1: + .skip PAGE_SIZE - empty_zero_page - 1b .text /* diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index f3e2631be144..486c06e18033 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -470,9 +470,10 @@ unsigned long get_wchan(struct task_struct *p) */ pc = thread_saved_pc(p); if (in_sched_functions(pc)) { - schedule_frame = ((unsigned long *)(long)p->thread.sp)[1]; - return (unsigned long)((unsigned long *)schedule_frame)[1]; + schedule_frame = (unsigned long)p->thread.sp; + return ((unsigned long *)schedule_frame)[21]; } + return pc; } @@ -498,6 +499,16 @@ asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5, { struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + /* Rewind */ regs->pc -= 2; + +#ifdef CONFIG_BUG + if (__kernel_text_address(instruction_pointer(regs))) { + u16 insn = *(u16 *)instruction_pointer(regs); + if (insn == TRAPA_BUG_OPCODE) + handle_BUG(regs); + } +#endif + force_sig(SIGTRAP, current); } diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index f8dd6b7bfab0..225f9ea5cdd7 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -84,8 +84,7 @@ unsigned long memory_start, memory_end; static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE], struct sh_machine_vector** mvp, - unsigned long *mv_io_base, - int *mv_mmio_enable) + unsigned long *mv_io_base) { char c = ' ', *to = command_line, *from = COMMAND_LINE; int len = 0; @@ -112,23 +111,6 @@ static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE], } } -#ifdef CONFIG_EARLY_PRINTK - if (c == ' ' && !memcmp(from, "earlyprintk=", 12)) { - char *ep_end; - - if (to != command_line) - to--; - - from += 12; - ep_end = strchr(from, ' '); - - setup_early_printk(from); - printk("early console enabled\n"); - - from = ep_end; - } -#endif - if (c == ' ' && !memcmp(from, "sh_mv=", 6)) { char* mv_end; char* mv_comma; @@ -145,7 +127,6 @@ static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE], int ints[3]; get_options(mv_comma+1, ARRAY_SIZE(ints), ints); *mv_io_base = ints[1]; - *mv_mmio_enable = ints[2]; mv_len = mv_comma - from; } else { mv_len = mv_end - from; @@ -158,6 +139,7 @@ static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE], *mvp = get_mv_byname(mv_name); } + c = *(from++); if (!c) break; @@ -177,9 +159,8 @@ static int __init sh_mv_setup(char **cmdline_p) struct sh_machine_vector *mv = NULL; char mv_name[MV_NAME_SIZE] = ""; unsigned long mv_io_base = 0; - int mv_mmio_enable = 0; - parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable); + parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base); #ifdef CONFIG_SH_UNKNOWN if (mv == NULL) { @@ -258,6 +239,7 @@ void __init setup_arch(char **cmdline_p) sh_mv_setup(cmdline_p); + /* * Find the highest page frame number we have available */ @@ -305,6 +287,7 @@ void __init setup_arch(char **cmdline_p) PFN_PHYS(pages)); } + /* * Reserve the kernel text and * Reserve the bootmem bitmap. We do this in two steps (first step @@ -325,14 +308,18 @@ void __init setup_arch(char **cmdline_p) ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); if (&__rd_start != &__rd_end) { LOADER_TYPE = 1; - INITRD_START = PHYSADDR((unsigned long)&__rd_start) - __MEMORY_START; - INITRD_SIZE = (unsigned long)&__rd_end - (unsigned long)&__rd_start; + INITRD_START = PHYSADDR((unsigned long)&__rd_start) - + __MEMORY_START; + INITRD_SIZE = (unsigned long)&__rd_end - + (unsigned long)&__rd_start; } if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { - reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE); - initrd_start = INITRD_START + PAGE_OFFSET + __MEMORY_START; + reserve_bootmem_node(NODE_DATA(0), INITRD_START + + __MEMORY_START, INITRD_SIZE); + initrd_start = INITRD_START + PAGE_OFFSET + + __MEMORY_START; initrd_end = initrd_start + INITRD_SIZE; } else { printk("initrd extends beyond end of memory " @@ -404,7 +391,7 @@ static const char *cpu_name[] = { [CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501", [CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780", [CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343", - [CPU_SH7785] = "SH7785", + [CPU_SH7785] = "SH7785", [CPU_SH7722] = "SH7722", [CPU_SH_NONE] = "Unknown" }; diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index ceee79143401..e6106239a0fe 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c @@ -70,13 +70,26 @@ DECLARE_EXPORT(__sdivsi3); DECLARE_EXPORT(__ashrdi3); DECLARE_EXPORT(__ashldi3); DECLARE_EXPORT(__lshrdi3); -DECLARE_EXPORT(__movstr); DECLARE_EXPORT(__movstrSI16); +#if __GNUC__ == 4 +DECLARE_EXPORT(__movmem); +#else +DECLARE_EXPORT(__movstr); +#endif #ifdef CONFIG_CPU_SH4 +#if __GNUC__ == 4 +DECLARE_EXPORT(__movmem_i4_even); +DECLARE_EXPORT(__movmem_i4_odd); +DECLARE_EXPORT(__movmemSI12_i4); +DECLARE_EXPORT(__sdivsi3_i4i); +DECLARE_EXPORT(__udiv_qrnnd_16); +DECLARE_EXPORT(__udivsi3_i4i); +#else /* GCC 3.x */ DECLARE_EXPORT(__movstr_i4_even); DECLARE_EXPORT(__movstr_i4_odd); DECLARE_EXPORT(__movstrSI12_i4); +#endif /* __GNUC__ == 4 */ #endif #if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB) diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index bb1c480a59c7..379c88bf5d9a 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c @@ -101,7 +101,7 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, */ #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */ -#if defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH2A) +#if defined(CONFIG_CPU_SH2) #define TRAP_NOARG 0xc320 /* Syscall w/no args (NR in R3) */ #else #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) */ diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index 5083b6ed4b39..e18f183e1035 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c @@ -314,6 +314,12 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1, #endif } +#if defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH2A) +#define SYSCALL_ARG3 "trapa #0x23" +#else +#define SYSCALL_ARG3 "trapa #0x13" +#endif + /* * Do a system call from kernel instead of calling sys_execve so we * end up with proper pt_regs. @@ -324,7 +330,7 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]) register long __sc4 __asm__ ("r4") = (long) filename; register long __sc5 __asm__ ("r5") = (long) argv; register long __sc6 __asm__ ("r6") = (long) envp; - __asm__ __volatile__ ("trapa #0x13" : "=z" (__sc0) + __asm__ __volatile__ (SYSCALL_ARG3 : "=z" (__sc0) : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6) : "memory"); return __sc0; diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 3762d9dc2046..ec110157992d 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -19,6 +19,7 @@ #include <linux/kallsyms.h> #include <linux/io.h> #include <linux/debug_locks.h> +#include <linux/limits.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -129,6 +130,40 @@ static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err) return -EFAULT; } +#ifdef CONFIG_BUG +#ifdef CONFIG_DEBUG_BUGVERBOSE +static inline void do_bug_verbose(struct pt_regs *regs) +{ + struct bug_frame f; + long len; + + if (__copy_from_user(&f, (const void __user *)regs->pc, + sizeof(struct bug_frame))) + return; + + len = __strnlen_user(f.file, PATH_MAX) - 1; + if (unlikely(len < 0 || len >= PATH_MAX)) + f.file = "<bad filename>"; + len = __strnlen_user(f.func, PATH_MAX) - 1; + if (unlikely(len < 0 || len >= PATH_MAX)) + f.func = "<bad function>"; + + printk(KERN_ALERT "kernel BUG in %s() at %s:%d!\n", + f.func, f.file, f.line); +} +#else +static inline void do_bug_verbose(struct pt_regs *regs) +{ +} +#endif /* CONFIG_DEBUG_BUGVERBOSE */ +#endif /* CONFIG_BUG */ + +void handle_BUG(struct pt_regs *regs) +{ + do_bug_verbose(regs); + die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); +} + /* * handle an instruction that does an unaligned memory access by emulating the * desired behaviour diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 77b4026d5688..f34bdcc33a7d 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -51,7 +51,7 @@ SECTIONS } . = ALIGN(PAGE_SIZE); - .data.page_aligned : { *(.data.idt) } + .data.page_aligned : { *(.data.page_aligned) } . = ALIGN(32); __per_cpu_start = .; diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 4e0362f50384..29f4ee35c6dc 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -35,6 +35,9 @@ config CPU_SUBTYPE_ST40 select CPU_SH4 select CPU_HAS_INTC2_IRQ +config CPU_SHX2 + bool + # # Processor subtypes # @@ -180,6 +183,7 @@ config CPU_SUBTYPE_SH7780 config CPU_SUBTYPE_SH7785 bool "Support SH7785 processor" select CPU_SH4A + select CPU_SHX2 select CPU_HAS_INTC2_IRQ comment "SH4AL-DSP Processor Support" @@ -192,6 +196,12 @@ config CPU_SUBTYPE_SH7343 bool "Support SH7343 processor" select CPU_SH4AL_DSP +config CPU_SUBTYPE_SH7722 + bool "Support SH7722 processor" + select CPU_SH4AL_DSP + select CPU_SHX2 + select CPU_HAS_IPR_IRQ + endmenu menu "Memory management options" @@ -250,7 +260,7 @@ config 32BIT config X2TLB bool "Enable extended TLB mode" - depends on CPU_SUBTYPE_SH7785 && MMU && EXPERIMENTAL + depends on CPU_SHX2 && MMU && EXPERIMENTAL help Selecting this option will enable the extended mode of the SH-X2 TLB. For legacy SH-X behaviour and interoperability, say N. For diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index ae531affccbd..c6955157c989 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -107,7 +107,7 @@ void __init p3_cache_init(void) emit_cache_params(); - if (remap_area_pages(P3SEG, 0, PAGE_SIZE * 4, _PAGE_CACHABLE)) + if (ioremap_page_range(P3SEG, P3SEG + (PAGE_SIZE * 4), 0, PAGE_KERNEL)) panic("%s failed.", __FUNCTION__); for (i = 0; i < cpu_data->dcache.n_aliases; i++) diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 59f4cc18235b..29bd37b1488e 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -77,6 +77,7 @@ void show_mem(void) printk("%d pages swap cached\n",cached); } +#ifdef CONFIG_MMU static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) { pgd_t *pgd; @@ -139,6 +140,7 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) set_pte_phys(address, phys, prot); } +#endif /* CONFIG_MMU */ /* References to section boundaries */ diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 54d51b404603..cbbc98846b00 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -317,9 +317,8 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp) if ((va = __get_free_pages(GFP_KERNEL|__GFP_COMP, order)) == 0) goto err_nopages; - if ((res = kmalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) + if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) goto err_nomem; - memset((char*)res, 0, sizeof(struct resource)); if (allocate_resource(&_sparc_dvma, res, len_total, _sparc_dvma.start, _sparc_dvma.end, PAGE_SIZE, NULL, NULL) != 0) { @@ -589,12 +588,11 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba) return NULL; } - if ((res = kmalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) { + if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) { free_pages(va, order); printk("pci_alloc_consistent: no core\n"); return NULL; } - memset((char*)res, 0, sizeof(struct resource)); if (allocate_resource(&_sparc_dvma, res, len_total, _sparc_dvma.start, _sparc_dvma.end, PAGE_SIZE, NULL, NULL) != 0) { diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index 46200c43ffb1..dab6169e31ca 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c @@ -793,10 +793,9 @@ struct of_device* of_platform_device_create(struct device_node *np, { struct of_device *dev; - dev = kmalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return NULL; - memset(dev, 0, sizeof(*dev)); dev->dev.parent = parent; dev->dev.bus = bus; diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c index 1baf13ed5c3a..003f8eed32f4 100644 --- a/arch/sparc/kernel/ptrace.c +++ b/arch/sparc/kernel/ptrace.c @@ -289,7 +289,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs) if (request == PTRACE_TRACEME) { ret = ptrace_traceme(); - pt_succ_return(regs, 0); + if (ret < 0) + pt_error_return(regs, -ret); + else + pt_succ_return(regs, 0); goto out; } diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index d4f9da8170c5..cf1b8baa57ea 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -545,8 +545,11 @@ void __init sun4d_init_sbi_irq(void) nsbi = 0; for_each_sbus(sbus) nsbi++; - sbus_actions = (struct sbus_action *)kmalloc (nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC); - memset (sbus_actions, 0, (nsbi * 8 * 4 * sizeof(struct sbus_action))); + sbus_actions = kzalloc (nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC); + if (!sbus_actions) { + prom_printf("SUN4D: Cannot allocate sbus_actions, halting.\n"); + prom_halt(); + } for_each_sbus(sbus) { #ifdef CONFIG_SMP extern unsigned char boot_cpu_id; diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 2bb1309003dd..4ccda77d08d6 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -22,6 +22,7 @@ #include <asm/cacheflush.h> #include <asm/tlbflush.h> #include <asm/dma.h> +#include <asm/oplib.h> /* #define IOUNIT_DEBUG */ #ifdef IOUNIT_DEBUG @@ -41,9 +42,12 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus) struct linux_prom_registers iommu_promregs[PROMREG_MAX]; struct resource r; - iounit = kmalloc(sizeof(struct iounit_struct), GFP_ATOMIC); + iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC); + if (!iounit) { + prom_printf("SUN4D: Cannot alloc iounit, halting.\n"); + prom_halt(); + } - memset(iounit, 0, sizeof(*iounit)); iounit->limit[0] = IOUNIT_BMAP1_START; iounit->limit[1] = IOUNIT_BMAP2_START; iounit->limit[2] = IOUNIT_BMAPM_START; diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index d391d11f245a..d41f66ac7fff 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -26,6 +26,14 @@ config MMU bool default y +config STACKTRACE_SUPPORT + bool + default y + +config LOCKDEP_SUPPORT + bool + default y + config TIME_INTERPOLATION bool default y diff --git a/arch/sparc64/Kconfig.debug b/arch/sparc64/Kconfig.debug index afe0a7720a26..1f130f3b6c24 100644 --- a/arch/sparc64/Kconfig.debug +++ b/arch/sparc64/Kconfig.debug @@ -1,5 +1,9 @@ menu "Kernel hacking" +config TRACE_IRQFLAGS_SUPPORT + bool + default y + source "lib/Kconfig.debug" config DEBUG_STACK_USAGE diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 2f4612fa81f2..0f0d38f6197c 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,24 +1,29 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc2 -# Tue Oct 17 19:29:20 2006 +# Linux kernel version: 2.6.19 +# Sat Dec 9 15:41:30 2006 # CONFIG_SPARC=y CONFIG_SPARC64=y CONFIG_64BIT=y CONFIG_MMU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y CONFIG_TIME_INTERPOLATION=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_AUDIT_ARCH=y CONFIG_SPARC64_PAGE_SIZE_8KB=y # CONFIG_SPARC64_PAGE_SIZE_64KB is not set # CONFIG_SPARC64_PAGE_SIZE_512KB is not set # CONFIG_SPARC64_PAGE_SIZE_4MB is not set CONFIG_SECCOMP=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set -CONFIG_HZ=250 +CONFIG_HZ=100 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -42,13 +47,14 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y CONFIG_RELAY=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -203,6 +209,7 @@ 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=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y @@ -219,7 +226,6 @@ CONFIG_INET6_XFRM_MODE_BEET=m # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set CONFIG_IPV6_SIT=m CONFIG_IPV6_TUNNEL=m -# CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set @@ -238,6 +244,8 @@ CONFIG_IP_DCCP_CCID2=m # CONFIG_IP_DCCP_CCID2_DEBUG is not set CONFIG_IP_DCCP_CCID3=m CONFIG_IP_DCCP_TFRC_LIB=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 # # DCCP Kernel Hacking @@ -405,6 +413,7 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_RAID_ATTRS=m CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y @@ -425,6 +434,7 @@ CONFIG_CHR_DEV_SG=m CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set # # SCSI Transports @@ -468,6 +478,7 @@ CONFIG_ISCSI_TCP=m # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SUNESP is not set +# CONFIG_SCSI_SRP is not set # # Serial ATA (prod) and Parallel ATA (experimental) drivers @@ -598,6 +609,7 @@ CONFIG_BNX2=m # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set # # Token Ring devices @@ -724,10 +736,6 @@ CONFIG_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set @@ -1039,6 +1047,11 @@ CONFIG_SND_SUN_CS4231=m # CONFIG_SOUND_PRIME is not set # +# HID Devices +# +CONFIG_HID=y + +# # USB support # CONFIG_USB_ARCH_HAS_HCD=y @@ -1053,6 +1066,7 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_MULTITHREAD_PROBE is not set # CONFIG_USB_OTG is not set # @@ -1089,8 +1103,7 @@ CONFIG_USB_UHCI_HCD=m # USB Input Devices # CONFIG_USB_HID=y -CONFIG_USB_HIDINPUT=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_USB_HID_POWERBOOK is not set # CONFIG_HID_FF is not set CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set @@ -1119,6 +1132,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_KAWETH is not set # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set # CONFIG_USB_USBNET is not set # CONFIG_USB_MON is not set @@ -1364,6 +1378,11 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_UTF8 is not set # +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# # Instrumentation Support # CONFIG_PROFILING=y @@ -1373,6 +1392,7 @@ CONFIG_KPROBES=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y @@ -1387,6 +1407,8 @@ CONFIG_SCHEDSTATS=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1420,8 +1442,9 @@ CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=y CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y @@ -1430,8 +1453,10 @@ CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_GF128MUL=m CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m @@ -1456,6 +1481,7 @@ CONFIG_CRYPTO_TEST=m # # Library routines # +CONFIG_BITREVERSE=y CONFIG_CRC_CCITT=m CONFIG_CRC16=m CONFIG_CRC32=y diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index e1eabebaed39..eff0c01d3579 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -14,6 +14,7 @@ obj-y := process.o setup.o cpu.o idprom.o \ power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ visemul.o prom.o of_device.o +obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ pci_psycho.o pci_sabre.o pci_schizo.o \ pci_sun4v.o pci_sun4v_asm.o diff --git a/arch/sparc64/kernel/chmc.c b/arch/sparc64/kernel/chmc.c index 259f37e516f5..9699abeb9907 100644 --- a/arch/sparc64/kernel/chmc.c +++ b/arch/sparc64/kernel/chmc.c @@ -341,7 +341,7 @@ static void fetch_decode_regs(struct mctrl_info *mp) static int init_one_mctrl(struct device_node *dp) { - struct mctrl_info *mp = kmalloc(sizeof(*mp), GFP_KERNEL); + struct mctrl_info *mp = kzalloc(sizeof(*mp), GFP_KERNEL); int portid = of_getintprop_default(dp, "portid", -1); struct linux_prom64_registers *regs; void *pval; @@ -349,7 +349,6 @@ static int init_one_mctrl(struct device_node *dp) if (!mp) return -1; - memset(mp, 0, sizeof(*mp)); if (portid == -1) goto fail; diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 6f28bec0a9bf..c15a3edcb826 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -597,7 +597,12 @@ __spitfire_cee_trap_continue: 1: ba,pt %xcc, etrap_irq rd %pc, %g7 -2: mov %l4, %o1 +2: +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif + mov %l4, %o1 mov %l5, %o2 call spitfire_access_error add %sp, PTREGS_OFF, %o0 @@ -824,6 +829,10 @@ do_cheetah_plus_data_parity: wrpr %g0, 15, %pil ba,pt %xcc, etrap_irq rd %pc, %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif mov 0x0, %o0 call cheetah_plus_parity_error add %sp, PTREGS_OFF, %o1 @@ -855,6 +864,10 @@ do_cheetah_plus_insn_parity: wrpr %g0, 15, %pil ba,pt %xcc, etrap_irq rd %pc, %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif mov 0x1, %o0 call cheetah_plus_parity_error add %sp, PTREGS_OFF, %o1 @@ -1183,6 +1196,10 @@ c_fast_ecc: wrpr %g0, 15, %pil ba,pt %xcc, etrap_irq rd %pc, %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif mov %l4, %o1 mov %l5, %o2 call cheetah_fecc_handler @@ -1211,6 +1228,10 @@ c_cee: wrpr %g0, 15, %pil ba,pt %xcc, etrap_irq rd %pc, %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif mov %l4, %o1 mov %l5, %o2 call cheetah_cee_handler @@ -1239,6 +1260,10 @@ c_deferred: wrpr %g0, 15, %pil ba,pt %xcc, etrap_irq rd %pc, %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif mov %l4, %o1 mov %l5, %o2 call cheetah_deferred_handler diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index c8e9dc9d68a9..03ffaf895a22 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S @@ -489,6 +489,14 @@ tlb_fixup_done: call __bzero sub %o1, %o0, %o1 +#ifdef CONFIG_LOCKDEP + /* We have this call this super early, as even prom_init can grab + * spinlocks and thus call into the lockdep code. + */ + call lockdep_init + nop +#endif + mov %l6, %o1 ! OpenPROM stack call prom_init mov %l7, %o0 ! OpenPROM cif handler diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c index f028e68b23f2..ad1c4f55420f 100644 --- a/arch/sparc64/kernel/isa.c +++ b/arch/sparc64/kernel/isa.c @@ -72,14 +72,12 @@ static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev) struct linux_prom_registers *regs; struct sparc_isa_device *isa_dev; - isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); + isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL); if (!isa_dev) { fatal_err("cannot allocate child isa_dev"); prom_halt(); } - memset(isa_dev, 0, sizeof(*isa_dev)); - /* Link it in to parent. */ isa_dev->next = parent_isa_dev->child; parent_isa_dev->child = isa_dev; @@ -104,14 +102,12 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) struct linux_prom_registers *regs; struct sparc_isa_device *isa_dev; - isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); + isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL); if (!isa_dev) { printk(KERN_DEBUG "ISA: cannot allocate isa_dev"); return; } - memset(isa_dev, 0, sizeof(*isa_dev)); - isa_dev->ofdev.node = dp; isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev; isa_dev->ofdev.dev.bus = &isa_bus_type; @@ -180,14 +176,12 @@ void __init isa_init(void) pbm = pdev_cookie->pbm; dp = pdev_cookie->prom_node; - isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL); + isa_br = kzalloc(sizeof(*isa_br), GFP_KERNEL); if (!isa_br) { printk(KERN_DEBUG "isa: cannot allocate sparc_isa_bridge"); return; } - memset(isa_br, 0, sizeof(*isa_br)); - isa_br->ofdev.node = dp; isa_br->ofdev.dev.parent = &pdev->dev; isa_br->ofdev.dev.bus = &isa_bus_type; diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index 8e75ed762fd8..ae221f0d4a6f 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c @@ -45,7 +45,11 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); int __kprobes arch_prepare_kprobe(struct kprobe *p) { p->ainsn.insn[0] = *p->addr; + flushi(&p->ainsn.insn[0]); + p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2; + flushi(&p->ainsn.insn[1]); + p->opcode = *p->addr; return 0; } @@ -185,16 +189,19 @@ no_kprobe: /* If INSN is a relative control transfer instruction, * return the corrected branch destination value. * - * The original INSN location was REAL_PC, it actually - * executed at PC and produced destination address NPC. + * regs->tpc and regs->tnpc still hold the values of the + * program counters at the time of trap due to the execution + * of the BREAKPOINT_INSTRUCTION_2 at p->ainsn.insn[1] + * */ -static unsigned long __kprobes relbranch_fixup(u32 insn, unsigned long real_pc, - unsigned long pc, - unsigned long npc) +static unsigned long __kprobes relbranch_fixup(u32 insn, struct kprobe *p, + struct pt_regs *regs) { + unsigned long real_pc = (unsigned long) p->addr; + /* Branch not taken, no mods necessary. */ - if (npc == pc + 0x4UL) - return real_pc + 0x4UL; + if (regs->tnpc == regs->tpc + 0x4UL) + return real_pc + 0x8UL; /* The three cases are call, branch w/prediction, * and traditional branch. @@ -202,14 +209,21 @@ static unsigned long __kprobes relbranch_fixup(u32 insn, unsigned long real_pc, if ((insn & 0xc0000000) == 0x40000000 || (insn & 0xc1c00000) == 0x00400000 || (insn & 0xc1c00000) == 0x00800000) { + unsigned long ainsn_addr; + + ainsn_addr = (unsigned long) &p->ainsn.insn[0]; + /* The instruction did all the work for us * already, just apply the offset to the correct * instruction location. */ - return (real_pc + (npc - pc)); + return (real_pc + (regs->tnpc - ainsn_addr)); } - return real_pc + 0x4UL; + /* It is jmpl or some other absolute PC modification instruction, + * leave NPC as-is. + */ + return regs->tnpc; } /* If INSN is an instruction which writes it's PC location @@ -220,12 +234,12 @@ static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn, { unsigned long *slot = NULL; - /* Simplest cast is call, which always uses %o7 */ + /* Simplest case is 'call', which always uses %o7 */ if ((insn & 0xc0000000) == 0x40000000) { slot = ®s->u_regs[UREG_I7]; } - /* Jmpl encodes the register inside of the opcode */ + /* 'jmpl' encodes the register inside of the opcode */ if ((insn & 0xc1f80000) == 0x81c00000) { unsigned long rd = ((insn >> 25) & 0x1f); @@ -247,11 +261,11 @@ static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn, /* * Called after single-stepping. p->addr is the address of the - * instruction whose first byte has been replaced by the breakpoint + * instruction which has been replaced by the breakpoint * instruction. To avoid the SMP problems that can occur when we * temporarily put back the original opcode to single-step, we * single-stepped a copy of the instruction. The address of this - * copy is p->ainsn.insn. + * copy is &p->ainsn.insn[0]. * * This function prepares to return from the post-single-step * breakpoint trap. @@ -261,11 +275,11 @@ static void __kprobes resume_execution(struct kprobe *p, { u32 insn = p->ainsn.insn[0]; + regs->tnpc = relbranch_fixup(insn, p, regs); + + /* This assignment must occur after relbranch_fixup() */ regs->tpc = kcb->kprobe_orig_tnpc; - regs->tnpc = relbranch_fixup(insn, - (unsigned long) p->addr, - (unsigned long) &p->ainsn.insn[0], - regs->tnpc); + retpc_fixup(regs, insn, (unsigned long) p->addr); regs->tstate = ((regs->tstate & ~TSTATE_PIL) | @@ -430,17 +444,8 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) struct jprobe *jp = container_of(p, struct jprobe, kp); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); - kcb->jprobe_saved_regs_location = regs; memcpy(&(kcb->jprobe_saved_regs), regs, sizeof(*regs)); - /* Save a whole stack frame, this gets arguments - * pushed onto the stack after using up all the - * arg registers. - */ - memcpy(&(kcb->jprobe_saved_stack), - (char *) (regs->u_regs[UREG_FP] + STACK_BIAS), - sizeof(kcb->jprobe_saved_stack)); - regs->tpc = (unsigned long) jp->entry; regs->tnpc = ((unsigned long) jp->entry) + 0x4UL; regs->tstate |= TSTATE_PIL; @@ -450,10 +455,19 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) void __kprobes jprobe_return(void) { - __asm__ __volatile__( - ".globl jprobe_return_trap_instruction\n" + struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); + register unsigned long orig_fp asm("g1"); + + orig_fp = kcb->jprobe_saved_regs.u_regs[UREG_FP]; + __asm__ __volatile__("\n" +"1: cmp %%sp, %0\n\t" + "blu,a,pt %%xcc, 1b\n\t" + " restore\n\t" + ".globl jprobe_return_trap_instruction\n" "jprobe_return_trap_instruction:\n\t" - "ta 0x70"); + "ta 0x70" + : /* no outputs */ + : "r" (orig_fp)); } extern void jprobe_return_trap_instruction(void); @@ -466,26 +480,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); if (addr == (u32 *) jprobe_return_trap_instruction) { - if (kcb->jprobe_saved_regs_location != regs) { - printk("JPROBE: Current regs (%p) does not match " - "saved regs (%p).\n", - regs, kcb->jprobe_saved_regs_location); - printk("JPROBE: Saved registers\n"); - __show_regs(kcb->jprobe_saved_regs_location); - printk("JPROBE: Current registers\n"); - __show_regs(regs); - BUG(); - } - /* Restore old register state. Do pt_regs - * first so that UREG_FP is the original one for - * the stack frame restore. - */ memcpy(regs, &(kcb->jprobe_saved_regs), sizeof(*regs)); - - memcpy((char *) (regs->u_regs[UREG_FP] + STACK_BIAS), - &(kcb->jprobe_saved_stack), - sizeof(kcb->jprobe_saved_stack)); - preempt_enable_no_resched(); return 1; } diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 8cc14fc6b6f1..cec0eceae552 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -1007,10 +1007,9 @@ struct of_device* of_platform_device_create(struct device_node *np, { struct of_device *dev; - dev = kmalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return NULL; - memset(dev, 0, sizeof(*dev)); dev->dev.parent = parent; dev->dev.bus = bus; diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 03ad4c06758e..6b04794b7a97 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -798,7 +798,7 @@ static struct pci_ops pci_sun4v_ops = { static void pbm_scan_bus(struct pci_controller_info *p, struct pci_pbm_info *pbm) { - struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL); + struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); if (!cookie) { prom_printf("%s: Critical allocation failure.\n", pbm->name); @@ -806,7 +806,6 @@ static void pbm_scan_bus(struct pci_controller_info *p, } /* All we care about is the PBM. */ - memset(cookie, 0, sizeof(*cookie)); cookie->pbm = pbm; pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, p->pci_ops, pbm); @@ -1048,12 +1047,11 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) /* Allocate and initialize the free area map. */ sz = num_tsb_entries / 8; sz = (sz + 7UL) & ~7UL; - iommu->arena.map = kmalloc(sz, GFP_KERNEL); + iommu->arena.map = kzalloc(sz, GFP_KERNEL); if (!iommu->arena.map) { prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n"); prom_halt(); } - memset(iommu->arena.map, 0, sz); iommu->arena.limit = num_tsb_entries; sz = probe_existing_entries(pbm, iommu); @@ -1164,24 +1162,20 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) per_cpu(pci_iommu_batch, i).pglist = (u64 *) page; } - p = kmalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); + p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); if (!p) goto fatal_memory_error; - memset(p, 0, sizeof(*p)); - - iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC); + iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); if (!iommu) goto fatal_memory_error; - memset(iommu, 0, sizeof(*iommu)); p->pbm_A.iommu = iommu; - iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC); + iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); if (!iommu) goto fatal_memory_error; - memset(iommu, 0, sizeof(*iommu)); p->pbm_B.iommu = iommu; p->next = pci_controller_root; diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index d31975e6d6f6..81111a12f0a8 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c @@ -202,7 +202,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs) #endif if (request == PTRACE_TRACEME) { ret = ptrace_traceme(); - pt_succ_return(regs, 0); + if (ret < 0) + pt_error_return(regs, -ret); + else + pt_succ_return(regs, 0); goto out; } diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index 3522cd66f3bb..079d18a11d24 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S @@ -165,14 +165,26 @@ rtrap: __handle_softirq_continue: rtrap_xcall: sethi %hi(0xf << 20), %l4 - andcc %l1, TSTATE_PRIV, %l3 and %l1, %l4, %l4 + andn %l1, %l4, %l1 + srl %l4, 20, %l4 +#ifdef CONFIG_TRACE_IRQFLAGS + brnz,pn %l4, rtrap_no_irq_enable + nop + call trace_hardirqs_on + nop + wrpr %l4, %pil +rtrap_no_irq_enable: +#endif + andcc %l1, TSTATE_PRIV, %l3 bne,pn %icc, to_kernel - andn %l1, %l4, %l1 + nop /* We must hold IRQs off and atomically test schedule+signal * state, then hold them off all the way back to userspace. - * If we are returning to kernel, none of this matters. + * If we are returning to kernel, none of this matters. Note + * that we are disabling interrupts via PSTATE_IE, not using + * %pil. * * If we do not do this, there is a window where we would do * the tests, later the signal/resched event arrives but we do @@ -256,7 +268,6 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 ld [%sp + PTREGS_OFF + PT_V9_Y], %o3 wr %o3, %g0, %y - srl %l4, 20, %l4 wrpr %l4, 0x0, %pil wrpr %g0, 0x1, %tl wrpr %l1, %g0, %tstate @@ -374,8 +385,8 @@ to_kernel: ldx [%g6 + TI_FLAGS], %l5 andcc %l5, _TIF_NEED_RESCHED, %g0 be,pt %xcc, kern_fpucheck - srl %l4, 20, %l5 - cmp %l5, 0 + nop + cmp %l4, 0 bne,pn %xcc, kern_fpucheck sethi %hi(PREEMPT_ACTIVE), %l6 stw %l6, [%g6 + TI_PRE_COUNT] diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c new file mode 100644 index 000000000000..c4d15f2762b9 --- /dev/null +++ b/arch/sparc64/kernel/stacktrace.c @@ -0,0 +1,41 @@ +#include <linux/sched.h> +#include <linux/stacktrace.h> +#include <linux/thread_info.h> +#include <asm/ptrace.h> + +void save_stack_trace(struct stack_trace *trace, struct task_struct *task) +{ + unsigned long ksp, fp, thread_base; + struct thread_info *tp; + + if (!task) + task = current; + tp = task_thread_info(task); + if (task == current) { + flushw_all(); + __asm__ __volatile__( + "mov %%fp, %0" + : "=r" (ksp) + ); + } else + ksp = tp->ksp; + + fp = ksp + STACK_BIAS; + thread_base = (unsigned long) tp; + do { + struct reg_window *rw; + + /* Bogus frame pointer? */ + if (fp < (thread_base + sizeof(struct thread_info)) || + fp >= (thread_base + THREAD_SIZE)) + break; + + rw = (struct reg_window *) fp; + if (trace->skip > 0) + trace->skip--; + else + trace->entries[trace->nr_entries++] = rw->ins[7]; + + fp = rw->ins[6] + STACK_BIAS; + } while (trace->nr_entries < trace->max_entries); +} diff --git a/arch/sparc64/kernel/sun4v_ivec.S b/arch/sparc64/kernel/sun4v_ivec.S index 49703c3c5769..405855dd886b 100644 --- a/arch/sparc64/kernel/sun4v_ivec.S +++ b/arch/sparc64/kernel/sun4v_ivec.S @@ -190,7 +190,10 @@ sun4v_res_mondo: mov %g1, %g4 ba,pt %xcc, etrap_irq rd %pc, %g7 - +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif /* Log the event. */ add %sp, PTREGS_OFF, %o0 call sun4v_resum_error @@ -216,7 +219,10 @@ sun4v_res_mondo_queue_full: wrpr %g0, 15, %pil ba,pt %xcc, etrap_irq rd %pc, %g7 - +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif call sun4v_resum_overflow add %sp, PTREGS_OFF, %o0 @@ -295,7 +301,10 @@ sun4v_nonres_mondo: mov %g1, %g4 ba,pt %xcc, etrap_irq rd %pc, %g7 - +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif /* Log the event. */ add %sp, PTREGS_OFF, %o0 call sun4v_nonresum_error @@ -321,7 +330,10 @@ sun4v_nonres_mondo_queue_full: wrpr %g0, 15, %pil ba,pt %xcc, etrap_irq rd %pc, %g7 - +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif call sun4v_nonresum_overflow add %sp, PTREGS_OFF, %o0 diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index fe1796c939c3..ad67784292db 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -10,7 +10,7 @@ */ #include <linux/module.h> -#include <linux/sched.h> /* for jiffies */ +#include <linux/sched.h> #include <linux/kernel.h> #include <linux/kallsyms.h> #include <linux/signal.h> @@ -1873,6 +1873,16 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset) put_cpu(); + if (ent->err_type == SUN4V_ERR_TYPE_WARNING_RES) { + /* If err_type is 0x4, it's a powerdown request. Do + * not do the usual resumable error log because that + * makes it look like some abnormal error. + */ + printk(KERN_INFO "Power down request...\n"); + kill_cad_pid(SIGINT, 1); + return; + } + sun4v_log_error(regs, &local_copy, cpu, KERN_ERR "RESUMABLE ERROR", &sun4v_resum_oflow_cnt); @@ -2261,8 +2271,12 @@ void die_if_kernel(char *str, struct pt_regs *regs) do_exit(SIGSEGV); } +#define VIS_OPCODE_MASK ((0x3 << 30) | (0x3f << 19)) +#define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19)) + extern int handle_popc(u32 insn, struct pt_regs *regs); extern int handle_ldf_stq(u32 insn, struct pt_regs *regs); +extern int vis_emul(struct pt_regs *, unsigned int); void do_illegal_instruction(struct pt_regs *regs) { @@ -2287,10 +2301,18 @@ void do_illegal_instruction(struct pt_regs *regs) if (handle_ldf_stq(insn, regs)) return; } else if (tlb_type == hypervisor) { - extern int vis_emul(struct pt_regs *, unsigned int); + if ((insn & VIS_OPCODE_MASK) == VIS_OPCODE_VAL) { + if (!vis_emul(regs, insn)) + return; + } else { + struct fpustate *f = FPUSTATE; - if (!vis_emul(regs, insn)) - return; + /* XXX maybe verify XFSR bits like + * XXX do_fpother() does? + */ + if (do_mathemu(regs, f)) + return; + } } } info.si_signo = SIGILL; diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c index a9b765271b85..bc18d480dd1c 100644 --- a/arch/sparc64/kernel/unaligned.c +++ b/arch/sparc64/kernel/unaligned.c @@ -243,7 +243,7 @@ static inline int ok_for_kernel(unsigned int insn) return !floating_point_load_or_store_p(insn); } -static void kernel_mna_trap_fault(void) +static void kernel_mna_trap_fault(int fixup_tstate_asi) { struct pt_regs *regs = current_thread_info()->kern_una_regs; unsigned int insn = current_thread_info()->kern_una_insn; @@ -274,18 +274,15 @@ static void kernel_mna_trap_fault(void) regs->tpc = entry->fixup; regs->tnpc = regs->tpc + 4; - regs->tstate &= ~TSTATE_ASI; - regs->tstate |= (ASI_AIUS << 24UL); + if (fixup_tstate_asi) { + regs->tstate &= ~TSTATE_ASI; + regs->tstate |= (ASI_AIUS << 24UL); + } } -asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) +static void log_unaligned(struct pt_regs *regs) { static unsigned long count, last_time; - enum direction dir = decode_direction(insn); - int size = decode_access_size(insn); - - current_thread_info()->kern_una_regs = regs; - current_thread_info()->kern_una_insn = insn; if (jiffies - last_time > 5 * HZ) count = 0; @@ -295,6 +292,28 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) printk("Kernel unaligned access at TPC[%lx] ", regs->tpc); print_symbol("%s\n", regs->tpc); } +} + +asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) +{ + enum direction dir = decode_direction(insn); + int size = decode_access_size(insn); + int orig_asi, asi; + + current_thread_info()->kern_una_regs = regs; + current_thread_info()->kern_una_insn = insn; + + orig_asi = asi = decode_asi(insn, regs); + + /* If this is a {get,put}_user() on an unaligned userspace pointer, + * just signal a fault and do not log the event. + */ + if (asi == ASI_AIUS) { + kernel_mna_trap_fault(0); + return; + } + + log_unaligned(regs); if (!ok_for_kernel(insn) || dir == both) { printk("Unsupported unaligned load/store trap for kernel " @@ -302,10 +321,10 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) unaligned_panic("Kernel does fpu/atomic " "unaligned load/store.", regs); - kernel_mna_trap_fault(); + kernel_mna_trap_fault(0); } else { unsigned long addr, *reg_addr; - int orig_asi, asi, err; + int err; addr = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f)); @@ -315,7 +334,6 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) regs->tpc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]); #endif - orig_asi = asi = decode_asi(insn, regs); switch (asi) { case ASI_NL: case ASI_AIUPL: @@ -365,7 +383,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) /* Not reached... */ } if (unlikely(err)) - kernel_mna_trap_fault(); + kernel_mna_trap_fault(1); else advance(regs); } diff --git a/arch/sparc64/kernel/visemul.c b/arch/sparc64/kernel/visemul.c index 84fedaa38aae..c3fd64706b53 100644 --- a/arch/sparc64/kernel/visemul.c +++ b/arch/sparc64/kernel/visemul.c @@ -128,9 +128,6 @@ /* 001001100 - Permute bytes as specified by GSR.MASK */ #define BSHUFFLE_OPF 0x04c -#define VIS_OPCODE_MASK ((0x3 << 30) | (0x3f << 19)) -#define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19)) - #define VIS_OPF_SHIFT 5 #define VIS_OPF_MASK (0x1ff << VIS_OPF_SHIFT) @@ -810,9 +807,6 @@ int vis_emul(struct pt_regs *regs, unsigned int insn) if (get_user(insn, (u32 __user *) pc)) return -EFAULT; - if ((insn & VIS_OPCODE_MASK) != VIS_OPCODE_VAL) - return -EINVAL; - opf = (insn & VIS_OPF_MASK) >> VIS_OPF_SHIFT; switch (opf) { default: diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index d70b60a3bbcc..737c26923c09 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S @@ -477,6 +477,10 @@ xcall_sync_tick: sethi %hi(109f), %g7 b,pt %xcc, etrap_irq 109: or %g7, %lo(109b), %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif call smp_synchronize_tick_client nop clr %l6 @@ -508,6 +512,10 @@ xcall_report_regs: sethi %hi(109f), %g7 b,pt %xcc, etrap_irq 109: or %g7, %lo(109b), %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif call __show_regs add %sp, PTREGS_OFF, %o0 clr %l6 diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 3ac581d17202..d4275537b25b 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -584,7 +584,7 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPRIMENTAL)" + bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" depends on EXPERIMENTAL help This option turns on the -fstack-protector GCC feature. This diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index 4a673f5397a0..2433d6fc68b1 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -225,8 +225,7 @@ out: static int vsyscall_sysctl_nostrat(ctl_table *t, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen, - void **context) + void __user *newval, size_t newlen) { return -ENOSYS; } diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 9eccfbd1b536..2e74cb0b7807 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -48,25 +48,10 @@ menu "Processor type and features" choice prompt "Xtensa Processor Configuration" - default XTENSA_CPU_LINUX_BE + default XTENSA_VARIANT_FSF -config XTENSA_CPU_LINUX_BE - bool "linux_be" - ---help--- - The linux_be processor configuration is the baseline Xtensa - configurations included in this kernel and also used by - binutils, gcc, and gdb. It contains no TIE, no coprocessors, - and the following configuration options: - - Code Density Option 2 Misc Special Registers - NSA/NSAU Instructions 128-bit Data Bus Width - Processor ID 8K, 2-way I and D Caches - Zero-Overhead Loops 2 Inst Address Break Registers - Big Endian 2 Data Address Break Registers - 64 General-Purpose Registers JTAG Interface and Trace Port - 17 Interrupts MMU w/ TLBs and Autorefill - 3 Interrupt Levels 8 Autorefill Ways (I/D TLBs) - 3 Timers Unaligned Exceptions +config XTENSA_VARIANT_FSF + bool "fsf" endchoice config MMU diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 3a3a4c66ef87..95f836db38fa 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -11,13 +11,13 @@ # this architecture # Core configuration. -# (Use CPU=<xtensa_config> to use another default compiler.) +# (Use VAR=<xtensa_config> to use another default compiler.) -cpu-$(CONFIG_XTENSA_CPU_LINUX_BE) := linux_be -cpu-$(CONFIG_XTENSA_CPU_LINUX_CUSTOM) := linux_custom +variant-$(CONFIG_XTENSA_VARIANT_FSF) := fsf +variant-$(CONFIG_XTENSA_VARIANT_LINUX_CUSTOM) := custom -CPU = $(cpu-y) -export CPU +VARIANT = $(variant-y) +export VARIANT # Platform configuration @@ -27,8 +27,6 @@ platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss PLATFORM = $(platform-y) export PLATFORM -CPPFLAGS += $(if $(KBUILD_SRC),-I$(srctree)/include/asm-xtensa/) -CPPFLAGS += -Iinclude/asm CFLAGS += -pipe -mlongcalls KBUILD_DEFCONFIG := iss_defconfig @@ -41,12 +39,12 @@ core-$(CONFIG_EMBEDDED_RAMDISK) += arch/xtensa/boot/ramdisk/ # Test for cross compiling -ifneq ($(CPU),) +ifneq ($(VARIANT),) COMPILE_ARCH = $(shell uname -m) ifneq ($(COMPILE_ARCH), xtensa) ifndef CROSS_COMPILE - CROSS_COMPILE = xtensa_$(CPU)- + CROSS_COMPILE = xtensa_$(VARIANT)- endif endif endif @@ -68,14 +66,13 @@ archinc := include/asm-xtensa archprepare: $(archinc)/.platform -# Update machine cpu and platform symlinks if something which affects +# Update processor variant and platform symlinks if something which affects # them changed. $(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/auto.conf - @echo ' SYMLINK $(archinc)/xtensa/config -> $(archinc)/xtensa/config-$(CPU)' + @echo ' SYMLINK $(archinc)/variant -> $(archinc)/variant-$(VARIANT)' $(Q)mkdir -p $(archinc) - $(Q)mkdir -p $(archinc)/xtensa - $(Q)ln -fsn $(srctree)/$(archinc)/xtensa/config-$(CPU) $(archinc)/xtensa/config + $(Q)ln -fsn $(srctree)/$(archinc)/variant-$(VARIANT) $(archinc)/variant @echo ' SYMLINK $(archinc)/platform -> $(archinc)/platform-$(PLATFORM)' $(Q)ln -fsn $(srctree)/$(archinc)/platform-$(PLATFORM) $(archinc)/platform @touch $@ @@ -89,7 +86,7 @@ zImage zImage.initrd: vmlinux $(Q)$(MAKE) $(build)=$(boot) $@ CLEAN_FILES += arch/xtensa/vmlinux.lds \ - $(archinc)/platform $(archinc)/xtensa/config \ + $(archinc)/platform $(archinc)/variant \ $(archinc)/.platform define archhelp diff --git a/arch/xtensa/boot/boot-elf/bootstrap.S b/arch/xtensa/boot/boot-elf/bootstrap.S index f857fc760aa8..464298bc348b 100644 --- a/arch/xtensa/boot/boot-elf/bootstrap.S +++ b/arch/xtensa/boot/boot-elf/bootstrap.S @@ -1,7 +1,4 @@ -#include <xtensa/config/specreg.h> -#include <xtensa/config/core.h> - #include <asm/bootparam.h> diff --git a/arch/xtensa/boot/boot-redboot/bootstrap.S b/arch/xtensa/boot/boot-redboot/bootstrap.S index ee636b0da81c..84848123e2a8 100644 --- a/arch/xtensa/boot/boot-redboot/bootstrap.S +++ b/arch/xtensa/boot/boot-redboot/bootstrap.S @@ -1,9 +1,7 @@ - -#define _ASMLANGUAGE -#include <xtensa/config/specreg.h> -#include <xtensa/config/core.h> -#include <xtensa/cacheasm.h> - +#include <asm/variant/core.h> +#include <asm/regs.h> +#include <asm/asmmacro.h> +#include <asm/cacheasm.h> /* * RB-Data: RedBoot data/bss * P: Boot-Parameters @@ -77,8 +75,14 @@ _start: /* Note: The assembler cannot relax "addi a0, a0, ..." to an l32r, so we load to a4 first. */ - addi a4, a0, __start - __start_a0 - mov a0, a4 + # addi a4, a0, __start - __start_a0 + # mov a0, a4 + + movi a4, __start + movi a5, __start_a0 + add a4, a0, a4 + sub a0, a4, a5 + movi a4, __start movi a5, __reloc_end @@ -106,9 +110,13 @@ _start: /* We have to flush and invalidate the caches here before we jump. */ #if XCHAL_DCACHE_IS_WRITEBACK - dcache_writeback_all a5, a6 + + ___flush_dcache_all a5 a6 + #endif - icache_invalidate_all a5, a6 + + ___invalidate_icache_all a5 a6 + isync movi a11, _reloc jx a11 @@ -209,9 +217,14 @@ _reloc: /* jump to the kernel */ 2: #if XCHAL_DCACHE_IS_WRITEBACK - dcache_writeback_all a5, a6 + + ___flush_dcache_all a5 a6 + #endif - icache_invalidate_all a5, a6 + + ___invalidate_icache_all a5 a6 + + isync movi a5, __start movi a3, boot_initrd_start diff --git a/arch/xtensa/configs/iss_defconfig b/arch/xtensa/configs/iss_defconfig index 802621dd4867..f19854035e61 100644 --- a/arch/xtensa/configs/iss_defconfig +++ b/arch/xtensa/configs/iss_defconfig @@ -53,11 +53,7 @@ CONFIG_CC_ALIGN_JUMPS=0 # # Processor type and features # -CONFIG_XTENSA_ARCH_LINUX_BE=y -# CONFIG_XTENSA_ARCH_LINUX_LE is not set -# CONFIG_XTENSA_ARCH_LINUX_TEST is not set -# CONFIG_XTENSA_ARCH_S5 is not set -# CONFIG_XTENSA_CUSTOM is not set +CONFIG_XTENSA_VARIANT_FSF=y CONFIG_MMU=y # CONFIG_XTENSA_UNALIGNED_USER is not set # CONFIG_PREEMPT is not set diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S index a4956578a24d..33d6e9d2e83c 100644 --- a/arch/xtensa/kernel/align.S +++ b/arch/xtensa/kernel/align.S @@ -16,14 +16,9 @@ */ #include <linux/linkage.h> -#include <asm/ptrace.h> -#include <asm/ptrace.h> #include <asm/current.h> #include <asm/asm-offsets.h> -#include <asm/pgtable.h> #include <asm/processor.h> -#include <asm/page.h> -#include <asm/thread_info.h> #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION @@ -216,7 +211,7 @@ ENTRY(fast_unaligned) extui a5, a4, INSN_OP0, 4 # get insn.op0 nibble -#if XCHAL_HAVE_NARROW +#if XCHAL_HAVE_DENSITY _beqi a5, OP0_L32I_N, .Lload # L32I.N, jump addi a6, a5, -OP0_S32I_N _beqz a6, .Lstore # S32I.N, do a store @@ -251,7 +246,7 @@ ENTRY(fast_unaligned) #endif __src_b a3, a5, a6 # a3 has the data word -#if XCHAL_HAVE_NARROW +#if XCHAL_HAVE_DENSITY addi a7, a7, 2 # increment PC (assume 16-bit insn) extui a5, a4, INSN_OP0, 4 @@ -279,14 +274,14 @@ ENTRY(fast_unaligned) 1: -#if XCHAL_HAVE_LOOP - rsr a3, LEND # check if we reached LEND - bne a7, a3, 1f - rsr a3, LCOUNT # and LCOUNT != 0 - beqz a3, 1f - addi a3, a3, -1 # decrement LCOUNT and set +#if XCHAL_HAVE_LOOPS + rsr a5, LEND # check if we reached LEND + bne a7, a5, 1f + rsr a5, LCOUNT # and LCOUNT != 0 + beqz a5, 1f + addi a5, a5, -1 # decrement LCOUNT and set rsr a7, LBEG # set PC to LBEGIN - wsr a3, LCOUNT + wsr a5, LCOUNT #endif 1: wsr a7, EPC_1 # skip load instruction @@ -336,7 +331,7 @@ ENTRY(fast_unaligned) movi a6, 0 # mask: ffffffff:00000000 -#if XCHAL_HAVE_NARROW +#if XCHAL_HAVE_DENSITY addi a7, a7, 2 # incr. PC,assume 16-bit instruction extui a5, a4, INSN_OP0, 4 # extract OP0 @@ -359,14 +354,14 @@ ENTRY(fast_unaligned) /* Get memory address */ 1: -#if XCHAL_HAVE_LOOP - rsr a3, LEND # check if we reached LEND - bne a7, a3, 1f - rsr a3, LCOUNT # and LCOUNT != 0 - beqz a3, 1f - addi a3, a3, -1 # decrement LCOUNT and set +#if XCHAL_HAVE_LOOPS + rsr a4, LEND # check if we reached LEND + bne a7, a4, 1f + rsr a4, LCOUNT # and LCOUNT != 0 + beqz a4, 1f + addi a4, a4, -1 # decrement LCOUNT and set rsr a7, LBEG # set PC to LBEGIN - wsr a3, LCOUNT + wsr a4, LCOUNT #endif 1: wsr a7, EPC_1 # skip store instruction @@ -416,6 +411,7 @@ ENTRY(fast_unaligned) /* Restore working register */ + l32i a8, a2, PT_AREG8 l32i a7, a2, PT_AREG7 l32i a6, a2, PT_AREG6 l32i a5, a2, PT_AREG5 @@ -446,7 +442,7 @@ ENTRY(fast_unaligned) mov a1, a2 rsr a0, PS - bbsi.l a2, PS_UM_SHIFT, 1f # jump if user mode + bbsi.l a2, PS_UM_BIT, 1f # jump if user mode movi a0, _kernel_exception jx a0 diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index 7cd1d7f8f608..b256cfbef344 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c @@ -87,6 +87,11 @@ int main(void) DEFINE(MM_CONTEXT, offsetof (struct mm_struct, context)); BLANK(); DEFINE(PT_SINGLESTEP_BIT, PT_SINGLESTEP_BIT); + + /* constants */ + DEFINE(_CLONE_VM, CLONE_VM); + DEFINE(_CLONE_UNTRACED, CLONE_UNTRACED); + return 0; } diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S index cf5a93fb6a2e..01bcb9fcfcbd 100644 --- a/arch/xtensa/kernel/coprocessor.S +++ b/arch/xtensa/kernel/coprocessor.S @@ -90,7 +90,6 @@ ENTRY(enable_coprocessor) rsync retw -#endif ENTRY(save_coprocessor_extra) entry sp, 16 @@ -197,4 +196,5 @@ _xtensa_reginfo_tables: XCHAL_CP7_SA_CONTENTS_LIBDB .word 0xFC000000 /* invalid register number,marks end of table*/ _xtensa_reginfo_table_end: +#endif diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 89e409e9e0de..9e271ba009bf 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -24,7 +24,7 @@ #include <asm/pgtable.h> #include <asm/page.h> #include <asm/signal.h> -#include <xtensa/coreasm.h> +#include <asm/tlbflush.h> /* Unimplemented features. */ @@ -364,7 +364,7 @@ common_exception: movi a2, 1 extui a3, a3, 0, 1 # a3 = PS.INTLEVEL[0] moveqz a3, a2, a0 # a3 = 1 iff interrupt exception - movi a2, PS_WOE_MASK + movi a2, 1 << PS_WOE_BIT or a3, a3, a2 rsr a0, EXCCAUSE xsr a3, PS @@ -399,7 +399,7 @@ common_exception_return: /* Jump if we are returning from kernel exceptions. */ 1: l32i a3, a1, PT_PS - _bbsi.l a3, PS_UM_SHIFT, 2f + _bbsi.l a3, PS_UM_BIT, 2f j kernel_exception_exit /* Specific to a user exception exit: @@ -422,7 +422,7 @@ common_exception_return: * (Hint: There is only one user exception frame on stack) */ - movi a3, PS_WOE_MASK + movi a3, 1 << PS_WOE_BIT _bbsi.l a4, TIF_NEED_RESCHED, 3f _bbci.l a4, TIF_SIGPENDING, 4f @@ -694,7 +694,7 @@ common_exception_exit: ENTRY(debug_exception) rsr a0, EPS + XCHAL_DEBUGLEVEL - bbsi.l a0, PS_EXCM_SHIFT, 1f # exception mode + bbsi.l a0, PS_EXCM_BIT, 1f # exception mode /* Set EPC_1 and EXCCAUSE */ @@ -707,7 +707,7 @@ ENTRY(debug_exception) /* Restore PS to the value before the debug exc but with PS.EXCM set.*/ - movi a2, 1 << PS_EXCM_SHIFT + movi a2, 1 << PS_EXCM_BIT or a2, a0, a2 movi a0, debug_exception # restore a3, debug jump vector wsr a2, PS @@ -715,7 +715,7 @@ ENTRY(debug_exception) /* Switch to kernel/user stack, restore jump vector, and save a0 */ - bbsi.l a2, PS_UM_SHIFT, 2f # jump if user mode + bbsi.l a2, PS_UM_BIT, 2f # jump if user mode addi a2, a1, -16-PT_SIZE # assume kernel stack s32i a0, a2, PT_AREG0 @@ -778,7 +778,7 @@ ENTRY(unrecoverable_exception) wsr a1, WINDOWBASE rsync - movi a1, PS_WOE_MASK | 1 + movi a1, (1 << PS_WOE_BIT) | 1 wsr a1, PS rsync @@ -1004,13 +1004,10 @@ ENTRY(fast_syscall_kernel) rsr a0, DEPC # get syscall-nr _beqz a0, fast_syscall_spill_registers - - addi a0, a0, -__NR_sysxtensa - _beqz a0, fast_syscall_sysxtensa + _beqi a0, __NR_xtensa, fast_syscall_xtensa j kernel_exception - ENTRY(fast_syscall_user) /* Skip syscall. */ @@ -1024,9 +1021,7 @@ ENTRY(fast_syscall_user) rsr a0, DEPC # get syscall-nr _beqz a0, fast_syscall_spill_registers - - addi a0, a0, -__NR_sysxtensa - _beqz a0, fast_syscall_sysxtensa + _beqi a0, __NR_xtensa, fast_syscall_xtensa j user_exception @@ -1047,18 +1042,19 @@ ENTRY(fast_syscall_unrecoverable) /* * sysxtensa syscall handler * - * int sysxtensa (XTENSA_ATOMIC_SET, ptr, val, unused); - * int sysxtensa (XTENSA_ATOMIC_ADD, ptr, val, unused); - * int sysxtensa (XTENSA_ATOMIC_EXG_ADD, ptr, val, unused); - * int sysxtensa (XTENSA_ATOMIC_CMP_SWP, ptr, oldval, newval); - * a2 a6 a3 a4 a5 + * int sysxtensa (SYS_XTENSA_ATOMIC_SET, ptr, val, unused); + * int sysxtensa (SYS_XTENSA_ATOMIC_ADD, ptr, val, unused); + * int sysxtensa (SYS_XTENSA_ATOMIC_EXG_ADD, ptr, val, unused); + * int sysxtensa (SYS_XTENSA_ATOMIC_CMP_SWP, ptr, oldval, newval); + * a2 a6 a3 a4 a5 * * Entry condition: * - * a0: trashed, original value saved on stack (PT_AREG0) + * a0: a2 (syscall-nr), original value saved on stack (PT_AREG0) * a1: a1 - * a2: new stack pointer, original in DEPC - * a3: dispatch table + * a2: new stack pointer, original in a0 and DEPC + * a3: dispatch table, original in excsave_1 + * a4..a15: unchanged * depc: a2, original value saved on stack (PT_DEPC) * excsave_1: a3 * @@ -1091,59 +1087,62 @@ ENTRY(fast_syscall_unrecoverable) #define CATCH \ 67: -ENTRY(fast_syscall_sysxtensa) - - _beqz a6, 1f - _blti a6, SYSXTENSA_COUNT, 2f +ENTRY(fast_syscall_xtensa) -1: j user_exception - -2: xsr a3, EXCSAVE_1 # restore a3, excsave1 - s32i a7, a2, PT_AREG7 + xsr a3, EXCSAVE_1 # restore a3, excsave1 + s32i a7, a2, PT_AREG7 # we need an additional register movi a7, 4 # sizeof(unsigned int) - access_ok a0, a3, a7, a2, .Leac + access_ok a3, a7, a0, a2, .Leac # a0: scratch reg, a2: sp - _beqi a6, SYSXTENSA_ATOMIC_SET, .Lset - _beqi a6, SYSXTENSA_ATOMIC_EXG_ADD, .Lexg - _beqi a6, SYSXTENSA_ATOMIC_ADD, .Ladd + addi a6, a6, -1 # assuming SYS_XTENSA_ATOMIC_SET = 1 + _bgeui a6, SYS_XTENSA_COUNT - 1, .Lill + _bnei a6, SYS_XTENSA_ATOMIC_CMP_SWP - 1, .Lnswp - /* Fall through for SYSXTENSA_ATOMIC_CMP_SWP */ + /* Fall through for ATOMIC_CMP_SWP. */ .Lswp: /* Atomic compare and swap */ -TRY l32i a7, a3, 0 # read old value - bne a7, a4, 1f # same as old value? jump - s32i a5, a3, 0 # different, modify value - movi a7, 1 # and return 1 - j .Lret - -1: movi a7, 0 # same values: return 0 - j .Lret - -.Ladd: /* Atomic add */ -.Lexg: /* Atomic (exchange) add */ +TRY l32i a0, a3, 0 # read old value + bne a0, a4, 1f # same as old value? jump +TRY s32i a5, a3, 0 # different, modify value + l32i a7, a2, PT_AREG7 # restore a7 + l32i a0, a2, PT_AREG0 # restore a0 + movi a2, 1 # and return 1 + addi a6, a6, 1 # restore a6 (really necessary?) + rfe -TRY l32i a7, a3, 0 - add a4, a4, a7 - s32i a4, a3, 0 - j .Lret +1: l32i a7, a2, PT_AREG7 # restore a7 + l32i a0, a2, PT_AREG0 # restore a0 + movi a2, 0 # return 0 (note that we cannot set + addi a6, a6, 1 # restore a6 (really necessary?) + rfe -.Lset: /* Atomic set */ +.Lnswp: /* Atomic set, add, and exg_add. */ -TRY l32i a7, a3, 0 # read old value as return value - s32i a4, a3, 0 # write new value +TRY l32i a7, a3, 0 # orig + add a0, a4, a7 # + arg + moveqz a0, a4, a6 # set +TRY s32i a0, a3, 0 # write new value -.Lret: mov a0, a2 + mov a0, a2 mov a2, a7 - l32i a7, a0, PT_AREG7 - l32i a3, a0, PT_AREG3 - l32i a0, a0, PT_AREG0 + l32i a7, a0, PT_AREG7 # restore a7 + l32i a0, a0, PT_AREG0 # restore a0 + addi a6, a6, 1 # restore a6 (really necessary?) rfe CATCH -.Leac: movi a7, -EFAULT - j .Lret +.Leac: l32i a7, a2, PT_AREG7 # restore a7 + l32i a0, a2, PT_AREG0 # restore a0 + movi a2, -EFAULT + rfe + +.Lill: l32i a7, a2, PT_AREG0 # restore a7 + l32i a0, a2, PT_AREG0 # restore a0 + movi a2, -EINVAL + rfe + @@ -1491,7 +1490,7 @@ ENTRY(_spill_registers) */ rsr a0, PS - _bbci.l a0, PS_UM_SHIFT, 1f + _bbci.l a0, PS_UM_BIT, 1f /* User space: Setup a dummy frame and kill application. * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer. @@ -1510,7 +1509,7 @@ ENTRY(_spill_registers) l32i a1, a3, EXC_TABLE_KSTK wsr a3, EXCSAVE_1 - movi a4, PS_WOE_MASK | 1 + movi a4, (1 << PS_WOE_BIT) | 1 wsr a4, PS rsync @@ -1612,7 +1611,7 @@ ENTRY(fast_second_level_miss) rsr a1, PTEVADDR srli a1, a1, PAGE_SHIFT slli a1, a1, PAGE_SHIFT # ptevaddr & PAGE_MASK - addi a1, a1, DTLB_WAY_PGTABLE # ... + way_number + addi a1, a1, DTLB_WAY_PGD # ... + way_number wdtlb a0, a1 dsync @@ -1654,7 +1653,7 @@ ENTRY(fast_second_level_miss) mov a1, a2 rsr a2, PS - bbsi.l a2, PS_UM_SHIFT, 1f + bbsi.l a2, PS_UM_BIT, 1f j _kernel_exception 1: j _user_exception @@ -1753,7 +1752,7 @@ ENTRY(fast_store_prohibited) mov a1, a2 rsr a2, PS - bbsi.l a2, PS_UM_SHIFT, 1f + bbsi.l a2, PS_UM_BIT, 1f j _kernel_exception 1: j _user_exception @@ -1907,6 +1906,103 @@ ENTRY(fast_coprocessor) #endif /* XCHAL_EXTRA_SA_SIZE */ /* + * System Calls. + * + * void system_call (struct pt_regs* regs, int exccause) + * a2 a3 + */ + +ENTRY(system_call) + entry a1, 32 + + /* regs->syscall = regs->areg[2] */ + + l32i a3, a2, PT_AREG2 + mov a6, a2 + movi a4, do_syscall_trace_enter + s32i a3, a2, PT_SYSCALL + callx4 a4 + + /* syscall = sys_call_table[syscall_nr] */ + + movi a4, sys_call_table; + movi a5, __NR_syscall_count + movi a6, -ENOSYS + bgeu a3, a5, 1f + + addx4 a4, a3, a4 + l32i a4, a4, 0 + movi a5, sys_ni_syscall; + beq a4, a5, 1f + + /* Load args: arg0 - arg5 are passed via regs. */ + + l32i a6, a2, PT_AREG6 + l32i a7, a2, PT_AREG3 + l32i a8, a2, PT_AREG4 + l32i a9, a2, PT_AREG5 + l32i a10, a2, PT_AREG8 + l32i a11, a2, PT_AREG9 + + /* Pass one additional argument to the syscall: pt_regs (on stack) */ + s32i a2, a1, 0 + + callx4 a4 + +1: /* regs->areg[2] = return_value */ + + s32i a6, a2, PT_AREG2 + movi a4, do_syscall_trace_leave + mov a6, a2 + callx4 a4 + retw + + +/* + * Create a kernel thread + * + * int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) + * a2 a2 a3 a4 + */ + +ENTRY(kernel_thread) + entry a1, 16 + + mov a5, a2 # preserve fn over syscall + mov a7, a3 # preserve args over syscall + + movi a3, _CLONE_VM | _CLONE_UNTRACED + movi a2, __NR_clone + or a6, a4, a3 # arg0: flags + mov a3, a1 # arg1: sp + syscall + + beq a3, a1, 1f # branch if parent + mov a6, a7 # args + callx4 a5 # fn(args) + + movi a2, __NR_exit + syscall # return value of fn(args) still in a6 + +1: retw + +/* + * Do a system call from kernel instead of calling sys_execve, so we end up + * with proper pt_regs. + * + * int kernel_execve(const char *fname, char *const argv[], charg *const envp[]) + * a2 a2 a3 a4 + */ + +ENTRY(kernel_execve) + entry a1, 16 + mov a6, a2 # arg0 is in a6 + movi a2, __NR_execve + syscall + + retw + +/* * Task switch. * * struct task* _switch_to (struct task* prev, struct task* next) @@ -1924,7 +2020,7 @@ ENTRY(_switch_to) /* Disable ints while we manipulate the stack pointer; spill regs. */ - movi a5, PS_EXCM_MASK | LOCKLEVEL + movi a5, (1 << PS_EXCM_BIT) | LOCKLEVEL xsr a5, PS rsr a3, EXCSAVE_1 rsync @@ -1964,33 +2060,9 @@ ENTRY(ret_from_fork) movi a4, schedule_tail callx4 a4 - movi a4, do_syscall_trace + movi a4, do_syscall_trace_leave + mov a6, a1 callx4 a4 j common_exception_return - - -/* - * Table of syscalls - */ - -.data -.align 4 -.global sys_call_table -sys_call_table: - -#define SYSCALL(call, narg) .word call -#include "syscalls.h" - -/* - * Number of arguments of each syscall - */ - -.global sys_narg_table -sys_narg_table: - -#undef SYSCALL -#define SYSCALL(call, narg) .byte narg -#include "syscalls.h" - diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index c07cb2522993..ea89910efa44 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S @@ -15,9 +15,9 @@ * Kevin Chea */ -#include <xtensa/cacheasm.h> #include <asm/processor.h> #include <asm/page.h> +#include <asm/cacheasm.h> /* * This module contains the entry code for kernel images. It performs the @@ -32,13 +32,6 @@ * */ - .macro iterate from, to , cmd - .ifeq ((\to - \from) & ~0xfff) - \cmd \from - iterate "(\from+1)", \to, \cmd - .endif - .endm - /* * _start * @@ -64,7 +57,7 @@ _startup: /* Disable interrupts and exceptions. */ - movi a0, XCHAL_PS_EXCM_MASK + movi a0, LOCKLEVEL wsr a0, PS /* Preserve the pointer to the boot parameter list in EXCSAVE_1 */ @@ -91,11 +84,11 @@ _startup: movi a1, 15 wsr a0, ICOUNTLEVEL - .macro reset_dbreak num - wsr a0, DBREAKC + \num - .endm - - iterate 0, XCHAL_NUM_IBREAK-1, reset_dbreak + .set _index, 0 + .rept XCHAL_NUM_DBREAK - 1 + wsr a0, DBREAKC + _index + .set _index, _index + 1 + .endr #endif /* Clear CCOUNT (not really necessary, but nice) */ @@ -110,10 +103,11 @@ _startup: /* Disable all timers. */ - .macro reset_timer num - wsr a0, CCOMPARE_0 + \num - .endm - iterate 0, XCHAL_NUM_TIMERS-1, reset_timer + .set _index, 0 + .rept XCHAL_NUM_TIMERS - 1 + wsr a0, CCOMPARE + _index + .set _index, _index + 1 + .endr /* Interrupt initialization. */ @@ -139,12 +133,21 @@ _startup: rsync /* Initialize the caches. - * Does not include flushing writeback d-cache. - * a6, a7 are just working registers (clobbered). + * a2, a3 are just working registers (clobbered). */ - icache_reset a2, a3 - dcache_reset a2, a3 +#if XCHAL_DCACHE_LINE_LOCKABLE + ___unlock_dcache_all a2 a3 +#endif + +#if XCHAL_ICACHE_LINE_LOCKABLE + ___unlock_icache_all a2 a3 +#endif + + ___invalidate_dcache_all a2 a3 + ___invalidate_icache_all a2 a3 + + isync /* Unpack data sections * @@ -181,9 +184,9 @@ _startup: movi a2, _bss_start # start of BSS movi a3, _bss_end # end of BSS -1: addi a2, a2, 4 + __loopt a2, a3, a4, 2 s32i a0, a2, 0 - blt a2, a3, 1b + __endla a2, a4, 4 #if XCHAL_DCACHE_IS_WRITEBACK @@ -191,7 +194,7 @@ _startup: * instructions/data are available. */ - dcache_writeback_all a2, a3 + ___flush_dcache_all a2 a3 #endif /* Setup stack and enable window exceptions (keep irqs disabled) */ diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index 1cf744ee0959..c9ea73b7031b 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c @@ -4,7 +4,7 @@ * Xtensa built-in interrupt controller and some generic functions copied * from i386. * - * Copyright (C) 2002 - 2005 Tensilica, Inc. + * Copyright (C) 2002 - 2006 Tensilica, Inc. * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar * * @@ -22,11 +22,6 @@ #include <asm/uaccess.h> #include <asm/platform.h> -static void enable_xtensa_irq(unsigned int irq); -static void disable_xtensa_irq(unsigned int irq); -static void mask_and_ack_xtensa(unsigned int irq); -static void end_xtensa_irq(unsigned int irq); - static unsigned int cached_irq_mask; atomic_t irq_err_count; @@ -46,8 +41,16 @@ void ack_bad_irq(unsigned int irq) * handlers). */ -unsigned int do_IRQ(int irq, struct pt_regs *regs) +asmlinkage void do_IRQ(int irq, struct pt_regs *regs) { + struct pt_regs *old_regs = set_irq_regs(regs); + struct irq_desc *desc = irq_desc + irq; + + if (irq >= NR_IRQS) { + printk(KERN_EMERG "%s: cannot handle IRQ %d\n", + __FUNCTION__, irq); + } + irq_enter(); #ifdef CONFIG_DEBUG_STACKOVERFLOW @@ -63,12 +66,10 @@ unsigned int do_IRQ(int irq, struct pt_regs *regs) sp - sizeof(struct thread_info)); } #endif - - __do_IRQ(irq, regs); + desc->handle_irq(irq, desc); irq_exit(); - - return 1; + set_irq_regs(old_regs); } /* @@ -118,72 +119,68 @@ skip: } return 0; } -/* shutdown is same as "disable" */ -#define shutdown_xtensa_irq disable_xtensa_irq -static unsigned int startup_xtensa_irq(unsigned int irq) -{ - enable_xtensa_irq(irq); - return 0; /* never anything pending */ -} - -static struct hw_interrupt_type xtensa_irq_type = { - "Xtensa-IRQ", - startup_xtensa_irq, - shutdown_xtensa_irq, - enable_xtensa_irq, - disable_xtensa_irq, - mask_and_ack_xtensa, - end_xtensa_irq -}; - -static inline void mask_irq(unsigned int irq) +static void xtensa_irq_mask(unsigned int irq) { cached_irq_mask &= ~(1 << irq); set_sr (cached_irq_mask, INTENABLE); } -static inline void unmask_irq(unsigned int irq) +static void xtensa_irq_unmask(unsigned int irq) { cached_irq_mask |= 1 << irq; set_sr (cached_irq_mask, INTENABLE); } -static void disable_xtensa_irq(unsigned int irq) +static void xtensa_irq_ack(unsigned int irq) { - unsigned long flags; - local_save_flags(flags); - mask_irq(irq); - local_irq_restore(flags); + set_sr(1 << irq, INTCLEAR); } -static void enable_xtensa_irq(unsigned int irq) +static int xtensa_irq_retrigger(unsigned int irq) { - unsigned long flags; - local_save_flags(flags); - unmask_irq(irq); - local_irq_restore(flags); -} - -static void mask_and_ack_xtensa(unsigned int irq) -{ - disable_xtensa_irq(irq); + set_sr (1 << irq, INTSET); + return 1; } -static void end_xtensa_irq(unsigned int irq) -{ - enable_xtensa_irq(irq); -} +static struct irq_chip xtensa_irq_chip = { + .name = "xtensa", + .mask = xtensa_irq_mask, + .unmask = xtensa_irq_unmask, + .ack = xtensa_irq_ack, + .retrigger = xtensa_irq_retrigger, +}; void __init init_IRQ(void) { - int i; + int index; - for (i=0; i < XTENSA_NR_IRQS; i++) - irq_desc[i].chip = &xtensa_irq_type; + for (index = 0; index < XTENSA_NR_IRQS; index++) { + int mask = 1 << index; - cached_irq_mask = 0; + if (mask & XCHAL_INTTYPE_MASK_SOFTWARE) + set_irq_chip_and_handler(index, &xtensa_irq_chip, + handle_simple_irq); - platform_init_irq(); + else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE) + set_irq_chip_and_handler(index, &xtensa_irq_chip, + handle_edge_irq); + + else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL) + set_irq_chip_and_handler(index, &xtensa_irq_chip, + handle_level_irq); + + else if (mask & XCHAL_INTTYPE_MASK_TIMER) + set_irq_chip_and_handler(index, &xtensa_irq_chip, + handle_edge_irq); + + else /* XCHAL_INTTYPE_MASK_WRITE_ERROR */ + /* XCHAL_INTTYPE_MASK_NMI */ + + set_irq_chip_and_handler(index, &xtensa_irq_chip, + handle_level_irq); + } + + cached_irq_mask = 0; } diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c index 6648fa9d9192..ca76f071666e 100644 --- a/arch/xtensa/kernel/pci-dma.c +++ b/arch/xtensa/kernel/pci-dma.c @@ -1,5 +1,5 @@ /* - * arch/xtensa/kernel/pci-dma.c + * arch/xtensa/pci-dma.c * * DMA coherent memory allocation. * @@ -29,28 +29,48 @@ */ void * -dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) +dma_alloc_coherent(struct device *dev,size_t size,dma_addr_t *handle,gfp_t flag) { - void *ret; + unsigned long ret; + unsigned long uncached = 0; /* ignore region speicifiers */ - gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); - if (dev == NULL || (*dev->dma_mask < 0xffffffff)) - gfp |= GFP_DMA; - ret = (void *)__get_free_pages(gfp, get_order(size)); + flag &= ~(__GFP_DMA | __GFP_HIGHMEM); - if (ret != NULL) { - memset(ret, 0, size); - *handle = virt_to_bus(ret); + if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) + flag |= GFP_DMA; + ret = (unsigned long)__get_free_pages(flag, get_order(size)); + + if (ret == 0) + return NULL; + + /* We currently don't support coherent memory outside KSEG */ + + if (ret < XCHAL_KSEG_CACHED_VADDR + || ret >= XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE) + BUG(); + + + if (ret != 0) { + memset((void*) ret, 0, size); + uncached = ret+XCHAL_KSEG_BYPASS_VADDR-XCHAL_KSEG_CACHED_VADDR; + *handle = virt_to_bus((void*)ret); + __flush_invalidate_dcache_range(ret, size); } - return (void*) BYPASS_ADDR((unsigned long)ret); + + return (void*)uncached; } void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) { - free_pages(CACHED_ADDR((unsigned long)vaddr), get_order(size)); + long addr=(long)vaddr+XCHAL_KSEG_CACHED_VADDR-XCHAL_KSEG_BYPASS_VADDR; + + if (addr < 0 || addr >= XCHAL_KSEG_SIZE) + BUG(); + + free_pages(addr, get_order(size)); } diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index a7c4178c2a8c..795bd5ac6f4c 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -1,4 +1,3 @@ -// TODO verify coprocessor handling /* * arch/xtensa/kernel/process.c * @@ -43,7 +42,7 @@ #include <asm/irq.h> #include <asm/atomic.h> #include <asm/asm-offsets.h> -#include <asm/coprocessor.h> +#include <asm/regs.h> extern void ret_from_fork(void); @@ -67,25 +66,6 @@ void (*pm_power_off)(void) = NULL; EXPORT_SYMBOL(pm_power_off); -#if XCHAL_CP_NUM > 0 - -/* - * Coprocessor ownership. - */ - -coprocessor_info_t coprocessor_info[] = { - { 0, XTENSA_CPE_CP0_OFFSET }, - { 0, XTENSA_CPE_CP1_OFFSET }, - { 0, XTENSA_CPE_CP2_OFFSET }, - { 0, XTENSA_CPE_CP3_OFFSET }, - { 0, XTENSA_CPE_CP4_OFFSET }, - { 0, XTENSA_CPE_CP5_OFFSET }, - { 0, XTENSA_CPE_CP6_OFFSET }, - { 0, XTENSA_CPE_CP7_OFFSET }, -}; - -#endif - /* * Powermanagement idle function, if any is provided by the platform. */ @@ -110,12 +90,10 @@ void cpu_idle(void) void exit_thread(void) { - release_coprocessors(current); /* Empty macro if no CPs are defined */ } void flush_thread(void) { - release_coprocessors(current); /* Empty macro if no CPs are defined */ } /* @@ -183,36 +161,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, /* - * Create a kernel thread - */ - -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -{ - long retval; - __asm__ __volatile__ - ("mov a5, %4\n\t" /* preserve fn in a5 */ - "mov a6, %3\n\t" /* preserve and setup arg in a6 */ - "movi a2, %1\n\t" /* load __NR_clone for syscall*/ - "mov a3, sp\n\t" /* sp check and sys_clone */ - "mov a4, %5\n\t" /* load flags for syscall */ - "syscall\n\t" - "beq a3, sp, 1f\n\t" /* branch if parent */ - "callx4 a5\n\t" /* call fn */ - "movi a2, %2\n\t" /* load __NR_exit for syscall */ - "mov a3, a6\n\t" /* load fn return value */ - "syscall\n" - "1:\n\t" - "mov %0, a2\n\t" /* parent returns zero */ - :"=r" (retval) - :"i" (__NR_clone), "i" (__NR_exit), - "r" (arg), "r" (fn), - "r" (flags | CLONE_VM) - : "a2", "a3", "a4", "a5", "a6" ); - return retval; -} - - -/* * These bracket the sleeping functions.. */ @@ -275,7 +223,7 @@ void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs, */ elfregs->pc = regs->pc; - elfregs->ps = (regs->ps & ~XCHAL_PS_EXCM_MASK); + elfregs->ps = (regs->ps & ~(1 << PS_EXCM_BIT)); elfregs->exccause = regs->exccause; elfregs->excvaddr = regs->excvaddr; elfregs->windowbase = regs->windowbase; @@ -325,7 +273,7 @@ void do_restore_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs, */ regs->pc = elfregs->pc; - regs->ps = (elfregs->ps | XCHAL_PS_EXCM_MASK); + regs->ps = (elfregs->ps | (1 << PS_EXCM_BIT)); regs->exccause = elfregs->exccause; regs->excvaddr = elfregs->excvaddr; regs->windowbase = elfregs->windowbase; @@ -459,16 +407,7 @@ int do_restore_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs, int dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r) { -/* see asm/coprocessor.h for this magic number 16 */ -#if XTENSA_CP_EXTRA_SIZE > 16 - do_save_fpregs (r, regs, task); - - /* For now, bit 16 means some extra state may be present: */ -// FIXME!! need to track to return more accurate mask - return 0x10000 | XCHAL_CP_MASK; -#else return 0; /* no coprocessors active on this processor */ -#endif } /* @@ -483,3 +422,44 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) { return dump_task_fpu(regs, current, r); } + +asmlinkage +long xtensa_clone(unsigned long clone_flags, unsigned long newsp, + void __user *parent_tid, void *child_tls, + void __user *child_tid, long a5, + struct pt_regs *regs) +{ + if (!newsp) + newsp = regs->areg[1]; + return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); +} + +/* + * * xtensa_execve() executes a new program. + * */ + +asmlinkage +long xtensa_execve(char __user *name, char __user * __user *argv, + char __user * __user *envp, + long a3, long a4, long a5, + struct pt_regs *regs) +{ + long error; + char * filename; + + filename = getname(name); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + // FIXME: release coprocessor?? + error = do_execve(filename, argv, envp, regs); + if (error == 0) { + task_lock(current); + current->ptrace &= ~PT_DTRACE; + task_unlock(current); + } + putname(filename); +out: + return error; +} + diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 9aea23cc0dc5..8b6d3d0623b6 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -96,7 +96,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) /* Note: PS.EXCM is not set while user task is running; * its being set in regs is for exception handling * convenience. */ - tmp = (regs->ps & ~XCHAL_PS_EXCM_MASK); + tmp = (regs->ps & ~(1 << PS_EXCM_BIT)); break; case REG_WB: tmp = regs->windowbase; @@ -332,12 +332,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) void do_syscall_trace(void) { - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - return; - - if (!(current->ptrace & PT_PTRACED)) - return; - /* * The 0x80 provides a way for the tracing parent to distinguish * between a syscall stop and SIGTRAP delivery @@ -354,3 +348,23 @@ void do_syscall_trace(void) current->exit_code = 0; } } + +void do_syscall_trace_enter(struct pt_regs *regs) +{ + if (test_thread_flag(TIF_SYSCALL_TRACE) + && (current->ptrace & PT_PTRACED)) + do_syscall_trace(); + +#if 0 + if (unlikely(current->audit_context)) + audit_syscall_entry(current, AUDIT_ARCH_XTENSA..); +#endif +} + +void do_syscall_trace_leave(struct pt_regs *regs) +{ + if ((test_thread_flag(TIF_SYSCALL_TRACE)) + && (current->ptrace & PT_PTRACED)) + do_syscall_trace(); +} + diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index c99ab72b41b6..b6374c09de20 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -42,8 +42,6 @@ #include <asm/page.h> #include <asm/setup.h> -#include <xtensa/config/system.h> - #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) struct screen_info screen_info = { 0, 24, 0, 0, 0, 80, 0, 0, 0, 24, 1, 16}; #endif @@ -336,7 +334,7 @@ c_show(struct seq_file *f, void *slot) /* high-level stuff */ seq_printf(f,"processor\t: 0\n" "vendor_id\t: Tensilica\n" - "model\t\t: Xtensa " XCHAL_HW_RELEASE_NAME "\n" + "model\t\t: Xtensa " XCHAL_HW_VERSION_NAME "\n" "core ID\t\t: " XCHAL_CORE_ID "\n" "build ID\t: 0x%x\n" "byte order\t: %s\n" @@ -420,25 +418,6 @@ c_show(struct seq_file *f, void *slot) XCHAL_NUM_TIMERS, XCHAL_DEBUGLEVEL); - /* Coprocessors */ -#if XCHAL_HAVE_CP - seq_printf(f, "coprocessors\t: %d\n", XCHAL_CP_NUM); -#else - seq_printf(f, "coprocessors\t: none\n"); -#endif - - /* {I,D}{RAM,ROM} and XLMI */ - seq_printf(f,"inst ROMs\t: %d\n" - "inst RAMs\t: %d\n" - "data ROMs\t: %d\n" - "data RAMs\t: %d\n" - "XLMI ports\t: %d\n", - XCHAL_NUM_IROM, - XCHAL_NUM_IRAM, - XCHAL_NUM_DROM, - XCHAL_NUM_DRAM, - XCHAL_NUM_XLMI); - /* Cache */ seq_printf(f,"icache line size: %d\n" "icache ways\t: %d\n" @@ -466,24 +445,6 @@ c_show(struct seq_file *f, void *slot) XCHAL_DCACHE_WAYS, XCHAL_DCACHE_SIZE); - /* MMU */ - seq_printf(f,"ASID bits\t: %d\n" - "ASID invalid\t: %d\n" - "ASID kernel\t: %d\n" - "rings\t\t: %d\n" - "itlb ways\t: %d\n" - "itlb AR ways\t: %d\n" - "dtlb ways\t: %d\n" - "dtlb AR ways\t: %d\n", - XCHAL_MMU_ASID_BITS, - XCHAL_MMU_ASID_INVALID, - XCHAL_MMU_ASID_KERNEL, - XCHAL_MMU_RINGS, - XCHAL_ITLB_WAYS, - XCHAL_ITLB_ARF_WAYS, - XCHAL_DTLB_WAYS, - XCHAL_DTLB_ARF_WAYS); - return 0; } diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index c494f0826fc5..c6d9880a4cdb 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -12,8 +12,8 @@ * */ -#include <xtensa/config/core.h> -#include <xtensa/hal.h> +#include <asm/variant/core.h> +#include <asm/coprocessor.h> #include <linux/sched.h> #include <linux/mm.h> #include <linux/smp.h> @@ -46,7 +46,7 @@ extern struct task_struct *coproc_owners[]; * Atomically swap in the new signal mask, and wait for a signal. */ -int sys_sigsuspend(struct pt_regs *regs) +int xtensa_sigsuspend(struct pt_regs *regs) { old_sigset_t mask = (old_sigset_t) regs->areg[3]; sigset_t saveset; @@ -68,7 +68,7 @@ int sys_sigsuspend(struct pt_regs *regs) } asmlinkage int -sys_rt_sigsuspend(struct pt_regs *regs) +xtensa_rt_sigsuspend(struct pt_regs *regs) { sigset_t *unewset = (sigset_t *) regs->areg[4]; size_t sigsetsize = (size_t) regs->areg[3]; @@ -96,7 +96,7 @@ sys_rt_sigsuspend(struct pt_regs *regs) } asmlinkage int -sys_sigaction(int sig, const struct old_sigaction *act, +xtensa_sigaction(int sig, const struct old_sigaction *act, struct old_sigaction *oact) { struct k_sigaction new_ka, old_ka; @@ -128,7 +128,7 @@ sys_sigaction(int sig, const struct old_sigaction *act, } asmlinkage int -sys_sigaltstack(struct pt_regs *regs) +xtensa_sigaltstack(struct pt_regs *regs) { const stack_t *uss = (stack_t *) regs->areg[4]; stack_t *uoss = (stack_t *) regs->areg[3]; @@ -216,8 +216,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) * handler, or the user mode value doesn't matter (e.g. PS.OWB). */ err |= __get_user(ps, &sc->sc_ps); - regs->ps = (regs->ps & ~XCHAL_PS_CALLINC_MASK) - | (ps & XCHAL_PS_CALLINC_MASK); + regs->ps = (regs->ps & ~PS_CALLINC_MASK) + | (ps & PS_CALLINC_MASK); /* Additional corruption checks */ @@ -280,7 +280,7 @@ flush_my_cpstate(struct task_struct *tsk) static int save_cpextra (struct _cpstate *buf) { -#if (XCHAL_EXTRA_SA_SIZE == 0) && (XCHAL_CP_NUM == 0) +#if XCHAL_CP_NUM == 0 return 0; #else @@ -350,7 +350,7 @@ setup_sigcontext(struct sigcontext *sc, struct _cpstate *cpstate, return err; } -asmlinkage int sys_sigreturn(struct pt_regs *regs) +asmlinkage int xtensa_sigreturn(struct pt_regs *regs) { struct sigframe *frame = (struct sigframe *)regs->areg[1]; sigset_t set; @@ -382,7 +382,7 @@ badframe: return 0; } -asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) +asmlinkage int xtensa_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe *frame = (struct rt_sigframe *)regs->areg[1]; sigset_t set; @@ -497,8 +497,10 @@ gen_return_code(unsigned char *codemem, unsigned int use_rt_sigreturn) /* Flush generated code out of the data cache */ - if (err == 0) - __flush_invalidate_cache_range((unsigned long)codemem, 6UL); + if (err == 0) { + __invalidate_icache_range((unsigned long)codemem, 6UL); + __flush_invalidate_dcache_range((unsigned long)codemem, 6UL); + } return err; } diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c new file mode 100644 index 000000000000..418268f49766 --- /dev/null +++ b/arch/xtensa/kernel/syscall.c @@ -0,0 +1,95 @@ +/* + * arch/xtensa/kernel/syscall.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2001 - 2005 Tensilica Inc. + * Copyright (C) 2000 Silicon Graphics, Inc. + * Copyright (C) 1995 - 2000 by Ralf Baechle + * + * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> + * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca> + * Chris Zankel <chris@zankel.net> + * Kevin Chea + * + */ +#include <asm/uaccess.h> +#include <asm/syscalls.h> +#include <asm/unistd.h> +#include <linux/linkage.h> +#include <linux/stringify.h> +#include <linux/errno.h> +#include <linux/syscalls.h> +#include <linux/file.h> +#include <linux/fs.h> +#include <linux/mman.h> +#include <linux/shm.h> + +typedef void (*syscall_t)(void); + +syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= { + [0 ... __NR_syscall_count - 1] = (syscall_t)&sys_ni_syscall, + +#undef __SYSCALL +#define __SYSCALL(nr,symbol,nargs) [ nr ] = (syscall_t)symbol, +#undef _XTENSA_UNISTD_H +#undef __KERNEL_SYSCALLS__ +#include <asm/unistd.h> +}; + +/* + * xtensa_pipe() is the normal C calling standard for creating a pipe. It's not + * the way unix traditional does this, though. + */ + +asmlinkage long xtensa_pipe(int __user *userfds) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(userfds, fd, 2 * sizeof(int))) + error = -EFAULT; + } + return error; +} + + +asmlinkage long xtensa_mmap2(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + int error = -EBADF; + struct file * file = NULL; + + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + if (!(flags & MAP_ANONYMOUS)) { + file = fget(fd); + if (!file) + goto out; + } + + down_write(¤t->mm->mmap_sem); + error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); + + if (file) + fput(file); +out: + return error; +} + +asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) +{ + unsigned long ret; + long err; + + err = do_shmat(shmid, shmaddr, shmflg, &ret); + if (err) + return err; + return (long)ret; +} + diff --git a/arch/xtensa/kernel/syscalls.c b/arch/xtensa/kernel/syscalls.c deleted file mode 100644 index f49cb239e603..000000000000 --- a/arch/xtensa/kernel/syscalls.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * arch/xtensa/kernel/syscalls.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001 - 2005 Tensilica Inc. - * Copyright (C) 2000 Silicon Graphics, Inc. - * Copyright (C) 1995 - 2000 by Ralf Baechle - * - * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> - * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca> - * Chris Zankel <chris@zankel.net> - * Kevin Chea - * - */ - -#define DEBUG 0 - -#include <linux/linkage.h> -#include <linux/mm.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> -#include <linux/mman.h> -#include <linux/sched.h> -#include <linux/file.h> -#include <linux/slab.h> -#include <linux/utsname.h> -#include <linux/unistd.h> -#include <linux/stringify.h> -#include <linux/syscalls.h> -#include <linux/sem.h> -#include <linux/msg.h> -#include <linux/shm.h> -#include <linux/errno.h> -#include <asm/ptrace.h> -#include <asm/signal.h> -#include <asm/uaccess.h> -#include <asm/hardirq.h> -#include <asm/mman.h> -#include <asm/shmparam.h> -#include <asm/page.h> - -extern void do_syscall_trace(void); -typedef int (*syscall_t)(void *a0,...); -extern syscall_t sys_call_table[]; -extern unsigned char sys_narg_table[]; - -/* - * sys_pipe() is the normal C calling standard for creating a pipe. It's not - * the way unix traditional does this, though. - */ - -int sys_pipe(int __user *userfds) -{ - int fd[2]; - int error; - - error = do_pipe(fd); - if (!error) { - if (copy_to_user(userfds, fd, 2 * sizeof(int))) - error = -EFAULT; - } - return error; -} - -/* - * Common code for old and new mmaps. - */ -long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, - unsigned long flags, unsigned long fd, unsigned long pgoff) -{ - int error = -EBADF; - struct file * file = NULL; - - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - if (!(flags & MAP_ANONYMOUS)) { - file = fget(fd); - if (!file) - goto out; - } - - down_write(¤t->mm->mmap_sem); - error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up_write(¤t->mm->mmap_sem); - - if (file) - fput(file); -out: - return error; -} - -int sys_clone(struct pt_regs *regs) -{ - unsigned long clone_flags; - unsigned long newsp; - int __user *parent_tidptr, *child_tidptr; - clone_flags = regs->areg[4]; - newsp = regs->areg[3]; - parent_tidptr = (int __user *)regs->areg[5]; - child_tidptr = (int __user *)regs->areg[6]; - if (!newsp) - newsp = regs->areg[1]; - return do_fork(clone_flags,newsp,regs,0,parent_tidptr,child_tidptr); -} - -/* - * sys_execve() executes a new program. - */ - -int sys_execve(struct pt_regs *regs) -{ - int error; - char * filename; - - filename = getname((char *) (long)regs->areg[5]); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - error = do_execve(filename, (char **) (long)regs->areg[3], - (char **) (long)regs->areg[4], regs); - putname(filename); - -out: - return error; -} - -int sys_uname(struct old_utsname * name) -{ - if (name && !copy_to_user(name, utsname(), sizeof (*name))) - return 0; - return -EFAULT; -} - -/* - * Build the string table for the builtin "poor man's strace". - */ - -#if DEBUG -#define SYSCALL(fun, narg) #fun, -static char *sfnames[] = { -#include "syscalls.h" -}; -#undef SYS -#endif - -void system_call (struct pt_regs *regs) -{ - syscall_t syscall; - unsigned long parm0, parm1, parm2, parm3, parm4, parm5; - int nargs, res; - unsigned int syscallnr; - int ps; - -#if DEBUG - int i; - unsigned long parms[6]; - char *sysname; -#endif - - regs->syscall = regs->areg[2]; - - do_syscall_trace(); - - /* Have to load after syscall_trace because strace - * sometimes changes regs->syscall. - */ - syscallnr = regs->syscall; - - parm0 = parm1 = parm2 = parm3 = parm4 = parm5 = 0; - - /* Restore interrupt level to syscall invoker's. - * If this were in assembly, we wouldn't disable - * interrupts in the first place: - */ - local_save_flags (ps); - local_irq_restore((ps & ~XCHAL_PS_INTLEVEL_MASK) | - (regs->ps & XCHAL_PS_INTLEVEL_MASK) ); - - if (syscallnr > __NR_Linux_syscalls) { - regs->areg[2] = -ENOSYS; - return; - } - - syscall = sys_call_table[syscallnr]; - nargs = sys_narg_table[syscallnr]; - - if (syscall == NULL) { - regs->areg[2] = -ENOSYS; - return; - } - - /* There shouldn't be more than six arguments in the table! */ - - if (nargs > 6) - panic("Internal error - too many syscall arguments (%d)!\n", - nargs); - - /* Linux takes system-call arguments in registers. The ABI - * and Xtensa software conventions require the system-call - * number in a2. If an argument exists in a2, we move it to - * the next available register. Note that for improved - * efficiency, we do NOT shift all parameters down one - * register to maintain the original order. - * - * At best case (zero arguments), we just write the syscall - * number to a2. At worst case (1 to 6 arguments), we move - * the argument in a2 to the next available register, then - * write the syscall number to a2. - * - * For clarity, the following truth table enumerates all - * possibilities. - * - * arguments syscall number arg0, arg1, arg2, arg3, arg4, arg5 - * --------- -------------- ---------------------------------- - * 0 a2 - * 1 a2 a3 - * 2 a2 a4, a3 - * 3 a2 a5, a3, a4 - * 4 a2 a6, a3, a4, a5 - * 5 a2 a7, a3, a4, a5, a6 - * 6 a2 a8, a3, a4, a5, a6, a7 - */ - if (nargs) { - parm0 = regs->areg[nargs+2]; - parm1 = regs->areg[3]; - parm2 = regs->areg[4]; - parm3 = regs->areg[5]; - parm4 = regs->areg[6]; - parm5 = regs->areg[7]; - } else /* nargs == 0 */ - parm0 = (unsigned long) regs; - -#if DEBUG - parms[0] = parm0; - parms[1] = parm1; - parms[2] = parm2; - parms[3] = parm3; - parms[4] = parm4; - parms[5] = parm5; - - sysname = sfnames[syscallnr]; - if (strncmp(sysname, "sys_", 4) == 0) - sysname = sysname + 4; - - printk("\017SYSCALL:I:%x:%d:%s %s(", regs->pc, current->pid, - current->comm, sysname); - for (i = 0; i < nargs; i++) - printk((i>0) ? ", %#lx" : "%#lx", parms[i]); - printk(")\n"); -#endif - - res = syscall((void *)parm0, parm1, parm2, parm3, parm4, parm5); - -#if DEBUG - printk("\017SYSCALL:O:%d:%s %s(",current->pid, current->comm, sysname); - for (i = 0; i < nargs; i++) - printk((i>0) ? ", %#lx" : "%#lx", parms[i]); - if (res < 4096) - printk(") = %d\n", res); - else - printk(") = %#x\n", res); -#endif /* DEBUG */ - - regs->areg[2] = res; - do_syscall_trace(); -} - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - long __res; - asm volatile ( - " mov a5, %2 \n" - " mov a4, %4 \n" - " mov a3, %3 \n" - " movi a2, %1 \n" - " syscall \n" - " mov %0, a2 \n" - : "=a" (__res) - : "i" (__NR_execve), "a" (filename), "a" (argv), "a" (envp) - : "a2", "a3", "a4", "a5"); - return __res; -} diff --git a/arch/xtensa/kernel/syscalls.h b/arch/xtensa/kernel/syscalls.h deleted file mode 100644 index 216c10a31501..000000000000 --- a/arch/xtensa/kernel/syscalls.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * arch/xtensa/kernel/syscalls.h - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle - * Copyright (C) 2001 - 2005 Tensilica Inc. - * - * Changes by Joe Taylor <joe@tensilica.com> - */ - -/* - * This file is being included twice - once to build a list of all - * syscalls and once to build a table of how many arguments each syscall - * accepts. Syscalls that receive a pointer to the saved registers are - * marked as having zero arguments. - * - * The binary compatibility calls are in a separate list. - * - * Entry '0' used to be system_call. It's removed to disable indirect - * system calls for now so user tasks can't recurse. See mips' - * sys_syscall for a comparable example. - */ - -SYSCALL(0, 0) /* 00 */ -SYSCALL(sys_exit, 1) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_read, 3) -SYSCALL(sys_write, 3) -SYSCALL(sys_open, 3) /* 05 */ -SYSCALL(sys_close, 1) -SYSCALL(sys_ni_syscall, 3) -SYSCALL(sys_creat, 2) -SYSCALL(sys_link, 2) -SYSCALL(sys_unlink, 1) /* 10 */ -SYSCALL(sys_execve, 0) -SYSCALL(sys_chdir, 1) -SYSCALL(sys_ni_syscall, 1) -SYSCALL(sys_mknod, 3) -SYSCALL(sys_chmod, 2) /* 15 */ -SYSCALL(sys_lchown, 3) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_newstat, 2) -SYSCALL(sys_lseek, 3) -SYSCALL(sys_getpid, 0) /* 20 */ -SYSCALL(sys_mount, 5) -SYSCALL(sys_ni_syscall, 1) -SYSCALL(sys_setuid, 1) -SYSCALL(sys_getuid, 0) -SYSCALL(sys_ni_syscall, 1) /* 25 */ -SYSCALL(sys_ptrace, 4) -SYSCALL(sys_ni_syscall, 1) -SYSCALL(sys_newfstat, 2) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_utime, 2) /* 30 */ -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_access, 2) -SYSCALL(sys_ni_syscall, 1) -SYSCALL(sys_ni_syscall, 0) /* 35 */ -SYSCALL(sys_sync, 0) -SYSCALL(sys_kill, 2) -SYSCALL(sys_rename, 2) -SYSCALL(sys_mkdir, 2) -SYSCALL(sys_rmdir, 1) /* 40 */ -SYSCALL(sys_dup, 1) -SYSCALL(sys_pipe, 1) -SYSCALL(sys_times, 1) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_brk, 1) /* 45 */ -SYSCALL(sys_setgid, 1) -SYSCALL(sys_getgid, 0) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_geteuid, 0) -SYSCALL(sys_getegid, 0) /* 50 */ -SYSCALL(sys_acct, 1) -SYSCALL(sys_umount, 2) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_ioctl, 3) -SYSCALL(sys_fcntl, 3) /* 55 */ -SYSCALL(sys_ni_syscall, 2) -SYSCALL(sys_setpgid, 2) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_umask, 1) /* 60 */ -SYSCALL(sys_chroot, 1) -SYSCALL(sys_ustat, 2) -SYSCALL(sys_dup2, 2) -SYSCALL(sys_getppid, 0) -SYSCALL(sys_ni_syscall, 0) /* 65 */ -SYSCALL(sys_setsid, 0) -SYSCALL(sys_sigaction, 3) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_ni_syscall, 1) -SYSCALL(sys_setreuid, 2) /* 70 */ -SYSCALL(sys_setregid, 2) -SYSCALL(sys_sigsuspend, 0) -SYSCALL(sys_ni_syscall, 1) -SYSCALL(sys_sethostname, 2) -SYSCALL(sys_setrlimit, 2) /* 75 */ -SYSCALL(sys_getrlimit, 2) -SYSCALL(sys_getrusage, 2) -SYSCALL(sys_gettimeofday, 2) -SYSCALL(sys_settimeofday, 2) -SYSCALL(sys_getgroups, 2) /* 80 */ -SYSCALL(sys_setgroups, 2) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_symlink, 2) -SYSCALL(sys_newlstat, 2) -SYSCALL(sys_readlink, 3) /* 85 */ -SYSCALL(sys_uselib, 1) -SYSCALL(sys_swapon, 2) -SYSCALL(sys_reboot, 3) -SYSCALL(sys_ni_syscall, 3) -SYSCALL(sys_ni_syscall, 6) /* 90 */ -SYSCALL(sys_munmap, 2) -SYSCALL(sys_truncate, 2) -SYSCALL(sys_ftruncate, 2) -SYSCALL(sys_fchmod, 2) -SYSCALL(sys_fchown, 3) /* 95 */ -SYSCALL(sys_getpriority, 2) -SYSCALL(sys_setpriority, 3) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_statfs, 2) -SYSCALL(sys_fstatfs, 2) /* 100 */ -SYSCALL(sys_ni_syscall, 3) -SYSCALL(sys_ni_syscall, 2) -SYSCALL(sys_syslog, 3) -SYSCALL(sys_setitimer, 3) -SYSCALL(sys_getitimer, 2) /* 105 */ -SYSCALL(sys_newstat, 2) -SYSCALL(sys_newlstat, 2) -SYSCALL(sys_newfstat, 2) -SYSCALL(sys_uname, 1) -SYSCALL(sys_ni_syscall, 0) /* 110 */ -SYSCALL(sys_vhangup, 0) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_wait4, 4) -SYSCALL(sys_swapoff, 1) /* 115 */ -SYSCALL(sys_sysinfo, 1) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_fsync, 1) -SYSCALL(sys_sigreturn, 0) -SYSCALL(sys_clone, 0) /* 120 */ -SYSCALL(sys_setdomainname, 2) -SYSCALL(sys_newuname, 1) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_adjtimex, 1) -SYSCALL(sys_mprotect, 3) /* 125 */ -SYSCALL(sys_ni_syscall, 3) -SYSCALL(sys_ni_syscall, 2) -SYSCALL(sys_init_module, 2) -SYSCALL(sys_delete_module, 1) -SYSCALL(sys_ni_syscall, 1) /* 130 */ -SYSCALL(sys_quotactl, 0) -SYSCALL(sys_getpgid, 1) -SYSCALL(sys_fchdir, 1) -SYSCALL(sys_bdflush, 2) -SYSCALL(sys_sysfs, 3) /* 135 */ -SYSCALL(sys_personality, 1) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_setfsuid, 1) -SYSCALL(sys_setfsgid, 1) -SYSCALL(sys_llseek, 5) /* 140 */ -SYSCALL(sys_getdents, 3) -SYSCALL(sys_select, 5) -SYSCALL(sys_flock, 2) -SYSCALL(sys_msync, 3) -SYSCALL(sys_readv, 3) /* 145 */ -SYSCALL(sys_writev, 3) -SYSCALL(sys_ni_syscall, 3) -SYSCALL(sys_ni_syscall, 3) -SYSCALL(sys_ni_syscall, 4) /* handled in fast syscall handler. */ -SYSCALL(sys_ni_syscall, 0) /* 150 */ -SYSCALL(sys_getsid, 1) -SYSCALL(sys_fdatasync, 1) -SYSCALL(sys_sysctl, 1) -SYSCALL(sys_mlock, 2) -SYSCALL(sys_munlock, 2) /* 155 */ -SYSCALL(sys_mlockall, 1) -SYSCALL(sys_munlockall, 0) -SYSCALL(sys_sched_setparam,2) -SYSCALL(sys_sched_getparam,2) -SYSCALL(sys_sched_setscheduler,3) /* 160 */ -SYSCALL(sys_sched_getscheduler,1) -SYSCALL(sys_sched_yield,0) -SYSCALL(sys_sched_get_priority_max,1) -SYSCALL(sys_sched_get_priority_min,1) -SYSCALL(sys_sched_rr_get_interval,2) /* 165 */ -SYSCALL(sys_nanosleep,2) -SYSCALL(sys_mremap,4) -SYSCALL(sys_accept, 3) -SYSCALL(sys_bind, 3) -SYSCALL(sys_connect, 3) /* 170 */ -SYSCALL(sys_getpeername, 3) -SYSCALL(sys_getsockname, 3) -SYSCALL(sys_getsockopt, 5) -SYSCALL(sys_listen, 2) -SYSCALL(sys_recv, 4) /* 175 */ -SYSCALL(sys_recvfrom, 6) -SYSCALL(sys_recvmsg, 3) -SYSCALL(sys_send, 4) -SYSCALL(sys_sendmsg, 3) -SYSCALL(sys_sendto, 6) /* 180 */ -SYSCALL(sys_setsockopt, 5) -SYSCALL(sys_shutdown, 2) -SYSCALL(sys_socket, 3) -SYSCALL(sys_socketpair, 4) -SYSCALL(sys_setresuid, 3) /* 185 */ -SYSCALL(sys_getresuid, 3) -SYSCALL(sys_ni_syscall, 5) -SYSCALL(sys_poll, 3) -SYSCALL(sys_nfsservctl, 3) -SYSCALL(sys_setresgid, 3) /* 190 */ -SYSCALL(sys_getresgid, 3) -SYSCALL(sys_prctl, 5) -SYSCALL(sys_rt_sigreturn, 0) -SYSCALL(sys_rt_sigaction, 4) -SYSCALL(sys_rt_sigprocmask, 4) /* 195 */ -SYSCALL(sys_rt_sigpending, 2) -SYSCALL(sys_rt_sigtimedwait, 4) -SYSCALL(sys_rt_sigqueueinfo, 3) -SYSCALL(sys_rt_sigsuspend, 0) -SYSCALL(sys_pread64, 5) /* 200 */ -SYSCALL(sys_pwrite64, 5) -SYSCALL(sys_chown, 3) -SYSCALL(sys_getcwd, 2) -SYSCALL(sys_capget, 2) -SYSCALL(sys_capset, 2) /* 205 */ -SYSCALL(sys_sigaltstack, 0) -SYSCALL(sys_sendfile, 4) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_mmap, 6) /* 210 */ -SYSCALL(sys_truncate64, 2) -SYSCALL(sys_ftruncate64, 2) -SYSCALL(sys_stat64, 2) -SYSCALL(sys_lstat64, 2) -SYSCALL(sys_fstat64, 2) /* 215 */ -SYSCALL(sys_pivot_root, 2) -SYSCALL(sys_mincore, 3) -SYSCALL(sys_madvise, 3) -SYSCALL(sys_getdents64, 3) -SYSCALL(sys_ni_syscall, 0) /* 220 */ diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 37347e369987..a350431363a0 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c @@ -47,7 +47,7 @@ unsigned long long sched_clock(void) return (unsigned long long)jiffies * (1000000000 / HZ); } -static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t timer_interrupt(int irq, void *dev_id); static struct irqaction timer_irqaction = { .handler = timer_interrupt, .flags = IRQF_DISABLED, @@ -150,7 +150,7 @@ EXPORT_SYMBOL(do_gettimeofday); * The timer interrupt is called HZ times per second. */ -irqreturn_t timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t timer_interrupt (int irq, void *dev_id) { unsigned long next; @@ -160,9 +160,9 @@ irqreturn_t timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) again: while ((signed long)(get_ccount() - next) > 0) { - profile_tick(CPU_PROFILING, regs); + profile_tick(CPU_PROFILING); #ifndef CONFIG_SMP - update_process_times(user_mode(regs)); + update_process_times(user_mode(get_irq_regs())); #endif write_seqlock(&xtime_lock); diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index ce077d6bf3a0..693ab268485e 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -75,7 +75,7 @@ extern void system_call (struct pt_regs*); #define USER 0x02 #define COPROCESSOR(x) \ -{ XCHAL_EXCCAUSE_COPROCESSOR ## x ## _DISABLED, USER, fast_coprocessor } +{ EXCCAUSE_COPROCESSOR ## x ## _DISABLED, USER, fast_coprocessor } typedef struct { int cause; @@ -85,38 +85,38 @@ typedef struct { dispatch_init_table_t __init dispatch_init_table[] = { -{ XCHAL_EXCCAUSE_ILLEGAL_INSTRUCTION, 0, do_illegal_instruction}, -{ XCHAL_EXCCAUSE_SYSTEM_CALL, KRNL, fast_syscall_kernel }, -{ XCHAL_EXCCAUSE_SYSTEM_CALL, USER, fast_syscall_user }, -{ XCHAL_EXCCAUSE_SYSTEM_CALL, 0, system_call }, -/* XCHAL_EXCCAUSE_INSTRUCTION_FETCH unhandled */ -/* XCHAL_EXCCAUSE_LOAD_STORE_ERROR unhandled*/ -{ XCHAL_EXCCAUSE_LEVEL1_INTERRUPT, 0, do_interrupt }, -{ XCHAL_EXCCAUSE_ALLOCA, USER|KRNL, fast_alloca }, -/* XCHAL_EXCCAUSE_INTEGER_DIVIDE_BY_ZERO unhandled */ -/* XCHAL_EXCCAUSE_PRIVILEGED unhandled */ +{ EXCCAUSE_ILLEGAL_INSTRUCTION, 0, do_illegal_instruction}, +{ EXCCAUSE_SYSTEM_CALL, KRNL, fast_syscall_kernel }, +{ EXCCAUSE_SYSTEM_CALL, USER, fast_syscall_user }, +{ EXCCAUSE_SYSTEM_CALL, 0, system_call }, +/* EXCCAUSE_INSTRUCTION_FETCH unhandled */ +/* EXCCAUSE_LOAD_STORE_ERROR unhandled*/ +{ EXCCAUSE_LEVEL1_INTERRUPT, 0, do_interrupt }, +{ EXCCAUSE_ALLOCA, USER|KRNL, fast_alloca }, +/* EXCCAUSE_INTEGER_DIVIDE_BY_ZERO unhandled */ +/* EXCCAUSE_PRIVILEGED unhandled */ #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION #ifdef CONFIG_UNALIGNED_USER -{ XCHAL_EXCCAUSE_UNALIGNED, USER, fast_unaligned }, +{ EXCCAUSE_UNALIGNED, USER, fast_unaligned }, #else -{ XCHAL_EXCCAUSE_UNALIGNED, 0, do_unaligned_user }, +{ EXCCAUSE_UNALIGNED, 0, do_unaligned_user }, #endif -{ XCHAL_EXCCAUSE_UNALIGNED, KRNL, fast_unaligned }, +{ EXCCAUSE_UNALIGNED, KRNL, fast_unaligned }, #endif -{ XCHAL_EXCCAUSE_ITLB_MISS, 0, do_page_fault }, -{ XCHAL_EXCCAUSE_ITLB_MISS, USER|KRNL, fast_second_level_miss}, -{ XCHAL_EXCCAUSE_ITLB_MULTIHIT, 0, do_multihit }, -{ XCHAL_EXCCAUSE_ITLB_PRIVILEGE, 0, do_page_fault }, -/* XCHAL_EXCCAUSE_SIZE_RESTRICTION unhandled */ -{ XCHAL_EXCCAUSE_FETCH_CACHE_ATTRIBUTE, 0, do_page_fault }, -{ XCHAL_EXCCAUSE_DTLB_MISS, USER|KRNL, fast_second_level_miss}, -{ XCHAL_EXCCAUSE_DTLB_MISS, 0, do_page_fault }, -{ XCHAL_EXCCAUSE_DTLB_MULTIHIT, 0, do_multihit }, -{ XCHAL_EXCCAUSE_DTLB_PRIVILEGE, 0, do_page_fault }, -/* XCHAL_EXCCAUSE_DTLB_SIZE_RESTRICTION unhandled */ -{ XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE, USER|KRNL, fast_store_prohibited }, -{ XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE, 0, do_page_fault }, -{ XCHAL_EXCCAUSE_LOAD_CACHE_ATTRIBUTE, 0, do_page_fault }, +{ EXCCAUSE_ITLB_MISS, 0, do_page_fault }, +{ EXCCAUSE_ITLB_MISS, USER|KRNL, fast_second_level_miss}, +{ EXCCAUSE_ITLB_MULTIHIT, 0, do_multihit }, +{ EXCCAUSE_ITLB_PRIVILEGE, 0, do_page_fault }, +/* EXCCAUSE_SIZE_RESTRICTION unhandled */ +{ EXCCAUSE_FETCH_CACHE_ATTRIBUTE, 0, do_page_fault }, +{ EXCCAUSE_DTLB_MISS, USER|KRNL, fast_second_level_miss}, +{ EXCCAUSE_DTLB_MISS, 0, do_page_fault }, +{ EXCCAUSE_DTLB_MULTIHIT, 0, do_multihit }, +{ EXCCAUSE_DTLB_PRIVILEGE, 0, do_page_fault }, +/* EXCCAUSE_DTLB_SIZE_RESTRICTION unhandled */ +{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, USER|KRNL, fast_store_prohibited }, +{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, 0, do_page_fault }, +{ EXCCAUSE_LOAD_CACHE_ATTRIBUTE, 0, do_page_fault }, /* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */ #if (XCHAL_CP_MASK & 1) COPROCESSOR(0), diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index 0e74397bfa2b..eb2d7bb69ee0 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S @@ -53,6 +53,8 @@ #include <asm/thread_info.h> #include <asm/processor.h> +#define WINDOW_VECTORS_SIZE 0x180 + /* * User exception vector. (Exceptions with PS.UM == 1, PS.EXCM == 0) @@ -210,7 +212,7 @@ ENTRY(_DoubleExceptionVector) /* Check for kernel double exception (usually fatal). */ rsr a3, PS - _bbci.l a3, PS_UM_SHIFT, .Lksp + _bbci.l a3, PS_UM_BIT, .Lksp /* Check if we are currently handling a window exception. */ /* Note: We don't need to indicate that we enter a critical section. */ @@ -219,7 +221,7 @@ ENTRY(_DoubleExceptionVector) movi a3, XCHAL_WINDOW_VECTORS_VADDR _bltu a0, a3, .Lfixup - addi a3, a3, XSHAL_WINDOW_VECTORS_SIZE + addi a3, a3, WINDOW_VECTORS_SIZE _bgeu a0, a3, .Lfixup /* Window overflow/underflow exception. Get stack pointer. */ @@ -245,7 +247,7 @@ ENTRY(_DoubleExceptionVector) wsr a2, DEPC # save stack pointer temporarily rsr a0, PS - extui a0, a0, XCHAL_PS_OWB_SHIFT, XCHAL_PS_OWB_BITS + extui a0, a0, PS_OWB_SHIFT, 4 wsr a0, WINDOWBASE rsync @@ -312,8 +314,8 @@ ENTRY(_DoubleExceptionVector) .Lksp: /* a0: a0, a1: a1, a2: a2, a3: trashed, depc: depc, excsave: a3 */ rsr a3, EXCCAUSE - beqi a3, XCHAL_EXCCAUSE_ITLB_MISS, 1f - addi a3, a3, -XCHAL_EXCCAUSE_DTLB_MISS + beqi a3, EXCCAUSE_ITLB_MISS, 1f + addi a3, a3, -EXCCAUSE_DTLB_MISS bnez a3, .Lunrecoverable 1: movi a3, fast_second_level_miss_double_kernel jx a3 diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index cfe75f528725..a36c104c3a52 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -16,19 +16,17 @@ #include <asm-generic/vmlinux.lds.h> -#define _NOCLANGUAGE -#include <xtensa/config/core.h> -#include <xtensa/config/system.h> +#include <asm/variant/core.h> OUTPUT_ARCH(xtensa) ENTRY(_start) -#if XCHAL_MEMORY_ORDER == XTHAL_BIGENDIAN +#ifdef __XTENSA_EB__ jiffies = jiffies_64 + 4; #else jiffies = jiffies_64; #endif -#define KERNELOFFSET 0x1000 +#define KERNELOFFSET 0xd0001000 /* Note: In the following macros, it would be nice to specify only the vector name and section kind and construct "sym" and "section" using @@ -75,7 +73,7 @@ jiffies = jiffies_64; SECTIONS { - . = XCHAL_KSEG_CACHED_VADDR + KERNELOFFSET; + . = KERNELOFFSET; /* .text section */ _text = .; @@ -159,7 +157,7 @@ SECTIONS /* Initialization code and data: */ - . = ALIGN(1<<XCHAL_MMU_MIN_PTE_PAGE_SIZE); + . = ALIGN(1 << 12); __init_begin = .; .init.text : { _sinittext = .; @@ -223,32 +221,32 @@ SECTIONS .dummy) SECTION_VECTOR (_DebugInterruptVector_literal, .DebugInterruptVector.literal, - XCHAL_INTLEVEL_VECTOR_VADDR(XCHAL_DEBUGLEVEL) - 4, + XCHAL_DEBUG_VECTOR_VADDR - 4, SIZEOF(.WindowVectors.text), .WindowVectors.text) SECTION_VECTOR (_DebugInterruptVector_text, .DebugInterruptVector.text, - XCHAL_INTLEVEL_VECTOR_VADDR(XCHAL_DEBUGLEVEL), + XCHAL_DEBUG_VECTOR_VADDR, 4, .DebugInterruptVector.literal) SECTION_VECTOR (_KernelExceptionVector_literal, .KernelExceptionVector.literal, - XCHAL_KERNELEXC_VECTOR_VADDR - 4, + XCHAL_KERNEL_VECTOR_VADDR - 4, SIZEOF(.DebugInterruptVector.text), .DebugInterruptVector.text) SECTION_VECTOR (_KernelExceptionVector_text, .KernelExceptionVector.text, - XCHAL_KERNELEXC_VECTOR_VADDR, + XCHAL_KERNEL_VECTOR_VADDR, 4, .KernelExceptionVector.literal) SECTION_VECTOR (_UserExceptionVector_literal, .UserExceptionVector.literal, - XCHAL_USEREXC_VECTOR_VADDR - 4, + XCHAL_USER_VECTOR_VADDR - 4, SIZEOF(.KernelExceptionVector.text), .KernelExceptionVector.text) SECTION_VECTOR (_UserExceptionVector_text, .UserExceptionVector.text, - XCHAL_USEREXC_VECTOR_VADDR, + XCHAL_USER_VECTOR_VADDR, 4, .UserExceptionVector.literal) SECTION_VECTOR (_DoubleExceptionVector_literal, @@ -263,7 +261,7 @@ SECTIONS .DoubleExceptionVector.literal) . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; - . = ALIGN(1<<XCHAL_MMU_MIN_PTE_PAGE_SIZE); + . = ALIGN(1 << 12); __init_end = .; diff --git a/arch/xtensa/lib/checksum.S b/arch/xtensa/lib/checksum.S index e2d64dfd530c..9d9cd990afa6 100644 --- a/arch/xtensa/lib/checksum.S +++ b/arch/xtensa/lib/checksum.S @@ -16,8 +16,7 @@ #include <asm/errno.h> #include <linux/linkage.h> -#define _ASMLANGUAGE -#include <xtensa/config/core.h> +#include <asm/variant/core.h> /* * computes a partial checksum, e.g. for TCP/UDP fragments diff --git a/arch/xtensa/lib/memcopy.S b/arch/xtensa/lib/memcopy.S index e8f6d7eb7222..ddda8f4bc862 100644 --- a/arch/xtensa/lib/memcopy.S +++ b/arch/xtensa/lib/memcopy.S @@ -9,7 +9,7 @@ * Copyright (C) 2002 - 2005 Tensilica Inc. */ -#include <xtensa/coreasm.h> +#include <asm/variant/core.h> .macro src_b r, w0, w1 #ifdef __XTENSA_EB__ diff --git a/arch/xtensa/lib/memset.S b/arch/xtensa/lib/memset.S index 4de25134bc62..56a17495b2db 100644 --- a/arch/xtensa/lib/memset.S +++ b/arch/xtensa/lib/memset.S @@ -11,7 +11,7 @@ * Copyright (C) 2002 Tensilica Inc. */ -#include <xtensa/coreasm.h> +#include <asm/variant/core.h> /* * void *memset(void *dst, int c, size_t length) diff --git a/arch/xtensa/lib/strncpy_user.S b/arch/xtensa/lib/strncpy_user.S index 71d55df43893..a834057bda6b 100644 --- a/arch/xtensa/lib/strncpy_user.S +++ b/arch/xtensa/lib/strncpy_user.S @@ -11,7 +11,7 @@ * Copyright (C) 2002 Tensilica Inc. */ -#include <xtensa/coreasm.h> +#include <asm/variant/core.h> #include <linux/errno.h> /* Load or store instructions that may cause exceptions use the EX macro. */ diff --git a/arch/xtensa/lib/strnlen_user.S b/arch/xtensa/lib/strnlen_user.S index cdff4d670f3b..5e9c1e709b2e 100644 --- a/arch/xtensa/lib/strnlen_user.S +++ b/arch/xtensa/lib/strnlen_user.S @@ -11,7 +11,7 @@ * Copyright (C) 2002 Tensilica Inc. */ -#include <xtensa/coreasm.h> +#include <asm/variant/core.h> /* Load or store instructions that may cause exceptions use the EX macro. */ diff --git a/arch/xtensa/lib/usercopy.S b/arch/xtensa/lib/usercopy.S index 4641ef510f0e..a8ab1d4fe0ae 100644 --- a/arch/xtensa/lib/usercopy.S +++ b/arch/xtensa/lib/usercopy.S @@ -53,7 +53,7 @@ * a11/ original length */ -#include <xtensa/coreasm.h> +#include <asm/variant/core.h> #ifdef __XTENSA_EB__ #define ALIGN(R, W0, W1) src R, W0, W1 diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c index dd0dbec2e57e..3dc6f2f07bbe 100644 --- a/arch/xtensa/mm/fault.c +++ b/arch/xtensa/mm/fault.c @@ -21,7 +21,7 @@ #include <asm/system.h> #include <asm/pgalloc.h> -unsigned long asid_cache = ASID_FIRST_VERSION; +unsigned long asid_cache = ASID_USER_FIRST; void bad_page_fault(struct pt_regs*, unsigned long, int); /* @@ -58,10 +58,10 @@ void do_page_fault(struct pt_regs *regs) return; } - is_write = (exccause == XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE) ? 1 : 0; - is_exec = (exccause == XCHAL_EXCCAUSE_ITLB_PRIVILEGE || - exccause == XCHAL_EXCCAUSE_ITLB_MISS || - exccause == XCHAL_EXCCAUSE_FETCH_CACHE_ATTRIBUTE) ? 1 : 0; + is_write = (exccause == EXCCAUSE_STORE_CACHE_ATTRIBUTE) ? 1 : 0; + is_exec = (exccause == EXCCAUSE_ITLB_PRIVILEGE || + exccause == EXCCAUSE_ITLB_MISS || + exccause == EXCCAUSE_FETCH_CACHE_ATTRIBUTE) ? 1 : 0; #if 0 printk("[%s:%d:%08x:%d:%08x:%s%s]\n", current->comm, current->pid, diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 660ef058c149..e1ec2d1e8189 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -141,8 +141,8 @@ void __init bootmem_init(void) if (min_low_pfn > max_pfn) panic("No memory found!\n"); - max_low_pfn = max_pfn < MAX_LOW_MEMORY >> PAGE_SHIFT ? - max_pfn : MAX_LOW_MEMORY >> PAGE_SHIFT; + max_low_pfn = max_pfn < MAX_MEM_PFN >> PAGE_SHIFT ? + max_pfn : MAX_MEM_PFN >> PAGE_SHIFT; /* Find an area to use for the bootmem bitmap. */ @@ -215,7 +215,7 @@ void __init init_mmu (void) /* Set rasid register to a known value. */ - set_rasid_register (ASID_ALL_RESERVED); + set_rasid_register (ASID_USER_FIRST); /* Set PTEVADDR special register to the start of the page * table, which is in kernel mappable space (ie. not diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S index 327c0f17187c..ae085332c607 100644 --- a/arch/xtensa/mm/misc.S +++ b/arch/xtensa/mm/misc.S @@ -19,9 +19,8 @@ #include <linux/linkage.h> #include <asm/page.h> #include <asm/pgtable.h> - -#include <xtensa/cacheasm.h> -#include <xtensa/cacheattrasm.h> +#include <asm/asmmacro.h> +#include <asm/cacheasm.h> /* clear_page (page) */ @@ -74,104 +73,66 @@ ENTRY(copy_page) retw - /* - * void __flush_invalidate_cache_all(void) + * void __invalidate_icache_page(ulong start) */ -ENTRY(__flush_invalidate_cache_all) +ENTRY(__invalidate_icache_page) entry sp, 16 - dcache_writeback_inv_all a2, a3 - icache_invalidate_all a2, a3 - retw -/* - * void __invalidate_icache_all(void) - */ + ___invalidate_icache_page a2 a3 + isync -ENTRY(__invalidate_icache_all) - entry sp, 16 - icache_invalidate_all a2, a3 retw /* - * void __flush_invalidate_dcache_all(void) + * void __invalidate_dcache_page(ulong start) */ -ENTRY(__flush_invalidate_dcache_all) +ENTRY(__invalidate_dcache_page) entry sp, 16 - dcache_writeback_inv_all a2, a3 - retw - -/* - * void __flush_invalidate_cache_range(ulong start, ulong size) - */ + ___invalidate_dcache_page a2 a3 + dsync -ENTRY(__flush_invalidate_cache_range) - entry sp, 16 - mov a4, a2 - mov a5, a3 - dcache_writeback_inv_region a4, a5, a6 - icache_invalidate_region a2, a3, a4 retw /* - * void __invalidate_icache_page(ulong start) + * void __flush_invalidate_dcache_page(ulong start) */ -ENTRY(__invalidate_icache_page) +ENTRY(__flush_invalidate_dcache_page) entry sp, 16 - movi a3, PAGE_SIZE - icache_invalidate_region a2, a3, a4 - retw -/* - * void __invalidate_dcache_page(ulong start) - */ + ___flush_invalidate_dcache_page a2 a3 -ENTRY(__invalidate_dcache_page) - entry sp, 16 - movi a3, PAGE_SIZE - dcache_invalidate_region a2, a3, a4 + dsync retw /* - * void __invalidate_icache_range(ulong start, ulong size) + * void __flush_dcache_page(ulong start) */ -ENTRY(__invalidate_icache_range) +ENTRY(__flush_dcache_page) entry sp, 16 - icache_invalidate_region a2, a3, a4 - retw -/* - * void __invalidate_dcache_range(ulong start, ulong size) - */ + ___flush_dcache_page a2 a3 -ENTRY(__invalidate_dcache_range) - entry sp, 16 - dcache_invalidate_region a2, a3, a4 + dsync retw -/* - * void __flush_dcache_page(ulong start) - */ -ENTRY(__flush_dcache_page) - entry sp, 16 - movi a3, PAGE_SIZE - dcache_writeback_region a2, a3, a4 - retw /* - * void __flush_invalidate_dcache_page(ulong start) + * void __invalidate_icache_range(ulong start, ulong size) */ -ENTRY(__flush_invalidate_dcache_page) +ENTRY(__invalidate_icache_range) entry sp, 16 - movi a3, PAGE_SIZE - dcache_writeback_inv_region a2, a3, a4 + + ___invalidate_icache_range a2 a3 a4 + isync + retw /* @@ -180,195 +141,69 @@ ENTRY(__flush_invalidate_dcache_page) ENTRY(__flush_invalidate_dcache_range) entry sp, 16 - dcache_writeback_inv_region a2, a3, a4 - retw -/* - * void __invalidate_dcache_all(void) - */ + ___flush_invalidate_dcache_range a2 a3 a4 + dsync -ENTRY(__invalidate_dcache_all) - entry sp, 16 - dcache_invalidate_all a2, a3 retw /* - * void __flush_invalidate_dcache_page_phys(ulong start) + * void _flush_dcache_range(ulong start, ulong size) */ -ENTRY(__flush_invalidate_dcache_page_phys) +ENTRY(__flush_dcache_range) entry sp, 16 - movi a3, XCHAL_DCACHE_SIZE - movi a4, PAGE_MASK | 1 - addi a2, a2, 1 - -1: addi a3, a3, -XCHAL_DCACHE_LINESIZE - - ldct a6, a3 + ___flush_dcache_range a2 a3 a4 dsync - and a6, a6, a4 - beq a6, a2, 2f - bgeui a3, 2, 1b - retw -2: diwbi a3, 0 - bgeui a3, 2, 1b retw -ENTRY(check_dcache_low0) - entry sp, 16 - - movi a3, XCHAL_DCACHE_SIZE / 4 - movi a4, PAGE_MASK | 1 - addi a2, a2, 1 - -1: addi a3, a3, -XCHAL_DCACHE_LINESIZE - - ldct a6, a3 - dsync - and a6, a6, a4 - beq a6, a2, 2f - bgeui a3, 2, 1b - retw - -2: j 2b - -ENTRY(check_dcache_high0) - entry sp, 16 - - movi a5, XCHAL_DCACHE_SIZE / 4 - movi a3, XCHAL_DCACHE_SIZE / 2 - movi a4, PAGE_MASK | 1 - addi a2, a2, 1 - -1: addi a3, a3, -XCHAL_DCACHE_LINESIZE - addi a5, a5, -XCHAL_DCACHE_LINESIZE - - ldct a6, a3 - dsync - and a6, a6, a4 - beq a6, a2, 2f - bgeui a5, 2, 1b - retw - -2: j 2b +/* + * void _invalidate_dcache_range(ulong start, ulong size) + */ -ENTRY(check_dcache_low1) +ENTRY(__invalidate_dcache_range) entry sp, 16 - movi a5, XCHAL_DCACHE_SIZE / 4 - movi a3, XCHAL_DCACHE_SIZE * 3 / 4 - movi a4, PAGE_MASK | 1 - addi a2, a2, 1 + ___invalidate_dcache_range a2 a3 a4 -1: addi a3, a3, -XCHAL_DCACHE_LINESIZE - addi a5, a5, -XCHAL_DCACHE_LINESIZE - ldct a6, a3 - dsync - and a6, a6, a4 - beq a6, a2, 2f - bgeui a5, 2, 1b retw -2: j 2b +/* + * void _invalidate_icache_all(void) + */ -ENTRY(check_dcache_high1) +ENTRY(__invalidate_icache_all) entry sp, 16 - movi a5, XCHAL_DCACHE_SIZE / 4 - movi a3, XCHAL_DCACHE_SIZE - movi a4, PAGE_MASK | 1 - addi a2, a2, 1 - -1: addi a3, a3, -XCHAL_DCACHE_LINESIZE - addi a5, a5, -XCHAL_DCACHE_LINESIZE + ___invalidate_icache_all a2 a3 + isync - ldct a6, a3 - dsync - and a6, a6, a4 - beq a6, a2, 2f - bgeui a5, 2, 1b retw -2: j 2b - - /* - * void __invalidate_icache_page_phys(ulong start) + * void _flush_invalidate_dcache_all(void) */ -ENTRY(__invalidate_icache_page_phys) +ENTRY(__flush_invalidate_dcache_all) entry sp, 16 - movi a3, XCHAL_ICACHE_SIZE - movi a4, PAGE_MASK | 1 - addi a2, a2, 1 - -1: addi a3, a3, -XCHAL_ICACHE_LINESIZE - - lict a6, a3 - isync - and a6, a6, a4 - beq a6, a2, 2f - bgeui a3, 2, 1b - retw + ___flush_invalidate_dcache_all a2 a3 + dsync -2: iii a3, 0 - bgeui a3, 2, 1b retw +/* + * void _invalidate_dcache_all(void) + */ -#if 0 - - movi a3, XCHAL_DCACHE_WAYS - 1 - movi a4, PAGE_SIZE - -1: mov a5, a2 - add a6, a2, a4 - -2: diwbi a5, 0 - diwbi a5, XCHAL_DCACHE_LINESIZE - diwbi a5, XCHAL_DCACHE_LINESIZE * 2 - diwbi a5, XCHAL_DCACHE_LINESIZE * 3 - - addi a5, a5, XCHAL_DCACHE_LINESIZE * 4 - blt a5, a6, 2b - - addi a3, a3, -1 - addi a2, a2, XCHAL_DCACHE_SIZE / XCHAL_DCACHE_WAYS - bgez a3, 1b - - retw - -ENTRY(__invalidate_icache_page_index) +ENTRY(__invalidate_dcache_all) entry sp, 16 - movi a3, XCHAL_ICACHE_WAYS - 1 - movi a4, PAGE_SIZE - -1: mov a5, a2 - add a6, a2, a4 - -2: iii a5, 0 - iii a5, XCHAL_ICACHE_LINESIZE - iii a5, XCHAL_ICACHE_LINESIZE * 2 - iii a5, XCHAL_ICACHE_LINESIZE * 3 - - addi a5, a5, XCHAL_ICACHE_LINESIZE * 4 - blt a5, a6, 2b - - addi a3, a3, -1 - addi a2, a2, XCHAL_ICACHE_SIZE / XCHAL_ICACHE_WAYS - bgez a3, 2b + ___invalidate_dcache_all a2 a3 + dsync retw -#endif - - - - - - diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c index 0fefb8666874..239461d8ea88 100644 --- a/arch/xtensa/mm/tlb.c +++ b/arch/xtensa/mm/tlb.c @@ -24,12 +24,12 @@ static inline void __flush_itlb_all (void) { - int way, index; + int w, i; - for (way = 0; way < XCHAL_ITLB_ARF_WAYS; way++) { - for (index = 0; index < ITLB_ENTRIES_PER_ARF_WAY; index++) { - int entry = way + (index << PAGE_SHIFT); - invalidate_itlb_entry_no_isync (entry); + for (w = 0; w < ITLB_ARF_WAYS; w++) { + for (i = 0; i < (1 << XCHAL_ITLB_ARF_ENTRIES_LOG2); i++) { + int e = w + (i << PAGE_SHIFT); + invalidate_itlb_entry_no_isync(e); } } asm volatile ("isync\n"); @@ -37,12 +37,12 @@ static inline void __flush_itlb_all (void) static inline void __flush_dtlb_all (void) { - int way, index; + int w, i; - for (way = 0; way < XCHAL_DTLB_ARF_WAYS; way++) { - for (index = 0; index < DTLB_ENTRIES_PER_ARF_WAY; index++) { - int entry = way + (index << PAGE_SHIFT); - invalidate_dtlb_entry_no_isync (entry); + for (w = 0; w < DTLB_ARF_WAYS; w++) { + for (i = 0; i < (1 << XCHAL_DTLB_ARF_ENTRIES_LOG2); i++) { + int e = w + (i << PAGE_SHIFT); + invalidate_dtlb_entry_no_isync(e); } } asm volatile ("isync\n"); @@ -63,21 +63,25 @@ void flush_tlb_all (void) void flush_tlb_mm(struct mm_struct *mm) { -#if 0 - printk("[tlbmm<%lx>]\n", (unsigned long)mm->context); -#endif - if (mm == current->active_mm) { int flags; local_save_flags(flags); - get_new_mmu_context(mm, asid_cache); - set_rasid_register(ASID_INSERT(mm->context)); + __get_new_mmu_context(mm); + __load_mmu_context(mm); local_irq_restore(flags); } else mm->context = 0; } +#define _ITLB_ENTRIES (ITLB_ARF_WAYS << XCHAL_ITLB_ARF_ENTRIES_LOG2) +#define _DTLB_ENTRIES (DTLB_ARF_WAYS << XCHAL_DTLB_ARF_ENTRIES_LOG2) +#if _ITLB_ENTRIES > _DTLB_ENTRIES +# define _TLB_ENTRIES _ITLB_ENTRIES +#else +# define _TLB_ENTRIES _DTLB_ENTRIES +#endif + void flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end) { @@ -93,7 +97,7 @@ void flush_tlb_range (struct vm_area_struct *vma, #endif local_save_flags(flags); - if (end-start + (PAGE_SIZE-1) <= SMALLEST_NTLB_ENTRIES << PAGE_SHIFT) { + if (end-start + (PAGE_SIZE-1) <= _TLB_ENTRIES << PAGE_SHIFT) { int oldpid = get_rasid_register(); set_rasid_register (ASID_INSERT(mm->context)); start &= PAGE_MASK; @@ -111,9 +115,7 @@ void flush_tlb_range (struct vm_area_struct *vma, set_rasid_register(oldpid); } else { - get_new_mmu_context(mm, asid_cache); - if (mm == current->active_mm) - set_rasid_register(ASID_INSERT(mm->context)); + flush_tlb_mm(mm); } local_irq_restore(flags); } @@ -123,10 +125,6 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page) struct mm_struct* mm = vma->vm_mm; unsigned long flags; int oldpid; -#if 0 - printk("[tlbpage<%02lx,%08lx>]\n", - (unsigned long)mm->context, page); -#endif if(mm->context == NO_CONTEXT) return; @@ -142,404 +140,5 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page) set_rasid_register(oldpid); local_irq_restore(flags); - -#if 0 - flush_tlb_all(); - return; -#endif -} - - -#ifdef DEBUG_TLB - -#define USE_ITLB 0 -#define USE_DTLB 1 - -struct way_config_t { - int indicies; - int indicies_log2; - int pgsz_log2; - int arf; -}; - -static struct way_config_t itlb[XCHAL_ITLB_WAYS] = -{ - { XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ENTRIES), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ENTRIES_LOG2), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, PAGESZ_LOG2_MIN), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ARF) - }, - { XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ENTRIES), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ENTRIES_LOG2), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, PAGESZ_LOG2_MIN), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ARF) - }, - { XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ENTRIES), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ENTRIES_LOG2), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, PAGESZ_LOG2_MIN), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ARF) - }, - { XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ENTRIES), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ENTRIES_LOG2), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, PAGESZ_LOG2_MIN), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ARF) - }, - { XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ENTRIES), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ENTRIES_LOG2), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, PAGESZ_LOG2_MIN), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ARF) - }, - { XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ENTRIES), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ENTRIES_LOG2), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, PAGESZ_LOG2_MIN), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ARF) - }, - { XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ENTRIES), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ENTRIES_LOG2), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, PAGESZ_LOG2_MIN), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ARF) - } -}; - -static struct way_config_t dtlb[XCHAL_DTLB_WAYS] = -{ - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ARF) - } -}; - -/* Total number of entries: */ -#define ITLB_TOTAL_ENTRIES \ - XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ENTRIES) + \ - XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ENTRIES) + \ - XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ENTRIES) + \ - XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ENTRIES) + \ - XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ENTRIES) + \ - XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ENTRIES) + \ - XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ENTRIES) -#define DTLB_TOTAL_ENTRIES \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ENTRIES) - - -typedef struct { - unsigned va; - unsigned pa; - unsigned char asid; - unsigned char ca; - unsigned char way; - unsigned char index; - unsigned char pgsz_log2; /* 0 .. 32 */ - unsigned char type; /* 0=ITLB 1=DTLB */ -} tlb_dump_entry_t; - -/* Return -1 if a precedes b, +1 if a follows b, 0 if same: */ -int cmp_tlb_dump_info( tlb_dump_entry_t *a, tlb_dump_entry_t *b ) -{ - if (a->asid < b->asid) return -1; - if (a->asid > b->asid) return 1; - if (a->va < b->va) return -1; - if (a->va > b->va) return 1; - if (a->pa < b->pa) return -1; - if (a->pa > b->pa) return 1; - if (a->ca < b->ca) return -1; - if (a->ca > b->ca) return 1; - if (a->way < b->way) return -1; - if (a->way > b->way) return 1; - if (a->index < b->index) return -1; - if (a->index > b->index) return 1; - return 0; -} - -void sort_tlb_dump_info( tlb_dump_entry_t *t, int n ) -{ - int i, j; - /* Simple O(n*n) sort: */ - for (i = 0; i < n-1; i++) - for (j = i+1; j < n; j++) - if (cmp_tlb_dump_info(t+i, t+j) > 0) { - tlb_dump_entry_t tmp = t[i]; - t[i] = t[j]; - t[j] = tmp; - } -} - - -static tlb_dump_entry_t itlb_dump_info[ITLB_TOTAL_ENTRIES]; -static tlb_dump_entry_t dtlb_dump_info[DTLB_TOTAL_ENTRIES]; - - -static inline char *way_type (int type) -{ - return type ? "autorefill" : "non-autorefill"; -} - -void print_entry (struct way_config_t *way_info, - unsigned int way, - unsigned int index, - unsigned int virtual, - unsigned int translation) -{ - char valid_chr; - unsigned int va, pa, asid, ca; - - va = virtual & - ~((1 << (way_info->pgsz_log2 + way_info->indicies_log2)) - 1); - asid = virtual & ((1 << XCHAL_MMU_ASID_BITS) - 1); - pa = translation & ~((1 << way_info->pgsz_log2) - 1); - ca = translation & ((1 << XCHAL_MMU_CA_BITS) - 1); - valid_chr = asid ? 'V' : 'I'; - - /* Compute and incorporate the effect of the index bits on the - * va. It's more useful for kernel debugging, since we always - * want to know the effective va anyway. */ - - va += index << way_info->pgsz_log2; - - printk ("\t[%d,%d] (%c) vpn 0x%.8x ppn 0x%.8x asid 0x%.2x am 0x%x\n", - way, index, valid_chr, va, pa, asid, ca); -} - -void print_itlb_entry (struct way_config_t *way_info, int way, int index) -{ - print_entry (way_info, way, index, - read_itlb_virtual (way + (index << way_info->pgsz_log2)), - read_itlb_translation (way + (index << way_info->pgsz_log2))); -} - -void print_dtlb_entry (struct way_config_t *way_info, int way, int index) -{ - print_entry (way_info, way, index, - read_dtlb_virtual (way + (index << way_info->pgsz_log2)), - read_dtlb_translation (way + (index << way_info->pgsz_log2))); -} - -void dump_itlb (void) -{ - int way, index; - - printk ("\nITLB: ways = %d\n", XCHAL_ITLB_WAYS); - - for (way = 0; way < XCHAL_ITLB_WAYS; way++) { - printk ("\nWay: %d, Entries: %d, MinPageSize: %d, Type: %s\n", - way, itlb[way].indicies, - itlb[way].pgsz_log2, way_type(itlb[way].arf)); - for (index = 0; index < itlb[way].indicies; index++) { - print_itlb_entry(&itlb[way], way, index); - } - } -} - -void dump_dtlb (void) -{ - int way, index; - - printk ("\nDTLB: ways = %d\n", XCHAL_DTLB_WAYS); - - for (way = 0; way < XCHAL_DTLB_WAYS; way++) { - printk ("\nWay: %d, Entries: %d, MinPageSize: %d, Type: %s\n", - way, dtlb[way].indicies, - dtlb[way].pgsz_log2, way_type(dtlb[way].arf)); - for (index = 0; index < dtlb[way].indicies; index++) { - print_dtlb_entry(&dtlb[way], way, index); - } - } -} - -void dump_tlb (tlb_dump_entry_t *tinfo, struct way_config_t *config, - int entries, int ways, int type, int show_invalid) -{ - tlb_dump_entry_t *e = tinfo; - int way, i; - - /* Gather all info: */ - for (way = 0; way < ways; way++) { - struct way_config_t *cfg = config + way; - for (i = 0; i < cfg->indicies; i++) { - unsigned wayindex = way + (i << cfg->pgsz_log2); - unsigned vv = (type ? read_dtlb_virtual (wayindex) - : read_itlb_virtual (wayindex)); - unsigned pp = (type ? read_dtlb_translation (wayindex) - : read_itlb_translation (wayindex)); - - /* Compute and incorporate the effect of the index bits on the - * va. It's more useful for kernel debugging, since we always - * want to know the effective va anyway. */ - - e->va = (vv & ~((1 << (cfg->pgsz_log2 + cfg->indicies_log2)) - 1)); - e->va += (i << cfg->pgsz_log2); - e->pa = (pp & ~((1 << cfg->pgsz_log2) - 1)); - e->asid = (vv & ((1 << XCHAL_MMU_ASID_BITS) - 1)); - e->ca = (pp & ((1 << XCHAL_MMU_CA_BITS) - 1)); - e->way = way; - e->index = i; - e->pgsz_log2 = cfg->pgsz_log2; - e->type = type; - e++; - } - } -#if 1 - /* Sort by ASID and VADDR: */ - sort_tlb_dump_info (tinfo, entries); -#endif - - /* Display all sorted info: */ - printk ("\n%cTLB dump:\n", (type ? 'D' : 'I')); - for (e = tinfo, i = 0; i < entries; i++, e++) { -#if 0 - if (e->asid == 0 && !show_invalid) - continue; -#endif - printk ("%c way=%d i=%d ASID=%02X V=%08X -> P=%08X CA=%X (%d %cB)\n", - (e->type ? 'D' : 'I'), e->way, e->index, - e->asid, e->va, e->pa, e->ca, - (1 << (e->pgsz_log2 % 10)), - " kMG"[e->pgsz_log2 / 10] - ); - } -} - -void dump_tlbs2 (int showinv) -{ - dump_tlb (itlb_dump_info, itlb, ITLB_TOTAL_ENTRIES, XCHAL_ITLB_WAYS, 0, showinv); - dump_tlb (dtlb_dump_info, dtlb, DTLB_TOTAL_ENTRIES, XCHAL_DTLB_WAYS, 1, showinv); -} - -void dump_all_tlbs (void) -{ - dump_tlbs2 (1); -} - -void dump_valid_tlbs (void) -{ - dump_tlbs2 (0); } - -void dump_tlbs (void) -{ - dump_itlb(); - dump_dtlb(); -} - -void dump_cache_tag(int dcache, int idx) -{ - int w, i, s, e; - unsigned long tag, index; - unsigned long num_lines, num_ways, cache_size, line_size; - - num_ways = dcache ? XCHAL_DCACHE_WAYS : XCHAL_ICACHE_WAYS; - cache_size = dcache ? XCHAL_DCACHE_SIZE : XCHAL_ICACHE_SIZE; - line_size = dcache ? XCHAL_DCACHE_LINESIZE : XCHAL_ICACHE_LINESIZE; - - num_lines = cache_size / num_ways; - - s = 0; e = num_lines; - - if (idx >= 0) - e = (s = idx * line_size) + 1; - - for (i = s; i < e; i+= line_size) { - printk("\nline %#08x:", i); - for (w = 0; w < num_ways; w++) { - index = w * num_lines + i; - if (dcache) - __asm__ __volatile__("ldct %0, %1\n\t" - : "=a"(tag) : "a"(index)); - else - __asm__ __volatile__("lict %0, %1\n\t" - : "=a"(tag) : "a"(index)); - - printk(" %#010lx", tag); - } - } - printk ("\n"); -} - -void dump_icache(int index) -{ - unsigned long data, addr; - int w, i; - - const unsigned long num_ways = XCHAL_ICACHE_WAYS; - const unsigned long cache_size = XCHAL_ICACHE_SIZE; - const unsigned long line_size = XCHAL_ICACHE_LINESIZE; - const unsigned long num_lines = cache_size / num_ways / line_size; - - for (w = 0; w < num_ways; w++) { - printk ("\nWay %d", w); - - for (i = 0; i < line_size; i+= 4) { - addr = w * num_lines + index * line_size + i; - __asm__ __volatile__("licw %0, %1\n\t" - : "=a"(data) : "a"(addr)); - printk(" %#010lx", data); - } - } - printk ("\n"); -} - -void dump_cache_tags(void) -{ - printk("Instruction cache\n"); - dump_cache_tag(0, -1); - printk("Data cache\n"); - dump_cache_tag(1, -1); -} - -#endif diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platform-iss/console.c index 5c947cae7520..2f4f20ffe666 100644 --- a/arch/xtensa/platform-iss/console.c +++ b/arch/xtensa/platform-iss/console.c @@ -25,11 +25,15 @@ #include <asm/uaccess.h> #include <asm/irq.h> -#include <xtensa/simcall.h> +#include <asm/platform/simcall.h> #include <linux/tty.h> #include <linux/tty_flip.h> +#ifdef SERIAL_INLINE +#define _INLINE_ inline +#endif + #define SERIAL_MAX_NUM_LINES 1 #define SERIAL_TIMER_VALUE (20 * HZ) @@ -191,7 +195,7 @@ static int rs_read_proc(char *page, char **start, off_t off, int count, } -static const struct tty_operations serial_ops = { +static struct tty_operations serial_ops = { .open = rs_open, .close = rs_close, .write = rs_write, diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c index 15d64414bd60..8ebfc8761229 100644 --- a/arch/xtensa/platform-iss/network.c +++ b/arch/xtensa/platform-iss/network.c @@ -34,7 +34,7 @@ #include <linux/timer.h> #include <linux/platform_device.h> -#include <xtensa/simcall.h> +#include <asm/platform/simcall.h> #define DRIVER_NAME "iss-netdev" #define ETH_MAX_PACKET 1500 |