forked from Minki/linux
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (36 commits) MIPS: Calculate proper ebase value for 64-bit kernels MIPS: Alchemy: DB1200: Remove custom wait implementation MIPS: Big Sur: Make defconfig more useful. MIPS: Fix __vmalloc() etc. on MIPS for non-GPL modules MIPS: Sibyte: Fix M3 TLB exception handler workaround. MIPS: BCM63xx: Fix build failure in board_bcm963xx.c MIPS: uasm: Add OR instruction. MIPS: Sibyte: Apply M3 workaround only on affected chip types and versions. MIPS: BCM63xx: Initialize gpio_out_low & out_high to current value at boot. MIPS: BCM63xx: Register SSB SPROM fallback in board's first stage callback MIPS: BCM63xx: Fix typo in cpu-feature-overrides file. MIPS: BCM63xx: Add support for second uart. MIPS: BCM63xx: Fix double gpio registration. MIPS: BCM63xx: Add DWVS0 board MIPS: BCM63xx: Add the RTA1025W-16 BCM6348-based board to suppported boards. MIPS: BCM63xx: Fix BCM6338 and BCM6345 gpio count MIPS: libgcc.h: Checkpatch cleanup MIPS: Loongson-2F: Flush the branch target history in BTB and RAS MIPS: Move signal trampolines off of the stack. MIPS: Preliminary VDSO ...
This commit is contained in:
commit
4505a49389
@ -60,43 +60,6 @@ void __init board_setup(void)
|
||||
wmb();
|
||||
}
|
||||
|
||||
/* use the hexleds to count the number of times the cpu has entered
|
||||
* wait, the dots to indicate whether the CPU is currently idle or
|
||||
* active (dots off = sleeping, dots on = working) for cases where
|
||||
* the number doesn't change for a long(er) period of time.
|
||||
*/
|
||||
static void db1200_wait(void)
|
||||
{
|
||||
__asm__(" .set push \n"
|
||||
" .set mips3 \n"
|
||||
" .set noreorder \n"
|
||||
" cache 0x14, 0(%0) \n"
|
||||
" cache 0x14, 32(%0) \n"
|
||||
" cache 0x14, 64(%0) \n"
|
||||
/* dots off: we're about to call wait */
|
||||
" lui $26, 0xb980 \n"
|
||||
" ori $27, $0, 3 \n"
|
||||
" sb $27, 0x18($26) \n"
|
||||
" sync \n"
|
||||
" nop \n"
|
||||
" wait \n"
|
||||
" nop \n"
|
||||
" nop \n"
|
||||
" nop \n"
|
||||
" nop \n"
|
||||
" nop \n"
|
||||
/* dots on: there's work to do, increment cntr */
|
||||
" lui $26, 0xb980 \n"
|
||||
" sb $0, 0x18($26) \n"
|
||||
" lui $26, 0xb9c0 \n"
|
||||
" lb $27, 0($26) \n"
|
||||
" addiu $27, $27, 1 \n"
|
||||
" sb $27, 0($26) \n"
|
||||
" sync \n"
|
||||
" .set pop \n"
|
||||
: : "r" (db1200_wait));
|
||||
}
|
||||
|
||||
static int __init db1200_arch_init(void)
|
||||
{
|
||||
/* GPIO7 is low-level triggered CPLD cascade */
|
||||
@ -110,9 +73,6 @@ static int __init db1200_arch_init(void)
|
||||
irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
|
||||
irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
|
||||
|
||||
if (cpu_wait)
|
||||
cpu_wait = db1200_wait;
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(db1200_arch_init);
|
||||
|
@ -168,7 +168,7 @@ static struct plat_vlynq_data vlynq_high_data = {
|
||||
.on = vlynq_on,
|
||||
.off = vlynq_off,
|
||||
},
|
||||
.reset_bit = 26,
|
||||
.reset_bit = 16,
|
||||
.gpio_bit = 19,
|
||||
};
|
||||
|
||||
@ -600,6 +600,7 @@ static int __init ar7_register_devices(void)
|
||||
}
|
||||
|
||||
if (ar7_has_high_cpmac()) {
|
||||
res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status);
|
||||
if (!res) {
|
||||
cpmac_get_mac(1, cpmac_high_data.dev_addr);
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <asm/addrspace.h>
|
||||
#include <bcm63xx_board.h>
|
||||
#include <bcm63xx_cpu.h>
|
||||
#include <bcm63xx_dev_uart.h>
|
||||
#include <bcm63xx_regs.h>
|
||||
#include <bcm63xx_io.h>
|
||||
#include <bcm63xx_dev_pci.h>
|
||||
@ -40,6 +41,7 @@ static struct board_info __initdata board_96338gw = {
|
||||
.name = "96338GW",
|
||||
.expected_cpu_id = 0x6338,
|
||||
|
||||
.has_uart0 = 1,
|
||||
.has_enet0 = 1,
|
||||
.enet0 = {
|
||||
.force_speed_100 = 1,
|
||||
@ -82,6 +84,7 @@ static struct board_info __initdata board_96338w = {
|
||||
.name = "96338W",
|
||||
.expected_cpu_id = 0x6338,
|
||||
|
||||
.has_uart0 = 1,
|
||||
.has_enet0 = 1,
|
||||
.enet0 = {
|
||||
.force_speed_100 = 1,
|
||||
@ -126,6 +129,8 @@ static struct board_info __initdata board_96338w = {
|
||||
static struct board_info __initdata board_96345gw2 = {
|
||||
.name = "96345GW2",
|
||||
.expected_cpu_id = 0x6345,
|
||||
|
||||
.has_uart0 = 1,
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -137,6 +142,7 @@ static struct board_info __initdata board_96348r = {
|
||||
.name = "96348R",
|
||||
.expected_cpu_id = 0x6348,
|
||||
|
||||
.has_uart0 = 1,
|
||||
.has_enet0 = 1,
|
||||
.has_pci = 1,
|
||||
|
||||
@ -180,6 +186,7 @@ static struct board_info __initdata board_96348gw_10 = {
|
||||
.name = "96348GW-10",
|
||||
.expected_cpu_id = 0x6348,
|
||||
|
||||
.has_uart0 = 1,
|
||||
.has_enet0 = 1,
|
||||
.has_enet1 = 1,
|
||||
.has_pci = 1,
|
||||
@ -239,6 +246,7 @@ static struct board_info __initdata board_96348gw_11 = {
|
||||
.name = "96348GW-11",
|
||||
.expected_cpu_id = 0x6348,
|
||||
|
||||
.has_uart0 = 1,
|
||||
.has_enet0 = 1,
|
||||
.has_enet1 = 1,
|
||||
.has_pci = 1,
|
||||
@ -292,6 +300,7 @@ static struct board_info __initdata board_96348gw = {
|
||||
.name = "96348GW",
|
||||
.expected_cpu_id = 0x6348,
|
||||
|
||||
.has_uart0 = 1,
|
||||
.has_enet0 = 1,
|
||||
.has_enet1 = 1,
|
||||
.has_pci = 1,
|
||||
@ -349,9 +358,10 @@ static struct board_info __initdata board_FAST2404 = {
|
||||
.name = "F@ST2404",
|
||||
.expected_cpu_id = 0x6348,
|
||||
|
||||
.has_enet0 = 1,
|
||||
.has_enet1 = 1,
|
||||
.has_pci = 1,
|
||||
.has_uart0 = 1,
|
||||
.has_enet0 = 1,
|
||||
.has_enet1 = 1,
|
||||
.has_pci = 1,
|
||||
|
||||
.enet0 = {
|
||||
.has_phy = 1,
|
||||
@ -368,10 +378,30 @@ static struct board_info __initdata board_FAST2404 = {
|
||||
.has_ehci0 = 1,
|
||||
};
|
||||
|
||||
static struct board_info __initdata board_rta1025w_16 = {
|
||||
.name = "RTA1025W_16",
|
||||
.expected_cpu_id = 0x6348,
|
||||
|
||||
.has_enet0 = 1,
|
||||
.has_enet1 = 1,
|
||||
.has_pci = 1,
|
||||
|
||||
.enet0 = {
|
||||
.has_phy = 1,
|
||||
.use_internal_phy = 1,
|
||||
},
|
||||
.enet1 = {
|
||||
.force_speed_100 = 1,
|
||||
.force_duplex_full = 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static struct board_info __initdata board_DV201AMR = {
|
||||
.name = "DV201AMR",
|
||||
.expected_cpu_id = 0x6348,
|
||||
|
||||
.has_uart0 = 1,
|
||||
.has_pci = 1,
|
||||
.has_ohci0 = 1,
|
||||
|
||||
@ -391,6 +421,7 @@ static struct board_info __initdata board_96348gw_a = {
|
||||
.name = "96348GW-A",
|
||||
.expected_cpu_id = 0x6348,
|
||||
|
||||
.has_uart0 = 1,
|
||||
.has_enet0 = 1,
|
||||
.has_enet1 = 1,
|
||||
.has_pci = 1,
|
||||
@ -416,6 +447,7 @@ static struct board_info __initdata board_96358vw = {
|
||||
.name = "96358VW",
|
||||
.expected_cpu_id = 0x6358,
|
||||
|
||||
.has_uart0 = 1,
|
||||
.has_enet0 = 1,
|
||||
.has_enet1 = 1,
|
||||
.has_pci = 1,
|
||||
@ -467,6 +499,7 @@ static struct board_info __initdata board_96358vw2 = {
|
||||
.name = "96358VW2",
|
||||
.expected_cpu_id = 0x6358,
|
||||
|
||||
.has_uart0 = 1,
|
||||
.has_enet0 = 1,
|
||||
.has_enet1 = 1,
|
||||
.has_pci = 1,
|
||||
@ -514,6 +547,7 @@ static struct board_info __initdata board_AGPFS0 = {
|
||||
.name = "AGPF-S0",
|
||||
.expected_cpu_id = 0x6358,
|
||||
|
||||
.has_uart0 = 1,
|
||||
.has_enet0 = 1,
|
||||
.has_enet1 = 1,
|
||||
.has_pci = 1,
|
||||
@ -531,6 +565,27 @@ static struct board_info __initdata board_AGPFS0 = {
|
||||
.has_ohci0 = 1,
|
||||
.has_ehci0 = 1,
|
||||
};
|
||||
|
||||
static struct board_info __initdata board_DWVS0 = {
|
||||
.name = "DWV-S0",
|
||||
.expected_cpu_id = 0x6358,
|
||||
|
||||
.has_enet0 = 1,
|
||||
.has_enet1 = 1,
|
||||
.has_pci = 1,
|
||||
|
||||
.enet0 = {
|
||||
.has_phy = 1,
|
||||
.use_internal_phy = 1,
|
||||
},
|
||||
|
||||
.enet1 = {
|
||||
.force_speed_100 = 1,
|
||||
.force_duplex_full = 1,
|
||||
},
|
||||
|
||||
.has_ohci0 = 1,
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -552,15 +607,87 @@ static const struct board_info __initdata *bcm963xx_boards[] = {
|
||||
&board_FAST2404,
|
||||
&board_DV201AMR,
|
||||
&board_96348gw_a,
|
||||
&board_rta1025w_16,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BCM63XX_CPU_6358
|
||||
&board_96358vw,
|
||||
&board_96358vw2,
|
||||
&board_AGPFS0,
|
||||
&board_DWVS0,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* Register a sane SPROMv2 to make the on-board
|
||||
* bcm4318 WLAN work
|
||||
*/
|
||||
#ifdef CONFIG_SSB_PCIHOST
|
||||
static struct ssb_sprom bcm63xx_sprom = {
|
||||
.revision = 0x02,
|
||||
.board_rev = 0x17,
|
||||
.country_code = 0x0,
|
||||
.ant_available_bg = 0x3,
|
||||
.pa0b0 = 0x15ae,
|
||||
.pa0b1 = 0xfa85,
|
||||
.pa0b2 = 0xfe8d,
|
||||
.pa1b0 = 0xffff,
|
||||
.pa1b1 = 0xffff,
|
||||
.pa1b2 = 0xffff,
|
||||
.gpio0 = 0xff,
|
||||
.gpio1 = 0xff,
|
||||
.gpio2 = 0xff,
|
||||
.gpio3 = 0xff,
|
||||
.maxpwr_bg = 0x004c,
|
||||
.itssi_bg = 0x00,
|
||||
.boardflags_lo = 0x2848,
|
||||
.boardflags_hi = 0x0000,
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* return board name for /proc/cpuinfo
|
||||
*/
|
||||
const char *board_get_name(void)
|
||||
{
|
||||
return board.name;
|
||||
}
|
||||
|
||||
/*
|
||||
* register & return a new board mac address
|
||||
*/
|
||||
static int board_get_mac_address(u8 *mac)
|
||||
{
|
||||
u8 *p;
|
||||
int count;
|
||||
|
||||
if (mac_addr_used >= nvram.mac_addr_count) {
|
||||
printk(KERN_ERR PFX "not enough mac address\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
|
||||
p = mac + ETH_ALEN - 1;
|
||||
count = mac_addr_used;
|
||||
|
||||
while (count--) {
|
||||
do {
|
||||
(*p)++;
|
||||
if (*p != 0)
|
||||
break;
|
||||
p--;
|
||||
} while (p != mac);
|
||||
}
|
||||
|
||||
if (p == mac) {
|
||||
printk(KERN_ERR PFX "unable to fetch mac address\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mac_addr_used++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* early init callback, read nvram data from flash and checksum it
|
||||
*/
|
||||
@ -659,6 +786,17 @@ void __init board_prom_init(void)
|
||||
}
|
||||
|
||||
bcm_gpio_writel(val, GPIO_MODE_REG);
|
||||
|
||||
/* Generate MAC address for WLAN and
|
||||
* register our SPROM */
|
||||
#ifdef CONFIG_SSB_PCIHOST
|
||||
if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
|
||||
memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
|
||||
memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
|
||||
if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
|
||||
printk(KERN_ERR "failed to register fallback SPROM\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -676,49 +814,6 @@ void __init board_setup(void)
|
||||
panic("unexpected CPU for bcm963xx board");
|
||||
}
|
||||
|
||||
/*
|
||||
* return board name for /proc/cpuinfo
|
||||
*/
|
||||
const char *board_get_name(void)
|
||||
{
|
||||
return board.name;
|
||||
}
|
||||
|
||||
/*
|
||||
* register & return a new board mac address
|
||||
*/
|
||||
static int board_get_mac_address(u8 *mac)
|
||||
{
|
||||
u8 *p;
|
||||
int count;
|
||||
|
||||
if (mac_addr_used >= nvram.mac_addr_count) {
|
||||
printk(KERN_ERR PFX "not enough mac address\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
|
||||
p = mac + ETH_ALEN - 1;
|
||||
count = mac_addr_used;
|
||||
|
||||
while (count--) {
|
||||
do {
|
||||
(*p)++;
|
||||
if (*p != 0)
|
||||
break;
|
||||
p--;
|
||||
} while (p != mac);
|
||||
}
|
||||
|
||||
if (p == mac) {
|
||||
printk(KERN_ERR PFX "unable to fetch mac address\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mac_addr_used++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mtd_partition mtd_partitions[] = {
|
||||
{
|
||||
.name = "cfe",
|
||||
@ -750,33 +845,6 @@ static struct platform_device mtd_dev = {
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Register a sane SPROMv2 to make the on-board
|
||||
* bcm4318 WLAN work
|
||||
*/
|
||||
#ifdef CONFIG_SSB_PCIHOST
|
||||
static struct ssb_sprom bcm63xx_sprom = {
|
||||
.revision = 0x02,
|
||||
.board_rev = 0x17,
|
||||
.country_code = 0x0,
|
||||
.ant_available_bg = 0x3,
|
||||
.pa0b0 = 0x15ae,
|
||||
.pa0b1 = 0xfa85,
|
||||
.pa0b2 = 0xfe8d,
|
||||
.pa1b0 = 0xffff,
|
||||
.pa1b1 = 0xffff,
|
||||
.pa1b2 = 0xffff,
|
||||
.gpio0 = 0xff,
|
||||
.gpio1 = 0xff,
|
||||
.gpio2 = 0xff,
|
||||
.gpio3 = 0xff,
|
||||
.maxpwr_bg = 0x004c,
|
||||
.itssi_bg = 0x00,
|
||||
.boardflags_lo = 0x2848,
|
||||
.boardflags_hi = 0x0000,
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct gpio_led_platform_data bcm63xx_led_data;
|
||||
|
||||
static struct platform_device bcm63xx_gpio_leds = {
|
||||
@ -792,6 +860,12 @@ int __init board_register_devices(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (board.has_uart0)
|
||||
bcm63xx_uart_register(0);
|
||||
|
||||
if (board.has_uart1)
|
||||
bcm63xx_uart_register(1);
|
||||
|
||||
if (board.has_pccard)
|
||||
bcm63xx_pcmcia_register();
|
||||
|
||||
@ -806,17 +880,6 @@ int __init board_register_devices(void)
|
||||
if (board.has_dsp)
|
||||
bcm63xx_dsp_register(&board.dsp);
|
||||
|
||||
/* Generate MAC address for WLAN and
|
||||
* register our SPROM */
|
||||
#ifdef CONFIG_SSB_PCIHOST
|
||||
if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
|
||||
memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
|
||||
memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
|
||||
if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
|
||||
printk(KERN_ERR "failed to register fallback SPROM\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* read base address of boot chip select (0) */
|
||||
if (BCMCPU_IS_6345())
|
||||
val = 0x1fc00000;
|
||||
|
@ -36,6 +36,7 @@ static const unsigned long bcm96338_regs_base[] = {
|
||||
[RSET_TIMER] = BCM_6338_TIMER_BASE,
|
||||
[RSET_WDT] = BCM_6338_WDT_BASE,
|
||||
[RSET_UART0] = BCM_6338_UART0_BASE,
|
||||
[RSET_UART1] = BCM_6338_UART1_BASE,
|
||||
[RSET_GPIO] = BCM_6338_GPIO_BASE,
|
||||
[RSET_SPI] = BCM_6338_SPI_BASE,
|
||||
[RSET_OHCI0] = BCM_6338_OHCI0_BASE,
|
||||
@ -72,6 +73,7 @@ static const unsigned long bcm96345_regs_base[] = {
|
||||
[RSET_TIMER] = BCM_6345_TIMER_BASE,
|
||||
[RSET_WDT] = BCM_6345_WDT_BASE,
|
||||
[RSET_UART0] = BCM_6345_UART0_BASE,
|
||||
[RSET_UART1] = BCM_6345_UART1_BASE,
|
||||
[RSET_GPIO] = BCM_6345_GPIO_BASE,
|
||||
[RSET_SPI] = BCM_6345_SPI_BASE,
|
||||
[RSET_UDC0] = BCM_6345_UDC0_BASE,
|
||||
@ -109,6 +111,7 @@ static const unsigned long bcm96348_regs_base[] = {
|
||||
[RSET_TIMER] = BCM_6348_TIMER_BASE,
|
||||
[RSET_WDT] = BCM_6348_WDT_BASE,
|
||||
[RSET_UART0] = BCM_6348_UART0_BASE,
|
||||
[RSET_UART1] = BCM_6348_UART1_BASE,
|
||||
[RSET_GPIO] = BCM_6348_GPIO_BASE,
|
||||
[RSET_SPI] = BCM_6348_SPI_BASE,
|
||||
[RSET_OHCI0] = BCM_6348_OHCI0_BASE,
|
||||
@ -150,6 +153,7 @@ static const unsigned long bcm96358_regs_base[] = {
|
||||
[RSET_TIMER] = BCM_6358_TIMER_BASE,
|
||||
[RSET_WDT] = BCM_6358_WDT_BASE,
|
||||
[RSET_UART0] = BCM_6358_UART0_BASE,
|
||||
[RSET_UART1] = BCM_6358_UART1_BASE,
|
||||
[RSET_GPIO] = BCM_6358_GPIO_BASE,
|
||||
[RSET_SPI] = BCM_6358_SPI_BASE,
|
||||
[RSET_OHCI0] = BCM_6358_OHCI0_BASE,
|
||||
@ -170,6 +174,7 @@ static const unsigned long bcm96358_regs_base[] = {
|
||||
static const int bcm96358_irqs[] = {
|
||||
[IRQ_TIMER] = BCM_6358_TIMER_IRQ,
|
||||
[IRQ_UART0] = BCM_6358_UART0_IRQ,
|
||||
[IRQ_UART1] = BCM_6358_UART1_IRQ,
|
||||
[IRQ_DSL] = BCM_6358_DSL_IRQ,
|
||||
[IRQ_ENET0] = BCM_6358_ENET0_IRQ,
|
||||
[IRQ_ENET1] = BCM_6358_ENET1_IRQ,
|
||||
|
@ -11,31 +11,65 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <bcm63xx_cpu.h>
|
||||
|
||||
static struct resource uart_resources[] = {
|
||||
static struct resource uart0_resources[] = {
|
||||
{
|
||||
.start = -1, /* filled at runtime */
|
||||
.end = -1, /* filled at runtime */
|
||||
/* start & end filled at runtime */
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = -1, /* filled at runtime */
|
||||
/* start filled at runtime */
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device bcm63xx_uart_device = {
|
||||
.name = "bcm63xx_uart",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(uart_resources),
|
||||
.resource = uart_resources,
|
||||
static struct resource uart1_resources[] = {
|
||||
{
|
||||
/* start & end filled at runtime */
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
/* start filled at runtime */
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
int __init bcm63xx_uart_register(void)
|
||||
static struct platform_device bcm63xx_uart_devices[] = {
|
||||
{
|
||||
.name = "bcm63xx_uart",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(uart0_resources),
|
||||
.resource = uart0_resources,
|
||||
},
|
||||
|
||||
{
|
||||
.name = "bcm63xx_uart",
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(uart1_resources),
|
||||
.resource = uart1_resources,
|
||||
}
|
||||
};
|
||||
|
||||
int __init bcm63xx_uart_register(unsigned int id)
|
||||
{
|
||||
uart_resources[0].start = bcm63xx_regset_address(RSET_UART0);
|
||||
uart_resources[0].end = uart_resources[0].start;
|
||||
uart_resources[0].end += RSET_UART_SIZE - 1;
|
||||
uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
|
||||
return platform_device_register(&bcm63xx_uart_device);
|
||||
if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
|
||||
return -ENODEV;
|
||||
|
||||
if (id == 1 && !BCMCPU_IS_6358())
|
||||
return -ENODEV;
|
||||
|
||||
if (id == 0) {
|
||||
uart0_resources[0].start = bcm63xx_regset_address(RSET_UART0);
|
||||
uart0_resources[0].end = uart0_resources[0].start +
|
||||
RSET_UART_SIZE - 1;
|
||||
uart0_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
|
||||
}
|
||||
|
||||
if (id == 1) {
|
||||
uart1_resources[0].start = bcm63xx_regset_address(RSET_UART1);
|
||||
uart1_resources[0].end = uart1_resources[0].start +
|
||||
RSET_UART_SIZE - 1;
|
||||
uart1_resources[1].start = bcm63xx_get_irq_number(IRQ_UART1);
|
||||
}
|
||||
|
||||
return platform_device_register(&bcm63xx_uart_devices[id]);
|
||||
}
|
||||
arch_initcall(bcm63xx_uart_register);
|
||||
|
@ -125,10 +125,10 @@ static struct gpio_chip bcm63xx_gpio_chip = {
|
||||
|
||||
int __init bcm63xx_gpio_init(void)
|
||||
{
|
||||
gpio_out_low = bcm_gpio_readl(GPIO_DATA_LO_REG);
|
||||
gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
|
||||
bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
|
||||
pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
|
||||
|
||||
return gpiochip_add(&bcm63xx_gpio_chip);
|
||||
}
|
||||
|
||||
arch_initcall(bcm63xx_gpio_init);
|
||||
|
@ -45,9 +45,6 @@ extern struct plat_smp_ops octeon_smp_ops;
|
||||
extern void pci_console_init(const char *arg);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CAVIUM_RESERVE32
|
||||
extern uint64_t octeon_reserve32_memory;
|
||||
#endif
|
||||
static unsigned long long MAX_MEMORY = 512ull << 20;
|
||||
|
||||
struct octeon_boot_descriptor *octeon_boot_desc_ptr;
|
||||
@ -186,54 +183,6 @@ void octeon_check_cpu_bist(void)
|
||||
write_octeon_c0_dcacheerr(0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
|
||||
/**
|
||||
* Called on every core to setup the wired tlb entry needed
|
||||
* if CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB is set.
|
||||
*
|
||||
*/
|
||||
static void octeon_hal_setup_per_cpu_reserved32(void *unused)
|
||||
{
|
||||
/*
|
||||
* The config has selected to wire the reserve32 memory for all
|
||||
* userspace applications. We need to put a wired TLB entry in for each
|
||||
* 512MB of reserve32 memory. We only handle double 256MB pages here,
|
||||
* so reserve32 must be multiple of 512MB.
|
||||
*/
|
||||
uint32_t size = CONFIG_CAVIUM_RESERVE32;
|
||||
uint32_t entrylo0 =
|
||||
0x7 | ((octeon_reserve32_memory & ((1ul << 40) - 1)) >> 6);
|
||||
uint32_t entrylo1 = entrylo0 + (256 << 14);
|
||||
uint32_t entryhi = (0x80000000UL - (CONFIG_CAVIUM_RESERVE32 << 20));
|
||||
while (size >= 512) {
|
||||
#if 0
|
||||
pr_info("CPU%d: Adding double wired TLB entry for 0x%lx\n",
|
||||
smp_processor_id(), entryhi);
|
||||
#endif
|
||||
add_wired_entry(entrylo0, entrylo1, entryhi, PM_256M);
|
||||
entrylo0 += 512 << 14;
|
||||
entrylo1 += 512 << 14;
|
||||
entryhi += 512 << 20;
|
||||
size -= 512;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB */
|
||||
|
||||
/**
|
||||
* Called to release the named block which was used to made sure
|
||||
* that nobody used the memory for something else during
|
||||
* init. Now we'll free it so userspace apps can use this
|
||||
* memory region with bootmem_alloc.
|
||||
*
|
||||
* This function is called only once from prom_free_prom_memory().
|
||||
*/
|
||||
void octeon_hal_setup_reserved32(void)
|
||||
{
|
||||
#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
|
||||
on_each_cpu(octeon_hal_setup_per_cpu_reserved32, NULL, 0, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Reboot Octeon
|
||||
*
|
||||
@ -294,18 +243,6 @@ static void octeon_halt(void)
|
||||
octeon_kill_core(NULL);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Platform time init specifics.
|
||||
* Returns
|
||||
*/
|
||||
void __init plat_time_init(void)
|
||||
{
|
||||
/* Nothing special here, but we are required to have one */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Handle all the error condition interrupts that might occur.
|
||||
*
|
||||
@ -502,25 +439,13 @@ void __init prom_init(void)
|
||||
* memory when it is getting memory from the
|
||||
* bootloader. Later, after the memory allocations are
|
||||
* complete, the reserve32 will be freed.
|
||||
*/
|
||||
#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
|
||||
if (CONFIG_CAVIUM_RESERVE32 & 0x1ff)
|
||||
pr_err("CAVIUM_RESERVE32 isn't a multiple of 512MB. "
|
||||
"This is required if CAVIUM_RESERVE32_USE_WIRED_TLB "
|
||||
"is set\n");
|
||||
else
|
||||
addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
|
||||
0, 0, 512 << 20,
|
||||
"CAVIUM_RESERVE32", 0);
|
||||
#else
|
||||
/*
|
||||
*
|
||||
* Allocate memory for RESERVED32 aligned on 2MB boundary. This
|
||||
* is in case we later use hugetlb entries with it.
|
||||
*/
|
||||
addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
|
||||
0, 0, 2 << 20,
|
||||
"CAVIUM_RESERVE32", 0);
|
||||
#endif
|
||||
if (addr < 0)
|
||||
pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
|
||||
else
|
||||
@ -817,9 +742,4 @@ void prom_free_prom_memory(void)
|
||||
panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This call is here so that it is performed after any TLB
|
||||
initializations. It needs to be after these in case the
|
||||
CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */
|
||||
octeon_hal_setup_reserved32();
|
||||
}
|
||||
|
@ -279,14 +279,6 @@ static void octeon_cpu_die(unsigned int cpu)
|
||||
uint32_t avail_coremask;
|
||||
struct cvmx_bootmem_named_block_desc *block_desc;
|
||||
|
||||
#ifdef CONFIG_CAVIUM_OCTEON_WATCHDOG
|
||||
/* Disable the watchdog */
|
||||
cvmx_ciu_wdogx_t ciu_wdog;
|
||||
ciu_wdog.u64 = cvmx_read_csr(CVMX_CIU_WDOGX(cpu));
|
||||
ciu_wdog.s.mode = 0;
|
||||
cvmx_write_csr(CVMX_CIU_WDOGX(cpu), ciu_wdog.u64);
|
||||
#endif
|
||||
|
||||
while (per_cpu(cpu_state, cpu) != CPU_DEAD)
|
||||
cpu_relax();
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -13,12 +13,14 @@
|
||||
#include <asm/siginfo.h>
|
||||
|
||||
struct mips_abi {
|
||||
int (* const setup_frame)(struct k_sigaction * ka,
|
||||
int (* const setup_frame)(void *sig_return, struct k_sigaction *ka,
|
||||
struct pt_regs *regs, int signr,
|
||||
sigset_t *set);
|
||||
int (* const setup_rt_frame)(struct k_sigaction * ka,
|
||||
const unsigned long signal_return_offset;
|
||||
int (* const setup_rt_frame)(void *sig_return, struct k_sigaction *ka,
|
||||
struct pt_regs *regs, int signr,
|
||||
sigset_t *set, siginfo_t *info);
|
||||
const unsigned long rt_signal_return_offset;
|
||||
const unsigned long restart;
|
||||
};
|
||||
|
||||
|
@ -310,6 +310,7 @@ do { \
|
||||
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
struct pt_regs;
|
||||
struct task_struct;
|
||||
|
||||
extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs);
|
||||
@ -367,4 +368,8 @@ extern const char *__elf_platform;
|
||||
#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
|
||||
#endif
|
||||
|
||||
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
|
||||
struct linux_binprm;
|
||||
extern int arch_setup_additional_pages(struct linux_binprm *bprm,
|
||||
int uses_interp);
|
||||
#endif /* _ASM_ELF_H */
|
||||
|
@ -41,7 +41,11 @@ struct mips_fpu_emulator_stats {
|
||||
DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
|
||||
|
||||
#define MIPS_FPU_EMU_INC_STATS(M) \
|
||||
cpu_local_wrap(__local_inc(&__get_cpu_var(fpuemustats).M))
|
||||
do { \
|
||||
preempt_disable(); \
|
||||
__local_inc(&__get_cpu_var(fpuemustats).M); \
|
||||
preempt_enable(); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
|
||||
|
@ -85,6 +85,7 @@ enum bcm63xx_regs_set {
|
||||
RSET_TIMER,
|
||||
RSET_WDT,
|
||||
RSET_UART0,
|
||||
RSET_UART1,
|
||||
RSET_GPIO,
|
||||
RSET_SPI,
|
||||
RSET_UDC0,
|
||||
@ -123,6 +124,7 @@ enum bcm63xx_regs_set {
|
||||
#define BCM_6338_TIMER_BASE (0xfffe0200)
|
||||
#define BCM_6338_WDT_BASE (0xfffe021c)
|
||||
#define BCM_6338_UART0_BASE (0xfffe0300)
|
||||
#define BCM_6338_UART1_BASE (0xdeadbeef)
|
||||
#define BCM_6338_GPIO_BASE (0xfffe0400)
|
||||
#define BCM_6338_SPI_BASE (0xfffe0c00)
|
||||
#define BCM_6338_UDC0_BASE (0xdeadbeef)
|
||||
@ -153,6 +155,7 @@ enum bcm63xx_regs_set {
|
||||
#define BCM_6345_TIMER_BASE (0xfffe0200)
|
||||
#define BCM_6345_WDT_BASE (0xfffe021c)
|
||||
#define BCM_6345_UART0_BASE (0xfffe0300)
|
||||
#define BCM_6345_UART1_BASE (0xdeadbeef)
|
||||
#define BCM_6345_GPIO_BASE (0xfffe0400)
|
||||
#define BCM_6345_SPI_BASE (0xdeadbeef)
|
||||
#define BCM_6345_UDC0_BASE (0xdeadbeef)
|
||||
@ -182,6 +185,7 @@ enum bcm63xx_regs_set {
|
||||
#define BCM_6348_TIMER_BASE (0xfffe0200)
|
||||
#define BCM_6348_WDT_BASE (0xfffe021c)
|
||||
#define BCM_6348_UART0_BASE (0xfffe0300)
|
||||
#define BCM_6348_UART1_BASE (0xdeadbeef)
|
||||
#define BCM_6348_GPIO_BASE (0xfffe0400)
|
||||
#define BCM_6348_SPI_BASE (0xfffe0c00)
|
||||
#define BCM_6348_UDC0_BASE (0xfffe1000)
|
||||
@ -208,6 +212,7 @@ enum bcm63xx_regs_set {
|
||||
#define BCM_6358_TIMER_BASE (0xfffe0040)
|
||||
#define BCM_6358_WDT_BASE (0xfffe005c)
|
||||
#define BCM_6358_UART0_BASE (0xfffe0100)
|
||||
#define BCM_6358_UART1_BASE (0xfffe0120)
|
||||
#define BCM_6358_GPIO_BASE (0xfffe0080)
|
||||
#define BCM_6358_SPI_BASE (0xdeadbeef)
|
||||
#define BCM_6358_UDC0_BASE (0xfffe0800)
|
||||
@ -246,6 +251,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
|
||||
return BCM_6338_WDT_BASE;
|
||||
case RSET_UART0:
|
||||
return BCM_6338_UART0_BASE;
|
||||
case RSET_UART1:
|
||||
return BCM_6338_UART1_BASE;
|
||||
case RSET_GPIO:
|
||||
return BCM_6338_GPIO_BASE;
|
||||
case RSET_SPI:
|
||||
@ -292,6 +299,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
|
||||
return BCM_6345_WDT_BASE;
|
||||
case RSET_UART0:
|
||||
return BCM_6345_UART0_BASE;
|
||||
case RSET_UART1:
|
||||
return BCM_6345_UART1_BASE;
|
||||
case RSET_GPIO:
|
||||
return BCM_6345_GPIO_BASE;
|
||||
case RSET_SPI:
|
||||
@ -338,6 +347,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
|
||||
return BCM_6348_WDT_BASE;
|
||||
case RSET_UART0:
|
||||
return BCM_6348_UART0_BASE;
|
||||
case RSET_UART1:
|
||||
return BCM_6348_UART1_BASE;
|
||||
case RSET_GPIO:
|
||||
return BCM_6348_GPIO_BASE;
|
||||
case RSET_SPI:
|
||||
@ -384,6 +395,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
|
||||
return BCM_6358_WDT_BASE;
|
||||
case RSET_UART0:
|
||||
return BCM_6358_UART0_BASE;
|
||||
case RSET_UART1:
|
||||
return BCM_6358_UART1_BASE;
|
||||
case RSET_GPIO:
|
||||
return BCM_6358_GPIO_BASE;
|
||||
case RSET_SPI:
|
||||
@ -429,6 +442,7 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
|
||||
enum bcm63xx_irq {
|
||||
IRQ_TIMER = 0,
|
||||
IRQ_UART0,
|
||||
IRQ_UART1,
|
||||
IRQ_DSL,
|
||||
IRQ_ENET0,
|
||||
IRQ_ENET1,
|
||||
@ -510,6 +524,7 @@ enum bcm63xx_irq {
|
||||
*/
|
||||
#define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
|
||||
#define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
|
||||
#define BCM_6358_UART1_IRQ (IRQ_INTERNAL_BASE + 3)
|
||||
#define BCM_6358_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5)
|
||||
#define BCM_6358_ENET1_IRQ (IRQ_INTERNAL_BASE + 6)
|
||||
#define BCM_6358_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
|
||||
|
6
arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
Normal file
6
arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef BCM63XX_DEV_UART_H_
|
||||
#define BCM63XX_DEV_UART_H_
|
||||
|
||||
int bcm63xx_uart_register(unsigned int id);
|
||||
|
||||
#endif /* BCM63XX_DEV_UART_H_ */
|
@ -10,6 +10,10 @@ static inline unsigned long bcm63xx_gpio_count(void)
|
||||
switch (bcm63xx_get_cpu_id()) {
|
||||
case BCM6358_CPU_ID:
|
||||
return 40;
|
||||
case BCM6338_CPU_ID:
|
||||
return 8;
|
||||
case BCM6345_CPU_ID:
|
||||
return 16;
|
||||
case BCM6348_CPU_ID:
|
||||
default:
|
||||
return 37;
|
||||
|
@ -45,6 +45,8 @@ struct board_info {
|
||||
unsigned int has_ohci0:1;
|
||||
unsigned int has_ehci0:1;
|
||||
unsigned int has_dsp:1;
|
||||
unsigned int has_uart0:1;
|
||||
unsigned int has_uart1:1;
|
||||
|
||||
/* ethernet config */
|
||||
struct bcm63xx_enet_platform_data enet0;
|
||||
|
@ -24,7 +24,7 @@
|
||||
#define cpu_has_smartmips 0
|
||||
#define cpu_has_vtag_icache 0
|
||||
|
||||
#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCMCPU_IS_6348) || defined(CONFIG_CPU_IS_6338) || defined(CONFIG_CPU_IS_BCM6345))
|
||||
#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338))
|
||||
#define cpu_has_dc_aliases 0
|
||||
#endif
|
||||
|
||||
|
@ -16,7 +16,11 @@
|
||||
#if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \
|
||||
defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
|
||||
|
||||
#define BCM1250_M3_WAR 1
|
||||
#ifndef __ASSEMBLY__
|
||||
extern int sb1250_m3_workaround_needed(void);
|
||||
#endif
|
||||
|
||||
#define BCM1250_M3_WAR sb1250_m3_workaround_needed()
|
||||
#define SIBYTE_1956_WAR 1
|
||||
|
||||
#else
|
||||
|
@ -1,6 +1,9 @@
|
||||
#ifndef __ASM_MMU_H
|
||||
#define __ASM_MMU_H
|
||||
|
||||
typedef unsigned long mm_context_t[NR_CPUS];
|
||||
typedef struct {
|
||||
unsigned long asid[NR_CPUS];
|
||||
void *vdso;
|
||||
} mm_context_t;
|
||||
|
||||
#endif /* __ASM_MMU_H */
|
||||
|
@ -104,7 +104,7 @@ extern unsigned long smtc_asid_mask;
|
||||
|
||||
#endif
|
||||
|
||||
#define cpu_context(cpu, mm) ((mm)->context[cpu])
|
||||
#define cpu_context(cpu, mm) ((mm)->context.asid[cpu])
|
||||
#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK)
|
||||
#define asid_cache(cpu) (cpu_data[cpu].asid_cache)
|
||||
|
||||
|
@ -188,8 +188,10 @@ typedef struct { unsigned long pgprot; } pgprot_t;
|
||||
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
|
||||
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
|
||||
|
||||
#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE)
|
||||
#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET)
|
||||
#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE + \
|
||||
PHYS_OFFSET)
|
||||
#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET - \
|
||||
PHYS_OFFSET)
|
||||
|
||||
#include <asm-generic/memory_model.h>
|
||||
#include <asm-generic/getorder.h>
|
||||
|
@ -33,13 +33,19 @@ extern void (*cpu_wait)(void);
|
||||
|
||||
extern unsigned int vced_count, vcei_count;
|
||||
|
||||
/*
|
||||
* A special page (the vdso) is mapped into all processes at the very
|
||||
* top of the virtual memory space.
|
||||
*/
|
||||
#define SPECIAL_PAGES_SIZE PAGE_SIZE
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
/*
|
||||
* User space process size: 2GB. This is hardcoded into a few places,
|
||||
* so don't change it unless you know what you are doing.
|
||||
*/
|
||||
#define TASK_SIZE 0x7fff8000UL
|
||||
#define STACK_TOP TASK_SIZE
|
||||
#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
|
||||
|
||||
/*
|
||||
* This decides where the kernel will search for a free chunk of vm
|
||||
@ -59,7 +65,8 @@ extern unsigned int vced_count, vcei_count;
|
||||
#define TASK_SIZE32 0x7fff8000UL
|
||||
#define TASK_SIZE 0x10000000000UL
|
||||
#define STACK_TOP \
|
||||
(test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
|
||||
(((test_thread_flag(TIF_32BIT_ADDR) ? \
|
||||
TASK_SIZE32 : TASK_SIZE) & PAGE_MASK) - SPECIAL_PAGES_SIZE)
|
||||
|
||||
/*
|
||||
* This decides where the kernel will search for a free chunk of vm
|
||||
|
@ -121,6 +121,25 @@
|
||||
.endm
|
||||
#else
|
||||
.macro get_saved_sp /* Uniprocessor variation */
|
||||
#ifdef CONFIG_CPU_LOONGSON2F
|
||||
/*
|
||||
* Clear BTB (branch target buffer), forbid RAS (return address
|
||||
* stack) to workaround the Out-of-order Issue in Loongson2F
|
||||
* via its diagnostic register.
|
||||
*/
|
||||
move k0, ra
|
||||
jal 1f
|
||||
nop
|
||||
1: jal 1f
|
||||
nop
|
||||
1: jal 1f
|
||||
nop
|
||||
1: jal 1f
|
||||
nop
|
||||
1: move ra, k0
|
||||
li k0, 3
|
||||
mtc0 k0, $22
|
||||
#endif /* CONFIG_CPU_LOONGSON2F */
|
||||
#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
|
||||
lui k1, %hi(kernelsp)
|
||||
#else
|
||||
|
@ -84,6 +84,7 @@ Ip_u2s3u1(_lw);
|
||||
Ip_u1u2u3(_mfc0);
|
||||
Ip_u1u2u3(_mtc0);
|
||||
Ip_u2u1u3(_ori);
|
||||
Ip_u3u1u2(_or);
|
||||
Ip_u2s3u1(_pref);
|
||||
Ip_0(_rfe);
|
||||
Ip_u2s3u1(_sc);
|
||||
@ -102,6 +103,7 @@ Ip_0(_tlbwr);
|
||||
Ip_u3u1u2(_xor);
|
||||
Ip_u2u1u3(_xori);
|
||||
Ip_u2u1msbu3(_dins);
|
||||
Ip_u1(_syscall);
|
||||
|
||||
/* Handle labels. */
|
||||
struct uasm_label {
|
||||
|
29
arch/mips/include/asm/vdso.h
Normal file
29
arch/mips/include/asm/vdso.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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) 2009 Cavium Networks
|
||||
*/
|
||||
|
||||
#ifndef __ASM_VDSO_H
|
||||
#define __ASM_VDSO_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
struct mips_vdso {
|
||||
u32 signal_trampoline[2];
|
||||
u32 rt_signal_trampoline[2];
|
||||
};
|
||||
#else /* !CONFIG_32BIT */
|
||||
struct mips_vdso {
|
||||
u32 o32_signal_trampoline[2];
|
||||
u32 o32_rt_signal_trampoline[2];
|
||||
u32 rt_signal_trampoline[2];
|
||||
u32 n32_rt_signal_trampoline[2];
|
||||
};
|
||||
#endif /* CONFIG_32BIT */
|
||||
|
||||
#endif /* __ASM_VDSO_H */
|
@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds
|
||||
|
||||
obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
|
||||
ptrace.o reset.o setup.o signal.o syscall.o \
|
||||
time.o topology.o traps.o unaligned.o watch.o
|
||||
time.o topology.o traps.o unaligned.o watch.o vdso.o
|
||||
|
||||
ifdef CONFIG_FUNCTION_TRACER
|
||||
CFLAGS_REMOVE_ftrace.o = -pg
|
||||
|
@ -164,3 +164,7 @@ void loongson2_cpu_wait(void)
|
||||
spin_unlock_irqrestore(&loongson2_wait_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
|
||||
|
||||
MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
|
||||
MODULE_DESCRIPTION("cpufreq driver for Loongson 2F");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -63,8 +63,13 @@ void __noreturn cpu_idle(void)
|
||||
|
||||
smtc_idle_loop_hook();
|
||||
#endif
|
||||
if (cpu_wait)
|
||||
|
||||
if (cpu_wait) {
|
||||
/* Don't trace irqs off for idle */
|
||||
stop_critical_timings();
|
||||
(*cpu_wait)();
|
||||
start_critical_timings();
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&
|
||||
|
@ -26,11 +26,6 @@
|
||||
*/
|
||||
extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
|
||||
size_t frame_size);
|
||||
/*
|
||||
* install trampoline code to get back from the sig handler
|
||||
*/
|
||||
extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);
|
||||
|
||||
/* Check and clear pending FPU exceptions in saved CSR */
|
||||
extern int fpcsr_pending(unsigned int __user *fpcsr);
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <asm/ucontext.h>
|
||||
#include <asm/cpu-features.h>
|
||||
#include <asm/war.h>
|
||||
#include <asm/vdso.h>
|
||||
|
||||
#include "signal-common.h"
|
||||
|
||||
@ -44,47 +45,20 @@ extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
|
||||
extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
|
||||
extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
|
||||
|
||||
/*
|
||||
* Horribly complicated - with the bloody RM9000 workarounds enabled
|
||||
* the signal trampolines is moving to the end of the structure so we can
|
||||
* increase the alignment without breaking software compatibility.
|
||||
*/
|
||||
#if ICACHE_REFILLS_WORKAROUND_WAR == 0
|
||||
|
||||
struct sigframe {
|
||||
u32 sf_ass[4]; /* argument save space for o32 */
|
||||
u32 sf_code[2]; /* signal trampoline */
|
||||
u32 sf_pad[2]; /* Was: signal trampoline */
|
||||
struct sigcontext sf_sc;
|
||||
sigset_t sf_mask;
|
||||
};
|
||||
|
||||
struct rt_sigframe {
|
||||
u32 rs_ass[4]; /* argument save space for o32 */
|
||||
u32 rs_code[2]; /* signal trampoline */
|
||||
u32 rs_pad[2]; /* Was: signal trampoline */
|
||||
struct siginfo rs_info;
|
||||
struct ucontext rs_uc;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
struct sigframe {
|
||||
u32 sf_ass[4]; /* argument save space for o32 */
|
||||
u32 sf_pad[2];
|
||||
struct sigcontext sf_sc; /* hw context */
|
||||
sigset_t sf_mask;
|
||||
u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
|
||||
};
|
||||
|
||||
struct rt_sigframe {
|
||||
u32 rs_ass[4]; /* argument save space for o32 */
|
||||
u32 rs_pad[2];
|
||||
struct siginfo rs_info;
|
||||
struct ucontext rs_uc;
|
||||
u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Helper routines
|
||||
*/
|
||||
@ -266,32 +240,6 @@ void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
|
||||
return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
|
||||
}
|
||||
|
||||
int install_sigtramp(unsigned int __user *tramp, unsigned int syscall)
|
||||
{
|
||||
int err;
|
||||
|
||||
/*
|
||||
* Set up the return code ...
|
||||
*
|
||||
* li v0, __NR__foo_sigreturn
|
||||
* syscall
|
||||
*/
|
||||
|
||||
err = __put_user(0x24020000 + syscall, tramp + 0);
|
||||
err |= __put_user(0x0000000c , tramp + 1);
|
||||
if (ICACHE_REFILLS_WORKAROUND_WAR) {
|
||||
err |= __put_user(0, tramp + 2);
|
||||
err |= __put_user(0, tramp + 3);
|
||||
err |= __put_user(0, tramp + 4);
|
||||
err |= __put_user(0, tramp + 5);
|
||||
err |= __put_user(0, tramp + 6);
|
||||
err |= __put_user(0, tramp + 7);
|
||||
}
|
||||
flush_cache_sigtramp((unsigned long) tramp);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Atomically swap in the new signal mask, and wait for a signal.
|
||||
*/
|
||||
@ -484,8 +432,8 @@ badframe:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TRAD_SIGNALS
|
||||
static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
int signr, sigset_t *set)
|
||||
static int setup_frame(void *sig_return, struct k_sigaction *ka,
|
||||
struct pt_regs *regs, int signr, sigset_t *set)
|
||||
{
|
||||
struct sigframe __user *frame;
|
||||
int err = 0;
|
||||
@ -494,8 +442,6 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||
goto give_sigsegv;
|
||||
|
||||
err |= install_sigtramp(frame->sf_code, __NR_sigreturn);
|
||||
|
||||
err |= setup_sigcontext(regs, &frame->sf_sc);
|
||||
err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
|
||||
if (err)
|
||||
@ -515,7 +461,7 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
regs->regs[ 5] = 0;
|
||||
regs->regs[ 6] = (unsigned long) &frame->sf_sc;
|
||||
regs->regs[29] = (unsigned long) frame;
|
||||
regs->regs[31] = (unsigned long) frame->sf_code;
|
||||
regs->regs[31] = (unsigned long) sig_return;
|
||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||
|
||||
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||
@ -529,8 +475,9 @@ give_sigsegv:
|
||||
}
|
||||
#endif
|
||||
|
||||
static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
int signr, sigset_t *set, siginfo_t *info)
|
||||
static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
|
||||
struct pt_regs *regs, int signr, sigset_t *set,
|
||||
siginfo_t *info)
|
||||
{
|
||||
struct rt_sigframe __user *frame;
|
||||
int err = 0;
|
||||
@ -539,8 +486,6 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||
goto give_sigsegv;
|
||||
|
||||
err |= install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
|
||||
|
||||
/* Create siginfo. */
|
||||
err |= copy_siginfo_to_user(&frame->rs_info, info);
|
||||
|
||||
@ -573,7 +518,7 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
regs->regs[ 5] = (unsigned long) &frame->rs_info;
|
||||
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
|
||||
regs->regs[29] = (unsigned long) frame;
|
||||
regs->regs[31] = (unsigned long) frame->rs_code;
|
||||
regs->regs[31] = (unsigned long) sig_return;
|
||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||
|
||||
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||
@ -590,8 +535,11 @@ give_sigsegv:
|
||||
struct mips_abi mips_abi = {
|
||||
#ifdef CONFIG_TRAD_SIGNALS
|
||||
.setup_frame = setup_frame,
|
||||
.signal_return_offset = offsetof(struct mips_vdso, signal_trampoline),
|
||||
#endif
|
||||
.setup_rt_frame = setup_rt_frame,
|
||||
.rt_signal_return_offset =
|
||||
offsetof(struct mips_vdso, rt_signal_trampoline),
|
||||
.restart = __NR_restart_syscall
|
||||
};
|
||||
|
||||
@ -599,6 +547,8 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
|
||||
struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
|
||||
{
|
||||
int ret;
|
||||
struct mips_abi *abi = current->thread.abi;
|
||||
void *vdso = current->mm->context.vdso;
|
||||
|
||||
switch(regs->regs[0]) {
|
||||
case ERESTART_RESTARTBLOCK:
|
||||
@ -619,9 +569,11 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
|
||||
regs->regs[0] = 0; /* Don't deal with this again. */
|
||||
|
||||
if (sig_uses_siginfo(ka))
|
||||
ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
|
||||
ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
|
||||
ka, regs, sig, oldset, info);
|
||||
else
|
||||
ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
|
||||
ret = abi->setup_frame(vdso + abi->signal_return_offset,
|
||||
ka, regs, sig, oldset);
|
||||
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask);
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <asm/system.h>
|
||||
#include <asm/fpu.h>
|
||||
#include <asm/war.h>
|
||||
#include <asm/vdso.h>
|
||||
|
||||
#include "signal-common.h"
|
||||
|
||||
@ -47,8 +48,6 @@ extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user
|
||||
/*
|
||||
* Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
|
||||
*/
|
||||
#define __NR_O32_sigreturn 4119
|
||||
#define __NR_O32_rt_sigreturn 4193
|
||||
#define __NR_O32_restart_syscall 4253
|
||||
|
||||
/* 32-bit compatibility types */
|
||||
@ -77,47 +76,20 @@ struct ucontext32 {
|
||||
compat_sigset_t uc_sigmask; /* mask last for extensibility */
|
||||
};
|
||||
|
||||
/*
|
||||
* Horribly complicated - with the bloody RM9000 workarounds enabled
|
||||
* the signal trampolines is moving to the end of the structure so we can
|
||||
* increase the alignment without breaking software compatibility.
|
||||
*/
|
||||
#if ICACHE_REFILLS_WORKAROUND_WAR == 0
|
||||
|
||||
struct sigframe32 {
|
||||
u32 sf_ass[4]; /* argument save space for o32 */
|
||||
u32 sf_code[2]; /* signal trampoline */
|
||||
u32 sf_pad[2]; /* Was: signal trampoline */
|
||||
struct sigcontext32 sf_sc;
|
||||
compat_sigset_t sf_mask;
|
||||
};
|
||||
|
||||
struct rt_sigframe32 {
|
||||
u32 rs_ass[4]; /* argument save space for o32 */
|
||||
u32 rs_code[2]; /* signal trampoline */
|
||||
u32 rs_pad[2]; /* Was: signal trampoline */
|
||||
compat_siginfo_t rs_info;
|
||||
struct ucontext32 rs_uc;
|
||||
};
|
||||
|
||||
#else /* ICACHE_REFILLS_WORKAROUND_WAR */
|
||||
|
||||
struct sigframe32 {
|
||||
u32 sf_ass[4]; /* argument save space for o32 */
|
||||
u32 sf_pad[2];
|
||||
struct sigcontext32 sf_sc; /* hw context */
|
||||
compat_sigset_t sf_mask;
|
||||
u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
|
||||
};
|
||||
|
||||
struct rt_sigframe32 {
|
||||
u32 rs_ass[4]; /* argument save space for o32 */
|
||||
u32 rs_pad[2];
|
||||
compat_siginfo_t rs_info;
|
||||
struct ucontext32 rs_uc;
|
||||
u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */
|
||||
};
|
||||
|
||||
#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
|
||||
|
||||
/*
|
||||
* sigcontext handlers
|
||||
*/
|
||||
@ -598,8 +570,8 @@ badframe:
|
||||
force_sig(SIGSEGV, current);
|
||||
}
|
||||
|
||||
static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
int signr, sigset_t *set)
|
||||
static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
|
||||
struct pt_regs *regs, int signr, sigset_t *set)
|
||||
{
|
||||
struct sigframe32 __user *frame;
|
||||
int err = 0;
|
||||
@ -608,8 +580,6 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||
goto give_sigsegv;
|
||||
|
||||
err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
|
||||
|
||||
err |= setup_sigcontext32(regs, &frame->sf_sc);
|
||||
err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
|
||||
|
||||
@ -630,7 +600,7 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
regs->regs[ 5] = 0;
|
||||
regs->regs[ 6] = (unsigned long) &frame->sf_sc;
|
||||
regs->regs[29] = (unsigned long) frame;
|
||||
regs->regs[31] = (unsigned long) frame->sf_code;
|
||||
regs->regs[31] = (unsigned long) sig_return;
|
||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||
|
||||
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||
@ -644,8 +614,9 @@ give_sigsegv:
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
int signr, sigset_t *set, siginfo_t *info)
|
||||
static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
|
||||
struct pt_regs *regs, int signr, sigset_t *set,
|
||||
siginfo_t *info)
|
||||
{
|
||||
struct rt_sigframe32 __user *frame;
|
||||
int err = 0;
|
||||
@ -655,8 +626,6 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||
goto give_sigsegv;
|
||||
|
||||
err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
|
||||
|
||||
/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
|
||||
err |= copy_siginfo_to_user32(&frame->rs_info, info);
|
||||
|
||||
@ -690,7 +659,7 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||
regs->regs[ 5] = (unsigned long) &frame->rs_info;
|
||||
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
|
||||
regs->regs[29] = (unsigned long) frame;
|
||||
regs->regs[31] = (unsigned long) frame->rs_code;
|
||||
regs->regs[31] = (unsigned long) sig_return;
|
||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||
|
||||
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||
@ -709,7 +678,11 @@ give_sigsegv:
|
||||
*/
|
||||
struct mips_abi mips_abi_32 = {
|
||||
.setup_frame = setup_frame_32,
|
||||
.signal_return_offset =
|
||||
offsetof(struct mips_vdso, o32_signal_trampoline),
|
||||
.setup_rt_frame = setup_rt_frame_32,
|
||||
.rt_signal_return_offset =
|
||||
offsetof(struct mips_vdso, o32_rt_signal_trampoline),
|
||||
.restart = __NR_O32_restart_syscall
|
||||
};
|
||||
|
||||
|
@ -39,13 +39,13 @@
|
||||
#include <asm/fpu.h>
|
||||
#include <asm/cpu-features.h>
|
||||
#include <asm/war.h>
|
||||
#include <asm/vdso.h>
|
||||
|
||||
#include "signal-common.h"
|
||||
|
||||
/*
|
||||
* Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
|
||||
*/
|
||||
#define __NR_N32_rt_sigreturn 6211
|
||||
#define __NR_N32_restart_syscall 6214
|
||||
|
||||
extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
|
||||
@ -67,27 +67,13 @@ struct ucontextn32 {
|
||||
compat_sigset_t uc_sigmask; /* mask last for extensibility */
|
||||
};
|
||||
|
||||
#if ICACHE_REFILLS_WORKAROUND_WAR == 0
|
||||
|
||||
struct rt_sigframe_n32 {
|
||||
u32 rs_ass[4]; /* argument save space for o32 */
|
||||
u32 rs_code[2]; /* signal trampoline */
|
||||
u32 rs_pad[2]; /* Was: signal trampoline */
|
||||
struct compat_siginfo rs_info;
|
||||
struct ucontextn32 rs_uc;
|
||||
};
|
||||
|
||||
#else /* ICACHE_REFILLS_WORKAROUND_WAR */
|
||||
|
||||
struct rt_sigframe_n32 {
|
||||
u32 rs_ass[4]; /* argument save space for o32 */
|
||||
u32 rs_pad[2];
|
||||
struct compat_siginfo rs_info;
|
||||
struct ucontextn32 rs_uc;
|
||||
u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
|
||||
};
|
||||
|
||||
#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
|
||||
|
||||
extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
|
||||
|
||||
asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||
@ -173,7 +159,7 @@ badframe:
|
||||
force_sig(SIGSEGV, current);
|
||||
}
|
||||
|
||||
static int setup_rt_frame_n32(struct k_sigaction * ka,
|
||||
static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
|
||||
struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
|
||||
{
|
||||
struct rt_sigframe_n32 __user *frame;
|
||||
@ -184,8 +170,6 @@ static int setup_rt_frame_n32(struct k_sigaction * ka,
|
||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||
goto give_sigsegv;
|
||||
|
||||
install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);
|
||||
|
||||
/* Create siginfo. */
|
||||
err |= copy_siginfo_to_user32(&frame->rs_info, info);
|
||||
|
||||
@ -219,7 +203,7 @@ static int setup_rt_frame_n32(struct k_sigaction * ka,
|
||||
regs->regs[ 5] = (unsigned long) &frame->rs_info;
|
||||
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
|
||||
regs->regs[29] = (unsigned long) frame;
|
||||
regs->regs[31] = (unsigned long) frame->rs_code;
|
||||
regs->regs[31] = (unsigned long) sig_return;
|
||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||
|
||||
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||
@ -235,5 +219,7 @@ give_sigsegv:
|
||||
|
||||
struct mips_abi mips_abi_n32 = {
|
||||
.setup_rt_frame = setup_rt_frame_n32,
|
||||
.rt_signal_return_offset =
|
||||
offsetof(struct mips_vdso, n32_rt_signal_trampoline),
|
||||
.restart = __NR_N32_restart_syscall
|
||||
};
|
||||
|
@ -182,7 +182,7 @@ static int vpemask[2][8] = {
|
||||
{0, 0, 0, 0, 0, 0, 0, 1}
|
||||
};
|
||||
int tcnoprog[NR_CPUS];
|
||||
static atomic_t idle_hook_initialized = {0};
|
||||
static atomic_t idle_hook_initialized = ATOMIC_INIT(0);
|
||||
static int clock_hang_reported[NR_CPUS];
|
||||
|
||||
#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
|
||||
|
@ -79,7 +79,11 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
||||
int do_color_align;
|
||||
unsigned long task_size;
|
||||
|
||||
task_size = STACK_TOP;
|
||||
#ifdef CONFIG_32BIT
|
||||
task_size = TASK_SIZE;
|
||||
#else /* Must be CONFIG_64BIT*/
|
||||
task_size = test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE;
|
||||
#endif
|
||||
|
||||
if (len > task_size)
|
||||
return -ENOMEM;
|
||||
|
@ -1599,7 +1599,7 @@ void __init trap_init(void)
|
||||
ebase = (unsigned long)
|
||||
__alloc_bootmem(size, 1 << fls(size), 0);
|
||||
} else {
|
||||
ebase = CAC_BASE;
|
||||
ebase = CKSEG0;
|
||||
if (cpu_has_mips_r2)
|
||||
ebase += (read_c0_ebase() & 0x3ffff000);
|
||||
}
|
||||
|
112
arch/mips/kernel/vdso.c
Normal file
112
arch/mips/kernel/vdso.c
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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) 2009, 2010 Cavium Networks, Inc.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/unistd.h>
|
||||
|
||||
#include <asm/vdso.h>
|
||||
#include <asm/uasm.h>
|
||||
|
||||
/*
|
||||
* Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
|
||||
*/
|
||||
#define __NR_O32_sigreturn 4119
|
||||
#define __NR_O32_rt_sigreturn 4193
|
||||
#define __NR_N32_rt_sigreturn 6211
|
||||
|
||||
static struct page *vdso_page;
|
||||
|
||||
static void __init install_trampoline(u32 *tramp, unsigned int sigreturn)
|
||||
{
|
||||
uasm_i_addiu(&tramp, 2, 0, sigreturn); /* li v0, sigreturn */
|
||||
uasm_i_syscall(&tramp, 0);
|
||||
}
|
||||
|
||||
static int __init init_vdso(void)
|
||||
{
|
||||
struct mips_vdso *vdso;
|
||||
|
||||
vdso_page = alloc_page(GFP_KERNEL);
|
||||
if (!vdso_page)
|
||||
panic("Cannot allocate vdso");
|
||||
|
||||
vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL);
|
||||
if (!vdso)
|
||||
panic("Cannot map vdso");
|
||||
clear_page(vdso);
|
||||
|
||||
install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn);
|
||||
#ifdef CONFIG_32BIT
|
||||
install_trampoline(vdso->signal_trampoline, __NR_sigreturn);
|
||||
#else
|
||||
install_trampoline(vdso->n32_rt_signal_trampoline,
|
||||
__NR_N32_rt_sigreturn);
|
||||
install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn);
|
||||
install_trampoline(vdso->o32_rt_signal_trampoline,
|
||||
__NR_O32_rt_sigreturn);
|
||||
#endif
|
||||
|
||||
vunmap(vdso);
|
||||
|
||||
pr_notice("init_vdso successfull\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
device_initcall(init_vdso);
|
||||
|
||||
static unsigned long vdso_addr(unsigned long start)
|
||||
{
|
||||
return STACK_TOP;
|
||||
}
|
||||
|
||||
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
||||
{
|
||||
int ret;
|
||||
unsigned long addr;
|
||||
struct mm_struct *mm = current->mm;
|
||||
|
||||
down_write(&mm->mmap_sem);
|
||||
|
||||
addr = vdso_addr(mm->start_stack);
|
||||
|
||||
addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0);
|
||||
if (IS_ERR_VALUE(addr)) {
|
||||
ret = addr;
|
||||
goto up_fail;
|
||||
}
|
||||
|
||||
ret = install_special_mapping(mm, addr, PAGE_SIZE,
|
||||
VM_READ|VM_EXEC|
|
||||
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
|
||||
VM_ALWAYSDUMP,
|
||||
&vdso_page);
|
||||
|
||||
if (ret)
|
||||
goto up_fail;
|
||||
|
||||
mm->context.vdso = (void *)addr;
|
||||
|
||||
up_fail:
|
||||
up_write(&mm->mmap_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *arch_vma_name(struct vm_area_struct *vma)
|
||||
{
|
||||
if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
|
||||
return "[vdso]";
|
||||
return NULL;
|
||||
}
|
@ -41,7 +41,7 @@ EXPORT_SYMBOL(__delay);
|
||||
|
||||
void __udelay(unsigned long us)
|
||||
{
|
||||
unsigned int lpj = current_cpu_data.udelay_val;
|
||||
unsigned int lpj = raw_current_cpu_data.udelay_val;
|
||||
|
||||
__delay((us * 0x000010c7ull * HZ * lpj) >> 32);
|
||||
}
|
||||
@ -49,7 +49,7 @@ EXPORT_SYMBOL(__udelay);
|
||||
|
||||
void __ndelay(unsigned long ns)
|
||||
{
|
||||
unsigned int lpj = current_cpu_data.udelay_val;
|
||||
unsigned int lpj = raw_current_cpu_data.udelay_val;
|
||||
|
||||
__delay((ns * 0x00000005ull * HZ * lpj) >> 32);
|
||||
}
|
||||
|
@ -17,8 +17,7 @@ struct DWstruct {
|
||||
#error I feel sick.
|
||||
#endif
|
||||
|
||||
typedef union
|
||||
{
|
||||
typedef union {
|
||||
struct DWstruct s;
|
||||
long long ll;
|
||||
} DWunion;
|
||||
|
@ -133,7 +133,7 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address,
|
||||
}
|
||||
|
||||
unsigned long _page_cachable_default;
|
||||
EXPORT_SYMBOL_GPL(_page_cachable_default);
|
||||
EXPORT_SYMBOL(_page_cachable_default);
|
||||
|
||||
static inline void setup_protection_map(void)
|
||||
{
|
||||
|
@ -788,10 +788,15 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
|
||||
* create the plain linear handler
|
||||
*/
|
||||
if (bcm1250_m3_war()) {
|
||||
UASM_i_MFC0(&p, K0, C0_BADVADDR);
|
||||
UASM_i_MFC0(&p, K1, C0_ENTRYHI);
|
||||
unsigned int segbits = 44;
|
||||
|
||||
uasm_i_dmfc0(&p, K0, C0_BADVADDR);
|
||||
uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
|
||||
uasm_i_xor(&p, K0, K0, K1);
|
||||
UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
|
||||
uasm_i_dsrl32(&p, K1, K0, 62 - 32);
|
||||
uasm_i_dsrl(&p, K0, K0, 12 + 1);
|
||||
uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32);
|
||||
uasm_i_or(&p, K0, K0, K1);
|
||||
uasm_il_bnez(&p, &r, K0, label_leave);
|
||||
/* No need for uasm_i_nop */
|
||||
}
|
||||
@ -1312,10 +1317,15 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
|
||||
memset(relocs, 0, sizeof(relocs));
|
||||
|
||||
if (bcm1250_m3_war()) {
|
||||
UASM_i_MFC0(&p, K0, C0_BADVADDR);
|
||||
UASM_i_MFC0(&p, K1, C0_ENTRYHI);
|
||||
unsigned int segbits = 44;
|
||||
|
||||
uasm_i_dmfc0(&p, K0, C0_BADVADDR);
|
||||
uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
|
||||
uasm_i_xor(&p, K0, K0, K1);
|
||||
UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
|
||||
uasm_i_dsrl32(&p, K1, K0, 62 - 32);
|
||||
uasm_i_dsrl(&p, K0, K0, 12 + 1);
|
||||
uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32);
|
||||
uasm_i_or(&p, K0, K0, K1);
|
||||
uasm_il_bnez(&p, &r, K0, label_leave);
|
||||
/* No need for uasm_i_nop */
|
||||
}
|
||||
|
@ -31,7 +31,8 @@ enum fields {
|
||||
BIMM = 0x040,
|
||||
JIMM = 0x080,
|
||||
FUNC = 0x100,
|
||||
SET = 0x200
|
||||
SET = 0x200,
|
||||
SCIMM = 0x400
|
||||
};
|
||||
|
||||
#define OP_MASK 0x3f
|
||||
@ -52,6 +53,8 @@ enum fields {
|
||||
#define FUNC_SH 0
|
||||
#define SET_MASK 0x7
|
||||
#define SET_SH 0
|
||||
#define SCIMM_MASK 0xfffff
|
||||
#define SCIMM_SH 6
|
||||
|
||||
enum opcode {
|
||||
insn_invalid,
|
||||
@ -61,10 +64,10 @@ enum opcode {
|
||||
insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
|
||||
insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal,
|
||||
insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
|
||||
insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
|
||||
insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
|
||||
insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw,
|
||||
insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
|
||||
insn_dins
|
||||
insn_dins, insn_syscall
|
||||
};
|
||||
|
||||
struct insn {
|
||||
@ -117,6 +120,7 @@ static struct insn insn_table[] __cpuinitdata = {
|
||||
{ insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
|
||||
{ insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET},
|
||||
{ insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET},
|
||||
{ insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD },
|
||||
{ insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
|
||||
{ insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
|
||||
{ insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 },
|
||||
@ -136,6 +140,7 @@ static struct insn insn_table[] __cpuinitdata = {
|
||||
{ insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD },
|
||||
{ insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
|
||||
{ insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
|
||||
{ insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
|
||||
{ insn_invalid, 0, 0 }
|
||||
};
|
||||
|
||||
@ -208,6 +213,14 @@ static inline __cpuinit u32 build_jimm(u32 arg)
|
||||
return (arg >> 2) & JIMM_MASK;
|
||||
}
|
||||
|
||||
static inline __cpuinit u32 build_scimm(u32 arg)
|
||||
{
|
||||
if (arg & ~SCIMM_MASK)
|
||||
printk(KERN_WARNING "Micro-assembler field overflow\n");
|
||||
|
||||
return (arg & SCIMM_MASK) << SCIMM_SH;
|
||||
}
|
||||
|
||||
static inline __cpuinit u32 build_func(u32 arg)
|
||||
{
|
||||
if (arg & ~FUNC_MASK)
|
||||
@ -266,6 +279,8 @@ static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...)
|
||||
op |= build_func(va_arg(ap, u32));
|
||||
if (ip->fields & SET)
|
||||
op |= build_set(va_arg(ap, u32));
|
||||
if (ip->fields & SCIMM)
|
||||
op |= build_scimm(va_arg(ap, u32));
|
||||
va_end(ap);
|
||||
|
||||
**buf = op;
|
||||
@ -373,6 +388,7 @@ I_u2s3u1(_lw)
|
||||
I_u1u2u3(_mfc0)
|
||||
I_u1u2u3(_mtc0)
|
||||
I_u2u1u3(_ori)
|
||||
I_u3u1u2(_or)
|
||||
I_u2s3u1(_pref)
|
||||
I_0(_rfe)
|
||||
I_u2s3u1(_sc)
|
||||
@ -391,6 +407,7 @@ I_0(_tlbwr)
|
||||
I_u3u1u2(_xor)
|
||||
I_u2u1u3(_xori)
|
||||
I_u2u1msbu3(_dins);
|
||||
I_u1(_syscall);
|
||||
|
||||
/* Handle labels. */
|
||||
void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
|
||||
|
@ -180,15 +180,21 @@ struct pci_ops loongson_pci_ops = {
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CS5536
|
||||
DEFINE_RAW_SPINLOCK(msr_lock);
|
||||
|
||||
void _rdmsr(u32 msr, u32 *hi, u32 *lo)
|
||||
{
|
||||
struct pci_bus bus = {
|
||||
.number = PCI_BUS_CS5536
|
||||
};
|
||||
u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&msr_lock, flags);
|
||||
loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
|
||||
loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
|
||||
loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
|
||||
raw_spin_unlock_irqrestore(&msr_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(_rdmsr);
|
||||
|
||||
@ -198,9 +204,13 @@ void _wrmsr(u32 msr, u32 hi, u32 lo)
|
||||
.number = PCI_BUS_CS5536
|
||||
};
|
||||
u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&msr_lock, flags);
|
||||
loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
|
||||
loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
|
||||
loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
|
||||
raw_spin_unlock_irqrestore(&msr_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(_wrmsr);
|
||||
#endif
|
||||
|
@ -87,6 +87,21 @@ static int __init setup_bcm1250(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sb1250_m3_workaround_needed(void)
|
||||
{
|
||||
switch (soc_type) {
|
||||
case K_SYS_SOC_TYPE_BCM1250:
|
||||
case K_SYS_SOC_TYPE_BCM1250_ALT:
|
||||
case K_SYS_SOC_TYPE_BCM1250_ALT2:
|
||||
case K_SYS_SOC_TYPE_BCM1125:
|
||||
case K_SYS_SOC_TYPE_BCM1125H:
|
||||
return soc_pass < K_SYS_REVISION_BCM1250_C0;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int __init setup_bcm112x(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -246,20 +246,12 @@ static struct pci_controller ssb_pcicore_controller = {
|
||||
.pci_ops = &ssb_pcicore_pciops,
|
||||
.io_resource = &ssb_pcicore_io_resource,
|
||||
.mem_resource = &ssb_pcicore_mem_resource,
|
||||
.mem_offset = 0x24000000,
|
||||
};
|
||||
|
||||
static u32 ssb_pcicore_pcibus_iobase = 0x100;
|
||||
static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA;
|
||||
|
||||
/* This function is called when doing a pci_enable_device().
|
||||
* We must first check if the device is a device on the PCI-core bridge. */
|
||||
int ssb_pcicore_plat_dev_init(struct pci_dev *d)
|
||||
{
|
||||
struct resource *res;
|
||||
int pos, size;
|
||||
u32 *base;
|
||||
|
||||
if (d->bus->ops != &ssb_pcicore_pciops) {
|
||||
/* This is not a device on the PCI-core bridge. */
|
||||
return -ENODEV;
|
||||
@ -268,27 +260,6 @@ int ssb_pcicore_plat_dev_init(struct pci_dev *d)
|
||||
ssb_printk(KERN_INFO "PCI: Fixing up device %s\n",
|
||||
pci_name(d));
|
||||
|
||||
/* Fix up resource bases */
|
||||
for (pos = 0; pos < 6; pos++) {
|
||||
res = &d->resource[pos];
|
||||
if (res->flags & IORESOURCE_IO)
|
||||
base = &ssb_pcicore_pcibus_iobase;
|
||||
else
|
||||
base = &ssb_pcicore_pcibus_membase;
|
||||
res->flags |= IORESOURCE_PCI_FIXED;
|
||||
if (res->end) {
|
||||
size = res->end - res->start + 1;
|
||||
if (*base & (size - 1))
|
||||
*base = (*base + size) & ~(size - 1);
|
||||
res->start = *base;
|
||||
res->end = res->start + size - 1;
|
||||
*base += size;
|
||||
pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
|
||||
}
|
||||
/* Fix up PCI bridge BAR0 only */
|
||||
if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0)
|
||||
break;
|
||||
}
|
||||
/* Fix up interrupt lines */
|
||||
d->irq = ssb_mips_irq(extpci_core->dev) + 2;
|
||||
pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
|
||||
|
Loading…
Reference in New Issue
Block a user