提交 d1447464 编写于 作者: L Linus Torvalds

Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus

Pull MIPS updates from Ralf Baechle:
 "MIPS updates:

   - All the things that didn't make 3.10.
   - Removes the Windriver PPMC platform.  Nobody will miss it.
   - Remove a workaround from kernel/irq/irqdomain.c which was there
     exclusivly for MIPS.  Patch by Grant Likely.
   - More small improvments for the SEAD 3 platform
   - Improvments on the BMIPS / SMP support for the BCM63xx series.
   - Various cleanups of dead leftovers.
   - Platform support for the Cavium Octeon-based EdgeRouter Lite.

  Two large KVM patchsets didn't make it for this pull request because
  their respective authors are vacationing"

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (124 commits)
  MIPS: Kconfig: Add missing MODULES dependency to VPE_LOADER
  MIPS: BCM63xx: CLK: Add dummy clk_{set,round}_rate() functions
  MIPS: SEAD3: Disable L2 cache on SEAD-3.
  MIPS: BCM63xx: Enable second core SMP on BCM6328 if available
  MIPS: BCM63xx: Add SMP support to prom.c
  MIPS: define write{b,w,l,q}_relaxed
  MIPS: Expose missing pci_io{map,unmap} declarations
  MIPS: Malta: Update GCMP detection.
  Revert "MIPS: make CAC_ADDR and UNCAC_ADDR account for PHYS_OFFSET"
  MIPS: APSP: Remove <asm/kspd.h>
  SSB: Kconfig: Amend SSB_EMBEDDED dependencies
  MIPS: microMIPS: Fix improper definition of ISA exception bit.
  MIPS: Don't try to decode microMIPS branch instructions where they cannot exist.
  MIPS: Declare emulate_load_store_microMIPS as a static function.
  MIPS: Fix typos and cleanup comment
  MIPS: Cleanup indentation and whitespace
  MIPS: BMIPS: support booting from physical CPU other than 0
  MIPS: Only set cpu_has_mmips if SYS_SUPPORTS_MICROMIPS
  MIPS: GIC: Fix gic_set_affinity infinite loop
  MIPS: Don't save/restore OCTEON wide multiplier state on syscalls.
  ...
...@@ -30,7 +30,6 @@ platforms += sibyte ...@@ -30,7 +30,6 @@ platforms += sibyte
platforms += sni platforms += sni
platforms += txx9 platforms += txx9
platforms += vr41xx platforms += vr41xx
platforms += wrppmc
# include the platform specific files # include the platform specific files
include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms)) include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms))
config MIPS config MIPS
bool bool
default y default y
select HAVE_CONTEXT_TRACKING
select HAVE_GENERIC_DMA_COHERENT select HAVE_GENERIC_DMA_COHERENT
select HAVE_IDE select HAVE_IDE
select HAVE_OPROFILE select HAVE_OPROFILE
...@@ -27,6 +28,7 @@ config MIPS ...@@ -27,6 +28,7 @@ config MIPS
select HAVE_GENERIC_HARDIRQS select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW select GENERIC_IRQ_SHOW
select GENERIC_PCI_IOMAP
select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_JUMP_LABEL
select ARCH_WANT_IPC_PARSE_VERSION select ARCH_WANT_IPC_PARSE_VERSION
select IRQ_FORCED_THREADING select IRQ_FORCED_THREADING
...@@ -46,9 +48,6 @@ config MIPS ...@@ -46,9 +48,6 @@ config MIPS
menu "Machine selection" menu "Machine selection"
config ZONE_DMA
bool
choice choice
prompt "System type" prompt "System type"
default SGI_IP22 default SGI_IP22
...@@ -124,11 +123,14 @@ config BCM47XX ...@@ -124,11 +123,14 @@ config BCM47XX
config BCM63XX config BCM63XX
bool "Broadcom BCM63XX based boards" bool "Broadcom BCM63XX based boards"
select BOOT_RAW
select CEVT_R4K select CEVT_R4K
select CSRC_R4K select CSRC_R4K
select DMA_NONCOHERENT select DMA_NONCOHERENT
select IRQ_CPU select IRQ_CPU
select SYS_HAS_CPU_MIPS32_R1 select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_BMIPS4350 if !BCM63XX_CPU_6338 && !BCM63XX_CPU_6345 && !BCM63XX_CPU_6348
select NR_CPUS_DEFAULT_2
select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_BIG_ENDIAN
select SYS_HAS_EARLY_PRINTK select SYS_HAS_EARLY_PRINTK
...@@ -341,7 +343,6 @@ config MIPS_SEAD3 ...@@ -341,7 +343,6 @@ config MIPS_SEAD3
select DMA_NONCOHERENT select DMA_NONCOHERENT
select IRQ_CPU select IRQ_CPU
select IRQ_GIC select IRQ_GIC
select MIPS_CPU_SCACHE
select MIPS_MSC select MIPS_MSC
select SYS_HAS_CPU_MIPS32_R1 select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_MIPS32_R2 select SYS_HAS_CPU_MIPS32_R2
...@@ -420,7 +421,6 @@ config POWERTV ...@@ -420,7 +421,6 @@ config POWERTV
select CSRC_POWERTV select CSRC_POWERTV
select DMA_NONCOHERENT select DMA_NONCOHERENT
select HW_HAS_PCI select HW_HAS_PCI
select SYS_HAS_EARLY_PRINTK
select SYS_HAS_CPU_MIPS32_R2 select SYS_HAS_CPU_MIPS32_R2
select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_BIG_ENDIAN
...@@ -713,46 +713,8 @@ config MIKROTIK_RB532 ...@@ -713,46 +713,8 @@ config MIKROTIK_RB532
Support the Mikrotik(tm) RouterBoard 532 series, Support the Mikrotik(tm) RouterBoard 532 series,
based on the IDT RC32434 SoC. based on the IDT RC32434 SoC.
config WR_PPMC config CAVIUM_OCTEON_SOC
bool "Wind River PPMC board" bool "Cavium Networks Octeon SoC based boards"
select CEVT_R4K
select CSRC_R4K
select IRQ_CPU
select BOOT_ELF32
select DMA_NONCOHERENT
select HW_HAS_PCI
select PCI_GT64XXX_PCI0
select SWAP_IO_SPACE
select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_MIPS32_R2
select SYS_HAS_CPU_MIPS64_R1
select SYS_HAS_CPU_NEVADA
select SYS_HAS_CPU_RM7000
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_LITTLE_ENDIAN
help
This enables support for the Wind River MIPS32 4KC PPMC evaluation
board, which is based on GT64120 bridge chip.
config CAVIUM_OCTEON_SIMULATOR
bool "Cavium Networks Octeon Simulator"
select CEVT_R4K
select 64BIT_PHYS_ADDR
select DMA_COHERENT
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_HOTPLUG_CPU
select SYS_HAS_CPU_CAVIUM_OCTEON
select HOLES_IN_ZONE
help
The Octeon simulator is software performance model of the Cavium
Octeon Processor. It supports simulating Octeon processors on x86
hardware.
config CAVIUM_OCTEON_REFERENCE_BOARD
bool "Cavium Networks Octeon reference board"
select CEVT_R4K select CEVT_R4K
select 64BIT_PHYS_ADDR select 64BIT_PHYS_ADDR
select DMA_COHERENT select DMA_COHERENT
...@@ -806,6 +768,8 @@ config NLM_XLR_BOARD ...@@ -806,6 +768,8 @@ config NLM_XLR_BOARD
select SYS_HAS_EARLY_PRINTK select SYS_HAS_EARLY_PRINTK
select USB_ARCH_HAS_OHCI if USB_SUPPORT select USB_ARCH_HAS_OHCI if USB_SUPPORT
select USB_ARCH_HAS_EHCI if USB_SUPPORT select USB_ARCH_HAS_EHCI if USB_SUPPORT
select SYS_SUPPORTS_ZBOOT
select SYS_SUPPORTS_ZBOOT_UART16550
help help
Support for systems based on Netlogic XLR and XLS processors. Support for systems based on Netlogic XLR and XLS processors.
Say Y here if you have a XLR or XLS based board. Say Y here if you have a XLR or XLS based board.
...@@ -832,6 +796,8 @@ config NLM_XLP_BOARD ...@@ -832,6 +796,8 @@ config NLM_XLP_BOARD
select SYNC_R4K select SYNC_R4K
select SYS_HAS_EARLY_PRINTK select SYS_HAS_EARLY_PRINTK
select USE_OF select USE_OF
select SYS_SUPPORTS_ZBOOT
select SYS_SUPPORTS_ZBOOT_UART16550
help help
This board is based on Netlogic XLP Processor. This board is based on Netlogic XLP Processor.
Say Y here if you have a XLP based board. Say Y here if you have a XLP based board.
...@@ -1031,7 +997,6 @@ config CPU_BIG_ENDIAN ...@@ -1031,7 +997,6 @@ config CPU_BIG_ENDIAN
config CPU_LITTLE_ENDIAN config CPU_LITTLE_ENDIAN
bool "Little endian" bool "Little endian"
depends on SYS_SUPPORTS_LITTLE_ENDIAN depends on SYS_SUPPORTS_LITTLE_ENDIAN
help
endchoice endchoice
...@@ -1964,7 +1929,7 @@ config MIPS_MT_FPAFF ...@@ -1964,7 +1929,7 @@ config MIPS_MT_FPAFF
config MIPS_VPE_LOADER config MIPS_VPE_LOADER
bool "VPE loader support." bool "VPE loader support."
depends on SYS_SUPPORTS_MULTITHREADING depends on SYS_SUPPORTS_MULTITHREADING && MODULES
select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_IRQ_VI
select CPU_MIPSR2_IRQ_EI select CPU_MIPSR2_IRQ_EI
select MIPS_MT select MIPS_MT
...@@ -2382,6 +2347,19 @@ config SECCOMP ...@@ -2382,6 +2347,19 @@ config SECCOMP
If unsure, say Y. Only embedded should say N here. If unsure, say Y. Only embedded should say N here.
config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
help
This option turns on the -fstack-protector GCC feature. This
feature puts, at the beginning of functions, a canary value on
the stack just before the return address, and validates
the value just before actually returning. Stack based buffer
overflows (that need to overwrite this return address) now also
overwrite the canary, which gets detected and the attack is then
neutralized via a kernel panic.
This feature requires gcc version 4.2 or above.
config USE_OF config USE_OF
bool bool
select OF select OF
...@@ -2413,7 +2391,6 @@ config PCI ...@@ -2413,7 +2391,6 @@ config PCI
bool "Support for PCI controller" bool "Support for PCI controller"
depends on HW_HAS_PCI depends on HW_HAS_PCI
select PCI_DOMAINS select PCI_DOMAINS
select GENERIC_PCI_IOMAP
select NO_GENERIC_PCI_IOPORT_MAP select NO_GENERIC_PCI_IOPORT_MAP
help help
Find out whether you have a PCI motherboard. PCI is the name of a Find out whether you have a PCI motherboard. PCI is the name of a
...@@ -2479,6 +2456,9 @@ config I8253 ...@@ -2479,6 +2456,9 @@ config I8253
select CLKEVT_I8253 select CLKEVT_I8253
select MIPS_EXTERNAL_TIMER select MIPS_EXTERNAL_TIMER
config ZONE_DMA
bool
config ZONE_DMA32 config ZONE_DMA32
bool bool
......
...@@ -227,6 +227,10 @@ KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0) ...@@ -227,6 +227,10 @@ KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)
LDFLAGS += -m $(ld-emul) LDFLAGS += -m $(ld-emul)
ifdef CONFIG_CC_STACKPROTECTOR
KBUILD_CFLAGS += -fstack-protector
endif
ifdef CONFIG_MIPS ifdef CONFIG_MIPS
CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \
egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \
......
...@@ -132,7 +132,7 @@ static void __init ap136_pci_init(u8 *eeprom) ...@@ -132,7 +132,7 @@ static void __init ap136_pci_init(u8 *eeprom)
ath79_register_pci(); ath79_register_pci();
} }
#else #else
static inline void ap136_pci_init(void) {} static inline void ap136_pci_init(u8 *eeprom) {}
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
static void __init ap136_setup(void) static void __init ap136_setup(void)
......
menu "CPU support" menu "CPU support"
depends on BCM63XX depends on BCM63XX
config BCM63XX_CPU_3368
bool "support 3368 CPU"
select HW_HAS_PCI
config BCM63XX_CPU_6328 config BCM63XX_CPU_6328
bool "support 6328 CPU" bool "support 6328 CPU"
select HW_HAS_PCI select HW_HAS_PCI
...@@ -8,14 +12,9 @@ config BCM63XX_CPU_6328 ...@@ -8,14 +12,9 @@ config BCM63XX_CPU_6328
config BCM63XX_CPU_6338 config BCM63XX_CPU_6338
bool "support 6338 CPU" bool "support 6338 CPU"
select HW_HAS_PCI select HW_HAS_PCI
select USB_ARCH_HAS_OHCI
select USB_OHCI_BIG_ENDIAN_DESC
select USB_OHCI_BIG_ENDIAN_MMIO
config BCM63XX_CPU_6345 config BCM63XX_CPU_6345
bool "support 6345 CPU" bool "support 6345 CPU"
select USB_OHCI_BIG_ENDIAN_DESC
select USB_OHCI_BIG_ENDIAN_MMIO
config BCM63XX_CPU_6348 config BCM63XX_CPU_6348
bool "support 6348 CPU" bool "support 6348 CPU"
......
...@@ -28,10 +28,46 @@ ...@@ -28,10 +28,46 @@
#include <bcm63xx_dev_usb_usbd.h> #include <bcm63xx_dev_usb_usbd.h>
#include <board_bcm963xx.h> #include <board_bcm963xx.h>
#include <uapi/linux/bcm933xx_hcs.h>
#define PFX "board_bcm963xx: " #define PFX "board_bcm963xx: "
#define HCS_OFFSET_128K 0x20000
static struct board_info board; static struct board_info board;
/*
* known 3368 boards
*/
#ifdef CONFIG_BCM63XX_CPU_3368
static struct board_info __initdata board_cvg834g = {
.name = "CVG834G_E15R3921",
.expected_cpu_id = 0x3368,
.has_uart0 = 1,
.has_uart1 = 1,
.has_enet0 = 1,
.has_pci = 1,
.enet0 = {
.has_phy = 1,
.use_internal_phy = 1,
},
.leds = {
{
.name = "CVG834G:green:power",
.gpio = 37,
.default_trigger= "default-on",
},
},
.ephy_reset_gpio = 36,
.ephy_reset_gpio_flags = GPIOF_INIT_HIGH,
};
#endif
/* /*
* known 6328 boards * known 6328 boards
*/ */
...@@ -639,6 +675,9 @@ static struct board_info __initdata board_DWVS0 = { ...@@ -639,6 +675,9 @@ static struct board_info __initdata board_DWVS0 = {
* all boards * all boards
*/ */
static const struct board_info __initconst *bcm963xx_boards[] = { static const struct board_info __initconst *bcm963xx_boards[] = {
#ifdef CONFIG_BCM63XX_CPU_3368
&board_cvg834g,
#endif
#ifdef CONFIG_BCM63XX_CPU_6328 #ifdef CONFIG_BCM63XX_CPU_6328
&board_96328avng, &board_96328avng,
#endif #endif
...@@ -722,8 +761,9 @@ void __init board_prom_init(void) ...@@ -722,8 +761,9 @@ void __init board_prom_init(void)
unsigned int i; unsigned int i;
u8 *boot_addr, *cfe; u8 *boot_addr, *cfe;
char cfe_version[32]; char cfe_version[32];
char *board_name; char *board_name = NULL;
u32 val; u32 val;
struct bcm_hcs *hcs;
/* read base address of boot chip select (0) /* read base address of boot chip select (0)
* 6328/6362 do not have MPI but boot from a fixed address * 6328/6362 do not have MPI but boot from a fixed address
...@@ -747,7 +787,12 @@ void __init board_prom_init(void) ...@@ -747,7 +787,12 @@ void __init board_prom_init(void)
bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET); bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET);
board_name = bcm63xx_nvram_get_name(); if (BCMCPU_IS_3368()) {
hcs = (struct bcm_hcs *)boot_addr;
board_name = hcs->filename;
} else {
board_name = bcm63xx_nvram_get_name();
}
/* find board by name */ /* find board by name */
for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
if (strncmp(board_name, bcm963xx_boards[i]->name, 16)) if (strncmp(board_name, bcm963xx_boards[i]->name, 16))
...@@ -877,5 +922,9 @@ int __init board_register_devices(void) ...@@ -877,5 +922,9 @@ int __init board_register_devices(void)
platform_device_register(&bcm63xx_gpio_leds); platform_device_register(&bcm63xx_gpio_leds);
if (board.ephy_reset_gpio && board.ephy_reset_gpio_flags)
gpio_request_one(board.ephy_reset_gpio,
board.ephy_reset_gpio_flags, "ephy-reset");
return 0; return 0;
} }
...@@ -84,7 +84,7 @@ static void enetx_set(struct clk *clk, int enable) ...@@ -84,7 +84,7 @@ static void enetx_set(struct clk *clk, int enable)
else else
clk_disable_unlocked(&clk_enet_misc); clk_disable_unlocked(&clk_enet_misc);
if (BCMCPU_IS_6358()) { if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) {
u32 mask; u32 mask;
if (clk->id == 0) if (clk->id == 0)
...@@ -110,9 +110,8 @@ static struct clk clk_enet1 = { ...@@ -110,9 +110,8 @@ static struct clk clk_enet1 = {
*/ */
static void ephy_set(struct clk *clk, int enable) static void ephy_set(struct clk *clk, int enable)
{ {
if (!BCMCPU_IS_6358()) if (BCMCPU_IS_3368() || BCMCPU_IS_6358())
return; bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable);
bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable);
} }
...@@ -155,9 +154,10 @@ static struct clk clk_enetsw = { ...@@ -155,9 +154,10 @@ static struct clk clk_enetsw = {
*/ */
static void pcm_set(struct clk *clk, int enable) static void pcm_set(struct clk *clk, int enable)
{ {
if (!BCMCPU_IS_6358()) if (BCMCPU_IS_3368())
return; bcm_hwclock_set(CKCTL_3368_PCM_EN, enable);
bcm_hwclock_set(CKCTL_6358_PCM_EN, enable); if (BCMCPU_IS_6358())
bcm_hwclock_set(CKCTL_6358_PCM_EN, enable);
} }
static struct clk clk_pcm = { static struct clk clk_pcm = {
...@@ -211,7 +211,7 @@ static void spi_set(struct clk *clk, int enable) ...@@ -211,7 +211,7 @@ static void spi_set(struct clk *clk, int enable)
mask = CKCTL_6338_SPI_EN; mask = CKCTL_6338_SPI_EN;
else if (BCMCPU_IS_6348()) else if (BCMCPU_IS_6348())
mask = CKCTL_6348_SPI_EN; mask = CKCTL_6348_SPI_EN;
else if (BCMCPU_IS_6358()) else if (BCMCPU_IS_3368() || BCMCPU_IS_6358())
mask = CKCTL_6358_SPI_EN; mask = CKCTL_6358_SPI_EN;
else if (BCMCPU_IS_6362()) else if (BCMCPU_IS_6362())
mask = CKCTL_6362_SPI_EN; mask = CKCTL_6362_SPI_EN;
...@@ -318,6 +318,18 @@ unsigned long clk_get_rate(struct clk *clk) ...@@ -318,6 +318,18 @@ unsigned long clk_get_rate(struct clk *clk)
EXPORT_SYMBOL(clk_get_rate); EXPORT_SYMBOL(clk_get_rate);
int clk_set_rate(struct clk *clk, unsigned long rate)
{
return 0;
}
EXPORT_SYMBOL_GPL(clk_set_rate);
long clk_round_rate(struct clk *clk, unsigned long rate)
{
return 0;
}
EXPORT_SYMBOL_GPL(clk_round_rate);
struct clk *clk_get(struct device *dev, const char *id) struct clk *clk_get(struct device *dev, const char *id)
{ {
if (!strcmp(id, "enet0")) if (!strcmp(id, "enet0"))
...@@ -338,7 +350,7 @@ struct clk *clk_get(struct device *dev, const char *id) ...@@ -338,7 +350,7 @@ struct clk *clk_get(struct device *dev, const char *id)
return &clk_xtm; return &clk_xtm;
if (!strcmp(id, "periph")) if (!strcmp(id, "periph"))
return &clk_periph; return &clk_periph;
if (BCMCPU_IS_6358() && !strcmp(id, "pcm")) if ((BCMCPU_IS_3368() || BCMCPU_IS_6358()) && !strcmp(id, "pcm"))
return &clk_pcm; return &clk_pcm;
if ((BCMCPU_IS_6362() || BCMCPU_IS_6368()) && !strcmp(id, "ipsec")) if ((BCMCPU_IS_6362() || BCMCPU_IS_6368()) && !strcmp(id, "ipsec"))
return &clk_ipsec; return &clk_ipsec;
......
...@@ -29,6 +29,14 @@ static u8 bcm63xx_cpu_rev; ...@@ -29,6 +29,14 @@ static u8 bcm63xx_cpu_rev;
static unsigned int bcm63xx_cpu_freq; static unsigned int bcm63xx_cpu_freq;
static unsigned int bcm63xx_memory_size; static unsigned int bcm63xx_memory_size;
static const unsigned long bcm3368_regs_base[] = {
__GEN_CPU_REGS_TABLE(3368)
};
static const int bcm3368_irqs[] = {
__GEN_CPU_IRQ_TABLE(3368)
};
static const unsigned long bcm6328_regs_base[] = { static const unsigned long bcm6328_regs_base[] = {
__GEN_CPU_REGS_TABLE(6328) __GEN_CPU_REGS_TABLE(6328)
}; };
...@@ -116,6 +124,9 @@ unsigned int bcm63xx_get_memory_size(void) ...@@ -116,6 +124,9 @@ unsigned int bcm63xx_get_memory_size(void)
static unsigned int detect_cpu_clock(void) static unsigned int detect_cpu_clock(void)
{ {
switch (bcm63xx_get_cpu_id()) { switch (bcm63xx_get_cpu_id()) {
case BCM3368_CPU_ID:
return 300000000;
case BCM6328_CPU_ID: case BCM6328_CPU_ID:
{ {
unsigned int tmp, mips_pll_fcvo; unsigned int tmp, mips_pll_fcvo;
...@@ -266,7 +277,7 @@ static unsigned int detect_memory_size(void) ...@@ -266,7 +277,7 @@ static unsigned int detect_memory_size(void)
banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1; banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1;
} }
if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) { if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
val = bcm_memc_readl(MEMC_CFG_REG); val = bcm_memc_readl(MEMC_CFG_REG);
rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT; rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT; cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
...@@ -302,10 +313,17 @@ void __init bcm63xx_cpu_init(void) ...@@ -302,10 +313,17 @@ void __init bcm63xx_cpu_init(void)
chipid_reg = BCM_6345_PERF_BASE; chipid_reg = BCM_6345_PERF_BASE;
break; break;
case CPU_BMIPS4350: case CPU_BMIPS4350:
if ((read_c0_prid() & 0xf0) == 0x10) switch ((read_c0_prid() & 0xff)) {
case 0x04:
chipid_reg = BCM_3368_PERF_BASE;
break;
case 0x10:
chipid_reg = BCM_6345_PERF_BASE; chipid_reg = BCM_6345_PERF_BASE;
else break;
default:
chipid_reg = BCM_6368_PERF_BASE; chipid_reg = BCM_6368_PERF_BASE;
break;
}
break; break;
} }
...@@ -322,6 +340,10 @@ void __init bcm63xx_cpu_init(void) ...@@ -322,6 +340,10 @@ void __init bcm63xx_cpu_init(void)
bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT; bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT;
switch (bcm63xx_cpu_id) { switch (bcm63xx_cpu_id) {
case BCM3368_CPU_ID:
bcm63xx_regs_base = bcm3368_regs_base;
bcm63xx_irqs = bcm3368_irqs;
break;
case BCM6328_CPU_ID: case BCM6328_CPU_ID:
bcm63xx_regs_base = bcm6328_regs_base; bcm63xx_regs_base = bcm6328_regs_base;
bcm63xx_irqs = bcm6328_irqs; bcm63xx_irqs = bcm6328_irqs;
......
...@@ -71,6 +71,7 @@ static int __init bcm63xx_detect_flash_type(void) ...@@ -71,6 +71,7 @@ static int __init bcm63xx_detect_flash_type(void)
case BCM6348_CPU_ID: case BCM6348_CPU_ID:
/* no way to auto detect so assume parallel */ /* no way to auto detect so assume parallel */
return BCM63XX_FLASH_TYPE_PARALLEL; return BCM63XX_FLASH_TYPE_PARALLEL;
case BCM3368_CPU_ID:
case BCM6358_CPU_ID: case BCM6358_CPU_ID:
val = bcm_gpio_readl(GPIO_STRAPBUS_REG); val = bcm_gpio_readl(GPIO_STRAPBUS_REG);
if (val & STRAPBUS_6358_BOOT_SEL_PARALLEL) if (val & STRAPBUS_6358_BOOT_SEL_PARALLEL)
......
...@@ -37,7 +37,8 @@ static __init void bcm63xx_spi_regs_init(void) ...@@ -37,7 +37,8 @@ static __init void bcm63xx_spi_regs_init(void)
{ {
if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) if (BCMCPU_IS_6338() || BCMCPU_IS_6348())
bcm63xx_regs_spi = bcm6348_regs_spi; bcm63xx_regs_spi = bcm6348_regs_spi;
if (BCMCPU_IS_6358() || BCMCPU_IS_6362() || BCMCPU_IS_6368()) if (BCMCPU_IS_3368() || BCMCPU_IS_6358() ||
BCMCPU_IS_6362() || BCMCPU_IS_6368())
bcm63xx_regs_spi = bcm6358_regs_spi; bcm63xx_regs_spi = bcm6358_regs_spi;
} }
#else #else
...@@ -87,7 +88,8 @@ int __init bcm63xx_spi_register(void) ...@@ -87,7 +88,8 @@ int __init bcm63xx_spi_register(void)
spi_pdata.msg_ctl_width = SPI_6348_MSG_CTL_WIDTH; spi_pdata.msg_ctl_width = SPI_6348_MSG_CTL_WIDTH;
} }
if (BCMCPU_IS_6358() || BCMCPU_IS_6362() || BCMCPU_IS_6368()) { if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6362() ||
BCMCPU_IS_6368()) {
spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1; spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1;
spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE; spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE;
spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT; spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT;
......
...@@ -54,7 +54,8 @@ int __init bcm63xx_uart_register(unsigned int id) ...@@ -54,7 +54,8 @@ int __init bcm63xx_uart_register(unsigned int id)
if (id >= ARRAY_SIZE(bcm63xx_uart_devices)) if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
return -ENODEV; return -ENODEV;
if (id == 1 && (!BCMCPU_IS_6358() && !BCMCPU_IS_6368())) if (id == 1 && (!BCMCPU_IS_3368() && !BCMCPU_IS_6358() &&
!BCMCPU_IS_6368()))
return -ENODEV; return -ENODEV;
if (id == 0) { if (id == 0) {
......
...@@ -27,6 +27,17 @@ static void __internal_irq_unmask_32(unsigned int irq) __maybe_unused; ...@@ -27,6 +27,17 @@ static void __internal_irq_unmask_32(unsigned int irq) __maybe_unused;
static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused; static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused;
#ifndef BCMCPU_RUNTIME_DETECT #ifndef BCMCPU_RUNTIME_DETECT
#ifdef CONFIG_BCM63XX_CPU_3368
#define irq_stat_reg PERF_IRQSTAT_3368_REG
#define irq_mask_reg PERF_IRQMASK_3368_REG
#define irq_bits 32
#define is_ext_irq_cascaded 0
#define ext_irq_start 0
#define ext_irq_end 0
#define ext_irq_count 4
#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_3368
#define ext_irq_cfg_reg2 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6328 #ifdef CONFIG_BCM63XX_CPU_6328
#define irq_stat_reg PERF_IRQSTAT_6328_REG #define irq_stat_reg PERF_IRQSTAT_6328_REG
#define irq_mask_reg PERF_IRQMASK_6328_REG #define irq_mask_reg PERF_IRQMASK_6328_REG
...@@ -140,6 +151,13 @@ static void bcm63xx_init_irq(void) ...@@ -140,6 +151,13 @@ static void bcm63xx_init_irq(void)
irq_mask_addr = bcm63xx_regset_address(RSET_PERF); irq_mask_addr = bcm63xx_regset_address(RSET_PERF);
switch (bcm63xx_get_cpu_id()) { switch (bcm63xx_get_cpu_id()) {
case BCM3368_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_3368_REG;
irq_mask_addr += PERF_IRQMASK_3368_REG;
irq_bits = 32;
ext_irq_count = 4;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368;
break;
case BCM6328_CPU_ID: case BCM6328_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6328_REG; irq_stat_addr += PERF_IRQSTAT_6328_REG;
irq_mask_addr += PERF_IRQMASK_6328_REG; irq_mask_addr += PERF_IRQMASK_6328_REG;
...@@ -294,6 +312,10 @@ asmlinkage void plat_irq_dispatch(void) ...@@ -294,6 +312,10 @@ asmlinkage void plat_irq_dispatch(void)
if (cause & CAUSEF_IP7) if (cause & CAUSEF_IP7)
do_IRQ(7); do_IRQ(7);
if (cause & CAUSEF_IP0)
do_IRQ(0);
if (cause & CAUSEF_IP1)
do_IRQ(1);
if (cause & CAUSEF_IP2) if (cause & CAUSEF_IP2)
dispatch_internal(); dispatch_internal();
if (!is_ext_irq_cascaded) { if (!is_ext_irq_cascaded) {
...@@ -475,6 +497,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d, ...@@ -475,6 +497,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d,
reg &= ~EXTIRQ_CFG_BOTHEDGE_6348(irq); reg &= ~EXTIRQ_CFG_BOTHEDGE_6348(irq);
break; break;
case BCM3368_CPU_ID:
case BCM6328_CPU_ID: case BCM6328_CPU_ID:
case BCM6338_CPU_ID: case BCM6338_CPU_ID:
case BCM6345_CPU_ID: case BCM6345_CPU_ID:
......
...@@ -42,6 +42,7 @@ void __init bcm63xx_nvram_init(void *addr) ...@@ -42,6 +42,7 @@ void __init bcm63xx_nvram_init(void *addr)
{ {
unsigned int check_len; unsigned int check_len;
u32 crc, expected_crc; u32 crc, expected_crc;
u8 hcs_mac_addr[ETH_ALEN] = { 0x00, 0x10, 0x18, 0xff, 0xff, 0xff };
/* extract nvram data */ /* extract nvram data */
memcpy(&nvram, addr, sizeof(nvram)); memcpy(&nvram, addr, sizeof(nvram));
...@@ -62,6 +63,15 @@ void __init bcm63xx_nvram_init(void *addr) ...@@ -62,6 +63,15 @@ void __init bcm63xx_nvram_init(void *addr)
if (crc != expected_crc) if (crc != expected_crc)
pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n", pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n",
expected_crc, crc); expected_crc, crc);
/* Cable modems have a different NVRAM which is embedded in the eCos
* firmware and not easily extractible, give at least a MAC address
* pool.
*/
if (BCMCPU_IS_3368()) {
memcpy(nvram.mac_addr_base, hcs_mac_addr, ETH_ALEN);
nvram.mac_addr_count = 2;
}
} }
u8 *bcm63xx_nvram_get_name(void) u8 *bcm63xx_nvram_get_name(void)
......
...@@ -8,7 +8,11 @@ ...@@ -8,7 +8,11 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/smp.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <asm/bmips.h>
#include <asm/smp-ops.h>
#include <asm/mipsregs.h>
#include <bcm63xx_board.h> #include <bcm63xx_board.h>
#include <bcm63xx_cpu.h> #include <bcm63xx_cpu.h>
#include <bcm63xx_io.h> #include <bcm63xx_io.h>
...@@ -26,7 +30,9 @@ void __init prom_init(void) ...@@ -26,7 +30,9 @@ void __init prom_init(void)
bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG); bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);
/* disable all hardware blocks clock for now */ /* disable all hardware blocks clock for now */
if (BCMCPU_IS_6328()) if (BCMCPU_IS_3368())
mask = CKCTL_3368_ALL_SAFE_EN;
else if (BCMCPU_IS_6328())
mask = CKCTL_6328_ALL_SAFE_EN; mask = CKCTL_6328_ALL_SAFE_EN;
else if (BCMCPU_IS_6338()) else if (BCMCPU_IS_6338())
mask = CKCTL_6338_ALL_SAFE_EN; mask = CKCTL_6338_ALL_SAFE_EN;
...@@ -52,6 +58,47 @@ void __init prom_init(void) ...@@ -52,6 +58,47 @@ void __init prom_init(void)
/* do low level board init */ /* do low level board init */
board_prom_init(); board_prom_init();
if (IS_ENABLED(CONFIG_CPU_BMIPS4350) && IS_ENABLED(CONFIG_SMP)) {
/* set up SMP */
register_smp_ops(&bmips_smp_ops);
/*
* BCM6328 might not have its second CPU enabled, while BCM6358
* needs special handling for its shared TLB, so disable SMP
* for now.
*/
if (BCMCPU_IS_6328()) {
reg = bcm_readl(BCM_6328_OTP_BASE +
OTP_USER_BITS_6328_REG(3));
if (reg & OTP_6328_REG3_TP1_DISABLED)
bmips_smp_enabled = 0;
} else if (BCMCPU_IS_6358()) {
bmips_smp_enabled = 0;
}
if (!bmips_smp_enabled)
return;
/*
* The bootloader has set up the CPU1 reset vector at
* 0xa000_0200.
* This conflicts with the special interrupt vector (IV).
* The bootloader has also set up CPU1 to respond to the wrong
* IPI interrupt.
* Here we will start up CPU1 in the background and ask it to
* reconfigure itself then go back to sleep.
*/
memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20);
__sync();
set_c0_cause(C_SW0);
cpumask_set_cpu(1, &bmips_booted_mask);
/*
* FIXME: we really should have some sort of hazard barrier here
*/
}
} }
void __init prom_free_prom_memory(void) void __init prom_free_prom_memory(void)
......
...@@ -30,6 +30,19 @@ ...@@ -30,6 +30,19 @@
[BCM63XX_RESET_PCIE] = BCM## __cpu ##_RESET_PCIE, \ [BCM63XX_RESET_PCIE] = BCM## __cpu ##_RESET_PCIE, \
[BCM63XX_RESET_PCIE_EXT] = BCM## __cpu ##_RESET_PCIE_EXT, [BCM63XX_RESET_PCIE_EXT] = BCM## __cpu ##_RESET_PCIE_EXT,
#define BCM3368_RESET_SPI SOFTRESET_3368_SPI_MASK
#define BCM3368_RESET_ENET SOFTRESET_3368_ENET_MASK
#define BCM3368_RESET_USBH 0
#define BCM3368_RESET_USBD SOFTRESET_3368_USBS_MASK
#define BCM3368_RESET_DSL 0
#define BCM3368_RESET_SAR 0
#define BCM3368_RESET_EPHY SOFTRESET_3368_EPHY_MASK
#define BCM3368_RESET_ENETSW 0
#define BCM3368_RESET_PCM SOFTRESET_3368_PCM_MASK
#define BCM3368_RESET_MPI SOFTRESET_3368_MPI_MASK
#define BCM3368_RESET_PCIE 0
#define BCM3368_RESET_PCIE_EXT 0
#define BCM6328_RESET_SPI SOFTRESET_6328_SPI_MASK #define BCM6328_RESET_SPI SOFTRESET_6328_SPI_MASK
#define BCM6328_RESET_ENET 0 #define BCM6328_RESET_ENET 0
#define BCM6328_RESET_USBH SOFTRESET_6328_USBH_MASK #define BCM6328_RESET_USBH SOFTRESET_6328_USBH_MASK
...@@ -117,6 +130,10 @@ ...@@ -117,6 +130,10 @@
/* /*
* core reset bits * core reset bits
*/ */
static const u32 bcm3368_reset_bits[] = {
__GEN_RESET_BITS_TABLE(3368)
};
static const u32 bcm6328_reset_bits[] = { static const u32 bcm6328_reset_bits[] = {
__GEN_RESET_BITS_TABLE(6328) __GEN_RESET_BITS_TABLE(6328)
}; };
...@@ -146,7 +163,10 @@ static int reset_reg; ...@@ -146,7 +163,10 @@ static int reset_reg;
static int __init bcm63xx_reset_bits_init(void) static int __init bcm63xx_reset_bits_init(void)
{ {
if (BCMCPU_IS_6328()) { if (BCMCPU_IS_3368()) {
reset_reg = PERF_SOFTRESET_6358_REG;
bcm63xx_reset_bits = bcm3368_reset_bits;
} else if (BCMCPU_IS_6328()) {
reset_reg = PERF_SOFTRESET_6328_REG; reset_reg = PERF_SOFTRESET_6328_REG;
bcm63xx_reset_bits = bcm6328_reset_bits; bcm63xx_reset_bits = bcm6328_reset_bits;
} else if (BCMCPU_IS_6338()) { } else if (BCMCPU_IS_6338()) {
...@@ -170,6 +190,13 @@ static int __init bcm63xx_reset_bits_init(void) ...@@ -170,6 +190,13 @@ static int __init bcm63xx_reset_bits_init(void)
} }
#else #else
#ifdef CONFIG_BCM63XX_CPU_3368
static const u32 bcm63xx_reset_bits[] = {
__GEN_RESET_BITS_TABLE(3368)
};
#define reset_reg PERF_SOFTRESET_6358_REG
#endif
#ifdef CONFIG_BCM63XX_CPU_6328 #ifdef CONFIG_BCM63XX_CPU_6328
static const u32 bcm63xx_reset_bits[] = { static const u32 bcm63xx_reset_bits[] = {
__GEN_RESET_BITS_TABLE(6328) __GEN_RESET_BITS_TABLE(6328)
......
...@@ -68,6 +68,9 @@ void bcm63xx_machine_reboot(void) ...@@ -68,6 +68,9 @@ void bcm63xx_machine_reboot(void)
/* mask and clear all external irq */ /* mask and clear all external irq */
switch (bcm63xx_get_cpu_id()) { switch (bcm63xx_get_cpu_id()) {
case BCM3368_CPU_ID:
perf_regs[0] = PERF_EXTIRQ_CFG_REG_3368;
break;
case BCM6328_CPU_ID: case BCM6328_CPU_ID:
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6328; perf_regs[0] = PERF_EXTIRQ_CFG_REG_6328;
break; break;
......
...@@ -18,6 +18,8 @@ BOOT_HEAP_SIZE := 0x400000 ...@@ -18,6 +18,8 @@ BOOT_HEAP_SIZE := 0x400000
# Disable Function Tracer # Disable Function Tracer
KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//") KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//")
KBUILD_CFLAGS := $(filter-out -fstack-protector, $(KBUILD_CFLAGS))
KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \ KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \
-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull"
......
...@@ -23,23 +23,39 @@ ...@@ -23,23 +23,39 @@
#define PORT(offset) (UART0_BASE + (4 * offset)) #define PORT(offset) (UART0_BASE + (4 * offset))
#endif #endif
#ifdef CONFIG_CPU_XLR
#define UART0_BASE 0x1EF14000
#define PORT(offset) (CKSEG1ADDR(UART0_BASE) + (4 * offset))
#define IOTYPE unsigned int
#endif
#ifdef CONFIG_CPU_XLP
#define UART0_BASE 0x18030100
#define PORT(offset) (CKSEG1ADDR(UART0_BASE) + (4 * offset))
#define IOTYPE unsigned int
#endif
#ifndef IOTYPE
#define IOTYPE char
#endif
#ifndef PORT #ifndef PORT
#error please define the serial port address for your own machine #error please define the serial port address for your own machine
#endif #endif
static inline unsigned int serial_in(int offset) static inline unsigned int serial_in(int offset)
{ {
return *((char *)PORT(offset)); return *((volatile IOTYPE *)PORT(offset)) & 0xFF;
} }
static inline void serial_out(int offset, int value) static inline void serial_out(int offset, int value)
{ {
*((char *)PORT(offset)) = value; *((volatile IOTYPE *)PORT(offset)) = value & 0xFF;
} }
void putc(char c) void putc(char c)
{ {
int timeout = 1024; int timeout = 1000000;
while (((serial_in(UART_LSR) & UART_LSR_THRE) == 0) && (timeout-- > 0)) while (((serial_in(UART_LSR) & UART_LSR_THRE) == 0) && (timeout-- > 0))
; ;
......
...@@ -10,6 +10,10 @@ config CAVIUM_CN63XXP1 ...@@ -10,6 +10,10 @@ config CAVIUM_CN63XXP1
non-CN63XXP1 hardware, so it is recommended to select "n" non-CN63XXP1 hardware, so it is recommended to select "n"
unless it is known the workarounds are needed. unless it is known the workarounds are needed.
endif # CPU_CAVIUM_OCTEON
if CAVIUM_OCTEON_SOC
config CAVIUM_OCTEON_2ND_KERNEL config CAVIUM_OCTEON_2ND_KERNEL
bool "Build the kernel to be used as a 2nd kernel on the same chip" bool "Build the kernel to be used as a 2nd kernel on the same chip"
default "n" default "n"
...@@ -19,17 +23,6 @@ config CAVIUM_OCTEON_2ND_KERNEL ...@@ -19,17 +23,6 @@ config CAVIUM_OCTEON_2ND_KERNEL
with this option to be run at the same time as one built without this with this option to be run at the same time as one built without this
option. option.
config CAVIUM_OCTEON_HW_FIX_UNALIGNED
bool "Enable hardware fixups of unaligned loads and stores"
default "y"
help
Configure the Octeon hardware to automatically fix unaligned loads
and stores. Normally unaligned accesses are fixed using a kernel
exception handler. This option enables the hardware automatic fixups,
which requires only an extra 3 cycles. Disable this option if you
are running code that relies on address exceptions on unaligned
accesses.
config CAVIUM_OCTEON_CVMSEG_SIZE config CAVIUM_OCTEON_CVMSEG_SIZE
int "Number of L1 cache lines reserved for CVMSEG memory" int "Number of L1 cache lines reserved for CVMSEG memory"
range 0 54 range 0 54
...@@ -103,4 +96,4 @@ config OCTEON_ILM ...@@ -103,4 +96,4 @@ config OCTEON_ILM
To compile this driver as a module, choose M here. The module To compile this driver as a module, choose M here. The module
will be called octeon-ilm will be called octeon-ilm
endif # CPU_CAVIUM_OCTEON endif # CAVIUM_OCTEON_SOC
...@@ -12,11 +12,12 @@ ...@@ -12,11 +12,12 @@
CFLAGS_octeon-platform.o = -I$(src)/../../../scripts/dtc/libfdt CFLAGS_octeon-platform.o = -I$(src)/../../../scripts/dtc/libfdt
CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
obj-y := cpu.o setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o obj-y := cpu.o setup.o octeon-platform.o octeon-irq.o csrc-octeon.o
obj-y += dma-octeon.o flash_setup.o obj-y += dma-octeon.o
obj-y += octeon-memcpy.o obj-y += octeon-memcpy.o
obj-y += executive/ obj-y += executive/
obj-$(CONFIG_MTD) += flash_setup.o
obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_OCTEON_ILM) += oct_ilm.o obj-$(CONFIG_OCTEON_ILM) += oct_ilm.o
......
# #
# Cavium Octeon # Cavium Octeon
# #
platform-$(CONFIG_CPU_CAVIUM_OCTEON) += cavium-octeon/ platform-$(CONFIG_CAVIUM_OCTEON_SOC) += cavium-octeon/
cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += \ cflags-$(CONFIG_CAVIUM_OCTEON_SOC) += \
-I$(srctree)/arch/mips/include/asm/mach-cavium-octeon -I$(srctree)/arch/mips/include/asm/mach-cavium-octeon
ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff84100000 load-$(CONFIG_CAVIUM_OCTEON_SOC) += 0xffffffff84100000
else else
load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff81100000 load-$(CONFIG_CAVIUM_OCTEON_SOC) += 0xffffffff81100000
endif endif
...@@ -181,6 +181,11 @@ int cvmx_helper_board_get_mii_address(int ipd_port) ...@@ -181,6 +181,11 @@ int cvmx_helper_board_get_mii_address(int ipd_port)
return ipd_port - 16 + 4; return ipd_port - 16 + 4;
else else
return -1; return -1;
case CVMX_BOARD_TYPE_UBNT_E100:
if (ipd_port >= 0 && ipd_port <= 2)
return 7 - ipd_port;
else
return -1;
} }
/* Some unknown board. Somebody forgot to update this function... */ /* Some unknown board. Somebody forgot to update this function... */
...@@ -706,6 +711,14 @@ int __cvmx_helper_board_hardware_enable(int interface) ...@@ -706,6 +711,14 @@ int __cvmx_helper_board_hardware_enable(int interface)
} }
} }
} }
} else if (cvmx_sysinfo_get()->board_type ==
CVMX_BOARD_TYPE_UBNT_E100) {
cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface), 0);
cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface), 0x10);
cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0);
cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0x10);
cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(2, interface), 0);
cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(2, interface), 0x10);
} }
return 0; return 0;
} }
...@@ -490,8 +490,15 @@ int __init octeon_prune_device_tree(void) ...@@ -490,8 +490,15 @@ int __init octeon_prune_device_tree(void)
if (alias_prop) { if (alias_prop) {
uart = fdt_path_offset(initial_boot_params, alias_prop); uart = fdt_path_offset(initial_boot_params, alias_prop);
if (uart_mask & (1 << i)) if (uart_mask & (1 << i)) {
__be32 f;
f = cpu_to_be32(octeon_get_io_clock_rate());
fdt_setprop_inplace(initial_boot_params,
uart, "clock-frequency",
&f, sizeof(f));
continue; continue;
}
pr_debug("Deleting uart%d\n", i); pr_debug("Deleting uart%d\n", i);
fdt_nop_node(initial_boot_params, uart); fdt_nop_node(initial_boot_params, uart);
fdt_nop_property(initial_boot_params, aliases, fdt_nop_property(initial_boot_params, aliases,
......
/*
* 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) 2004-2007 Cavium Networks
*/
#include <linux/console.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
#include <linux/tty.h>
#include <linux/irq.h>
#include <asm/time.h>
#include <asm/octeon/octeon.h>
#define DEBUG_UART 1
unsigned int octeon_serial_in(struct uart_port *up, int offset)
{
int rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3)));
if (offset == UART_IIR && (rv & 0xf) == 7) {
/* Busy interrupt, read the USR (39) and try again. */
cvmx_read_csr((uint64_t)(up->membase + (39 << 3)));
rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3)));
}
return rv;
}
void octeon_serial_out(struct uart_port *up, int offset, int value)
{
/*
* If bits 6 or 7 of the OCTEON UART's LCR are set, it quits
* working.
*/
if (offset == UART_LCR)
value &= 0x9f;
cvmx_write_csr((uint64_t)(up->membase + (offset << 3)), (u8)value);
}
static int octeon_serial_probe(struct platform_device *pdev)
{
int irq, res;
struct resource *res_mem;
struct uart_8250_port up;
/* All adaptors have an irq. */
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
memset(&up, 0, sizeof(up));
up.port.flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
up.port.type = PORT_OCTEON;
up.port.iotype = UPIO_MEM;
up.port.regshift = 3;
up.port.dev = &pdev->dev;
if (octeon_is_simulation())
/* Make simulator output fast*/
up.port.uartclk = 115200 * 16;
else
up.port.uartclk = octeon_get_io_clock_rate();
up.port.serial_in = octeon_serial_in;
up.port.serial_out = octeon_serial_out;
up.port.irq = irq;
res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res_mem == NULL) {
dev_err(&pdev->dev, "found no memory resource\n");
return -ENXIO;
}
up.port.mapbase = res_mem->start;
up.port.membase = ioremap(res_mem->start, resource_size(res_mem));
res = serial8250_register_8250_port(&up);
return res >= 0 ? 0 : res;
}
static struct of_device_id octeon_serial_match[] = {
{
.compatible = "cavium,octeon-3860-uart",
},
{},
};
MODULE_DEVICE_TABLE(of, octeon_serial_match);
static struct platform_driver octeon_serial_driver = {
.probe = octeon_serial_probe,
.driver = {
.owner = THIS_MODULE,
.name = "octeon_serial",
.of_match_table = octeon_serial_match,
},
};
static int __init octeon_serial_init(void)
{
return platform_driver_register(&octeon_serial_driver);
}
late_initcall(octeon_serial_init);
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* Copyright (C) 2008, 2009 Wind River Systems * Copyright (C) 2008, 2009 Wind River Systems
* written by Ralf Baechle <ralf@linux-mips.org> * written by Ralf Baechle <ralf@linux-mips.org>
*/ */
#include <linux/compiler.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/console.h> #include <linux/console.h>
...@@ -40,12 +41,6 @@ ...@@ -40,12 +41,6 @@
#include <asm/octeon/pci-octeon.h> #include <asm/octeon/pci-octeon.h>
#include <asm/octeon/cvmx-mio-defs.h> #include <asm/octeon/cvmx-mio-defs.h>
#ifdef CONFIG_CAVIUM_DECODE_RSL
extern void cvmx_interrupt_rsl_decode(void);
extern int __cvmx_interrupt_ecc_report_single_bit_errors;
extern void cvmx_interrupt_rsl_enable(void);
#endif
extern struct plat_smp_ops octeon_smp_ops; extern struct plat_smp_ops octeon_smp_ops;
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
...@@ -462,18 +457,6 @@ static void octeon_halt(void) ...@@ -462,18 +457,6 @@ static void octeon_halt(void)
octeon_kill_core(NULL); octeon_kill_core(NULL);
} }
/**
* Handle all the error condition interrupts that might occur.
*
*/
#ifdef CONFIG_CAVIUM_DECODE_RSL
static irqreturn_t octeon_rlm_interrupt(int cpl, void *dev_id)
{
cvmx_interrupt_rsl_decode();
return IRQ_HANDLED;
}
#endif
/** /**
* Return a string representing the system type * Return a string representing the system type
* *
...@@ -712,7 +695,7 @@ void __init prom_init(void) ...@@ -712,7 +695,7 @@ void __init prom_init(void)
if (cvmx_read_csr(CVMX_L2D_FUS3) & (3ull << 34)) { if (cvmx_read_csr(CVMX_L2D_FUS3) & (3ull << 34)) {
pr_info("Skipping L2 locking due to reduced L2 cache size\n"); pr_info("Skipping L2 locking due to reduced L2 cache size\n");
} else { } else {
uint32_t ebase = read_c0_ebase() & 0x3ffff000; uint32_t __maybe_unused ebase = read_c0_ebase() & 0x3ffff000;
#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB #ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB
/* TLB refill */ /* TLB refill */
cvmx_l2c_lock_mem_region(ebase, 0x100); cvmx_l2c_lock_mem_region(ebase, 0x100);
...@@ -996,7 +979,7 @@ void __init plat_mem_setup(void) ...@@ -996,7 +979,7 @@ void __init plat_mem_setup(void)
cvmx_bootmem_unlock(); cvmx_bootmem_unlock();
/* Add the memory region for the kernel. */ /* Add the memory region for the kernel. */
kernel_start = (unsigned long) _text; kernel_start = (unsigned long) _text;
kernel_size = ALIGN(_end - _text, 0x100000); kernel_size = _end - _text;
/* Adjust for physical offset. */ /* Adjust for physical offset. */
kernel_start &= ~0xffffffff80000000ULL; kernel_start &= ~0xffffffff80000000ULL;
...@@ -1064,15 +1047,6 @@ void prom_free_prom_memory(void) ...@@ -1064,15 +1047,6 @@ void prom_free_prom_memory(void)
panic("Core-14449 WAR not in place (%04x).\n" panic("Core-14449 WAR not in place (%04x).\n"
"Please build kernel with proper options (CONFIG_CAVIUM_CN63XXP1).", insn); "Please build kernel with proper options (CONFIG_CAVIUM_CN63XXP1).", insn);
} }
#ifdef CONFIG_CAVIUM_DECODE_RSL
cvmx_interrupt_rsl_enable();
/* Add an interrupt handler for general failures. */
if (request_irq(OCTEON_IRQ_RML, octeon_rlm_interrupt, IRQF_SHARED,
"RML/RSL", octeon_rlm_interrupt)) {
panic("Unable to request_irq(OCTEON_IRQ_RML)");
}
#endif
} }
int octeon_prune_device_tree(void); int octeon_prune_device_tree(void);
......
CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD=y CONFIG_CAVIUM_OCTEON_SOC=y
CONFIG_CAVIUM_CN63XXP1=y CONFIG_CAVIUM_CN63XXP1=y
CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=2 CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=2
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_SMP=y CONFIG_SMP=y
CONFIG_NR_CPUS=32 CONFIG_NR_CPUS=32
CONFIG_HZ_100=y CONFIG_HZ_100=y
CONFIG_PREEMPT=y CONFIG_PREEMPT=y
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT=y
...@@ -50,7 +48,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ...@@ -50,7 +48,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_FW_LOADER is not set # CONFIG_FW_LOADER is not set
CONFIG_MTD=y CONFIG_MTD=y
# CONFIG_MTD_OF_PARTS is not set # CONFIG_MTD_OF_PARTS is not set
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_AMDSTD=y
...@@ -114,6 +111,7 @@ CONFIG_SERIAL_8250=y ...@@ -114,6 +111,7 @@ CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=2 CONFIG_SERIAL_8250_NR_UARTS=2
CONFIG_SERIAL_8250_RUNTIME_UARTS=2 CONFIG_SERIAL_8250_RUNTIME_UARTS=2
CONFIG_SERIAL_8250_DW=y
# CONFIG_HW_RANDOM is not set # CONFIG_HW_RANDOM is not set
CONFIG_I2C=y CONFIG_I2C=y
CONFIG_I2C_OCTEON=y CONFIG_I2C_OCTEON=y
......
CONFIG_WR_PPMC=y
CONFIG_HZ_1000=y
CONFIG_EXPERIMENTAL=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_EXPERT=y
CONFIG_KALLSYMS_EXTRA_PASS=y
# CONFIG_EPOLL is not set
CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_PCI=y
CONFIG_HOTPLUG_PCI=y
CONFIG_BINFMT_MISC=y
CONFIG_PM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_XFRM_MIGRATE=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_IP_MROUTE=y
CONFIG_ARPD=y
CONFIG_INET_XFRM_MODE_TRANSPORT=m
CONFIG_INET_XFRM_MODE_TUNNEL=m
CONFIG_INET_XFRM_MODE_BEET=m
CONFIG_TCP_MD5SIG=y
# CONFIG_IPV6 is not set
CONFIG_NETWORK_SECMARK=y
CONFIG_FW_LOADER=m
CONFIG_BLK_DEV_RAM=y
CONFIG_SGI_IOC4=m
CONFIG_NETDEVICES=y
CONFIG_PHYLIB=y
CONFIG_VITESSE_PHY=m
CONFIG_SMSC_PHY=m
CONFIG_NET_ETHERNET=y
CONFIG_NET_PCI=y
CONFIG_E100=y
CONFIG_QLA3XXX=m
CONFIG_CHELSIO_T3=m
CONFIG_NETXEN_NIC=m
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=1
CONFIG_SERIAL_8250_RUNTIME_UARTS=1
# CONFIG_HW_RANDOM is not set
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_DLM=m
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="console=ttyS0,115200n8"
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRC_CCITT=y
CONFIG_CRC16=y
CONFIG_LIBCRC32C=y
...@@ -5,6 +5,5 @@ ...@@ -5,6 +5,5 @@
obj-y := ecc-berr.o int-handler.o ioasic-irq.o kn01-berr.o \ obj-y := ecc-berr.o int-handler.o ioasic-irq.o kn01-berr.o \
kn02-irq.o kn02xa-berr.o reset.o setup.o time.o kn02-irq.o kn02xa-berr.o reset.o setup.o time.o
obj-$(CONFIG_PROM_CONSOLE) += promcon.o
obj-$(CONFIG_TC) += tc.o obj-$(CONFIG_TC) += tc.o
obj-$(CONFIG_CPU_HAS_WB) += wbflush.o obj-$(CONFIG_CPU_HAS_WB) += wbflush.o
/*
* Wrap-around code for a console using the
* DECstation PROM io-routines.
*
* Copyright (c) 1998 Harald Koerfgen
*/
#include <linux/tty.h>
#include <linux/ptrace.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/fs.h>
#include <asm/dec/prom.h>
static void prom_console_write(struct console *co, const char *s,
unsigned count)
{
unsigned i;
/*
* Now, do each character
*/
for (i = 0; i < count; i++) {
if (*s == 10)
prom_printf("%c", 13);
prom_printf("%c", *s++);
}
}
static int __init prom_console_setup(struct console *co, char *options)
{
return 0;
}
static struct console sercons = {
.name = "ttyS",
.write = prom_console_write,
.setup = prom_console_setup,
.flags = CON_PRINTBUFFER,
.index = -1,
};
/*
* Register console.
*/
static int __init prom_console_init(void)
{
register_console(&sercons);
return 0;
}
console_initcall(prom_console_init);
...@@ -406,12 +406,12 @@ int cfe_setenv(char *name, char *val) ...@@ -406,12 +406,12 @@ int cfe_setenv(char *name, char *val)
return xiocb.xiocb_status; return xiocb.xiocb_status;
} }
int cfe_write(int handle, unsigned char *buffer, int length) int cfe_write(int handle, const char *buffer, int length)
{ {
return cfe_writeblk(handle, 0, buffer, length); return cfe_writeblk(handle, 0, buffer, length);
} }
int cfe_writeblk(int handle, s64 offset, unsigned char *buffer, int length) int cfe_writeblk(int handle, s64 offset, const char *buffer, int length)
{ {
struct cfe_xiocb xiocb; struct cfe_xiocb xiocb;
......
...@@ -11,6 +11,35 @@ ...@@ -11,6 +11,35 @@
#include <linux/notifier.h> #include <linux/notifier.h>
#if defined(CONFIG_CPU_CAVIUM_OCTEON)
extern void octeon_cop2_save(struct octeon_cop2_state *);
extern void octeon_cop2_restore(struct octeon_cop2_state *);
#define cop2_save(r) octeon_cop2_save(r)
#define cop2_restore(r) octeon_cop2_restore(r)
#define cop2_present 1
#define cop2_lazy_restore 1
#elif defined(CONFIG_CPU_XLP)
extern void nlm_cop2_save(struct nlm_cop2_state *);
extern void nlm_cop2_restore(struct nlm_cop2_state *);
#define cop2_save(r) nlm_cop2_save(r)
#define cop2_restore(r) nlm_cop2_restore(r)
#define cop2_present 1
#define cop2_lazy_restore 0
#else
#define cop2_present 0
#define cop2_lazy_restore 0
#define cop2_save(r)
#define cop2_restore(r)
#endif
enum cu2_ops { enum cu2_ops {
CU2_EXCEPTION, CU2_EXCEPTION,
CU2_LWC2_OP, CU2_LWC2_OP,
......
...@@ -24,6 +24,16 @@ ...@@ -24,6 +24,16 @@
#ifndef cpu_has_tlb #ifndef cpu_has_tlb
#define cpu_has_tlb (cpu_data[0].options & MIPS_CPU_TLB) #define cpu_has_tlb (cpu_data[0].options & MIPS_CPU_TLB)
#endif #endif
/*
* For the moment we don't consider R6000 and R8000 so we can assume that
* anything that doesn't support R4000-style exceptions and interrupts is
* R3000-like. Users should still treat these two macro definitions as
* opaque.
*/
#ifndef cpu_has_3kex
#define cpu_has_3kex (!cpu_has_4kex)
#endif
#ifndef cpu_has_4kex #ifndef cpu_has_4kex
#define cpu_has_4kex (cpu_data[0].options & MIPS_CPU_4KEX) #define cpu_has_4kex (cpu_data[0].options & MIPS_CPU_4KEX)
#endif #endif
...@@ -87,19 +97,23 @@ ...@@ -87,19 +97,23 @@
#define cpu_has_mips16 (cpu_data[0].ases & MIPS_ASE_MIPS16) #define cpu_has_mips16 (cpu_data[0].ases & MIPS_ASE_MIPS16)
#endif #endif
#ifndef cpu_has_mdmx #ifndef cpu_has_mdmx
#define cpu_has_mdmx (cpu_data[0].ases & MIPS_ASE_MDMX) #define cpu_has_mdmx (cpu_data[0].ases & MIPS_ASE_MDMX)
#endif #endif
#ifndef cpu_has_mips3d #ifndef cpu_has_mips3d
#define cpu_has_mips3d (cpu_data[0].ases & MIPS_ASE_MIPS3D) #define cpu_has_mips3d (cpu_data[0].ases & MIPS_ASE_MIPS3D)
#endif #endif
#ifndef cpu_has_smartmips #ifndef cpu_has_smartmips
#define cpu_has_smartmips (cpu_data[0].ases & MIPS_ASE_SMARTMIPS) #define cpu_has_smartmips (cpu_data[0].ases & MIPS_ASE_SMARTMIPS)
#endif #endif
#ifndef cpu_has_rixi #ifndef cpu_has_rixi
#define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI) #define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI)
#endif #endif
#ifndef cpu_has_mmips #ifndef cpu_has_mmips
#define cpu_has_mmips (cpu_data[0].options & MIPS_CPU_MICROMIPS) # ifdef CONFIG_SYS_SUPPORTS_MICROMIPS
# define cpu_has_mmips (cpu_data[0].options & MIPS_CPU_MICROMIPS)
# else
# define cpu_has_mmips 0
# endif
#endif #endif
#ifndef cpu_has_vtag_icache #ifndef cpu_has_vtag_icache
#define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG) #define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
...@@ -111,7 +125,7 @@ ...@@ -111,7 +125,7 @@
#define cpu_has_ic_fills_f_dc (cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC) #define cpu_has_ic_fills_f_dc (cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC)
#endif #endif
#ifndef cpu_has_pindexed_dcache #ifndef cpu_has_pindexed_dcache
#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX) #define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
#endif #endif
#ifndef cpu_has_local_ebase #ifndef cpu_has_local_ebase
#define cpu_has_local_ebase 1 #define cpu_has_local_ebase 1
...@@ -136,7 +150,6 @@ ...@@ -136,7 +150,6 @@
#endif #endif
#endif #endif
# define cpu_has_mips_1 (cpu_data[0].isa_level & MIPS_CPU_ISA_I)
#ifndef cpu_has_mips_2 #ifndef cpu_has_mips_2
# define cpu_has_mips_2 (cpu_data[0].isa_level & MIPS_CPU_ISA_II) # define cpu_has_mips_2 (cpu_data[0].isa_level & MIPS_CPU_ISA_II)
#endif #endif
...@@ -149,18 +162,18 @@ ...@@ -149,18 +162,18 @@
#ifndef cpu_has_mips_5 #ifndef cpu_has_mips_5
# define cpu_has_mips_5 (cpu_data[0].isa_level & MIPS_CPU_ISA_V) # define cpu_has_mips_5 (cpu_data[0].isa_level & MIPS_CPU_ISA_V)
#endif #endif
# ifndef cpu_has_mips32r1 #ifndef cpu_has_mips32r1
# define cpu_has_mips32r1 (cpu_data[0].isa_level & MIPS_CPU_ISA_M32R1) # define cpu_has_mips32r1 (cpu_data[0].isa_level & MIPS_CPU_ISA_M32R1)
# endif #endif
# ifndef cpu_has_mips32r2 #ifndef cpu_has_mips32r2
# define cpu_has_mips32r2 (cpu_data[0].isa_level & MIPS_CPU_ISA_M32R2) # define cpu_has_mips32r2 (cpu_data[0].isa_level & MIPS_CPU_ISA_M32R2)
# endif #endif
# ifndef cpu_has_mips64r1 #ifndef cpu_has_mips64r1
# define cpu_has_mips64r1 (cpu_data[0].isa_level & MIPS_CPU_ISA_M64R1) # define cpu_has_mips64r1 (cpu_data[0].isa_level & MIPS_CPU_ISA_M64R1)
# endif #endif
# ifndef cpu_has_mips64r2 #ifndef cpu_has_mips64r2
# define cpu_has_mips64r2 (cpu_data[0].isa_level & MIPS_CPU_ISA_M64R2) # define cpu_has_mips64r2 (cpu_data[0].isa_level & MIPS_CPU_ISA_M64R2)
# endif #endif
/* /*
* Shortcuts ... * Shortcuts ...
...@@ -182,9 +195,9 @@ ...@@ -182,9 +195,9 @@
* has CLO and CLZ but not DCLO nor DCLZ. For 64-bit kernels * has CLO and CLZ but not DCLO nor DCLZ. For 64-bit kernels
* cpu_has_clo_clz also indicates the availability of DCLO and DCLZ. * cpu_has_clo_clz also indicates the availability of DCLO and DCLZ.
*/ */
# ifndef cpu_has_clo_clz #ifndef cpu_has_clo_clz
# define cpu_has_clo_clz cpu_has_mips_r #define cpu_has_clo_clz cpu_has_mips_r
# endif #endif
#ifndef cpu_has_dsp #ifndef cpu_has_dsp
#define cpu_has_dsp (cpu_data[0].ases & MIPS_ASE_DSP) #define cpu_has_dsp (cpu_data[0].ases & MIPS_ASE_DSP)
...@@ -210,7 +223,7 @@ ...@@ -210,7 +223,7 @@
# define cpu_has_64bits (cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT) # define cpu_has_64bits (cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT)
# endif # endif
# ifndef cpu_has_64bit_zero_reg # ifndef cpu_has_64bit_zero_reg
# define cpu_has_64bit_zero_reg (cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT) # define cpu_has_64bit_zero_reg (cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT)
# endif # endif
# ifndef cpu_has_64bit_gp_regs # ifndef cpu_has_64bit_gp_regs
# define cpu_has_64bit_gp_regs 0 # define cpu_has_64bit_gp_regs 0
......
...@@ -282,18 +282,17 @@ enum cpu_type_enum { ...@@ -282,18 +282,17 @@ enum cpu_type_enum {
* ISA Level encodings * ISA Level encodings
* *
*/ */
#define MIPS_CPU_ISA_I 0x00000001 #define MIPS_CPU_ISA_II 0x00000001
#define MIPS_CPU_ISA_II 0x00000002 #define MIPS_CPU_ISA_III 0x00000002
#define MIPS_CPU_ISA_III 0x00000004 #define MIPS_CPU_ISA_IV 0x00000004
#define MIPS_CPU_ISA_IV 0x00000008 #define MIPS_CPU_ISA_V 0x00000008
#define MIPS_CPU_ISA_V 0x00000010 #define MIPS_CPU_ISA_M32R1 0x00000010
#define MIPS_CPU_ISA_M32R1 0x00000020 #define MIPS_CPU_ISA_M32R2 0x00000020
#define MIPS_CPU_ISA_M32R2 0x00000040 #define MIPS_CPU_ISA_M64R1 0x00000040
#define MIPS_CPU_ISA_M64R1 0x00000080 #define MIPS_CPU_ISA_M64R2 0x00000080
#define MIPS_CPU_ISA_M64R2 0x00000100
#define MIPS_CPU_ISA_32BIT (MIPS_CPU_ISA_II | MIPS_CPU_ISA_M32R1 | \
#define MIPS_CPU_ISA_32BIT (MIPS_CPU_ISA_I | MIPS_CPU_ISA_II | \ MIPS_CPU_ISA_M32R2)
MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2)
#define MIPS_CPU_ISA_64BIT (MIPS_CPU_ISA_III | MIPS_CPU_ISA_IV | \ #define MIPS_CPU_ISA_64BIT (MIPS_CPU_ISA_III | MIPS_CPU_ISA_IV | \
MIPS_CPU_ISA_V | MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2) MIPS_CPU_ISA_V | MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)
......
...@@ -115,8 +115,8 @@ int cfe_read(int handle, unsigned char *buffer, int length); ...@@ -115,8 +115,8 @@ int cfe_read(int handle, unsigned char *buffer, int length);
int cfe_readblk(int handle, int64_t offset, unsigned char *buffer, int cfe_readblk(int handle, int64_t offset, unsigned char *buffer,
int length); int length);
int cfe_setenv(char *name, char *val); int cfe_setenv(char *name, char *val);
int cfe_write(int handle, unsigned char *buffer, int length); int cfe_write(int handle, const char *buffer, int length);
int cfe_writeblk(int handle, int64_t offset, unsigned char *buffer, int cfe_writeblk(int handle, int64_t offset, const char *buffer,
int length); int length);
#endif /* CFE_API_H */ #endif /* CFE_API_H */
...@@ -347,7 +347,7 @@ struct gic_shared_intr_map { ...@@ -347,7 +347,7 @@ struct gic_shared_intr_map {
#define GIC_CPU_INT2 2 /* . */ #define GIC_CPU_INT2 2 /* . */
#define GIC_CPU_INT3 3 /* . */ #define GIC_CPU_INT3 3 /* . */
#define GIC_CPU_INT4 4 /* . */ #define GIC_CPU_INT4 4 /* . */
#define GIC_CPU_INT5 5 /* Core Interrupt 5 */ #define GIC_CPU_INT5 5 /* Core Interrupt 7 */
/* Local GIC interrupts. */ /* Local GIC interrupts. */
#define GIC_INT_TMR (GIC_CPU_INT5) #define GIC_INT_TMR (GIC_CPU_INT5)
......
...@@ -170,6 +170,11 @@ static inline void * isa_bus_to_virt(unsigned long address) ...@@ -170,6 +170,11 @@ static inline void * isa_bus_to_virt(unsigned long address)
extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags); extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags);
extern void __iounmap(const volatile void __iomem *addr); extern void __iounmap(const volatile void __iomem *addr);
#ifndef CONFIG_PCI
struct pci_dev;
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
#endif
static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
unsigned long flags) unsigned long flags)
{ {
...@@ -449,6 +454,11 @@ __BUILDIO(q, u64) ...@@ -449,6 +454,11 @@ __BUILDIO(q, u64)
#define readl_relaxed readl #define readl_relaxed readl
#define readq_relaxed readq #define readq_relaxed readq
#define writeb_relaxed writeb
#define writew_relaxed writew
#define writel_relaxed writel
#define writeq_relaxed writeq
#define readb_be(addr) \ #define readb_be(addr) \
__raw_readb((__force unsigned *)(addr)) __raw_readb((__force unsigned *)(addr))
#define readw_be(addr) \ #define readw_be(addr) \
......
/*
* Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
* published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
*/
#ifndef _ASM_KSPD_H
#define _ASM_KSPD_H
struct kspd_notifications {
void (*kspd_sp_exit)(int sp_id);
struct list_head list;
};
static inline void kspd_notify(struct kspd_notifications *notify)
{
}
#endif
...@@ -14,8 +14,11 @@ ...@@ -14,8 +14,11 @@
* This handles the memory map. * This handles the memory map.
* We handle pages at KSEG0 for kernels with 32 bit address space. * We handle pages at KSEG0 for kernels with 32 bit address space.
*/ */
#define PAGE_OFFSET 0x94000000UL #define PAGE_OFFSET _AC(0x94000000, UL)
#define PHYS_OFFSET 0x14000000UL #define PHYS_OFFSET _AC(0x14000000, UL)
#define UNCAC_BASE _AC(0xb4000000, UL) /* 0xa0000000 + PHYS_OFFSET */
#define IO_BASE UNCAC_BASE
#include <asm/mach-generic/spaces.h> #include <asm/mach-generic/spaces.h>
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
* compile time if only one CPU support is enabled (idea stolen from * compile time if only one CPU support is enabled (idea stolen from
* arm mach-types) * arm mach-types)
*/ */
#define BCM3368_CPU_ID 0x3368
#define BCM6328_CPU_ID 0x6328 #define BCM6328_CPU_ID 0x6328
#define BCM6338_CPU_ID 0x6338 #define BCM6338_CPU_ID 0x6338
#define BCM6345_CPU_ID 0x6345 #define BCM6345_CPU_ID 0x6345
...@@ -22,6 +23,19 @@ u16 __bcm63xx_get_cpu_id(void); ...@@ -22,6 +23,19 @@ u16 __bcm63xx_get_cpu_id(void);
u8 bcm63xx_get_cpu_rev(void); u8 bcm63xx_get_cpu_rev(void);
unsigned int bcm63xx_get_cpu_freq(void); unsigned int bcm63xx_get_cpu_freq(void);
#ifdef CONFIG_BCM63XX_CPU_3368
# ifdef bcm63xx_get_cpu_id
# undef bcm63xx_get_cpu_id
# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
# define BCMCPU_RUNTIME_DETECT
# else
# define bcm63xx_get_cpu_id() BCM3368_CPU_ID
# endif
# define BCMCPU_IS_3368() (bcm63xx_get_cpu_id() == BCM3368_CPU_ID)
#else
# define BCMCPU_IS_3368() (0)
#endif
#ifdef CONFIG_BCM63XX_CPU_6328 #ifdef CONFIG_BCM63XX_CPU_6328
# ifdef bcm63xx_get_cpu_id # ifdef bcm63xx_get_cpu_id
# undef bcm63xx_get_cpu_id # undef bcm63xx_get_cpu_id
...@@ -193,6 +207,53 @@ enum bcm63xx_regs_set { ...@@ -193,6 +207,53 @@ enum bcm63xx_regs_set {
#define RSET_XTMDMAS_SIZE(chans) (16 * (chans)) #define RSET_XTMDMAS_SIZE(chans) (16 * (chans))
#define RSET_RNG_SIZE 20 #define RSET_RNG_SIZE 20
/*
* 3368 register sets base address
*/
#define BCM_3368_DSL_LMEM_BASE (0xdeadbeef)
#define BCM_3368_PERF_BASE (0xfff8c000)
#define BCM_3368_TIMER_BASE (0xfff8c040)
#define BCM_3368_WDT_BASE (0xfff8c080)
#define BCM_3368_UART0_BASE (0xfff8c100)
#define BCM_3368_UART1_BASE (0xfff8c120)
#define BCM_3368_GPIO_BASE (0xfff8c080)
#define BCM_3368_SPI_BASE (0xfff8c800)
#define BCM_3368_HSSPI_BASE (0xdeadbeef)
#define BCM_3368_UDC0_BASE (0xdeadbeef)
#define BCM_3368_USBDMA_BASE (0xdeadbeef)
#define BCM_3368_OHCI0_BASE (0xdeadbeef)
#define BCM_3368_OHCI_PRIV_BASE (0xdeadbeef)
#define BCM_3368_USBH_PRIV_BASE (0xdeadbeef)
#define BCM_3368_USBD_BASE (0xdeadbeef)
#define BCM_3368_MPI_BASE (0xfff80000)
#define BCM_3368_PCMCIA_BASE (0xfff80054)
#define BCM_3368_PCIE_BASE (0xdeadbeef)
#define BCM_3368_SDRAM_REGS_BASE (0xdeadbeef)
#define BCM_3368_DSL_BASE (0xdeadbeef)
#define BCM_3368_UBUS_BASE (0xdeadbeef)
#define BCM_3368_ENET0_BASE (0xfff98000)
#define BCM_3368_ENET1_BASE (0xfff98800)
#define BCM_3368_ENETDMA_BASE (0xfff99800)
#define BCM_3368_ENETDMAC_BASE (0xfff99900)
#define BCM_3368_ENETDMAS_BASE (0xfff99a00)
#define BCM_3368_ENETSW_BASE (0xdeadbeef)
#define BCM_3368_EHCI0_BASE (0xdeadbeef)
#define BCM_3368_SDRAM_BASE (0xdeadbeef)
#define BCM_3368_MEMC_BASE (0xfff84000)
#define BCM_3368_DDR_BASE (0xdeadbeef)
#define BCM_3368_M2M_BASE (0xdeadbeef)
#define BCM_3368_ATM_BASE (0xdeadbeef)
#define BCM_3368_XTM_BASE (0xdeadbeef)
#define BCM_3368_XTMDMA_BASE (0xdeadbeef)
#define BCM_3368_XTMDMAC_BASE (0xdeadbeef)
#define BCM_3368_XTMDMAS_BASE (0xdeadbeef)
#define BCM_3368_PCM_BASE (0xfff9c200)
#define BCM_3368_PCMDMA_BASE (0xdeadbeef)
#define BCM_3368_PCMDMAC_BASE (0xdeadbeef)
#define BCM_3368_PCMDMAS_BASE (0xdeadbeef)
#define BCM_3368_RNG_BASE (0xdeadbeef)
#define BCM_3368_MISC_BASE (0xdeadbeef)
/* /*
* 6328 register sets base address * 6328 register sets base address
*/ */
...@@ -238,6 +299,8 @@ enum bcm63xx_regs_set { ...@@ -238,6 +299,8 @@ enum bcm63xx_regs_set {
#define BCM_6328_PCMDMAS_BASE (0xdeadbeef) #define BCM_6328_PCMDMAS_BASE (0xdeadbeef)
#define BCM_6328_RNG_BASE (0xdeadbeef) #define BCM_6328_RNG_BASE (0xdeadbeef)
#define BCM_6328_MISC_BASE (0xb0001800) #define BCM_6328_MISC_BASE (0xb0001800)
#define BCM_6328_OTP_BASE (0xb0000600)
/* /*
* 6338 register sets base address * 6338 register sets base address
*/ */
...@@ -623,6 +686,9 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) ...@@ -623,6 +686,9 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
#ifdef BCMCPU_RUNTIME_DETECT #ifdef BCMCPU_RUNTIME_DETECT
return bcm63xx_regs_base[set]; return bcm63xx_regs_base[set];
#else #else
#ifdef CONFIG_BCM63XX_CPU_3368
__GEN_RSET(3368)
#endif
#ifdef CONFIG_BCM63XX_CPU_6328 #ifdef CONFIG_BCM63XX_CPU_6328
__GEN_RSET(6328) __GEN_RSET(6328)
#endif #endif
...@@ -689,6 +755,52 @@ enum bcm63xx_irq { ...@@ -689,6 +755,52 @@ enum bcm63xx_irq {
IRQ_XTM_DMA0, IRQ_XTM_DMA0,
}; };
/*
* 3368 irqs
*/
#define BCM_3368_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
#define BCM_3368_SPI_IRQ (IRQ_INTERNAL_BASE + 1)
#define BCM_3368_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_3368_UART1_IRQ (IRQ_INTERNAL_BASE + 3)
#define BCM_3368_DSL_IRQ 0
#define BCM_3368_UDC0_IRQ 0
#define BCM_3368_OHCI0_IRQ 0
#define BCM_3368_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
#define BCM_3368_ENET1_IRQ (IRQ_INTERNAL_BASE + 6)
#define BCM_3368_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
#define BCM_3368_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 15)
#define BCM_3368_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 16)
#define BCM_3368_HSSPI_IRQ 0
#define BCM_3368_EHCI0_IRQ 0
#define BCM_3368_USBD_IRQ 0
#define BCM_3368_USBD_RXDMA0_IRQ 0
#define BCM_3368_USBD_TXDMA0_IRQ 0
#define BCM_3368_USBD_RXDMA1_IRQ 0
#define BCM_3368_USBD_TXDMA1_IRQ 0
#define BCM_3368_USBD_RXDMA2_IRQ 0
#define BCM_3368_USBD_TXDMA2_IRQ 0
#define BCM_3368_ENET1_RXDMA_IRQ (IRQ_INTERNAL_BASE + 17)
#define BCM_3368_ENET1_TXDMA_IRQ (IRQ_INTERNAL_BASE + 18)
#define BCM_3368_PCI_IRQ (IRQ_INTERNAL_BASE + 31)
#define BCM_3368_PCMCIA_IRQ 0
#define BCM_3368_ATM_IRQ 0
#define BCM_3368_ENETSW_RXDMA0_IRQ 0
#define BCM_3368_ENETSW_RXDMA1_IRQ 0
#define BCM_3368_ENETSW_RXDMA2_IRQ 0
#define BCM_3368_ENETSW_RXDMA3_IRQ 0
#define BCM_3368_ENETSW_TXDMA0_IRQ 0
#define BCM_3368_ENETSW_TXDMA1_IRQ 0
#define BCM_3368_ENETSW_TXDMA2_IRQ 0
#define BCM_3368_ENETSW_TXDMA3_IRQ 0
#define BCM_3368_XTM_IRQ 0
#define BCM_3368_XTM_DMA0_IRQ 0
#define BCM_3368_EXT_IRQ0 (IRQ_INTERNAL_BASE + 25)
#define BCM_3368_EXT_IRQ1 (IRQ_INTERNAL_BASE + 26)
#define BCM_3368_EXT_IRQ2 (IRQ_INTERNAL_BASE + 27)
#define BCM_3368_EXT_IRQ3 (IRQ_INTERNAL_BASE + 28)
/* /*
* 6328 irqs * 6328 irqs
*/ */
......
...@@ -11,6 +11,7 @@ static inline unsigned long bcm63xx_gpio_count(void) ...@@ -11,6 +11,7 @@ static inline unsigned long bcm63xx_gpio_count(void)
switch (bcm63xx_get_cpu_id()) { switch (bcm63xx_get_cpu_id()) {
case BCM6328_CPU_ID: case BCM6328_CPU_ID:
return 32; return 32;
case BCM3368_CPU_ID:
case BCM6358_CPU_ID: case BCM6358_CPU_ID:
return 40; return 40;
case BCM6338_CPU_ID: case BCM6338_CPU_ID:
......
...@@ -15,6 +15,39 @@ ...@@ -15,6 +15,39 @@
/* Clock Control register */ /* Clock Control register */
#define PERF_CKCTL_REG 0x4 #define PERF_CKCTL_REG 0x4
#define CKCTL_3368_MAC_EN (1 << 3)
#define CKCTL_3368_TC_EN (1 << 5)
#define CKCTL_3368_US_TOP_EN (1 << 6)
#define CKCTL_3368_DS_TOP_EN (1 << 7)
#define CKCTL_3368_APM_EN (1 << 8)
#define CKCTL_3368_SPI_EN (1 << 9)
#define CKCTL_3368_USBS_EN (1 << 10)
#define CKCTL_3368_BMU_EN (1 << 11)
#define CKCTL_3368_PCM_EN (1 << 12)
#define CKCTL_3368_NTP_EN (1 << 13)
#define CKCTL_3368_ACP_B_EN (1 << 14)
#define CKCTL_3368_ACP_A_EN (1 << 15)
#define CKCTL_3368_EMUSB_EN (1 << 17)
#define CKCTL_3368_ENET0_EN (1 << 18)
#define CKCTL_3368_ENET1_EN (1 << 19)
#define CKCTL_3368_USBU_EN (1 << 20)
#define CKCTL_3368_EPHY_EN (1 << 21)
#define CKCTL_3368_ALL_SAFE_EN (CKCTL_3368_MAC_EN | \
CKCTL_3368_TC_EN | \
CKCTL_3368_US_TOP_EN | \
CKCTL_3368_DS_TOP_EN | \
CKCTL_3368_APM_EN | \
CKCTL_3368_SPI_EN | \
CKCTL_3368_USBS_EN | \
CKCTL_3368_BMU_EN | \
CKCTL_3368_PCM_EN | \
CKCTL_3368_NTP_EN | \
CKCTL_3368_ACP_B_EN | \
CKCTL_3368_ACP_A_EN | \
CKCTL_3368_EMUSB_EN | \
CKCTL_3368_USBU_EN)
#define CKCTL_6328_PHYMIPS_EN (1 << 0) #define CKCTL_6328_PHYMIPS_EN (1 << 0)
#define CKCTL_6328_ADSL_QPROC_EN (1 << 1) #define CKCTL_6328_ADSL_QPROC_EN (1 << 1)
#define CKCTL_6328_ADSL_AFE_EN (1 << 2) #define CKCTL_6328_ADSL_AFE_EN (1 << 2)
...@@ -181,6 +214,7 @@ ...@@ -181,6 +214,7 @@
#define SYS_PLL_SOFT_RESET 0x1 #define SYS_PLL_SOFT_RESET 0x1
/* Interrupt Mask register */ /* Interrupt Mask register */
#define PERF_IRQMASK_3368_REG 0xc
#define PERF_IRQMASK_6328_REG 0x20 #define PERF_IRQMASK_6328_REG 0x20
#define PERF_IRQMASK_6338_REG 0xc #define PERF_IRQMASK_6338_REG 0xc
#define PERF_IRQMASK_6345_REG 0xc #define PERF_IRQMASK_6345_REG 0xc
...@@ -190,6 +224,7 @@ ...@@ -190,6 +224,7 @@
#define PERF_IRQMASK_6368_REG 0x20 #define PERF_IRQMASK_6368_REG 0x20
/* Interrupt Status register */ /* Interrupt Status register */
#define PERF_IRQSTAT_3368_REG 0x10
#define PERF_IRQSTAT_6328_REG 0x28 #define PERF_IRQSTAT_6328_REG 0x28
#define PERF_IRQSTAT_6338_REG 0x10 #define PERF_IRQSTAT_6338_REG 0x10
#define PERF_IRQSTAT_6345_REG 0x10 #define PERF_IRQSTAT_6345_REG 0x10
...@@ -199,6 +234,7 @@ ...@@ -199,6 +234,7 @@
#define PERF_IRQSTAT_6368_REG 0x28 #define PERF_IRQSTAT_6368_REG 0x28
/* External Interrupt Configuration register */ /* External Interrupt Configuration register */
#define PERF_EXTIRQ_CFG_REG_3368 0x14
#define PERF_EXTIRQ_CFG_REG_6328 0x18 #define PERF_EXTIRQ_CFG_REG_6328 0x18
#define PERF_EXTIRQ_CFG_REG_6338 0x14 #define PERF_EXTIRQ_CFG_REG_6338 0x14
#define PERF_EXTIRQ_CFG_REG_6345 0x14 #define PERF_EXTIRQ_CFG_REG_6345 0x14
...@@ -236,6 +272,13 @@ ...@@ -236,6 +272,13 @@
#define PERF_SOFTRESET_6362_REG 0x10 #define PERF_SOFTRESET_6362_REG 0x10
#define PERF_SOFTRESET_6368_REG 0x10 #define PERF_SOFTRESET_6368_REG 0x10
#define SOFTRESET_3368_SPI_MASK (1 << 0)
#define SOFTRESET_3368_ENET_MASK (1 << 2)
#define SOFTRESET_3368_MPI_MASK (1 << 3)
#define SOFTRESET_3368_EPHY_MASK (1 << 6)
#define SOFTRESET_3368_USBS_MASK (1 << 11)
#define SOFTRESET_3368_PCM_MASK (1 << 13)
#define SOFTRESET_6328_SPI_MASK (1 << 0) #define SOFTRESET_6328_SPI_MASK (1 << 0)
#define SOFTRESET_6328_EPHY_MASK (1 << 1) #define SOFTRESET_6328_EPHY_MASK (1 << 1)
#define SOFTRESET_6328_SAR_MASK (1 << 2) #define SOFTRESET_6328_SAR_MASK (1 << 2)
...@@ -1370,7 +1413,7 @@ ...@@ -1370,7 +1413,7 @@
#define SPI_6348_RX_DATA 0x80 #define SPI_6348_RX_DATA 0x80
#define SPI_6348_RX_DATA_SIZE 0x3f #define SPI_6348_RX_DATA_SIZE 0x3f
/* BCM 6358/6262/6368 SPI core */ /* BCM 3368/6358/6262/6368 SPI core */
#define SPI_6358_MSG_CTL 0x00 /* 16-bits register */ #define SPI_6358_MSG_CTL 0x00 /* 16-bits register */
#define SPI_6358_MSG_CTL_WIDTH 16 #define SPI_6358_MSG_CTL_WIDTH 16
#define SPI_6358_MSG_DATA 0x02 #define SPI_6358_MSG_DATA 0x02
...@@ -1511,4 +1554,11 @@ ...@@ -1511,4 +1554,11 @@
#define PCIE_DEVICE_OFFSET 0x8000 #define PCIE_DEVICE_OFFSET 0x8000
/*************************************************************************
* _REG relative to RSET_OTP
*************************************************************************/
#define OTP_USER_BITS_6328_REG(i) (0x20 + (i) * 4)
#define OTP_6328_REG3_TP1_DISABLED BIT(9)
#endif /* BCM63XX_REGS_H_ */ #endif /* BCM63XX_REGS_H_ */
...@@ -47,6 +47,12 @@ struct board_info { ...@@ -47,6 +47,12 @@ struct board_info {
/* GPIO LEDs */ /* GPIO LEDs */
struct gpio_led leds[5]; struct gpio_led leds[5];
/* External PHY reset GPIO */
unsigned int ephy_reset_gpio;
/* External PHY reset GPIO flags from gpio.h */
unsigned long ephy_reset_gpio_flags;
}; };
#endif /* ! BOARD_BCM963XX_H_ */ #endif /* ! BOARD_BCM963XX_H_ */
...@@ -11,6 +11,10 @@ static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) ...@@ -11,6 +11,10 @@ static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
static inline int is_bcm63xx_internal_registers(phys_t offset) static inline int is_bcm63xx_internal_registers(phys_t offset)
{ {
switch (bcm63xx_get_cpu_id()) { switch (bcm63xx_get_cpu_id()) {
case BCM3368_CPU_ID:
if (offset >= 0xfff80000)
return 1;
break;
case BCM6338_CPU_ID: case BCM6338_CPU_ID:
case BCM6345_CPU_ID: case BCM6345_CPU_ID:
case BCM6348_CPU_ID: case BCM6348_CPU_ID:
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#ifndef __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H #ifndef __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H
#define __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H #define __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H
#include <linux/bug.h>
struct device; struct device;
extern void octeon_pci_dma_init(void); extern void octeon_pci_dma_init(void);
...@@ -21,18 +23,21 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, ...@@ -21,18 +23,21 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
size_t size) size_t size)
{ {
BUG(); BUG();
return 0;
} }
static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
struct page *page) struct page *page)
{ {
BUG(); BUG();
return 0;
} }
static inline unsigned long plat_dma_addr_to_phys(struct device *dev, static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
dma_addr_t dma_addr) dma_addr_t dma_addr)
{ {
BUG(); BUG();
return 0;
} }
static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
...@@ -44,6 +49,7 @@ static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, ...@@ -44,6 +49,7 @@ static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
static inline int plat_dma_supported(struct device *dev, u64 mask) static inline int plat_dma_supported(struct device *dev, u64 mask)
{ {
BUG(); BUG();
return 0;
} }
static inline void plat_extra_sync_for_device(struct device *dev) static inline void plat_extra_sync_for_device(struct device *dev)
...@@ -60,6 +66,7 @@ static inline int plat_dma_mapping_error(struct device *dev, ...@@ -60,6 +66,7 @@ static inline int plat_dma_mapping_error(struct device *dev,
dma_addr_t dma_addr) dma_addr_t dma_addr)
{ {
BUG(); BUG();
return 0;
} }
dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr); dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
......
...@@ -34,15 +34,10 @@ ...@@ -34,15 +34,10 @@
ori v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE ori v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
dmtc0 v0, CP0_CVMMEMCTL_REG # Write the cavium mem control register dmtc0 v0, CP0_CVMMEMCTL_REG # Write the cavium mem control register
dmfc0 v0, CP0_CVMCTL_REG # Read the cavium control register dmfc0 v0, CP0_CVMCTL_REG # Read the cavium control register
#ifdef CONFIG_CAVIUM_OCTEON_HW_FIX_UNALIGNED
# Disable unaligned load/store support but leave HW fixup enabled # Disable unaligned load/store support but leave HW fixup enabled
# Needed for octeon specific memcpy
or v0, v0, 0x5001 or v0, v0, 0x5001
xor v0, v0, 0x1001 xor v0, v0, 0x1001
#else
# Disable unaligned load/store and HW fixup support
or v0, v0, 0x5001
xor v0, v0, 0x5001
#endif
# Read the processor ID register # Read the processor ID register
mfc0 v1, CP0_PRID_REG mfc0 v1, CP0_PRID_REG
# Disable instruction prefetching (Octeon Pass1 errata) # Disable instruction prefetching (Octeon Pass1 errata)
......
/*
* 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) 2012 Cavium, Inc.
*/
#ifndef _ASM_MACH_CAVIUM_OCTEON_SPACES_H
#define _ASM_MACH_CAVIUM_OCTEON_SPACES_H
#include <linux/const.h>
#ifdef CONFIG_64BIT
/* They are all the same and some OCTEON II cores cannot handle 0xa8.. */
#define CAC_BASE _AC(0x8000000000000000, UL)
#define UNCAC_BASE _AC(0x8000000000000000, UL)
#define IO_BASE _AC(0x8000000000000000, UL)
#endif /* CONFIG_64BIT */
#include <asm/mach-generic/spaces.h>
#endif /* _ASM_MACH_CAVIUM_OCTEON_SPACES_H */
...@@ -66,4 +66,16 @@ static inline int plat_device_is_coherent(struct device *dev) ...@@ -66,4 +66,16 @@ static inline int plat_device_is_coherent(struct device *dev)
#endif #endif
} }
#ifdef CONFIG_SWIOTLB
static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
{
return paddr;
}
static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
{
return daddr;
}
#endif
#endif /* __ASM_MACH_GENERIC_DMA_COHERENCE_H */ #endif /* __ASM_MACH_GENERIC_DMA_COHERENCE_H */
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
/* Intentionally empty macro, used in head.S. Override in /* Intentionally empty macro, used in head.S. Override in
* arch/mips/mach-xxx/kernel-entry-init.h when necessary. * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
*/ */
.macro kernel_entry_setup .macro kernel_entry_setup
.endm .endm
/* /*
* Do SMP slave processor setup necessary before we can savely execute C code. * Do SMP slave processor setup necessary before we can savely execute C code.
......
...@@ -23,6 +23,53 @@ ...@@ -23,6 +23,53 @@
dsrl \res, NSRI_NODEID_SHFT dsrl \res, NSRI_NODEID_SHFT
.endm .endm
/*
* TLB bits
*/
#define PAGE_GLOBAL (1 << 6)
#define PAGE_VALID (1 << 7)
#define PAGE_DIRTY (1 << 8)
#define CACHE_CACHABLE_COW (5 << 9)
/*
* inputs are the text nasid in t1, data nasid in t2.
*/
.macro MAPPED_KERNEL_SETUP_TLB
#ifdef CONFIG_MAPPED_KERNEL
/*
* This needs to read the nasid - assume 0 for now.
* Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0,
* 0+DVG in tlblo_1.
*/
dli t0, 0xffffffffc0000000
dmtc0 t0, CP0_ENTRYHI
li t0, 0x1c000 # Offset of text into node memory
dsll t1, NASID_SHFT # Shift text nasid into place
dsll t2, NASID_SHFT # Same for data nasid
or t1, t1, t0 # Physical load address of kernel text
or t2, t2, t0 # Physical load address of kernel data
dsrl t1, 12 # 4K pfn
dsrl t2, 12 # 4K pfn
dsll t1, 6 # Get pfn into place
dsll t2, 6 # Get pfn into place
li t0, ((PAGE_GLOBAL | PAGE_VALID | CACHE_CACHABLE_COW) >> 6)
or t0, t0, t1
mtc0 t0, CP0_ENTRYLO0 # physaddr, VG, cach exlwr
li t0, ((PAGE_GLOBAL | PAGE_VALID | PAGE_DIRTY | CACHE_CACHABLE_COW) >> 6)
or t0, t0, t2
mtc0 t0, CP0_ENTRYLO1 # physaddr, DVG, cach exlwr
li t0, 0x1ffe000 # MAPPED_KERN_TLBMASK, TLBPGMASK_16M
mtc0 t0, CP0_PAGEMASK
li t0, 0 # KMAP_INX
mtc0 t0, CP0_INDEX
li t0, 1
mtc0 t0, CP0_WIRED
tlbwi
#else
mtc0 zero, CP0_WIRED
#endif
.endm
/* /*
* Intentionally empty macro, used in head.S. Override in * Intentionally empty macro, used in head.S. Override in
* arch/mips/mach-xxx/kernel-entry-init.h when necessary. * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
......
...@@ -11,11 +11,14 @@ ...@@ -11,11 +11,14 @@
#ifndef _ASM_MACH_IP28_SPACES_H #ifndef _ASM_MACH_IP28_SPACES_H
#define _ASM_MACH_IP28_SPACES_H #define _ASM_MACH_IP28_SPACES_H
#define CAC_BASE 0xa800000000000000 #define CAC_BASE _AC(0xa800000000000000, UL)
#define HIGHMEM_START (~0UL) #define HIGHMEM_START (~0UL)
#define PHYS_OFFSET _AC(0x20000000, UL) #define PHYS_OFFSET _AC(0x20000000, UL)
#define UNCAC_BASE _AC(0xc0000000, UL) /* 0xa0000000 + PHYS_OFFSET */
#define IO_BASE UNCAC_BASE
#include <asm/mach-generic/spaces.h> #include <asm/mach-generic/spaces.h>
......
/*
* include/asm-mips/pmc-sierra/msp71xx/gpio.h
*
* 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.
*
* @author Patrick Glass <patrickglass@gmail.com>
*/
#ifndef __PMC_MSP71XX_GPIO_H
#define __PMC_MSP71XX_GPIO_H
/* Max number of gpio's is 28 on chip plus 3 banks of I2C IO Expanders */
#define ARCH_NR_GPIOS (28 + (3 * 8))
/* new generic GPIO API - see Documentation/gpio.txt */
#include <asm-generic/gpio.h>
#define gpio_get_value __gpio_get_value
#define gpio_set_value __gpio_set_value
#define gpio_cansleep __gpio_cansleep
/* Setup calls for the gpio and gpio extended */
extern void msp71xx_init_gpio(void);
extern void msp71xx_init_gpio_extended(void);
extern int msp71xx_set_output_drive(unsigned gpio, int value);
/* Custom output drive functionss */
static inline int gpio_set_output_drive(unsigned gpio, int value)
{
return msp71xx_set_output_drive(gpio, value);
}
/* IRQ's are not supported for gpio lines */
static inline int gpio_to_irq(unsigned gpio)
{
return -EINVAL;
}
static inline int irq_to_gpio(unsigned irq)
{
return -EINVAL;
}
#endif /* __PMC_MSP71XX_GPIO_H */
/*
* This is a direct copy of the ev96100.h file, with a global
* search and replace. The numbers are the same.
*
* The reason I'm duplicating this is so that the 64120/96100
* defines won't be confusing in the source code.
*/
#ifndef __ASM_MIPS_GT64120_H
#define __ASM_MIPS_GT64120_H
/*
* This is the CPU physical memory map of PPMC Board:
*
* 0x00000000-0x03FFFFFF - 64MB SDRAM (SCS[0]#)
* 0x1C000000-0x1C000000 - LED (CS0)
* 0x1C800000-0x1C800007 - UART 16550 port (CS1)
* 0x1F000000-0x1F000000 - MailBox (CS3)
* 0x1FC00000-0x20000000 - 4MB Flash (BOOT CS)
*/
#define WRPPMC_SDRAM_SCS0_BASE 0x00000000
#define WRPPMC_SDRAM_SCS0_SIZE 0x04000000
#define WRPPMC_UART16550_BASE 0x1C800000
#define WRPPMC_UART16550_CLOCK 3686400 /* 3.68MHZ */
#define WRPPMC_LED_BASE 0x1C000000
#define WRPPMC_MBOX_BASE 0x1F000000
#define WRPPMC_BOOTROM_BASE 0x1FC00000
#define WRPPMC_BOOTROM_SIZE 0x00400000 /* 4M Flash */
#define WRPPMC_MIPS_TIMER_IRQ 7 /* MIPS compare/count timer interrupt */
#define WRPPMC_UART16550_IRQ 6
#define WRPPMC_PCI_INTA_IRQ 3
/*
* PCI Bus I/O and Memory resources allocation
*
* NOTE: We only have PCI_0 hose interface
*/
#define GT_PCI_MEM_BASE 0x13000000UL
#define GT_PCI_MEM_SIZE 0x02000000UL
#define GT_PCI_IO_BASE 0x11000000UL
#define GT_PCI_IO_SIZE 0x02000000UL
/*
* PCI interrupts will come in on either the INTA or INTD interrupt lines,
* which are mapped to the #2 and #5 interrupt pins of the MIPS. On our
* boards, they all either come in on IntD or they all come in on IntA, they
* aren't mixed. There can be numerous PCI interrupts, so we keep a list of the
* "requested" interrupt numbers and go through the list whenever we get an
* IntA/D.
*
* Interrupts < 8 are directly wired to the processor; PCI INTA is 8 and
* INTD is 11.
*/
#define GT_TIMER 4
#define GT_INTA 2
#define GT_INTD 5
#ifndef __ASSEMBLY__
/*
* GT64120 internal register space base address
*/
extern unsigned long gt64120_base;
#define GT64120_BASE (gt64120_base)
/* define WRPPMC_EARLY_DEBUG to enable early output something to UART */
#undef WRPPMC_EARLY_DEBUG
#ifdef WRPPMC_EARLY_DEBUG
extern void wrppmc_led_on(int mask);
extern void wrppmc_led_off(int mask);
extern void wrppmc_early_printk(const char *fmt, ...);
#else
#define wrppmc_early_printk(fmt, ...) do {} while (0)
#endif /* WRPPMC_EARLY_DEBUG */
#endif /* __ASSEMBLY__ */
#endif /* __ASM_MIPS_GT64120_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) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
*/
#ifndef __ASM_MIPS_MACH_WRPPMC_WAR_H
#define __ASM_MIPS_MACH_WRPPMC_WAR_H
#define R4600_V1_INDEX_ICACHEOP_WAR 0
#define R4600_V1_HIT_CACHEOP_WAR 0
#define R4600_V2_HIT_CACHEOP_WAR 0
#define R5432_CP0_INTERRUPT_WAR 0
#define BCM1250_M3_WAR 0
#define SIBYTE_1956_WAR 0
#define MIPS4K_ICACHE_REFILL_WAR 0
#define MIPS_CACHE_SYNC_WAR 0
#define TX49XX_ICACHE_INDEX_INV_WAR 0
#define ICACHE_REFILLS_WORKAROUND_WAR 1
#define R10000_LLSC_WAR 0
#define MIPS34K_MISSED_ITLB_WAR 0
#endif /* __ASM_MIPS_MACH_WRPPMC_WAR_H */
...@@ -23,12 +23,6 @@ ...@@ -23,12 +23,6 @@
#define ASCII_DISPLAY_WORD_BASE 0x1f000410 #define ASCII_DISPLAY_WORD_BASE 0x1f000410
#define ASCII_DISPLAY_POS_BASE 0x1f000418 #define ASCII_DISPLAY_POS_BASE 0x1f000418
/*
* Reset register.
*/
#define SOFTRES_REG 0x1f000500
#define GORESET 0x42
/* /*
* Revision register. * Revision register.
*/ */
......
...@@ -596,7 +596,7 @@ ...@@ -596,7 +596,7 @@
#define MIPS_CONF3_RXI (_ULCAST_(1) << 12) #define MIPS_CONF3_RXI (_ULCAST_(1) << 12)
#define MIPS_CONF3_ULRI (_ULCAST_(1) << 13) #define MIPS_CONF3_ULRI (_ULCAST_(1) << 13)
#define MIPS_CONF3_ISA (_ULCAST_(3) << 14) #define MIPS_CONF3_ISA (_ULCAST_(3) << 14)
#define MIPS_CONF3_ISA_OE (_ULCAST_(3) << 16) #define MIPS_CONF3_ISA_OE (_ULCAST_(1) << 16)
#define MIPS_CONF3_VZ (_ULCAST_(1) << 23) #define MIPS_CONF3_VZ (_ULCAST_(1) << 23)
#define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0) #define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0)
......
...@@ -28,11 +28,7 @@ ...@@ -28,11 +28,7 @@
#define TLBMISS_HANDLER_SETUP_PGD(pgd) \ #define TLBMISS_HANDLER_SETUP_PGD(pgd) \
do { \ do { \
void (*tlbmiss_handler_setup_pgd)(unsigned long); \ extern void tlbmiss_handler_setup_pgd(unsigned long); \
extern u32 tlbmiss_handler_setup_pgd_array[16]; \
\
tlbmiss_handler_setup_pgd = \
(__typeof__(tlbmiss_handler_setup_pgd)) tlbmiss_handler_setup_pgd_array; \
tlbmiss_handler_setup_pgd((unsigned long)(pgd)); \ tlbmiss_handler_setup_pgd((unsigned long)(pgd)); \
} while (0) } while (0)
......
...@@ -39,11 +39,17 @@ ...@@ -39,11 +39,17 @@
* Common SMP definitions * Common SMP definitions
*/ */
#define RESET_VEC_PHYS 0x1fc00000 #define RESET_VEC_PHYS 0x1fc00000
#define RESET_VEC_SIZE 8192 /* 8KB reset code and data */
#define RESET_DATA_PHYS (RESET_VEC_PHYS + (1<<10)) #define RESET_DATA_PHYS (RESET_VEC_PHYS + (1<<10))
/* Offsets of parameters in the RESET_DATA_PHYS area */
#define BOOT_THREAD_MODE 0 #define BOOT_THREAD_MODE 0
#define BOOT_NMI_LOCK 4 #define BOOT_NMI_LOCK 4
#define BOOT_NMI_HANDLER 8 #define BOOT_NMI_HANDLER 8
/* CPU ready flags for each CPU */
#define BOOT_CPU_READY 2048
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
...@@ -59,23 +65,32 @@ int nlm_wakeup_secondary_cpus(void); ...@@ -59,23 +65,32 @@ int nlm_wakeup_secondary_cpus(void);
void nlm_rmiboot_preboot(void); void nlm_rmiboot_preboot(void);
void nlm_percpu_init(int hwcpuid); void nlm_percpu_init(int hwcpuid);
static inline void *
nlm_get_boot_data(int offset)
{
return (void *)(CKSEG1ADDR(RESET_DATA_PHYS) + offset);
}
static inline void static inline void
nlm_set_nmi_handler(void *handler) nlm_set_nmi_handler(void *handler)
{ {
char *reset_data; void *nmih = nlm_get_boot_data(BOOT_NMI_HANDLER);
reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS); *(int64_t *)nmih = (long)handler;
*(int64_t *)(reset_data + BOOT_NMI_HANDLER) = (long)handler;
} }
/* /*
* Misc. * Misc.
*/ */
void nlm_init_boot_cpu(void);
unsigned int nlm_get_cpu_frequency(void); unsigned int nlm_get_cpu_frequency(void);
void nlm_node_init(int node); void nlm_node_init(int node);
extern struct plat_smp_ops nlm_smp_ops; extern struct plat_smp_ops nlm_smp_ops;
extern char nlm_reset_entry[], nlm_reset_entry_end[]; extern char nlm_reset_entry[], nlm_reset_entry_end[];
/* SWIOTLB */
extern struct dma_map_ops nlm_swiotlb_dma_ops;
extern unsigned int nlm_threads_per_core; extern unsigned int nlm_threads_per_core;
extern cpumask_t nlm_cpumask; extern cpumask_t nlm_cpumask;
......
...@@ -315,7 +315,7 @@ nlm_pic_send_ipi(uint64_t base, int hwt, int irq, int nmi) ...@@ -315,7 +315,7 @@ nlm_pic_send_ipi(uint64_t base, int hwt, int irq, int nmi)
{ {
uint64_t ipi; uint64_t ipi;
ipi = (nmi << 31) | (irq << 20); ipi = ((uint64_t)nmi << 31) | (irq << 20);
ipi |= ((hwt >> 4) << 16) | (1 << (hwt & 0xf)); /* cpuset and mask */ ipi |= ((hwt >> 4) << 16) | (1 << (hwt & 0xf)); /* cpuset and mask */
nlm_write_pic_reg(base, PIC_IPI_CTL, ipi); nlm_write_pic_reg(base, PIC_IPI_CTL, ipi);
} }
......
...@@ -59,6 +59,7 @@ void xlp_wakeup_secondary_cpus(void); ...@@ -59,6 +59,7 @@ void xlp_wakeup_secondary_cpus(void);
void xlp_mmu_init(void); void xlp_mmu_init(void);
void nlm_hal_init(void); void nlm_hal_init(void);
void *xlp_dt_init(void *fdtp);
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* _ASM_NLM_XLP_H */ #endif /* _ASM_NLM_XLP_H */
...@@ -175,6 +175,10 @@ ...@@ -175,6 +175,10 @@
#define nlm_write_c2_cc14(s, v) __write_32bit_c2_register($30, s, v) #define nlm_write_c2_cc14(s, v) __write_32bit_c2_register($30, s, v)
#define nlm_write_c2_cc15(s, v) __write_32bit_c2_register($31, s, v) #define nlm_write_c2_cc15(s, v) __write_32bit_c2_register($31, s, v)
#define nlm_read_c2_status0() __read_32bit_c2_register($2, 0)
#define nlm_write_c2_status0(v) __write_32bit_c2_register($2, 0, v)
#define nlm_read_c2_status1() __read_32bit_c2_register($2, 1)
#define nlm_write_c2_status1(v) __write_32bit_c2_register($2, 1, v)
#define nlm_read_c2_status(sel) __read_32bit_c2_register($2, 0) #define nlm_read_c2_status(sel) __read_32bit_c2_register($2, 0)
#define nlm_read_c2_config() __read_32bit_c2_register($3, 0) #define nlm_read_c2_config() __read_32bit_c2_register($3, 0)
#define nlm_write_c2_config(v) __write_32bit_c2_register($3, 0, v) #define nlm_write_c2_config(v) __write_32bit_c2_register($3, 0, v)
...@@ -237,7 +241,7 @@ static inline void nlm_msgwait(unsigned int mask) ...@@ -237,7 +241,7 @@ static inline void nlm_msgwait(unsigned int mask)
/* /*
* Disable interrupts and enable COP2 access * Disable interrupts and enable COP2 access
*/ */
static inline uint32_t nlm_cop2_enable(void) static inline uint32_t nlm_cop2_enable_irqsave(void)
{ {
uint32_t sr = read_c0_status(); uint32_t sr = read_c0_status();
...@@ -245,7 +249,7 @@ static inline uint32_t nlm_cop2_enable(void) ...@@ -245,7 +249,7 @@ static inline uint32_t nlm_cop2_enable(void)
return sr; return sr;
} }
static inline void nlm_cop2_restore(uint32_t sr) static inline void nlm_cop2_disable_irqrestore(uint32_t sr)
{ {
write_c0_status(sr); write_c0_status(sr);
} }
...@@ -296,7 +300,7 @@ static inline int nlm_fmn_send(unsigned int size, unsigned int code, ...@@ -296,7 +300,7 @@ static inline int nlm_fmn_send(unsigned int size, unsigned int code,
*/ */
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
nlm_msgsnd(dest); nlm_msgsnd(dest);
status = nlm_read_c2_status(0); status = nlm_read_c2_status0();
if ((status & 0x2) == 1) if ((status & 0x2) == 1)
pr_info("Send pending fail!\n"); pr_info("Send pending fail!\n");
if ((status & 0x4) == 0) if ((status & 0x4) == 0)
...@@ -316,7 +320,7 @@ static inline int nlm_fmn_receive(int bucket, int *size, int *code, int *stid, ...@@ -316,7 +320,7 @@ static inline int nlm_fmn_receive(int bucket, int *size, int *code, int *stid,
/* wait for load pending to clear */ /* wait for load pending to clear */
do { do {
status = nlm_read_c2_status(1); status = nlm_read_c2_status0();
} while ((status & 0x08) != 0); } while ((status & 0x08) != 0);
/* receive error bits */ /* receive error bits */
......
...@@ -227,6 +227,7 @@ enum cvmx_board_types_enum { ...@@ -227,6 +227,7 @@ enum cvmx_board_types_enum {
* use any numbers in this range. * use any numbers in this range.
*/ */
CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001, CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,
CVMX_BOARD_TYPE_UBNT_E100 = 20002,
CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000, CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
/* The remaining range is reserved for future use. */ /* The remaining range is reserved for future use. */
...@@ -325,6 +326,7 @@ static inline const char *cvmx_board_type_to_string(enum ...@@ -325,6 +326,7 @@ static inline const char *cvmx_board_type_to_string(enum
/* Customer private range */ /* Customer private range */
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN) ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX) ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
} }
return "Unsupported Board"; return "Unsupported Board";
......
...@@ -205,10 +205,8 @@ extern int __virt_addr_valid(const volatile void *kaddr); ...@@ -205,10 +205,8 @@ extern int __virt_addr_valid(const volatile void *kaddr);
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE + \ #define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE)
PHYS_OFFSET) #define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET)
#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET - \
PHYS_OFFSET)
#include <asm-generic/memory_model.h> #include <asm-generic/memory_model.h>
#include <asm-generic/getorder.h> #include <asm-generic/getorder.h>
......
...@@ -52,7 +52,6 @@ struct pci_controller { ...@@ -52,7 +52,6 @@ struct pci_controller {
/* /*
* Used by boards to register their PCI busses before the actual scanning. * Used by boards to register their PCI busses before the actual scanning.
*/ */
extern struct pci_controller * alloc_pci_controller(void);
extern void register_pci_controller(struct pci_controller *hose); extern void register_pci_controller(struct pci_controller *hose);
/* /*
......
...@@ -137,7 +137,7 @@ union mips_watch_reg_state { ...@@ -137,7 +137,7 @@ union mips_watch_reg_state {
struct mips3264_watch_reg_state mips3264; struct mips3264_watch_reg_state mips3264;
}; };
#ifdef CONFIG_CPU_CAVIUM_OCTEON #if defined(CONFIG_CPU_CAVIUM_OCTEON)
struct octeon_cop2_state { struct octeon_cop2_state {
/* DMFC2 rt, 0x0201 */ /* DMFC2 rt, 0x0201 */
...@@ -182,13 +182,26 @@ struct octeon_cop2_state { ...@@ -182,13 +182,26 @@ struct octeon_cop2_state {
/* DMFC2 rt, 0x025A; DMFC2 rt, 0x025B - Pass2 */ /* DMFC2 rt, 0x025A; DMFC2 rt, 0x025B - Pass2 */
unsigned long cop2_gfm_result[2]; unsigned long cop2_gfm_result[2];
}; };
#define INIT_OCTEON_COP2 {0,} #define COP2_INIT \
.cp2 = {0,},
struct octeon_cvmseg_state { struct octeon_cvmseg_state {
unsigned long cvmseg[CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE] unsigned long cvmseg[CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE]
[cpu_dcache_line_size() / sizeof(unsigned long)]; [cpu_dcache_line_size() / sizeof(unsigned long)];
}; };
#elif defined(CONFIG_CPU_XLP)
struct nlm_cop2_state {
u64 rx[4];
u64 tx[4];
u32 tx_msg_status;
u32 rx_msg_status;
};
#define COP2_INIT \
.cp2 = {{0}, {0}, 0, 0},
#else
#define COP2_INIT
#endif #endif
typedef struct { typedef struct {
...@@ -231,8 +244,11 @@ struct thread_struct { ...@@ -231,8 +244,11 @@ struct thread_struct {
unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */ unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */
unsigned long error_code; unsigned long error_code;
#ifdef CONFIG_CPU_CAVIUM_OCTEON #ifdef CONFIG_CPU_CAVIUM_OCTEON
struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128))); struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));
struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128))); struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));
#endif
#ifdef CONFIG_CPU_XLP
struct nlm_cop2_state cp2;
#endif #endif
struct mips_abi *abi; struct mips_abi *abi;
}; };
...@@ -245,13 +261,6 @@ struct thread_struct { ...@@ -245,13 +261,6 @@ struct thread_struct {
#define FPAFF_INIT #define FPAFF_INIT
#endif /* CONFIG_MIPS_MT_FPAFF */ #endif /* CONFIG_MIPS_MT_FPAFF */
#ifdef CONFIG_CPU_CAVIUM_OCTEON
#define OCTEON_INIT \
.cp2 = INIT_OCTEON_COP2,
#else
#define OCTEON_INIT
#endif /* CONFIG_CPU_CAVIUM_OCTEON */
#define INIT_THREAD { \ #define INIT_THREAD { \
/* \ /* \
* Saved main processor registers \ * Saved main processor registers \
...@@ -300,9 +309,9 @@ struct thread_struct { ...@@ -300,9 +309,9 @@ struct thread_struct {
.cp0_baduaddr = 0, \ .cp0_baduaddr = 0, \
.error_code = 0, \ .error_code = 0, \
/* \ /* \
* Cavium Octeon specifics (null if not Octeon) \ * Platform specific cop2 registers(null if no COP2) \
*/ \ */ \
OCTEON_INIT \ COP2_INIT \
} }
struct task_struct; struct task_struct;
......
...@@ -69,6 +69,14 @@ ...@@ -69,6 +69,14 @@
LONG_S $24, PT_R24(sp) LONG_S $24, PT_R24(sp)
#ifndef CONFIG_CPU_HAS_SMARTMIPS #ifndef CONFIG_CPU_HAS_SMARTMIPS
LONG_S v1, PT_LO(sp) LONG_S v1, PT_LO(sp)
#endif
#ifdef CONFIG_CPU_CAVIUM_OCTEON
/*
* The Octeon multiplier state is affected by general
* multiply instructions. It must be saved before and
* kernel code might corrupt it
*/
jal octeon_mult_save
#endif #endif
.endm .endm
...@@ -218,17 +226,8 @@ ...@@ -218,17 +226,8 @@
ori $28, sp, _THREAD_MASK ori $28, sp, _THREAD_MASK
xori $28, _THREAD_MASK xori $28, _THREAD_MASK
#ifdef CONFIG_CPU_CAVIUM_OCTEON #ifdef CONFIG_CPU_CAVIUM_OCTEON
.set mips64 .set mips64
pref 0, 0($28) /* Prefetch the current pointer */ pref 0, 0($28) /* Prefetch the current pointer */
pref 0, PT_R31(sp) /* Prefetch the $31(ra) */
/* The Octeon multiplier state is affected by general multiply
instructions. It must be saved before and kernel code might
corrupt it */
jal octeon_mult_save
LONG_L v1, 0($28) /* Load the current pointer */
/* Restore $31(ra) that was changed by the jal */
LONG_L ra, PT_R31(sp)
pref 0, 0(v1) /* Prefetch the current thread */
#endif #endif
.set pop .set pop
.endm .endm
...@@ -248,6 +247,10 @@ ...@@ -248,6 +247,10 @@
.endm .endm
.macro RESTORE_TEMP .macro RESTORE_TEMP
#ifdef CONFIG_CPU_CAVIUM_OCTEON
/* Restore the Octeon multiplier state */
jal octeon_mult_restore
#endif
#ifdef CONFIG_CPU_HAS_SMARTMIPS #ifdef CONFIG_CPU_HAS_SMARTMIPS
LONG_L $24, PT_ACX(sp) LONG_L $24, PT_ACX(sp)
mtlhx $24 mtlhx $24
...@@ -360,10 +363,6 @@ ...@@ -360,10 +363,6 @@
DVPE 5 # dvpe a1 DVPE 5 # dvpe a1
jal mips_ihb jal mips_ihb
#endif /* CONFIG_MIPS_MT_SMTC */ #endif /* CONFIG_MIPS_MT_SMTC */
#ifdef CONFIG_CPU_CAVIUM_OCTEON
/* Restore the Octeon multiplier state */
jal octeon_mult_restore
#endif
mfc0 a0, CP0_STATUS mfc0 a0, CP0_STATUS
ori a0, STATMASK ori a0, STATMASK
xori a0, STATMASK xori a0, STATMASK
......
/*
* GCC stack protector support.
*
* (This is directly adopted from the ARM implementation)
*
* Stack protector works by putting predefined pattern at the start of
* the stack frame and verifying that it hasn't been overwritten when
* returning from the function. The pattern is called stack canary
* and gcc expects it to be defined by a global variable called
* "__stack_chk_guard" on MIPS. This unfortunately means that on SMP
* we cannot have a different canary value per task.
*/
#ifndef _ASM_STACKPROTECTOR_H
#define _ASM_STACKPROTECTOR_H 1
#include <linux/random.h>
#include <linux/version.h>
extern unsigned long __stack_chk_guard;
/*
* Initialize the stackprotector canary value.
*
* NOTE: this must only be called from functions that never return,
* and it must always be inlined.
*/
static __always_inline void boot_init_stack_canary(void)
{
unsigned long canary;
/* Try to get a semi random initial value. */
get_random_bytes(&canary, sizeof(canary));
canary ^= LINUX_VERSION_CODE;
current->stack_canary = canary;
__stack_chk_guard = current->stack_canary;
}
#endif /* _ASM_STACKPROTECTOR_H */
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <asm/cpu-features.h> #include <asm/cpu-features.h>
#include <asm/watch.h> #include <asm/watch.h>
#include <asm/dsp.h> #include <asm/dsp.h>
#include <asm/cop2.h>
struct task_struct; struct task_struct;
...@@ -66,10 +67,18 @@ do { \ ...@@ -66,10 +67,18 @@ do { \
#define switch_to(prev, next, last) \ #define switch_to(prev, next, last) \
do { \ do { \
u32 __usedfpu; \ u32 __usedfpu, __c0_stat; \
__mips_mt_fpaff_switch_to(prev); \ __mips_mt_fpaff_switch_to(prev); \
if (cpu_has_dsp) \ if (cpu_has_dsp) \
__save_dsp(prev); \ __save_dsp(prev); \
if (cop2_present && (KSTK_STATUS(prev) & ST0_CU2)) { \
if (cop2_lazy_restore) \
KSTK_STATUS(prev) &= ~ST0_CU2; \
__c0_stat = read_c0_status(); \
write_c0_status(__c0_stat | ST0_CU2); \
cop2_save(&prev->thread.cp2); \
write_c0_status(__c0_stat & ~ST0_CU2); \
} \
__clear_software_ll_bit(); \ __clear_software_ll_bit(); \
__usedfpu = test_and_clear_tsk_thread_flag(prev, TIF_USEDFPU); \ __usedfpu = test_and_clear_tsk_thread_flag(prev, TIF_USEDFPU); \
(last) = resume(prev, next, task_thread_info(next), __usedfpu); \ (last) = resume(prev, next, task_thread_info(next), __usedfpu); \
...@@ -77,6 +86,14 @@ do { \ ...@@ -77,6 +86,14 @@ do { \
#define finish_arch_switch(prev) \ #define finish_arch_switch(prev) \
do { \ do { \
u32 __c0_stat; \
if (cop2_present && !cop2_lazy_restore && \
(KSTK_STATUS(current) & ST0_CU2)) { \
__c0_stat = read_c0_status(); \
write_c0_status(__c0_stat | ST0_CU2); \
cop2_restore(&current->thread.cp2); \
write_c0_status(__c0_stat & ~ST0_CU2); \
} \
if (cpu_has_dsp) \ if (cpu_has_dsp) \
__restore_dsp(current); \ __restore_dsp(current); \
if (cpu_has_userlocal) \ if (cpu_has_userlocal) \
......
...@@ -109,6 +109,7 @@ static inline struct thread_info *current_thread_info(void) ...@@ -109,6 +109,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_NOHZ 19 /* in adaptive nohz mode */
#define TIF_FIXADE 20 /* Fix address errors in software */ #define TIF_FIXADE 20 /* Fix address errors in software */
#define TIF_LOGADE 21 /* Log address errors to syslog */ #define TIF_LOGADE 21 /* Log address errors to syslog */
#define TIF_32BIT_REGS 22 /* also implies 16/32 fprs */ #define TIF_32BIT_REGS 22 /* also implies 16/32 fprs */
...@@ -124,6 +125,7 @@ static inline struct thread_info *current_thread_info(void) ...@@ -124,6 +125,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SECCOMP (1<<TIF_SECCOMP) #define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_USEDFPU (1<<TIF_USEDFPU) #define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_NOHZ (1<<TIF_NOHZ)
#define _TIF_FIXADE (1<<TIF_FIXADE) #define _TIF_FIXADE (1<<TIF_FIXADE)
#define _TIF_LOGADE (1<<TIF_LOGADE) #define _TIF_LOGADE (1<<TIF_LOGADE)
#define _TIF_32BIT_REGS (1<<TIF_32BIT_REGS) #define _TIF_32BIT_REGS (1<<TIF_32BIT_REGS)
...@@ -131,14 +133,19 @@ static inline struct thread_info *current_thread_info(void) ...@@ -131,14 +133,19 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_FPUBOUND (1<<TIF_FPUBOUND) #define _TIF_FPUBOUND (1<<TIF_FPUBOUND)
#define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) #define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH)
#define _TIF_WORK_SYSCALL_ENTRY (_TIF_NOHZ | _TIF_SYSCALL_TRACE | \
_TIF_SYSCALL_AUDIT)
/* work to do in syscall_trace_leave() */ /* work to do in syscall_trace_leave() */
#define _TIF_WORK_SYSCALL_EXIT (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT) #define _TIF_WORK_SYSCALL_EXIT (_TIF_NOHZ | _TIF_SYSCALL_TRACE | \
_TIF_SYSCALL_AUDIT)
/* work to do on interrupt/exception return */ /* work to do on interrupt/exception return */
#define _TIF_WORK_MASK \ #define _TIF_WORK_MASK \
(_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME) (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
/* work to do on any return to u-space */ /* work to do on any return to u-space */
#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | _TIF_WORK_SYSCALL_EXIT) #define _TIF_ALLWORK_MASK (_TIF_NOHZ | _TIF_WORK_MASK | \
_TIF_WORK_SYSCALL_EXIT)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -47,6 +47,15 @@ typedef struct xtalk_piomap_s *xtalk_piomap_t; ...@@ -47,6 +47,15 @@ typedef struct xtalk_piomap_s *xtalk_piomap_t;
#define XIO_PORT(x) ((xwidgetnum_t)(((x)&XIO_PORT_BITS) >> XIO_PORT_SHIFT)) #define XIO_PORT(x) ((xwidgetnum_t)(((x)&XIO_PORT_BITS) >> XIO_PORT_SHIFT))
#define XIO_PACK(p, o) ((((uint64_t)(p))<<XIO_PORT_SHIFT) | ((o)&XIO_ADDR_BITS)) #define XIO_PACK(p, o) ((((uint64_t)(p))<<XIO_PORT_SHIFT) | ((o)&XIO_ADDR_BITS))
#ifdef CONFIG_PCI
extern int bridge_probe(nasid_t nasid, int widget, int masterwid);
#else
static inline int bridge_probe(nasid_t nasid, int widget, int masterwid)
{
return 0;
}
#endif
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* _ASM_XTALK_XTALK_H */ #endif /* _ASM_XTALK_XTALK_H */
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
* *
* Copyright (C) 1995, 96, 97, 98, 99, 2003, 05 Ralf Baechle * Copyright (C) 1995, 96, 97, 98, 99, 2003, 05 Ralf Baechle
*/ */
#ifndef _ASM_FCNTL_H #ifndef _UAPI_ASM_FCNTL_H
#define _ASM_FCNTL_H #define _UAPI_ASM_FCNTL_H
#include <asm/sgidefs.h>
#define O_APPEND 0x0008 #define O_APPEND 0x0008
#define O_DSYNC 0x0010 /* used to be O_SYNC, see below */ #define O_DSYNC 0x0010 /* used to be O_SYNC, see below */
...@@ -55,14 +56,15 @@ ...@@ -55,14 +56,15 @@
* contain all the same fields as struct flock. * contain all the same fields as struct flock.
*/ */
#ifdef CONFIG_32BIT #if _MIPS_SIM != _MIPS_SIM_ABI64
#include <linux/types.h> #include <linux/types.h>
struct flock { struct flock {
short l_type; short l_type;
short l_whence; short l_whence;
off_t l_start; __kernel_off_t l_start;
off_t l_len; __kernel_off_t l_len;
long l_sysid; long l_sysid;
__kernel_pid_t l_pid; __kernel_pid_t l_pid;
long pad[4]; long pad[4];
...@@ -70,8 +72,8 @@ struct flock { ...@@ -70,8 +72,8 @@ struct flock {
#define HAVE_ARCH_STRUCT_FLOCK #define HAVE_ARCH_STRUCT_FLOCK
#endif /* CONFIG_32BIT */ #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
#include <asm-generic/fcntl.h> #include <asm-generic/fcntl.h>
#endif /* _ASM_FCNTL_H */ #endif /* _UAPI_ASM_FCNTL_H */
...@@ -409,10 +409,11 @@ enum mm_32f_73_minor_op { ...@@ -409,10 +409,11 @@ enum mm_32f_73_minor_op {
enum mm_16c_minor_op { enum mm_16c_minor_op {
mm_lwm16_op = 0x04, mm_lwm16_op = 0x04,
mm_swm16_op = 0x05, mm_swm16_op = 0x05,
mm_jr16_op = 0x18, mm_jr16_op = 0x0c,
mm_jrc_op = 0x1a, mm_jrc_op = 0x0d,
mm_jalr16_op = 0x1c, mm_jalr16_op = 0x0e,
mm_jalrs16_op = 0x1e, mm_jalrs16_op = 0x0f,
mm_jraddiusp_op = 0x18,
}; };
/* /*
......
...@@ -14,25 +14,25 @@ ...@@ -14,25 +14,25 @@
struct msqid64_ds { struct msqid64_ds {
struct ipc64_perm msg_perm; struct ipc64_perm msg_perm;
#if defined(CONFIG_32BIT) && !defined(CONFIG_CPU_LITTLE_ENDIAN) #if !defined(__mips64) && defined(__MIPSEB__)
unsigned long __unused1; unsigned long __unused1;
#endif #endif
__kernel_time_t msg_stime; /* last msgsnd time */ __kernel_time_t msg_stime; /* last msgsnd time */
#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_LITTLE_ENDIAN) #if !defined(__mips64) && defined(__MIPSEL__)
unsigned long __unused1; unsigned long __unused1;
#endif #endif
#if defined(CONFIG_32BIT) && !defined(CONFIG_CPU_LITTLE_ENDIAN) #if !defined(__mips64) && defined(__MIPSEB__)
unsigned long __unused2; unsigned long __unused2;
#endif #endif
__kernel_time_t msg_rtime; /* last msgrcv time */ __kernel_time_t msg_rtime; /* last msgrcv time */
#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_LITTLE_ENDIAN) #if !defined(__mips64) && defined(__MIPSEL__)
unsigned long __unused2; unsigned long __unused2;
#endif #endif
#if defined(CONFIG_32BIT) && !defined(CONFIG_CPU_LITTLE_ENDIAN) #if !defined(__mips64) && defined(__MIPSEB__)
unsigned long __unused3; unsigned long __unused3;
#endif #endif
__kernel_time_t msg_ctime; /* last change time */ __kernel_time_t msg_ctime; /* last change time */
#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_LITTLE_ENDIAN) #if !defined(__mips64) && defined(__MIPSEL__)
unsigned long __unused3; unsigned long __unused3;
#endif #endif
unsigned long msg_cbytes; /* current number of bytes on queue */ unsigned long msg_cbytes; /* current number of bytes on queue */
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* but we keep the old value on MIPS32, * but we keep the old value on MIPS32,
* for compatibility: * for compatibility:
*/ */
#ifdef CONFIG_32BIT #ifndef __mips64
# define RLIM_INFINITY 0x7fffffffUL # define RLIM_INFINITY 0x7fffffffUL
#endif #endif
......
...@@ -25,10 +25,10 @@ struct siginfo; ...@@ -25,10 +25,10 @@ struct siginfo;
/* /*
* Careful to keep union _sifields from shifting ... * Careful to keep union _sifields from shifting ...
*/ */
#ifdef CONFIG_32BIT #if __SIZEOF_LONG__ == 4
#define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int)) #define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int))
#endif #endif
#ifdef CONFIG_64BIT #if __SIZEOF_LONG__ == 8
#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
#endif #endif
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#define __SWAB_64_THRU_32__ #define __SWAB_64_THRU_32__
#ifdef CONFIG_CPU_MIPSR2 #if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
static inline __attribute_const__ __u16 __arch_swab16(__u16 x) static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
{ {
...@@ -39,10 +39,10 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x) ...@@ -39,10 +39,10 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
#define __arch_swab32 __arch_swab32 #define __arch_swab32 __arch_swab32
/* /*
* Having already checked for CONFIG_CPU_MIPSR2, enable the * Having already checked for MIPS R2, enable the optimized version for
* optimized version for 64-bit kernel on r2 CPUs. * 64-bit kernel on r2 CPUs.
*/ */
#ifdef CONFIG_64BIT #ifdef __mips64
static inline __attribute_const__ __u64 __arch_swab64(__u64 x) static inline __attribute_const__ __u64 __arch_swab64(__u64 x)
{ {
__asm__( __asm__(
...@@ -54,6 +54,6 @@ static inline __attribute_const__ __u64 __arch_swab64(__u64 x) ...@@ -54,6 +54,6 @@ static inline __attribute_const__ __u64 __arch_swab64(__u64 x)
return x; return x;
} }
#define __arch_swab64 __arch_swab64 #define __arch_swab64 __arch_swab64
#endif /* CONFIG_64BIT */ #endif /* __mips64 */
#endif /* CONFIG_CPU_MIPSR2 */ #endif /* MIPS R2 or newer */
#endif /* _ASM_SWAB_H */ #endif /* _ASM_SWAB_H */
...@@ -82,6 +82,9 @@ void output_task_defines(void) ...@@ -82,6 +82,9 @@ void output_task_defines(void)
OFFSET(TASK_FLAGS, task_struct, flags); OFFSET(TASK_FLAGS, task_struct, flags);
OFFSET(TASK_MM, task_struct, mm); OFFSET(TASK_MM, task_struct, mm);
OFFSET(TASK_PID, task_struct, pid); OFFSET(TASK_PID, task_struct, pid);
#if defined(CONFIG_CC_STACKPROTECTOR)
OFFSET(TASK_STACK_CANARY, task_struct, stack_canary);
#endif
DEFINE(TASK_STRUCT_SIZE, sizeof(struct task_struct)); DEFINE(TASK_STRUCT_SIZE, sizeof(struct task_struct));
BLANK(); BLANK();
} }
......
...@@ -467,5 +467,4 @@ int __compute_return_epc(struct pt_regs *regs) ...@@ -467,5 +467,4 @@ int __compute_return_epc(struct pt_regs *regs)
printk("%s: unaligned epc - sending SIGBUS.\n", current->comm); printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
force_sig(SIGBUS, current); force_sig(SIGBUS, current);
return -EFAULT; return -EFAULT;
} }
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#include <linux/context_tracking.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
...@@ -171,8 +172,12 @@ static volatile int daddi_ov __cpuinitdata; ...@@ -171,8 +172,12 @@ static volatile int daddi_ov __cpuinitdata;
asmlinkage void __init do_daddi_ov(struct pt_regs *regs) asmlinkage void __init do_daddi_ov(struct pt_regs *regs)
{ {
enum ctx_state prev_state;
prev_state = exception_enter();
daddi_ov = 1; daddi_ov = 1;
regs->cp0_epc += 4; regs->cp0_epc += 4;
exception_exit(prev_state);
} }
static inline void check_daddi(void) static inline void check_daddi(void)
......
...@@ -146,8 +146,7 @@ static void __cpuinit set_isa(struct cpuinfo_mips *c, unsigned int isa) ...@@ -146,8 +146,7 @@ static void __cpuinit set_isa(struct cpuinfo_mips *c, unsigned int isa)
case MIPS_CPU_ISA_IV: case MIPS_CPU_ISA_IV:
c->isa_level |= MIPS_CPU_ISA_IV; c->isa_level |= MIPS_CPU_ISA_IV;
case MIPS_CPU_ISA_III: case MIPS_CPU_ISA_III:
c->isa_level |= MIPS_CPU_ISA_I | MIPS_CPU_ISA_II | c->isa_level |= MIPS_CPU_ISA_II | MIPS_CPU_ISA_III;
MIPS_CPU_ISA_III;
break; break;
case MIPS_CPU_ISA_M32R2: case MIPS_CPU_ISA_M32R2:
...@@ -156,8 +155,6 @@ static void __cpuinit set_isa(struct cpuinfo_mips *c, unsigned int isa) ...@@ -156,8 +155,6 @@ static void __cpuinit set_isa(struct cpuinfo_mips *c, unsigned int isa)
c->isa_level |= MIPS_CPU_ISA_M32R1; c->isa_level |= MIPS_CPU_ISA_M32R1;
case MIPS_CPU_ISA_II: case MIPS_CPU_ISA_II:
c->isa_level |= MIPS_CPU_ISA_II; c->isa_level |= MIPS_CPU_ISA_II;
case MIPS_CPU_ISA_I:
c->isa_level |= MIPS_CPU_ISA_I;
break; break;
} }
} }
...@@ -272,9 +269,6 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) ...@@ -272,9 +269,6 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
c->options |= MIPS_CPU_ULRI; c->options |= MIPS_CPU_ULRI;
if (config3 & MIPS_CONF3_ISA) if (config3 & MIPS_CONF3_ISA)
c->options |= MIPS_CPU_MICROMIPS; c->options |= MIPS_CPU_MICROMIPS;
#ifdef CONFIG_CPU_MICROMIPS
write_c0_config3(read_c0_config3() | MIPS_CONF3_ISA_OE);
#endif
if (config3 & MIPS_CONF3_VZ) if (config3 & MIPS_CONF3_VZ)
c->ases |= MIPS_ASE_VZ; c->ases |= MIPS_ASE_VZ;
...@@ -332,7 +326,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) ...@@ -332,7 +326,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
case PRID_IMP_R2000: case PRID_IMP_R2000:
c->cputype = CPU_R2000; c->cputype = CPU_R2000;
__cpu_name[cpu] = "R2000"; __cpu_name[cpu] = "R2000";
set_isa(c, MIPS_CPU_ISA_I);
c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
MIPS_CPU_NOFPUEX; MIPS_CPU_NOFPUEX;
if (__cpu_has_fpu()) if (__cpu_has_fpu())
...@@ -352,7 +345,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) ...@@ -352,7 +345,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
c->cputype = CPU_R3000; c->cputype = CPU_R3000;
__cpu_name[cpu] = "R3000"; __cpu_name[cpu] = "R3000";
} }
set_isa(c, MIPS_CPU_ISA_I);
c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
MIPS_CPU_NOFPUEX; MIPS_CPU_NOFPUEX;
if (__cpu_has_fpu()) if (__cpu_has_fpu())
...@@ -455,7 +447,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) ...@@ -455,7 +447,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
break; break;
#endif #endif
case PRID_IMP_TX39: case PRID_IMP_TX39:
set_isa(c, MIPS_CPU_ISA_I);
c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE; c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE;
if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
...@@ -959,6 +950,7 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu) ...@@ -959,6 +950,7 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
set_isa(c, MIPS_CPU_ISA_M64R1); set_isa(c, MIPS_CPU_ISA_M64R1);
c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1; c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;
} }
c->kscratch_mask = 0xf;
} }
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
......
...@@ -27,45 +27,6 @@ ...@@ -27,45 +27,6 @@
#include <kernel-entry-init.h> #include <kernel-entry-init.h>
/*
* inputs are the text nasid in t1, data nasid in t2.
*/
.macro MAPPED_KERNEL_SETUP_TLB
#ifdef CONFIG_MAPPED_KERNEL
/*
* This needs to read the nasid - assume 0 for now.
* Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0,
* 0+DVG in tlblo_1.
*/
dli t0, 0xffffffffc0000000
dmtc0 t0, CP0_ENTRYHI
li t0, 0x1c000 # Offset of text into node memory
dsll t1, NASID_SHFT # Shift text nasid into place
dsll t2, NASID_SHFT # Same for data nasid
or t1, t1, t0 # Physical load address of kernel text
or t2, t2, t0 # Physical load address of kernel data
dsrl t1, 12 # 4K pfn
dsrl t2, 12 # 4K pfn
dsll t1, 6 # Get pfn into place
dsll t2, 6 # Get pfn into place
li t0, ((_PAGE_GLOBAL|_PAGE_VALID| _CACHE_CACHABLE_COW) >> 6)
or t0, t0, t1
mtc0 t0, CP0_ENTRYLO0 # physaddr, VG, cach exlwr
li t0, ((_PAGE_GLOBAL|_PAGE_VALID| _PAGE_DIRTY|_CACHE_CACHABLE_COW) >> 6)
or t0, t0, t2
mtc0 t0, CP0_ENTRYLO1 # physaddr, DVG, cach exlwr
li t0, 0x1ffe000 # MAPPED_KERN_TLBMASK, TLBPGMASK_16M
mtc0 t0, CP0_PAGEMASK
li t0, 0 # KMAP_INX
mtc0 t0, CP0_INDEX
li t0, 1
mtc0 t0, CP0_WIRED
tlbwi
#else
mtc0 zero, CP0_WIRED
#endif
.endm
/* /*
* For the moment disable interrupts, mark the kernel mode and * For the moment disable interrupts, mark the kernel mode and
* set ST0_KX so that the CPU does not spit fire when using * set ST0_KX so that the CPU does not spit fire when using
......
...@@ -219,16 +219,15 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, ...@@ -219,16 +219,15 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
/* Assumption : cpumask refers to a single CPU */ /* Assumption : cpumask refers to a single CPU */
spin_lock_irqsave(&gic_lock, flags); spin_lock_irqsave(&gic_lock, flags);
for (;;) {
/* Re-route this IRQ */
GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp));
/* Update the pcpu_masks */ /* Re-route this IRQ */
for (i = 0; i < NR_CPUS; i++) GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp));
clear_bit(irq, pcpu_masks[i].pcpu_mask);
set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask); /* Update the pcpu_masks */
for (i = 0; i < NR_CPUS; i++)
clear_bit(irq, pcpu_masks[i].pcpu_mask);
set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask);
}
cpumask_copy(d->affinity, cpumask); cpumask_copy(d->affinity, cpumask);
spin_unlock_irqrestore(&gic_lock, flags); spin_unlock_irqrestore(&gic_lock, flags);
......
...@@ -168,14 +168,10 @@ NESTED(ftrace_graph_caller, PT_SIZE, ra) ...@@ -168,14 +168,10 @@ NESTED(ftrace_graph_caller, PT_SIZE, ra)
#endif #endif
/* arg3: Get frame pointer of current stack */ /* arg3: Get frame pointer of current stack */
#ifdef CONFIG_FRAME_POINTER
move a2, fp
#else /* ! CONFIG_FRAME_POINTER */
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
PTR_LA a2, PT_SIZE(sp) PTR_LA a2, PT_SIZE(sp)
#else #else
PTR_LA a2, (PT_SIZE+8)(sp) PTR_LA a2, (PT_SIZE+8)(sp)
#endif
#endif #endif
jal prepare_ftrace_return jal prepare_ftrace_return
......
...@@ -40,33 +40,6 @@ ...@@ -40,33 +40,6 @@
cpu_save_nonscratch a0 cpu_save_nonscratch a0
LONG_S ra, THREAD_REG31(a0) LONG_S ra, THREAD_REG31(a0)
/* check if we need to save COP2 registers */
PTR_L t2, TASK_THREAD_INFO(a0)
LONG_L t0, ST_OFF(t2)
bbit0 t0, 30, 1f
/* Disable COP2 in the stored process state */
li t1, ST0_CU2
xor t0, t1
LONG_S t0, ST_OFF(t2)
/* Enable COP2 so we can save it */
mfc0 t0, CP0_STATUS
or t0, t1
mtc0 t0, CP0_STATUS
/* Save COP2 */
daddu a0, THREAD_CP2
jal octeon_cop2_save
dsubu a0, THREAD_CP2
/* Disable COP2 now that we are done */
mfc0 t0, CP0_STATUS
li t1, ST0_CU2
xor t0, t1
mtc0 t0, CP0_STATUS
1:
#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0 #if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
/* Check if we need to store CVMSEG state */ /* Check if we need to store CVMSEG state */
mfc0 t0, $11,7 /* CvmMemCtl */ mfc0 t0, $11,7 /* CvmMemCtl */
...@@ -98,6 +71,13 @@ ...@@ -98,6 +71,13 @@
mtc0 t0, $11,7 /* CvmMemCtl */ mtc0 t0, $11,7 /* CvmMemCtl */
#endif #endif
3: 3:
#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
PTR_L t8, __stack_chk_guard
LONG_L t9, TASK_STACK_CANARY(a1)
LONG_S t9, 0(t8)
#endif
/* /*
* The order of restoring the registers takes care of the race * The order of restoring the registers takes care of the race
* updating $28, $29 and kernelsp without disabling ints. * updating $28, $29 and kernelsp without disabling ints.
......
...@@ -66,9 +66,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) ...@@ -66,9 +66,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "]\n"); seq_printf(m, "]\n");
} }
if (cpu_has_mips_r) { if (cpu_has_mips_r) {
seq_printf(m, "isa\t\t\t:"); seq_printf(m, "isa\t\t\t: mips1");
if (cpu_has_mips_1)
seq_printf(m, "%s", " mips1");
if (cpu_has_mips_2) if (cpu_has_mips_2)
seq_printf(m, "%s", " mips2"); seq_printf(m, "%s", " mips2");
if (cpu_has_mips_3) if (cpu_has_mips_3)
......
...@@ -201,9 +201,12 @@ int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpr) ...@@ -201,9 +201,12 @@ int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpr)
return 1; return 1;
} }
/* #ifdef CONFIG_CC_STACKPROTECTOR
* #include <linux/stackprotector.h>
*/ unsigned long __stack_chk_guard __read_mostly;
EXPORT_SYMBOL(__stack_chk_guard);
#endif
struct mips_frame_info { struct mips_frame_info {
void *func; void *func;
unsigned long func_size; unsigned long func_size;
......
...@@ -30,7 +30,7 @@ __init void mips_set_machine_name(const char *name) ...@@ -30,7 +30,7 @@ __init void mips_set_machine_name(const char *name)
if (name == NULL) if (name == NULL)
return; return;
strncpy(mips_machine_name, name, sizeof(mips_machine_name)); strlcpy(mips_machine_name, name, sizeof(mips_machine_name));
pr_info("MIPS: machine is %s\n", mips_get_machine_name()); pr_info("MIPS: machine is %s\n", mips_get_machine_name());
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
* binaries. * binaries.
*/ */
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/context_tracking.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/mm.h> #include <linux/mm.h>
...@@ -534,6 +535,8 @@ static inline int audit_arch(void) ...@@ -534,6 +535,8 @@ static inline int audit_arch(void)
*/ */
asmlinkage void syscall_trace_enter(struct pt_regs *regs) asmlinkage void syscall_trace_enter(struct pt_regs *regs)
{ {
user_exit();
/* do the secure computing check first */ /* do the secure computing check first */
secure_computing_strict(regs->regs[2]); secure_computing_strict(regs->regs[2]);
...@@ -570,6 +573,13 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs) ...@@ -570,6 +573,13 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs)
*/ */
asmlinkage void syscall_trace_leave(struct pt_regs *regs) asmlinkage void syscall_trace_leave(struct pt_regs *regs)
{ {
/*
* We may come here right after calling schedule_user()
* or do_notify_resume(), in which case we can be in RCU
* user mode.
*/
user_exit();
audit_syscall_exit(regs); audit_syscall_exit(regs);
if (!(current->ptrace & PT_PTRACED)) if (!(current->ptrace & PT_PTRACED))
...@@ -592,4 +602,6 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs) ...@@ -592,4 +602,6 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs)
send_sig(current->exit_code, current, 1); send_sig(current->exit_code, current, 1);
current->exit_code = 0; current->exit_code = 0;
} }
user_enter();
} }
...@@ -65,6 +65,13 @@ LEAF(resume) ...@@ -65,6 +65,13 @@ LEAF(resume)
fpu_save_single a0, t0 # clobbers t0 fpu_save_single a0, t0 # clobbers t0
1: 1:
#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
PTR_L t8, __stack_chk_guard
LONG_L t9, TASK_STACK_CANARY(a1)
LONG_S t9, 0(t8)
#endif
/* /*
* The order of restoring the registers takes care of the race * The order of restoring the registers takes care of the race
* updating $28, $29 and kernelsp without disabling ints. * updating $28, $29 and kernelsp without disabling ints.
......
...@@ -68,6 +68,12 @@ ...@@ -68,6 +68,12 @@
# clobbers t1 # clobbers t1
1: 1:
#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
PTR_L t8, __stack_chk_guard
LONG_L t9, TASK_STACK_CANARY(a1)
LONG_S t9, 0(t8)
#endif
/* /*
* The order of restoring the registers takes care of the race * The order of restoring the registers takes care of the race
* updating $28, $29 and kernelsp without disabling ints. * updating $28, $29 and kernelsp without disabling ints.
......
...@@ -437,7 +437,6 @@ static ssize_t file_write(struct file *file, const char __user * buffer, ...@@ -437,7 +437,6 @@ static ssize_t file_write(struct file *file, const char __user * buffer,
size_t count, loff_t * ppos) size_t count, loff_t * ppos)
{ {
int minor = iminor(file_inode(file)); int minor = iminor(file_inode(file));
struct rtlx_channel *rt = &rtlx->channel[minor];
/* any space left... */ /* any space left... */
if (!rtlx_write_poll(minor)) { if (!rtlx_write_poll(minor)) {
......
...@@ -52,7 +52,7 @@ NESTED(handle_sys, PT_SIZE, sp) ...@@ -52,7 +52,7 @@ NESTED(handle_sys, PT_SIZE, sp)
stack_done: stack_done:
lw t0, TI_FLAGS($28) # syscall tracing enabled? lw t0, TI_FLAGS($28) # syscall tracing enabled?
li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT li t1, _TIF_WORK_SYSCALL_ENTRY
and t0, t1 and t0, t1
bnez t0, syscall_trace_entry # -> yes bnez t0, syscall_trace_entry # -> yes
......
...@@ -54,7 +54,7 @@ NESTED(handle_sys64, PT_SIZE, sp) ...@@ -54,7 +54,7 @@ NESTED(handle_sys64, PT_SIZE, sp)
sd a3, PT_R26(sp) # save a3 for syscall restarting sd a3, PT_R26(sp) # save a3 for syscall restarting
li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT li t1, _TIF_WORK_SYSCALL_ENTRY
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
and t0, t1, t0 and t0, t1, t0
bnez t0, syscall_trace_entry bnez t0, syscall_trace_entry
......
...@@ -47,7 +47,7 @@ NESTED(handle_sysn32, PT_SIZE, sp) ...@@ -47,7 +47,7 @@ NESTED(handle_sysn32, PT_SIZE, sp)
sd a3, PT_R26(sp) # save a3 for syscall restarting sd a3, PT_R26(sp) # save a3 for syscall restarting
li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT li t1, _TIF_WORK_SYSCALL_ENTRY
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
and t0, t1, t0 and t0, t1, t0
bnez t0, n32_syscall_trace_entry bnez t0, n32_syscall_trace_entry
......
...@@ -81,7 +81,7 @@ NESTED(handle_sys, PT_SIZE, sp) ...@@ -81,7 +81,7 @@ NESTED(handle_sys, PT_SIZE, sp)
PTR 4b, bad_stack PTR 4b, bad_stack
.previous .previous
li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT li t1, _TIF_WORK_SYSCALL_ENTRY
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
and t0, t1, t0 and t0, t1, t0
bnez t0, trace_a_syscall bnez t0, trace_a_syscall
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/ */
#include <linux/cache.h> #include <linux/cache.h>
#include <linux/context_tracking.h>
#include <linux/irqflags.h> #include <linux/irqflags.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/mm.h> #include <linux/mm.h>
...@@ -573,6 +574,8 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, ...@@ -573,6 +574,8 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
{ {
local_irq_enable(); local_irq_enable();
user_exit();
/* deal with pending signal delivery */ /* deal with pending signal delivery */
if (thread_info_flags & _TIF_SIGPENDING) if (thread_info_flags & _TIF_SIGPENDING)
do_signal(regs); do_signal(regs);
...@@ -581,6 +584,8 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, ...@@ -581,6 +584,8 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
clear_thread_flag(TIF_NOTIFY_RESUME); clear_thread_flag(TIF_NOTIFY_RESUME);
tracehook_notify_resume(regs); tracehook_notify_resume(regs);
} }
user_enter();
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
......
...@@ -63,7 +63,7 @@ static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id); ...@@ -63,7 +63,7 @@ static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id);
static void __init bmips_smp_setup(void) static void __init bmips_smp_setup(void)
{ {
int i; int i, cpu = 1, boot_cpu = 0;
#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380) #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
/* arbitration priority */ /* arbitration priority */
...@@ -72,13 +72,22 @@ static void __init bmips_smp_setup(void) ...@@ -72,13 +72,22 @@ static void __init bmips_smp_setup(void)
/* NBK and weak order flags */ /* NBK and weak order flags */
set_c0_brcm_config_0(0x30000); set_c0_brcm_config_0(0x30000);
/* Find out if we are running on TP0 or TP1 */
boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
/* /*
* MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread
* MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
* MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
*
* If booting from TP1, leave the existing CMT interrupt routing
* such that TP0 responds to SW1 and TP1 responds to SW0.
*/ */
change_c0_brcm_cmt_intr(0xf8018000, if (boot_cpu == 0)
(0x02 << 27) | (0x03 << 15)); change_c0_brcm_cmt_intr(0xf8018000,
(0x02 << 27) | (0x03 << 15));
else
change_c0_brcm_cmt_intr(0xf8018000, (0x1d << 27));
/* single core, 2 threads (2 pipelines) */ /* single core, 2 threads (2 pipelines) */
max_cpus = 2; max_cpus = 2;
...@@ -106,9 +115,15 @@ static void __init bmips_smp_setup(void) ...@@ -106,9 +115,15 @@ static void __init bmips_smp_setup(void)
if (!board_ebase_setup) if (!board_ebase_setup)
board_ebase_setup = &bmips_ebase_setup; board_ebase_setup = &bmips_ebase_setup;
__cpu_number_map[boot_cpu] = 0;
__cpu_logical_map[0] = boot_cpu;
for (i = 0; i < max_cpus; i++) { for (i = 0; i < max_cpus; i++) {
__cpu_number_map[i] = 1; if (i != boot_cpu) {
__cpu_logical_map[i] = 1; __cpu_number_map[i] = cpu;
__cpu_logical_map[cpu] = i;
cpu++;
}
set_cpu_possible(i, 1); set_cpu_possible(i, 1);
set_cpu_present(i, 1); set_cpu_present(i, 1);
} }
...@@ -157,7 +172,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) ...@@ -157,7 +172,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
bmips_send_ipi_single(cpu, 0); bmips_send_ipi_single(cpu, 0);
else { else {
#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380) #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
set_c0_brcm_cmt_ctrl(0x01); /* Reset slave TP1 if booting from TP0 */
if (cpu_logical_map(cpu) == 0)
set_c0_brcm_cmt_ctrl(0x01);
#elif defined(CONFIG_CPU_BMIPS5000) #elif defined(CONFIG_CPU_BMIPS5000)
if (cpu & 0x01) if (cpu & 0x01)
write_c0_brcm_action(ACTION_BOOT_THREAD(cpu)); write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
*/ */
#include <linux/bug.h> #include <linux/bug.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/context_tracking.h>
#include <linux/kexec.h> #include <linux/kexec.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -264,7 +265,7 @@ static void __show_regs(const struct pt_regs *regs) ...@@ -264,7 +265,7 @@ static void __show_regs(const struct pt_regs *regs)
printk("Status: %08x ", (uint32_t) regs->cp0_status); printk("Status: %08x ", (uint32_t) regs->cp0_status);
if (current_cpu_data.isa_level == MIPS_CPU_ISA_I) { if (cpu_has_3kex) {
if (regs->cp0_status & ST0_KUO) if (regs->cp0_status & ST0_KUO)
printk("KUo "); printk("KUo ");
if (regs->cp0_status & ST0_IEO) if (regs->cp0_status & ST0_IEO)
...@@ -277,7 +278,7 @@ static void __show_regs(const struct pt_regs *regs) ...@@ -277,7 +278,7 @@ static void __show_regs(const struct pt_regs *regs)
printk("KUc "); printk("KUc ");
if (regs->cp0_status & ST0_IEC) if (regs->cp0_status & ST0_IEC)
printk("IEc "); printk("IEc ");
} else { } else if (cpu_has_4kex) {
if (regs->cp0_status & ST0_KX) if (regs->cp0_status & ST0_KX)
printk("KX "); printk("KX ");
if (regs->cp0_status & ST0_SX) if (regs->cp0_status & ST0_SX)
...@@ -423,7 +424,9 @@ asmlinkage void do_be(struct pt_regs *regs) ...@@ -423,7 +424,9 @@ asmlinkage void do_be(struct pt_regs *regs)
const struct exception_table_entry *fixup = NULL; const struct exception_table_entry *fixup = NULL;
int data = regs->cp0_cause & 4; int data = regs->cp0_cause & 4;
int action = MIPS_BE_FATAL; int action = MIPS_BE_FATAL;
enum ctx_state prev_state;
prev_state = exception_enter();
/* XXX For now. Fixme, this searches the wrong table ... */ /* XXX For now. Fixme, this searches the wrong table ... */
if (data && !user_mode(regs)) if (data && !user_mode(regs))
fixup = search_dbe_tables(exception_epc(regs)); fixup = search_dbe_tables(exception_epc(regs));
...@@ -436,11 +439,11 @@ asmlinkage void do_be(struct pt_regs *regs) ...@@ -436,11 +439,11 @@ asmlinkage void do_be(struct pt_regs *regs)
switch (action) { switch (action) {
case MIPS_BE_DISCARD: case MIPS_BE_DISCARD:
return; goto out;
case MIPS_BE_FIXUP: case MIPS_BE_FIXUP:
if (fixup) { if (fixup) {
regs->cp0_epc = fixup->nextinsn; regs->cp0_epc = fixup->nextinsn;
return; goto out;
} }
break; break;
default: default:
...@@ -455,10 +458,13 @@ asmlinkage void do_be(struct pt_regs *regs) ...@@ -455,10 +458,13 @@ asmlinkage void do_be(struct pt_regs *regs)
field, regs->cp0_epc, field, regs->regs[31]); field, regs->cp0_epc, field, regs->regs[31]);
if (notify_die(DIE_OOPS, "bus error", regs, 0, regs_to_trapnr(regs), SIGBUS) if (notify_die(DIE_OOPS, "bus error", regs, 0, regs_to_trapnr(regs), SIGBUS)
== NOTIFY_STOP) == NOTIFY_STOP)
return; goto out;
die_if_kernel("Oops", regs); die_if_kernel("Oops", regs);
force_sig(SIGBUS, current); force_sig(SIGBUS, current);
out:
exception_exit(prev_state);
} }
/* /*
...@@ -673,8 +679,10 @@ static int simulate_sync(struct pt_regs *regs, unsigned int opcode) ...@@ -673,8 +679,10 @@ static int simulate_sync(struct pt_regs *regs, unsigned int opcode)
asmlinkage void do_ov(struct pt_regs *regs) asmlinkage void do_ov(struct pt_regs *regs)
{ {
enum ctx_state prev_state;
siginfo_t info; siginfo_t info;
prev_state = exception_enter();
die_if_kernel("Integer overflow", regs); die_if_kernel("Integer overflow", regs);
info.si_code = FPE_INTOVF; info.si_code = FPE_INTOVF;
...@@ -682,6 +690,7 @@ asmlinkage void do_ov(struct pt_regs *regs) ...@@ -682,6 +690,7 @@ asmlinkage void do_ov(struct pt_regs *regs)
info.si_errno = 0; info.si_errno = 0;
info.si_addr = (void __user *) regs->cp0_epc; info.si_addr = (void __user *) regs->cp0_epc;
force_sig_info(SIGFPE, &info, current); force_sig_info(SIGFPE, &info, current);
exception_exit(prev_state);
} }
int process_fpemu_return(int sig, void __user *fault_addr) int process_fpemu_return(int sig, void __user *fault_addr)
...@@ -713,11 +722,13 @@ int process_fpemu_return(int sig, void __user *fault_addr) ...@@ -713,11 +722,13 @@ int process_fpemu_return(int sig, void __user *fault_addr)
*/ */
asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
{ {
enum ctx_state prev_state;
siginfo_t info = {0}; siginfo_t info = {0};
prev_state = exception_enter();
if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE) if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE)
== NOTIFY_STOP) == NOTIFY_STOP)
return; goto out;
die_if_kernel("FP exception in kernel code", regs); die_if_kernel("FP exception in kernel code", regs);
if (fcr31 & FPU_CSR_UNI_X) { if (fcr31 & FPU_CSR_UNI_X) {
...@@ -753,7 +764,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) ...@@ -753,7 +764,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
/* If something went wrong, signal */ /* If something went wrong, signal */
process_fpemu_return(sig, fault_addr); process_fpemu_return(sig, fault_addr);
return; goto out;
} else if (fcr31 & FPU_CSR_INV_X) } else if (fcr31 & FPU_CSR_INV_X)
info.si_code = FPE_FLTINV; info.si_code = FPE_FLTINV;
else if (fcr31 & FPU_CSR_DIV_X) else if (fcr31 & FPU_CSR_DIV_X)
...@@ -770,6 +781,9 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) ...@@ -770,6 +781,9 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
info.si_errno = 0; info.si_errno = 0;
info.si_addr = (void __user *) regs->cp0_epc; info.si_addr = (void __user *) regs->cp0_epc;
force_sig_info(SIGFPE, &info, current); force_sig_info(SIGFPE, &info, current);
out:
exception_exit(prev_state);
} }
static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, static void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
...@@ -835,9 +849,11 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, ...@@ -835,9 +849,11 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
asmlinkage void do_bp(struct pt_regs *regs) asmlinkage void do_bp(struct pt_regs *regs)
{ {
unsigned int opcode, bcode; unsigned int opcode, bcode;
enum ctx_state prev_state;
unsigned long epc; unsigned long epc;
u16 instr[2]; u16 instr[2];
prev_state = exception_enter();
if (get_isa16_mode(regs->cp0_epc)) { if (get_isa16_mode(regs->cp0_epc)) {
/* Calculate EPC. */ /* Calculate EPC. */
epc = exception_epc(regs); epc = exception_epc(regs);
...@@ -852,7 +868,7 @@ asmlinkage void do_bp(struct pt_regs *regs) ...@@ -852,7 +868,7 @@ asmlinkage void do_bp(struct pt_regs *regs)
goto out_sigsegv; goto out_sigsegv;
bcode = (instr[0] >> 6) & 0x3f; bcode = (instr[0] >> 6) & 0x3f;
do_trap_or_bp(regs, bcode, "Break"); do_trap_or_bp(regs, bcode, "Break");
return; goto out;
} }
} else { } else {
if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
...@@ -876,12 +892,12 @@ asmlinkage void do_bp(struct pt_regs *regs) ...@@ -876,12 +892,12 @@ asmlinkage void do_bp(struct pt_regs *regs)
switch (bcode) { switch (bcode) {
case BRK_KPROBE_BP: case BRK_KPROBE_BP:
if (notify_die(DIE_BREAK, "debug", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP) if (notify_die(DIE_BREAK, "debug", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
return; goto out;
else else
break; break;
case BRK_KPROBE_SSTEPBP: case BRK_KPROBE_SSTEPBP:
if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP) if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
return; goto out;
else else
break; break;
default: default:
...@@ -889,18 +905,24 @@ asmlinkage void do_bp(struct pt_regs *regs) ...@@ -889,18 +905,24 @@ asmlinkage void do_bp(struct pt_regs *regs)
} }
do_trap_or_bp(regs, bcode, "Break"); do_trap_or_bp(regs, bcode, "Break");
out:
exception_exit(prev_state);
return; return;
out_sigsegv: out_sigsegv:
force_sig(SIGSEGV, current); force_sig(SIGSEGV, current);
goto out;
} }
asmlinkage void do_tr(struct pt_regs *regs) asmlinkage void do_tr(struct pt_regs *regs)
{ {
u32 opcode, tcode = 0; u32 opcode, tcode = 0;
enum ctx_state prev_state;
u16 instr[2]; u16 instr[2];
unsigned long epc = msk_isa16_mode(exception_epc(regs)); unsigned long epc = msk_isa16_mode(exception_epc(regs));
prev_state = exception_enter();
if (get_isa16_mode(regs->cp0_epc)) { if (get_isa16_mode(regs->cp0_epc)) {
if (__get_user(instr[0], (u16 __user *)(epc + 0)) || if (__get_user(instr[0], (u16 __user *)(epc + 0)) ||
__get_user(instr[1], (u16 __user *)(epc + 2))) __get_user(instr[1], (u16 __user *)(epc + 2)))
...@@ -918,10 +940,14 @@ asmlinkage void do_tr(struct pt_regs *regs) ...@@ -918,10 +940,14 @@ asmlinkage void do_tr(struct pt_regs *regs)
} }
do_trap_or_bp(regs, tcode, "Trap"); do_trap_or_bp(regs, tcode, "Trap");
out:
exception_exit(prev_state);
return; return;
out_sigsegv: out_sigsegv:
force_sig(SIGSEGV, current); force_sig(SIGSEGV, current);
goto out;
} }
asmlinkage void do_ri(struct pt_regs *regs) asmlinkage void do_ri(struct pt_regs *regs)
...@@ -929,17 +955,19 @@ asmlinkage void do_ri(struct pt_regs *regs) ...@@ -929,17 +955,19 @@ asmlinkage void do_ri(struct pt_regs *regs)
unsigned int __user *epc = (unsigned int __user *)exception_epc(regs); unsigned int __user *epc = (unsigned int __user *)exception_epc(regs);
unsigned long old_epc = regs->cp0_epc; unsigned long old_epc = regs->cp0_epc;
unsigned long old31 = regs->regs[31]; unsigned long old31 = regs->regs[31];
enum ctx_state prev_state;
unsigned int opcode = 0; unsigned int opcode = 0;
int status = -1; int status = -1;
prev_state = exception_enter();
if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs), SIGILL) if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs), SIGILL)
== NOTIFY_STOP) == NOTIFY_STOP)
return; goto out;
die_if_kernel("Reserved instruction in kernel code", regs); die_if_kernel("Reserved instruction in kernel code", regs);
if (unlikely(compute_return_epc(regs) < 0)) if (unlikely(compute_return_epc(regs) < 0))
return; goto out;
if (get_isa16_mode(regs->cp0_epc)) { if (get_isa16_mode(regs->cp0_epc)) {
unsigned short mmop[2] = { 0 }; unsigned short mmop[2] = { 0 };
...@@ -974,6 +1002,9 @@ asmlinkage void do_ri(struct pt_regs *regs) ...@@ -974,6 +1002,9 @@ asmlinkage void do_ri(struct pt_regs *regs)
regs->regs[31] = old31; regs->regs[31] = old31;
force_sig(status, current); force_sig(status, current);
} }
out:
exception_exit(prev_state);
} }
/* /*
...@@ -1025,21 +1056,16 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action, ...@@ -1025,21 +1056,16 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
{ {
struct pt_regs *regs = data; struct pt_regs *regs = data;
switch (action) { die_if_kernel("COP2: Unhandled kernel unaligned access or invalid "
default:
die_if_kernel("Unhandled kernel unaligned access or invalid "
"instruction", regs); "instruction", regs);
/* Fall through */ force_sig(SIGILL, current);
case CU2_EXCEPTION:
force_sig(SIGILL, current);
}
return NOTIFY_OK; return NOTIFY_OK;
} }
asmlinkage void do_cpu(struct pt_regs *regs) asmlinkage void do_cpu(struct pt_regs *regs)
{ {
enum ctx_state prev_state;
unsigned int __user *epc; unsigned int __user *epc;
unsigned long old_epc, old31; unsigned long old_epc, old31;
unsigned int opcode; unsigned int opcode;
...@@ -1047,10 +1073,12 @@ asmlinkage void do_cpu(struct pt_regs *regs) ...@@ -1047,10 +1073,12 @@ asmlinkage void do_cpu(struct pt_regs *regs)
int status; int status;
unsigned long __maybe_unused flags; unsigned long __maybe_unused flags;
die_if_kernel("do_cpu invoked from kernel context!", regs); prev_state = exception_enter();
cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
if (cpid != 2)
die_if_kernel("do_cpu invoked from kernel context!", regs);
switch (cpid) { switch (cpid) {
case 0: case 0:
epc = (unsigned int __user *)exception_epc(regs); epc = (unsigned int __user *)exception_epc(regs);
...@@ -1060,7 +1088,7 @@ asmlinkage void do_cpu(struct pt_regs *regs) ...@@ -1060,7 +1088,7 @@ asmlinkage void do_cpu(struct pt_regs *regs)
status = -1; status = -1;
if (unlikely(compute_return_epc(regs) < 0)) if (unlikely(compute_return_epc(regs) < 0))
return; goto out;
if (get_isa16_mode(regs->cp0_epc)) { if (get_isa16_mode(regs->cp0_epc)) {
unsigned short mmop[2] = { 0 }; unsigned short mmop[2] = { 0 };
...@@ -1093,7 +1121,7 @@ asmlinkage void do_cpu(struct pt_regs *regs) ...@@ -1093,7 +1121,7 @@ asmlinkage void do_cpu(struct pt_regs *regs)
force_sig(status, current); force_sig(status, current);
} }
return; goto out;
case 3: case 3:
/* /*
...@@ -1131,19 +1159,26 @@ asmlinkage void do_cpu(struct pt_regs *regs) ...@@ -1131,19 +1159,26 @@ asmlinkage void do_cpu(struct pt_regs *regs)
mt_ase_fp_affinity(); mt_ase_fp_affinity();
} }
return; goto out;
case 2: case 2:
raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs); raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
return; goto out;
} }
force_sig(SIGILL, current); force_sig(SIGILL, current);
out:
exception_exit(prev_state);
} }
asmlinkage void do_mdmx(struct pt_regs *regs) asmlinkage void do_mdmx(struct pt_regs *regs)
{ {
enum ctx_state prev_state;
prev_state = exception_enter();
force_sig(SIGILL, current); force_sig(SIGILL, current);
exception_exit(prev_state);
} }
/* /*
...@@ -1151,8 +1186,10 @@ asmlinkage void do_mdmx(struct pt_regs *regs) ...@@ -1151,8 +1186,10 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
*/ */
asmlinkage void do_watch(struct pt_regs *regs) asmlinkage void do_watch(struct pt_regs *regs)
{ {
enum ctx_state prev_state;
u32 cause; u32 cause;
prev_state = exception_enter();
/* /*
* Clear WP (bit 22) bit of cause register so we don't loop * Clear WP (bit 22) bit of cause register so we don't loop
* forever. * forever.
...@@ -1174,13 +1211,16 @@ asmlinkage void do_watch(struct pt_regs *regs) ...@@ -1174,13 +1211,16 @@ asmlinkage void do_watch(struct pt_regs *regs)
mips_clear_watch_registers(); mips_clear_watch_registers();
local_irq_enable(); local_irq_enable();
} }
exception_exit(prev_state);
} }
asmlinkage void do_mcheck(struct pt_regs *regs) asmlinkage void do_mcheck(struct pt_regs *regs)
{ {
const int field = 2 * sizeof(unsigned long); const int field = 2 * sizeof(unsigned long);
int multi_match = regs->cp0_status & ST0_TS; int multi_match = regs->cp0_status & ST0_TS;
enum ctx_state prev_state;
prev_state = exception_enter();
show_regs(regs); show_regs(regs);
if (multi_match) { if (multi_match) {
...@@ -1202,6 +1242,7 @@ asmlinkage void do_mcheck(struct pt_regs *regs) ...@@ -1202,6 +1242,7 @@ asmlinkage void do_mcheck(struct pt_regs *regs)
panic("Caught Machine Check exception - %scaused by multiple " panic("Caught Machine Check exception - %scaused by multiple "
"matching entries in the TLB.", "matching entries in the TLB.",
(multi_match) ? "" : "not "); (multi_match) ? "" : "not ");
exception_exit(prev_state);
} }
asmlinkage void do_mt(struct pt_regs *regs) asmlinkage void do_mt(struct pt_regs *regs)
...@@ -1627,7 +1668,6 @@ void *set_vi_handler(int n, vi_handler_t addr) ...@@ -1627,7 +1668,6 @@ void *set_vi_handler(int n, vi_handler_t addr)
} }
extern void tlb_init(void); extern void tlb_init(void);
extern void flush_tlb_handlers(void);
/* /*
* Timer interrupt * Timer interrupt
...@@ -1837,6 +1877,15 @@ void __init trap_init(void) ...@@ -1837,6 +1877,15 @@ void __init trap_init(void)
ebase += (read_c0_ebase() & 0x3ffff000); ebase += (read_c0_ebase() & 0x3ffff000);
} }
if (cpu_has_mmips) {
unsigned int config3 = read_c0_config3();
if (IS_ENABLED(CONFIG_CPU_MICROMIPS))
write_c0_config3(config3 | MIPS_CONF3_ISA_OE);
else
write_c0_config3(config3 & ~MIPS_CONF3_ISA_OE);
}
if (board_ebase_setup) if (board_ebase_setup)
board_ebase_setup(); board_ebase_setup();
per_cpu_trap_init(true); per_cpu_trap_init(true);
...@@ -1956,7 +2005,6 @@ void __init trap_init(void) ...@@ -1956,7 +2005,6 @@ void __init trap_init(void)
set_handler(0x080, &except_vec3_generic, 0x80); set_handler(0x080, &except_vec3_generic, 0x80);
local_flush_icache_range(ebase, ebase + 0x400); local_flush_icache_range(ebase, ebase + 0x400);
flush_tlb_handlers();
sort_extable(__start___dbe_table, __stop___dbe_table); sort_extable(__start___dbe_table, __stop___dbe_table);
......
...@@ -72,6 +72,7 @@ ...@@ -72,6 +72,7 @@
* A store crossing a page boundary might be executed only partially. * A store crossing a page boundary might be executed only partially.
* Undo the partial store in this case. * Undo the partial store in this case.
*/ */
#include <linux/context_tracking.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/smp.h> #include <linux/smp.h>
...@@ -684,7 +685,8 @@ const int reg16to32[] = { 16, 17, 2, 3, 4, 5, 6, 7 }; ...@@ -684,7 +685,8 @@ const int reg16to32[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
/* Recode table from 16-bit STORE register notation to 32-bit GPR. */ /* Recode table from 16-bit STORE register notation to 32-bit GPR. */
const int reg16to32st[] = { 0, 17, 2, 3, 4, 5, 6, 7 }; const int reg16to32st[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
void emulate_load_store_microMIPS(struct pt_regs *regs, void __user * addr) static void emulate_load_store_microMIPS(struct pt_regs *regs,
void __user *addr)
{ {
unsigned long value; unsigned long value;
unsigned int res; unsigned int res;
...@@ -1548,11 +1550,14 @@ static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr) ...@@ -1548,11 +1550,14 @@ static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr)
("Unhandled kernel unaligned access or invalid instruction", regs); ("Unhandled kernel unaligned access or invalid instruction", regs);
force_sig(SIGILL, current); force_sig(SIGILL, current);
} }
asmlinkage void do_ade(struct pt_regs *regs) asmlinkage void do_ade(struct pt_regs *regs)
{ {
enum ctx_state prev_state;
unsigned int __user *pc; unsigned int __user *pc;
mm_segment_t seg; mm_segment_t seg;
prev_state = exception_enter();
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS,
1, regs, regs->cp0_badvaddr); 1, regs, regs->cp0_badvaddr);
/* /*
...@@ -1628,6 +1633,7 @@ asmlinkage void do_ade(struct pt_regs *regs) ...@@ -1628,6 +1633,7 @@ asmlinkage void do_ade(struct pt_regs *regs)
/* /*
* XXX On return from the signal handler we should advance the epc * XXX On return from the signal handler we should advance the epc
*/ */
exception_exit(prev_state);
} }
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
......
...@@ -111,6 +111,7 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c) ...@@ -111,6 +111,7 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c)
* disable the register. * disable the register.
*/ */
write_c0_watchlo0(7); write_c0_watchlo0(7);
back_to_back_c0_hazard();
t = read_c0_watchlo0(); t = read_c0_watchlo0();
write_c0_watchlo0(0); write_c0_watchlo0(0);
c->watch_reg_masks[0] = t & 7; c->watch_reg_masks[0] = t & 7;
...@@ -121,12 +122,14 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c) ...@@ -121,12 +122,14 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c)
c->watch_reg_use_cnt = 1; c->watch_reg_use_cnt = 1;
t = read_c0_watchhi0(); t = read_c0_watchhi0();
write_c0_watchhi0(t | 0xff8); write_c0_watchhi0(t | 0xff8);
back_to_back_c0_hazard();
t = read_c0_watchhi0(); t = read_c0_watchhi0();
c->watch_reg_masks[0] |= (t & 0xff8); c->watch_reg_masks[0] |= (t & 0xff8);
if ((t & 0x80000000) == 0) if ((t & 0x80000000) == 0)
return; return;
write_c0_watchlo1(7); write_c0_watchlo1(7);
back_to_back_c0_hazard();
t = read_c0_watchlo1(); t = read_c0_watchlo1();
write_c0_watchlo1(0); write_c0_watchlo1(0);
c->watch_reg_masks[1] = t & 7; c->watch_reg_masks[1] = t & 7;
...@@ -135,12 +138,14 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c) ...@@ -135,12 +138,14 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c)
c->watch_reg_use_cnt = 2; c->watch_reg_use_cnt = 2;
t = read_c0_watchhi1(); t = read_c0_watchhi1();
write_c0_watchhi1(t | 0xff8); write_c0_watchhi1(t | 0xff8);
back_to_back_c0_hazard();
t = read_c0_watchhi1(); t = read_c0_watchhi1();
c->watch_reg_masks[1] |= (t & 0xff8); c->watch_reg_masks[1] |= (t & 0xff8);
if ((t & 0x80000000) == 0) if ((t & 0x80000000) == 0)
return; return;
write_c0_watchlo2(7); write_c0_watchlo2(7);
back_to_back_c0_hazard();
t = read_c0_watchlo2(); t = read_c0_watchlo2();
write_c0_watchlo2(0); write_c0_watchlo2(0);
c->watch_reg_masks[2] = t & 7; c->watch_reg_masks[2] = t & 7;
...@@ -149,12 +154,14 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c) ...@@ -149,12 +154,14 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c)
c->watch_reg_use_cnt = 3; c->watch_reg_use_cnt = 3;
t = read_c0_watchhi2(); t = read_c0_watchhi2();
write_c0_watchhi2(t | 0xff8); write_c0_watchhi2(t | 0xff8);
back_to_back_c0_hazard();
t = read_c0_watchhi2(); t = read_c0_watchhi2();
c->watch_reg_masks[2] |= (t & 0xff8); c->watch_reg_masks[2] |= (t & 0xff8);
if ((t & 0x80000000) == 0) if ((t & 0x80000000) == 0)
return; return;
write_c0_watchlo3(7); write_c0_watchlo3(7);
back_to_back_c0_hazard();
t = read_c0_watchlo3(); t = read_c0_watchlo3();
write_c0_watchlo3(0); write_c0_watchlo3(0);
c->watch_reg_masks[3] = t & 7; c->watch_reg_masks[3] = t & 7;
...@@ -163,6 +170,7 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c) ...@@ -163,6 +170,7 @@ __cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c)
c->watch_reg_use_cnt = 4; c->watch_reg_use_cnt = 4;
t = read_c0_watchhi3(); t = read_c0_watchhi3();
write_c0_watchhi3(t | 0xff8); write_c0_watchhi3(t | 0xff8);
back_to_back_c0_hazard();
t = read_c0_watchhi3(); t = read_c0_watchhi3();
c->watch_reg_masks[3] |= (t & 0xff8); c->watch_reg_masks[3] |= (t & 0xff8);
if ((t & 0x80000000) == 0) if ((t & 0x80000000) == 0)
......
...@@ -112,7 +112,7 @@ int __init plat_of_setup(void) ...@@ -112,7 +112,7 @@ int __init plat_of_setup(void)
if (!of_have_populated_dt()) if (!of_have_populated_dt())
panic("device tree not present"); panic("device tree not present");
strncpy(of_ids[0].compatible, soc_info.compatible, strlcpy(of_ids[0].compatible, soc_info.compatible,
sizeof(of_ids[0].compatible)); sizeof(of_ids[0].compatible));
strncpy(of_ids[1].compatible, "simple-bus", strncpy(of_ids[1].compatible, "simple-bus",
sizeof(of_ids[1].compatible)); sizeof(of_ids[1].compatible));
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
/* And the same for proc */ /* And the same for proc */
int proc_dolasatstring(ctl_table *table, int write, int proc_dolasatstring(struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int r; int r;
...@@ -54,7 +54,7 @@ int proc_dolasatstring(ctl_table *table, int write, ...@@ -54,7 +54,7 @@ int proc_dolasatstring(ctl_table *table, int write,
} }
/* proc function to write EEPROM after changing int entry */ /* proc function to write EEPROM after changing int entry */
int proc_dolasatint(ctl_table *table, int write, int proc_dolasatint(struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int r; int r;
...@@ -72,7 +72,7 @@ int proc_dolasatint(ctl_table *table, int write, ...@@ -72,7 +72,7 @@ int proc_dolasatint(ctl_table *table, int write,
static int rtctmp; static int rtctmp;
/* proc function to read/write RealTime Clock */ /* proc function to read/write RealTime Clock */
int proc_dolasatrtc(ctl_table *table, int write, int proc_dolasatrtc(struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct timespec ts; struct timespec ts;
...@@ -97,7 +97,7 @@ int proc_dolasatrtc(ctl_table *table, int write, ...@@ -97,7 +97,7 @@ int proc_dolasatrtc(ctl_table *table, int write,
#endif #endif
#ifdef CONFIG_INET #ifdef CONFIG_INET
int proc_lasat_ip(ctl_table *table, int write, int proc_lasat_ip(struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
unsigned int ip; unsigned int ip;
...@@ -157,7 +157,7 @@ int proc_lasat_ip(ctl_table *table, int write, ...@@ -157,7 +157,7 @@ int proc_lasat_ip(ctl_table *table, int write,
} }
#endif #endif
int proc_lasat_prid(ctl_table *table, int write, int proc_lasat_prid(struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
int r; int r;
...@@ -176,7 +176,7 @@ int proc_lasat_prid(ctl_table *table, int write, ...@@ -176,7 +176,7 @@ int proc_lasat_prid(ctl_table *table, int write,
extern int lasat_boot_to_service; extern int lasat_boot_to_service;
static ctl_table lasat_table[] = { static struct ctl_table lasat_table[] = {
{ {
.procname = "cpu-hz", .procname = "cpu-hz",
.data = &lasat_board_info.li_cpu_hz, .data = &lasat_board_info.li_cpu_hz,
...@@ -262,7 +262,7 @@ static ctl_table lasat_table[] = { ...@@ -262,7 +262,7 @@ static ctl_table lasat_table[] = {
{} {}
}; };
static ctl_table lasat_root_table[] = { static struct ctl_table lasat_root_table[] = {
{ {
.procname = "lasat", .procname = "lasat",
.mode = 0555, .mode = 0555,
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* option) any later version. * option) any later version.
*/ */
#include <linux/pci.h>
#include <cs5536/cs5536.h> #include <cs5536/cs5536.h>
#include <cs5536/cs5536_pci.h> #include <cs5536/cs5536_pci.h>
...@@ -314,3 +315,16 @@ u32 pci_isa_read_reg(int reg) ...@@ -314,3 +315,16 @@ u32 pci_isa_read_reg(int reg)
return conf_data; return conf_data;
} }
/*
* The mfgpt timer interrupt is running early, so we must keep the south bridge
* mmio always enabled. Otherwise we may race with the PCI configuration which
* may temporarily disable it. When that happens and the timer interrupt fires,
* we are not able to clear it and the system will hang.
*/
static void cs5536_isa_mmio_always_on(struct pci_dev *dev)
{
dev->mmio_always_on = 1;
}
DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA,
PCI_CLASS_BRIDGE_ISA, 8, cs5536_isa_mmio_always_on);
...@@ -471,6 +471,9 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -471,6 +471,9 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
unsigned int fcr31; unsigned int fcr31;
unsigned int bit; unsigned int bit;
if (!cpu_has_mmips)
return 0;
switch (insn.mm_i_format.opcode) { switch (insn.mm_i_format.opcode) {
case mm_pool32a_op: case mm_pool32a_op:
if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MASK) == if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MASK) ==
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
obj-y += cache.o dma-default.o extable.o fault.o \ obj-y += cache.o dma-default.o extable.o fault.o \
gup.o init.o mmap.o page.o page-funcs.o \ gup.o init.o mmap.o page.o page-funcs.o \
tlbex.o tlbex-fault.o uasm-mips.o tlbex.o tlbex-fault.o tlb-funcs.o uasm-mips.o
obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o
obj-$(CONFIG_64BIT) += pgtable-64.o obj-$(CONFIG_64BIT) += pgtable-64.o
......
...@@ -182,11 +182,7 @@ asmlinkage void sb1_cache_error(void) ...@@ -182,11 +182,7 @@ asmlinkage void sb1_cache_error(void)
#ifdef CONFIG_SIBYTE_BW_TRACE #ifdef CONFIG_SIBYTE_BW_TRACE
/* Freeze the trace buffer now */ /* Freeze the trace buffer now */
#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
csr_out32(M_BCM1480_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
#else
csr_out32(M_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG)); csr_out32(M_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
#endif
printk("Trace buffer frozen\n"); printk("Trace buffer frozen\n");
#endif #endif
......
...@@ -246,6 +246,9 @@ static int mips_dma_map_sg(struct device *dev, struct scatterlist *sg, ...@@ -246,6 +246,9 @@ static int mips_dma_map_sg(struct device *dev, struct scatterlist *sg,
if (!plat_device_is_coherent(dev)) if (!plat_device_is_coherent(dev))
__dma_sync(sg_page(sg), sg->offset, sg->length, __dma_sync(sg_page(sg), sg->offset, sg->length,
direction); direction);
#ifdef CONFIG_NEED_SG_DMA_LENGTH
sg->dma_length = sg->length;
#endif
sg->dma_address = plat_map_dma_mem_page(dev, sg_page(sg)) + sg->dma_address = plat_map_dma_mem_page(dev, sg_page(sg)) +
sg->offset; sg->offset;
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* *
* Copyright (C) 1995 - 2000 by Ralf Baechle * Copyright (C) 1995 - 2000 by Ralf Baechle
*/ */
#include <linux/context_tracking.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -32,8 +33,8 @@ ...@@ -32,8 +33,8 @@
* and the problem, and then passes it off to one of the appropriate * and the problem, and then passes it off to one of the appropriate
* routines. * routines.
*/ */
asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long write, static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
unsigned long address) unsigned long address)
{ {
struct vm_area_struct * vma = NULL; struct vm_area_struct * vma = NULL;
struct task_struct *tsk = current; struct task_struct *tsk = current;
...@@ -312,3 +313,13 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long writ ...@@ -312,3 +313,13 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long writ
} }
#endif #endif
} }
asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
unsigned long write, unsigned long address)
{
enum ctx_state prev_state;
prev_state = exception_enter();
__do_page_fault(regs, write, address);
exception_exit(prev_state);
}
...@@ -232,7 +232,7 @@ static inline void __cpuinit build_clear_pref(u32 **buf, int off) ...@@ -232,7 +232,7 @@ static inline void __cpuinit build_clear_pref(u32 **buf, int off)
uasm_i_cache(buf, Create_Dirty_Excl_D, off, A0); uasm_i_cache(buf, Create_Dirty_Excl_D, off, A0);
} }
} }
} }
extern u32 __clear_page_start; extern u32 __clear_page_start;
......
/*
* 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.
*
* Micro-assembler generated tlb handler functions.
*
* Copyright (C) 2013 Broadcom Corporation.
*
* Based on mm/page-funcs.c
* Copyright (C) 2012 MIPS Technologies, Inc.
* Copyright (C) 2012 Ralf Baechle <ralf@linux-mips.org>
*/
#include <asm/asm.h>
#include <asm/regdef.h>
#define FASTPATH_SIZE 128
LEAF(tlbmiss_handler_setup_pgd)
.space 16 * 4
END(tlbmiss_handler_setup_pgd)
EXPORT(tlbmiss_handler_setup_pgd_end)
LEAF(handle_tlbm)
.space FASTPATH_SIZE * 4
END(handle_tlbm)
EXPORT(handle_tlbm_end)
LEAF(handle_tlbs)
.space FASTPATH_SIZE * 4
END(handle_tlbs)
EXPORT(handle_tlbs_end)
LEAF(handle_tlbl)
.space FASTPATH_SIZE * 4
END(handle_tlbl)
EXPORT(handle_tlbl_end)
...@@ -305,6 +305,17 @@ static int check_for_high_segbits __cpuinitdata; ...@@ -305,6 +305,17 @@ static int check_for_high_segbits __cpuinitdata;
static unsigned int kscratch_used_mask __cpuinitdata; static unsigned int kscratch_used_mask __cpuinitdata;
static inline int __maybe_unused c0_kscratch(void)
{
switch (current_cpu_type()) {
case CPU_XLP:
case CPU_XLR:
return 22;
default:
return 31;
}
}
static int __cpuinit allocate_kscratch(void) static int __cpuinit allocate_kscratch(void)
{ {
int r; int r;
...@@ -334,9 +345,9 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p) ...@@ -334,9 +345,9 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p)
int smp_processor_id_sel; int smp_processor_id_sel;
int smp_processor_id_shift; int smp_processor_id_shift;
if (scratch_reg > 0) { if (scratch_reg >= 0) {
/* Save in CPU local C0_KScratch? */ /* Save in CPU local C0_KScratch? */
UASM_i_MTC0(p, 1, 31, scratch_reg); UASM_i_MTC0(p, 1, c0_kscratch(), scratch_reg);
r.r1 = K0; r.r1 = K0;
r.r2 = K1; r.r2 = K1;
r.r3 = 1; r.r3 = 1;
...@@ -384,8 +395,8 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p) ...@@ -384,8 +395,8 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p)
static void __cpuinit build_restore_work_registers(u32 **p) static void __cpuinit build_restore_work_registers(u32 **p)
{ {
if (scratch_reg > 0) { if (scratch_reg >= 0) {
UASM_i_MFC0(p, 1, 31, scratch_reg); UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
return; return;
} }
/* K0 already points to save area, restore $1 and $2 */ /* K0 already points to save area, restore $1 and $2 */
...@@ -673,8 +684,8 @@ static __cpuinit void build_restore_pagemask(u32 **p, ...@@ -673,8 +684,8 @@ static __cpuinit void build_restore_pagemask(u32 **p,
uasm_i_mtc0(p, 0, C0_PAGEMASK); uasm_i_mtc0(p, 0, C0_PAGEMASK);
uasm_il_b(p, r, lid); uasm_il_b(p, r, lid);
} }
if (scratch_reg > 0) if (scratch_reg >= 0)
UASM_i_MFC0(p, 1, 31, scratch_reg); UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
else else
UASM_i_LW(p, 1, scratchpad_offset(0), 0); UASM_i_LW(p, 1, scratchpad_offset(0), 0);
} else { } else {
...@@ -817,7 +828,7 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, ...@@ -817,7 +828,7 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT #ifdef CONFIG_MIPS_PGD_C0_CONTEXT
if (pgd_reg != -1) { if (pgd_reg != -1) {
/* pgd is in pgd_reg */ /* pgd is in pgd_reg */
UASM_i_MFC0(p, ptr, 31, pgd_reg); UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg);
} else { } else {
/* /*
* &pgd << 11 stored in CONTEXT [23..63]. * &pgd << 11 stored in CONTEXT [23..63].
...@@ -929,8 +940,8 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, ...@@ -929,8 +940,8 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
uasm_i_jr(p, ptr); uasm_i_jr(p, ptr);
if (mode == refill_scratch) { if (mode == refill_scratch) {
if (scratch_reg > 0) if (scratch_reg >= 0)
UASM_i_MFC0(p, 1, 31, scratch_reg); UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
else else
UASM_i_LW(p, 1, scratchpad_offset(0), 0); UASM_i_LW(p, 1, scratchpad_offset(0), 0);
} else { } else {
...@@ -961,7 +972,7 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) ...@@ -961,7 +972,7 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
uasm_i_srl(p, ptr, ptr, 19); uasm_i_srl(p, ptr, ptr, 19);
#else #else
/* /*
* smp_processor_id() << 3 is stored in CONTEXT. * smp_processor_id() << 2 is stored in CONTEXT.
*/ */
uasm_i_mfc0(p, ptr, C0_CONTEXT); uasm_i_mfc0(p, ptr, C0_CONTEXT);
UASM_i_LA_mostly(p, tmp, pgdc); UASM_i_LA_mostly(p, tmp, pgdc);
...@@ -1096,7 +1107,7 @@ struct mips_huge_tlb_info { ...@@ -1096,7 +1107,7 @@ struct mips_huge_tlb_info {
static struct mips_huge_tlb_info __cpuinit static struct mips_huge_tlb_info __cpuinit
build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l, build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
struct uasm_reloc **r, unsigned int tmp, struct uasm_reloc **r, unsigned int tmp,
unsigned int ptr, int c0_scratch) unsigned int ptr, int c0_scratch_reg)
{ {
struct mips_huge_tlb_info rv; struct mips_huge_tlb_info rv;
unsigned int even, odd; unsigned int even, odd;
...@@ -1110,12 +1121,12 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l, ...@@ -1110,12 +1121,12 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
UASM_i_MFC0(p, tmp, C0_BADVADDR); UASM_i_MFC0(p, tmp, C0_BADVADDR);
if (pgd_reg != -1) if (pgd_reg != -1)
UASM_i_MFC0(p, ptr, 31, pgd_reg); UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg);
else else
UASM_i_MFC0(p, ptr, C0_CONTEXT); UASM_i_MFC0(p, ptr, C0_CONTEXT);
if (c0_scratch >= 0) if (c0_scratch_reg >= 0)
UASM_i_MTC0(p, scratch, 31, c0_scratch); UASM_i_MTC0(p, scratch, c0_kscratch(), c0_scratch_reg);
else else
UASM_i_SW(p, scratch, scratchpad_offset(0), 0); UASM_i_SW(p, scratch, scratchpad_offset(0), 0);
...@@ -1130,14 +1141,14 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l, ...@@ -1130,14 +1141,14 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
} }
} else { } else {
if (pgd_reg != -1) if (pgd_reg != -1)
UASM_i_MFC0(p, ptr, 31, pgd_reg); UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg);
else else
UASM_i_MFC0(p, ptr, C0_CONTEXT); UASM_i_MFC0(p, ptr, C0_CONTEXT);
UASM_i_MFC0(p, tmp, C0_BADVADDR); UASM_i_MFC0(p, tmp, C0_BADVADDR);
if (c0_scratch >= 0) if (c0_scratch_reg >= 0)
UASM_i_MTC0(p, scratch, 31, c0_scratch); UASM_i_MTC0(p, scratch, c0_kscratch(), c0_scratch_reg);
else else
UASM_i_SW(p, scratch, scratchpad_offset(0), 0); UASM_i_SW(p, scratch, scratchpad_offset(0), 0);
...@@ -1242,8 +1253,8 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l, ...@@ -1242,8 +1253,8 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
} }
UASM_i_MTC0(p, odd, C0_ENTRYLO1); /* load it */ UASM_i_MTC0(p, odd, C0_ENTRYLO1); /* load it */
if (c0_scratch >= 0) { if (c0_scratch_reg >= 0) {
UASM_i_MFC0(p, scratch, 31, c0_scratch); UASM_i_MFC0(p, scratch, c0_kscratch(), c0_scratch_reg);
build_tlb_write_entry(p, l, r, tlb_random); build_tlb_write_entry(p, l, r, tlb_random);
uasm_l_leave(l, *p); uasm_l_leave(l, *p);
rv.restore_scratch = 1; rv.restore_scratch = 1;
...@@ -1286,7 +1297,7 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) ...@@ -1286,7 +1297,7 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
memset(final_handler, 0, sizeof(final_handler)); memset(final_handler, 0, sizeof(final_handler));
if ((scratch_reg > 0 || scratchpad_available()) && use_bbit_insns()) { if ((scratch_reg >= 0 || scratchpad_available()) && use_bbit_insns()) {
htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1, htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1,
scratch_reg); scratch_reg);
vmalloc_mode = refill_scratch; vmalloc_mode = refill_scratch;
...@@ -1444,27 +1455,25 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) ...@@ -1444,27 +1455,25 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
dump_handler("r4000_tlb_refill", (u32 *)ebase, 64); dump_handler("r4000_tlb_refill", (u32 *)ebase, 64);
} }
/* extern u32 handle_tlbl[], handle_tlbl_end[];
* 128 instructions for the fastpath handler is generous and should extern u32 handle_tlbs[], handle_tlbs_end[];
* never be exceeded. extern u32 handle_tlbm[], handle_tlbm_end[];
*/
#define FASTPATH_SIZE 128
u32 handle_tlbl[FASTPATH_SIZE] __cacheline_aligned;
u32 handle_tlbs[FASTPATH_SIZE] __cacheline_aligned;
u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned;
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT #ifdef CONFIG_MIPS_PGD_C0_CONTEXT
u32 tlbmiss_handler_setup_pgd_array[16] __cacheline_aligned; extern u32 tlbmiss_handler_setup_pgd[], tlbmiss_handler_setup_pgd_end[];
static void __cpuinit build_r4000_setup_pgd(void) static void __cpuinit build_r4000_setup_pgd(void)
{ {
const int a0 = 4; const int a0 = 4;
const int a1 = 5; const int a1 = 5;
u32 *p = tlbmiss_handler_setup_pgd_array; u32 *p = tlbmiss_handler_setup_pgd_array;
const int tlbmiss_handler_setup_pgd_size =
tlbmiss_handler_setup_pgd_end - tlbmiss_handler_setup_pgd;
struct uasm_label *l = labels; struct uasm_label *l = labels;
struct uasm_reloc *r = relocs; struct uasm_reloc *r = relocs;
memset(tlbmiss_handler_setup_pgd_array, 0, sizeof(tlbmiss_handler_setup_pgd_array)); memset(tlbmiss_handler_setup_pgd, 0, tlbmiss_handler_setup_pgd_size *
sizeof(tlbmiss_handler_setup_pgd[0]));
memset(labels, 0, sizeof(labels)); memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
...@@ -1490,17 +1499,17 @@ static void __cpuinit build_r4000_setup_pgd(void) ...@@ -1490,17 +1499,17 @@ static void __cpuinit build_r4000_setup_pgd(void)
} else { } else {
/* PGD in c0_KScratch */ /* PGD in c0_KScratch */
uasm_i_jr(&p, 31); uasm_i_jr(&p, 31);
UASM_i_MTC0(&p, a0, 31, pgd_reg); UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg);
} }
if (p - tlbmiss_handler_setup_pgd_array > ARRAY_SIZE(tlbmiss_handler_setup_pgd_array)) if (p >= tlbmiss_handler_setup_pgd_end)
panic("tlbmiss_handler_setup_pgd_array space exceeded"); panic("tlbmiss_handler_setup_pgd space exceeded");
uasm_resolve_relocs(relocs, labels); uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote tlbmiss_handler_setup_pgd_array (%u instructions).\n", pr_debug("Wrote tlbmiss_handler_setup_pgd (%u instructions).\n",
(unsigned int)(p - tlbmiss_handler_setup_pgd_array)); (unsigned int)(p - tlbmiss_handler_setup_pgd));
dump_handler("tlbmiss_handler", dump_handler("tlbmiss_handler", tlbmiss_handler_setup_pgd,
tlbmiss_handler_setup_pgd_array, tlbmiss_handler_setup_pgd_size);
ARRAY_SIZE(tlbmiss_handler_setup_pgd_array));
} }
#endif #endif
...@@ -1745,10 +1754,11 @@ build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte, ...@@ -1745,10 +1754,11 @@ build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte,
static void __cpuinit build_r3000_tlb_load_handler(void) static void __cpuinit build_r3000_tlb_load_handler(void)
{ {
u32 *p = handle_tlbl; u32 *p = handle_tlbl;
const int handle_tlbl_size = handle_tlbl_end - handle_tlbl;
struct uasm_label *l = labels; struct uasm_label *l = labels;
struct uasm_reloc *r = relocs; struct uasm_reloc *r = relocs;
memset(handle_tlbl, 0, sizeof(handle_tlbl)); memset(handle_tlbl, 0, handle_tlbl_size * sizeof(handle_tlbl[0]));
memset(labels, 0, sizeof(labels)); memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
...@@ -1762,23 +1772,24 @@ static void __cpuinit build_r3000_tlb_load_handler(void) ...@@ -1762,23 +1772,24 @@ static void __cpuinit build_r3000_tlb_load_handler(void)
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
uasm_i_nop(&p); uasm_i_nop(&p);
if ((p - handle_tlbl) > FASTPATH_SIZE) if (p >= handle_tlbl_end)
panic("TLB load handler fastpath space exceeded"); panic("TLB load handler fastpath space exceeded");
uasm_resolve_relocs(relocs, labels); uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote TLB load handler fastpath (%u instructions).\n", pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
(unsigned int)(p - handle_tlbl)); (unsigned int)(p - handle_tlbl));
dump_handler("r3000_tlb_load", handle_tlbl, ARRAY_SIZE(handle_tlbl)); dump_handler("r3000_tlb_load", handle_tlbl, handle_tlbl_size);
} }
static void __cpuinit build_r3000_tlb_store_handler(void) static void __cpuinit build_r3000_tlb_store_handler(void)
{ {
u32 *p = handle_tlbs; u32 *p = handle_tlbs;
const int handle_tlbs_size = handle_tlbs_end - handle_tlbs;
struct uasm_label *l = labels; struct uasm_label *l = labels;
struct uasm_reloc *r = relocs; struct uasm_reloc *r = relocs;
memset(handle_tlbs, 0, sizeof(handle_tlbs)); memset(handle_tlbs, 0, handle_tlbs_size * sizeof(handle_tlbs[0]));
memset(labels, 0, sizeof(labels)); memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
...@@ -1792,23 +1803,24 @@ static void __cpuinit build_r3000_tlb_store_handler(void) ...@@ -1792,23 +1803,24 @@ static void __cpuinit build_r3000_tlb_store_handler(void)
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
uasm_i_nop(&p); uasm_i_nop(&p);
if ((p - handle_tlbs) > FASTPATH_SIZE) if (p >= handle_tlbs)
panic("TLB store handler fastpath space exceeded"); panic("TLB store handler fastpath space exceeded");
uasm_resolve_relocs(relocs, labels); uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote TLB store handler fastpath (%u instructions).\n", pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
(unsigned int)(p - handle_tlbs)); (unsigned int)(p - handle_tlbs));
dump_handler("r3000_tlb_store", handle_tlbs, ARRAY_SIZE(handle_tlbs)); dump_handler("r3000_tlb_store", handle_tlbs, handle_tlbs_size);
} }
static void __cpuinit build_r3000_tlb_modify_handler(void) static void __cpuinit build_r3000_tlb_modify_handler(void)
{ {
u32 *p = handle_tlbm; u32 *p = handle_tlbm;
const int handle_tlbm_size = handle_tlbm_end - handle_tlbm;
struct uasm_label *l = labels; struct uasm_label *l = labels;
struct uasm_reloc *r = relocs; struct uasm_reloc *r = relocs;
memset(handle_tlbm, 0, sizeof(handle_tlbm)); memset(handle_tlbm, 0, handle_tlbm_size * sizeof(handle_tlbm[0]));
memset(labels, 0, sizeof(labels)); memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
...@@ -1822,14 +1834,14 @@ static void __cpuinit build_r3000_tlb_modify_handler(void) ...@@ -1822,14 +1834,14 @@ static void __cpuinit build_r3000_tlb_modify_handler(void)
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
uasm_i_nop(&p); uasm_i_nop(&p);
if ((p - handle_tlbm) > FASTPATH_SIZE) if (p >= handle_tlbm_end)
panic("TLB modify handler fastpath space exceeded"); panic("TLB modify handler fastpath space exceeded");
uasm_resolve_relocs(relocs, labels); uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n", pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
(unsigned int)(p - handle_tlbm)); (unsigned int)(p - handle_tlbm));
dump_handler("r3000_tlb_modify", handle_tlbm, ARRAY_SIZE(handle_tlbm)); dump_handler("r3000_tlb_modify", handle_tlbm, handle_tlbm_size);
} }
#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */ #endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
...@@ -1893,11 +1905,12 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l, ...@@ -1893,11 +1905,12 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l,
static void __cpuinit build_r4000_tlb_load_handler(void) static void __cpuinit build_r4000_tlb_load_handler(void)
{ {
u32 *p = handle_tlbl; u32 *p = handle_tlbl;
const int handle_tlbl_size = handle_tlbl_end - handle_tlbl;
struct uasm_label *l = labels; struct uasm_label *l = labels;
struct uasm_reloc *r = relocs; struct uasm_reloc *r = relocs;
struct work_registers wr; struct work_registers wr;
memset(handle_tlbl, 0, sizeof(handle_tlbl)); memset(handle_tlbl, 0, handle_tlbl_size * sizeof(handle_tlbl[0]));
memset(labels, 0, sizeof(labels)); memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
...@@ -1935,6 +1948,19 @@ static void __cpuinit build_r4000_tlb_load_handler(void) ...@@ -1935,6 +1948,19 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
uasm_i_nop(&p); uasm_i_nop(&p);
uasm_i_tlbr(&p); uasm_i_tlbr(&p);
switch (current_cpu_type()) {
default:
if (cpu_has_mips_r2) {
uasm_i_ehb(&p);
case CPU_CAVIUM_OCTEON:
case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2:
break;
}
}
/* Examine entrylo 0 or 1 based on ptr. */ /* Examine entrylo 0 or 1 based on ptr. */
if (use_bbit_insns()) { if (use_bbit_insns()) {
uasm_i_bbit0(&p, wr.r2, ilog2(sizeof(pte_t)), 8); uasm_i_bbit0(&p, wr.r2, ilog2(sizeof(pte_t)), 8);
...@@ -1989,6 +2015,19 @@ static void __cpuinit build_r4000_tlb_load_handler(void) ...@@ -1989,6 +2015,19 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
uasm_i_nop(&p); uasm_i_nop(&p);
uasm_i_tlbr(&p); uasm_i_tlbr(&p);
switch (current_cpu_type()) {
default:
if (cpu_has_mips_r2) {
uasm_i_ehb(&p);
case CPU_CAVIUM_OCTEON:
case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2:
break;
}
}
/* Examine entrylo 0 or 1 based on ptr. */ /* Examine entrylo 0 or 1 based on ptr. */
if (use_bbit_insns()) { if (use_bbit_insns()) {
uasm_i_bbit0(&p, wr.r2, ilog2(sizeof(pte_t)), 8); uasm_i_bbit0(&p, wr.r2, ilog2(sizeof(pte_t)), 8);
...@@ -2036,24 +2075,25 @@ static void __cpuinit build_r4000_tlb_load_handler(void) ...@@ -2036,24 +2075,25 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
uasm_i_nop(&p); uasm_i_nop(&p);
if ((p - handle_tlbl) > FASTPATH_SIZE) if (p >= handle_tlbl_end)
panic("TLB load handler fastpath space exceeded"); panic("TLB load handler fastpath space exceeded");
uasm_resolve_relocs(relocs, labels); uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote TLB load handler fastpath (%u instructions).\n", pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
(unsigned int)(p - handle_tlbl)); (unsigned int)(p - handle_tlbl));
dump_handler("r4000_tlb_load", handle_tlbl, ARRAY_SIZE(handle_tlbl)); dump_handler("r4000_tlb_load", handle_tlbl, handle_tlbl_size);
} }
static void __cpuinit build_r4000_tlb_store_handler(void) static void __cpuinit build_r4000_tlb_store_handler(void)
{ {
u32 *p = handle_tlbs; u32 *p = handle_tlbs;
const int handle_tlbs_size = handle_tlbs_end - handle_tlbs;
struct uasm_label *l = labels; struct uasm_label *l = labels;
struct uasm_reloc *r = relocs; struct uasm_reloc *r = relocs;
struct work_registers wr; struct work_registers wr;
memset(handle_tlbs, 0, sizeof(handle_tlbs)); memset(handle_tlbs, 0, handle_tlbs_size * sizeof(handle_tlbs[0]));
memset(labels, 0, sizeof(labels)); memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
...@@ -2090,24 +2130,25 @@ static void __cpuinit build_r4000_tlb_store_handler(void) ...@@ -2090,24 +2130,25 @@ static void __cpuinit build_r4000_tlb_store_handler(void)
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
uasm_i_nop(&p); uasm_i_nop(&p);
if ((p - handle_tlbs) > FASTPATH_SIZE) if (p >= handle_tlbs_end)
panic("TLB store handler fastpath space exceeded"); panic("TLB store handler fastpath space exceeded");
uasm_resolve_relocs(relocs, labels); uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote TLB store handler fastpath (%u instructions).\n", pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
(unsigned int)(p - handle_tlbs)); (unsigned int)(p - handle_tlbs));
dump_handler("r4000_tlb_store", handle_tlbs, ARRAY_SIZE(handle_tlbs)); dump_handler("r4000_tlb_store", handle_tlbs, handle_tlbs_size);
} }
static void __cpuinit build_r4000_tlb_modify_handler(void) static void __cpuinit build_r4000_tlb_modify_handler(void)
{ {
u32 *p = handle_tlbm; u32 *p = handle_tlbm;
const int handle_tlbm_size = handle_tlbm_end - handle_tlbm;
struct uasm_label *l = labels; struct uasm_label *l = labels;
struct uasm_reloc *r = relocs; struct uasm_reloc *r = relocs;
struct work_registers wr; struct work_registers wr;
memset(handle_tlbm, 0, sizeof(handle_tlbm)); memset(handle_tlbm, 0, handle_tlbm_size * sizeof(handle_tlbm[0]));
memset(labels, 0, sizeof(labels)); memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs)); memset(relocs, 0, sizeof(relocs));
...@@ -2145,14 +2186,28 @@ static void __cpuinit build_r4000_tlb_modify_handler(void) ...@@ -2145,14 +2186,28 @@ static void __cpuinit build_r4000_tlb_modify_handler(void)
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
uasm_i_nop(&p); uasm_i_nop(&p);
if ((p - handle_tlbm) > FASTPATH_SIZE) if (p >= handle_tlbm_end)
panic("TLB modify handler fastpath space exceeded"); panic("TLB modify handler fastpath space exceeded");
uasm_resolve_relocs(relocs, labels); uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n", pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
(unsigned int)(p - handle_tlbm)); (unsigned int)(p - handle_tlbm));
dump_handler("r4000_tlb_modify", handle_tlbm, ARRAY_SIZE(handle_tlbm)); dump_handler("r4000_tlb_modify", handle_tlbm, handle_tlbm_size);
}
static void __cpuinit flush_tlb_handlers(void)
{
local_flush_icache_range((unsigned long)handle_tlbl,
(unsigned long)handle_tlbl_end);
local_flush_icache_range((unsigned long)handle_tlbs,
(unsigned long)handle_tlbs_end);
local_flush_icache_range((unsigned long)handle_tlbm,
(unsigned long)handle_tlbm_end);
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd,
(unsigned long)tlbmiss_handler_setup_pgd_end);
#endif
} }
void __cpuinit build_tlb_refill_handler(void) void __cpuinit build_tlb_refill_handler(void)
...@@ -2187,6 +2242,7 @@ void __cpuinit build_tlb_refill_handler(void) ...@@ -2187,6 +2242,7 @@ void __cpuinit build_tlb_refill_handler(void)
build_r3000_tlb_load_handler(); build_r3000_tlb_load_handler();
build_r3000_tlb_store_handler(); build_r3000_tlb_store_handler();
build_r3000_tlb_modify_handler(); build_r3000_tlb_modify_handler();
flush_tlb_handlers();
run_once++; run_once++;
} }
#else #else
...@@ -2214,23 +2270,10 @@ void __cpuinit build_tlb_refill_handler(void) ...@@ -2214,23 +2270,10 @@ void __cpuinit build_tlb_refill_handler(void)
build_r4000_tlb_modify_handler(); build_r4000_tlb_modify_handler();
if (!cpu_has_local_ebase) if (!cpu_has_local_ebase)
build_r4000_tlb_refill_handler(); build_r4000_tlb_refill_handler();
flush_tlb_handlers();
run_once++; run_once++;
} }
if (cpu_has_local_ebase) if (cpu_has_local_ebase)
build_r4000_tlb_refill_handler(); build_r4000_tlb_refill_handler();
} }
} }
void __cpuinit flush_tlb_handlers(void)
{
local_flush_icache_range((unsigned long)handle_tlbl,
(unsigned long)handle_tlbl + sizeof(handle_tlbl));
local_flush_icache_range((unsigned long)handle_tlbs,
(unsigned long)handle_tlbs + sizeof(handle_tlbs));
local_flush_icache_range((unsigned long)handle_tlbm,
(unsigned long)handle_tlbm + sizeof(handle_tlbm));
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd_array,
(unsigned long)tlbmiss_handler_setup_pgd_array + sizeof(handle_tlbm));
#endif
}
...@@ -10,7 +10,6 @@ obj-y := malta-amon.o malta-display.o malta-init.o \ ...@@ -10,7 +10,6 @@ obj-y := malta-amon.o malta-display.o malta-init.o \
malta-reset.o malta-setup.o malta-time.o malta-reset.o malta-setup.o malta-time.o
obj-$(CONFIG_EARLY_PRINTK) += malta-console.o obj-$(CONFIG_EARLY_PRINTK) += malta-console.o
obj-$(CONFIG_PCI) += malta-pci.o
# FIXME FIXME FIXME # FIXME FIXME FIXME
obj-$(CONFIG_MIPS_MT_SMTC) += malta-smtc.o obj-$(CONFIG_MIPS_MT_SMTC) += malta-smtc.o
...@@ -422,8 +422,10 @@ static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { ...@@ -422,8 +422,10 @@ static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
*/ */
int __init gcmp_probe(unsigned long addr, unsigned long size) int __init gcmp_probe(unsigned long addr, unsigned long size)
{ {
if (mips_revision_sconid != MIPS_REVISION_SCON_ROCIT) { if ((mips_revision_sconid != MIPS_REVISION_SCON_ROCIT) &&
(mips_revision_sconid != MIPS_REVISION_SCON_GT64120)) {
gcmp_present = 0; gcmp_present = 0;
pr_debug("GCMP NOT present\n");
return gcmp_present; return gcmp_present;
} }
......
/* /*
* 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.
*
* Carsten Langgaard, carstenl@mips.com * Carsten Langgaard, carstenl@mips.com
* Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
*
* ########################################################################
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
* published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* ########################################################################
*
* Reset the MIPS boards.
*
*/ */
#include <linux/init.h> #include <linux/io.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <asm/io.h>
#include <asm/reboot.h> #include <asm/reboot.h>
#include <asm/mips-boards/generic.h>
#define SOFTRES_REG 0x1f000500
#define GORESET 0x42
static void mips_machine_restart(char *command) static void mips_machine_restart(char *command)
{ {
...@@ -45,7 +30,6 @@ static void mips_machine_halt(void) ...@@ -45,7 +30,6 @@ static void mips_machine_halt(void)
__raw_writel(GORESET, softres_reg); __raw_writel(GORESET, softres_reg);
} }
static int __init mips_reboot_setup(void) static int __init mips_reboot_setup(void)
{ {
_machine_restart = mips_machine_restart; _machine_restart = mips_machine_restart;
...@@ -54,5 +38,4 @@ static int __init mips_reboot_setup(void) ...@@ -54,5 +38,4 @@ static int __init mips_reboot_setup(void)
return 0; return 0;
} }
arch_initcall(mips_reboot_setup); arch_initcall(mips_reboot_setup);
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
#include <linux/pm.h> #include <linux/pm.h>
#include <asm/reboot.h> #include <asm/reboot.h>
#include <asm/mips-boards/generic.h>
#define SOFTRES_REG 0x1f000050
#define GORESET 0x4d
static void mips_machine_restart(char *command) static void mips_machine_restart(char *command)
{ {
...@@ -35,5 +37,4 @@ static int __init mips_reboot_setup(void) ...@@ -35,5 +37,4 @@ static int __init mips_reboot_setup(void)
return 0; return 0;
} }
arch_initcall(mips_reboot_setup); arch_initcall(mips_reboot_setup);
...@@ -51,4 +51,15 @@ endif ...@@ -51,4 +51,15 @@ endif
config NLM_COMMON config NLM_COMMON
bool bool
config IOMMU_HELPER
bool
config NEED_SG_DMA_LENGTH
bool
config SWIOTLB
def_bool y
select NEED_SG_DMA_LENGTH
select IOMMU_HELPER
endif endif
obj-y += irq.o time.o obj-y += irq.o time.o
obj-y += nlm-dma.o
obj-y += reset.o
obj-$(CONFIG_SMP) += smp.o smpboot.o obj-$(CONFIG_SMP) += smp.o smpboot.o
obj-$(CONFIG_EARLY_PRINTK) += earlycons.o obj-$(CONFIG_EARLY_PRINTK) += earlycons.o
...@@ -253,13 +253,12 @@ asmlinkage void plat_irq_dispatch(void) ...@@ -253,13 +253,12 @@ asmlinkage void plat_irq_dispatch(void)
node = nlm_nodeid(); node = nlm_nodeid();
eirr = read_c0_eirr_and_eimr(); eirr = read_c0_eirr_and_eimr();
if (eirr == 0)
i = __ilog2_u64(eirr);
if (i == -1)
return; return;
i = __ffs64(eirr);
/* per-CPU IRQs don't need translation */ /* per-CPU IRQs don't need translation */
if (eirr & PERCPU_IRQ_MASK) { if (i < PIC_IRQ_BASE) {
do_IRQ(i); do_IRQ(i);
return; return;
} }
......
/*
* Copyright (C) 2003-2013 Broadcom Corporation
* All Rights Reserved
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the Broadcom
* license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
#include <linux/bootmem.h>
#include <linux/export.h>
#include <linux/swiotlb.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <asm/bootinfo.h>
static char *nlm_swiotlb;
static void *nlm_dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
{
void *ret;
if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
return ret;
/* ignore region specifiers */
gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
#ifdef CONFIG_ZONE_DMA32
if (dev->coherent_dma_mask <= DMA_BIT_MASK(32))
gfp |= __GFP_DMA32;
#endif
/* Don't invoke OOM killer */
gfp |= __GFP_NORETRY;
return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
}
static void nlm_dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs)
{
int order = get_order(size);
if (dma_release_from_coherent(dev, order, vaddr))
return;
swiotlb_free_coherent(dev, size, vaddr, dma_handle);
}
struct dma_map_ops nlm_swiotlb_dma_ops = {
.alloc = nlm_dma_alloc_coherent,
.free = nlm_dma_free_coherent,
.map_page = swiotlb_map_page,
.unmap_page = swiotlb_unmap_page,
.map_sg = swiotlb_map_sg_attrs,
.unmap_sg = swiotlb_unmap_sg_attrs,
.sync_single_for_cpu = swiotlb_sync_single_for_cpu,
.sync_single_for_device = swiotlb_sync_single_for_device,
.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
.sync_sg_for_device = swiotlb_sync_sg_for_device,
.mapping_error = swiotlb_dma_mapping_error,
.dma_supported = swiotlb_dma_supported
};
void __init plat_swiotlb_setup(void)
{
size_t swiotlbsize;
unsigned long swiotlb_nslabs;
swiotlbsize = 1 << 20; /* 1 MB for now */
swiotlb_nslabs = swiotlbsize >> IO_TLB_SHIFT;
swiotlb_nslabs = ALIGN(swiotlb_nslabs, IO_TLB_SEGSIZE);
swiotlbsize = swiotlb_nslabs << IO_TLB_SHIFT;
nlm_swiotlb = alloc_bootmem_low_pages(swiotlbsize);
swiotlb_init_with_tbl(nlm_swiotlb, swiotlb_nslabs, 1);
}
/*
* Copyright 2003-2013 Broadcom Corporation.
* All Rights Reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the Broadcom
* license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/init.h>
#include <asm/asm.h>
#include <asm/asm-offsets.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/stackframe.h>
#include <asm/asmmacro.h>
#include <asm/addrspace.h>
#include <asm/netlogic/common.h>
#include <asm/netlogic/xlp-hal/iomap.h>
#include <asm/netlogic/xlp-hal/xlp.h>
#include <asm/netlogic/xlp-hal/sys.h>
#include <asm/netlogic/xlp-hal/cpucontrol.h>
#define CP0_EBASE $15
#define SYS_CPU_COHERENT_BASE(node) CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \
XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \
SYS_CPU_NONCOHERENT_MODE * 4
/* Enable XLP features and workarounds in the LSU */
.macro xlp_config_lsu
li t0, LSU_DEFEATURE
mfcr t1, t0
lui t2, 0xc080 /* SUE, Enable Unaligned Access, L2HPE */
or t1, t1, t2
mtcr t1, t0
li t0, ICU_DEFEATURE
mfcr t1, t0
ori t1, 0x1000 /* Enable Icache partitioning */
mtcr t1, t0
li t0, SCHED_DEFEATURE
lui t1, 0x0100 /* Disable BRU accepting ALU ops */
mtcr t1, t0
.endm
/*
* Low level flush for L1D cache on XLP, the normal cache ops does
* not do the complete and correct cache flush.
*/
.macro xlp_flush_l1_dcache
li t0, LSU_DEBUG_DATA0
li t1, LSU_DEBUG_ADDR
li t2, 0 /* index */
li t3, 0x1000 /* loop count */
1:
sll v0, t2, 5
mtcr zero, t0
ori v1, v0, 0x3 /* way0 | write_enable | write_active */
mtcr v1, t1
2:
mfcr v1, t1
andi v1, 0x1 /* wait for write_active == 0 */
bnez v1, 2b
nop
mtcr zero, t0
ori v1, v0, 0x7 /* way1 | write_enable | write_active */
mtcr v1, t1
3:
mfcr v1, t1
andi v1, 0x1 /* wait for write_active == 0 */
bnez v1, 3b
nop
addi t2, 1
bne t3, t2, 1b
nop
.endm
/*
* nlm_reset_entry will be copied to the reset entry point for
* XLR and XLP. The XLP cores start here when they are woken up. This
* is also the NMI entry point.
*
* We use scratch reg 6/7 to save k0/k1 and check for NMI first.
*
* The data corresponding to reset/NMI is stored at RESET_DATA_PHYS
* location, this will have the thread mask (used when core is woken up)
* and the current NMI handler in case we reached here for an NMI.
*
* When a core or thread is newly woken up, it marks itself ready and
* loops in a 'wait'. When the CPU really needs waking up, we send an NMI
* IPI to it, with the NMI handler set to prom_boot_secondary_cpus
*/
.set noreorder
.set noat
.set arch=xlr /* for mfcr/mtcr, XLR is sufficient */
FEXPORT(nlm_reset_entry)
dmtc0 k0, $22, 6
dmtc0 k1, $22, 7
mfc0 k0, CP0_STATUS
li k1, 0x80000
and k1, k0, k1
beqz k1, 1f /* go to real reset entry */
nop
li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */
ld k0, BOOT_NMI_HANDLER(k1)
jr k0
nop
1: /* Entry point on core wakeup */
mfc0 t0, CP0_EBASE, 1
mfc0 t1, CP0_EBASE, 1
srl t1, 5
andi t1, 0x3 /* t1 <- node */
li t2, 0x40000
mul t3, t2, t1 /* t3 = node * 0x40000 */
srl t0, t0, 2
and t0, t0, 0x7 /* t0 <- core */
li t1, 0x1
sll t0, t1, t0
nor t0, t0, zero /* t0 <- ~(1 << core) */
li t2, SYS_CPU_COHERENT_BASE(0)
add t2, t2, t3 /* t2 <- SYS offset for node */
lw t1, 0(t2)
and t1, t1, t0
sw t1, 0(t2)
/* read back to ensure complete */
lw t1, 0(t2)
sync
/* Configure LSU on Non-0 Cores. */
xlp_config_lsu
/* FALL THROUGH */
/*
* Wake up sibling threads from the initial thread in
* a core.
*/
EXPORT(nlm_boot_siblings)
/* core L1D flush before enable threads */
xlp_flush_l1_dcache
/* Enable hw threads by writing to MAP_THREADMODE of the core */
li t0, CKSEG1ADDR(RESET_DATA_PHYS)
lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */
li t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE)
mfcr t2, t0
or t2, t2, t1
mtcr t2, t0
/*
* The new hardware thread starts at the next instruction
* For all the cases other than core 0 thread 0, we will
* jump to the secondary wait function.
*/
mfc0 v0, CP0_EBASE, 1
andi v0, 0x3ff /* v0 <- node/core */
beqz v0, 4f /* boot cpu (cpuid == 0)? */
nop
/* setup status reg */
move t1, zero
#ifdef CONFIG_64BIT
ori t1, ST0_KX
#endif
mtc0 t1, CP0_STATUS
/* mark CPU ready, careful here, previous mtcr trashed registers */
li t3, CKSEG1ADDR(RESET_DATA_PHYS)
ADDIU t1, t3, BOOT_CPU_READY
sll v1, v0, 2
PTR_ADDU t1, v1
li t2, 1
sw t2, 0(t1)
/* Wait until NMI hits */
3: wait
b 3b
nop
/*
* For the boot CPU, we have to restore registers and
* return
*/
4: dmfc0 t0, $4, 2 /* restore SP from UserLocal */
li t1, 0xfadebeef
dmtc0 t1, $4, 2 /* restore SP from UserLocal */
PTR_SUBU sp, t0, PT_SIZE
RESTORE_ALL
jr ra
nop
EXPORT(nlm_reset_entry_end)
LEAF(nlm_init_boot_cpu)
#ifdef CONFIG_CPU_XLP
xlp_config_lsu
#endif
jr ra
nop
END(nlm_init_boot_cpu)
...@@ -145,7 +145,6 @@ void nlm_cpus_done(void) ...@@ -145,7 +145,6 @@ void nlm_cpus_done(void)
* Boot all other cpus in the system, initialize them, and bring them into * Boot all other cpus in the system, initialize them, and bring them into
* the boot function * the boot function
*/ */
int nlm_cpu_ready[NR_CPUS];
unsigned long nlm_next_gp; unsigned long nlm_next_gp;
unsigned long nlm_next_sp; unsigned long nlm_next_sp;
static cpumask_t phys_cpu_present_mask; static cpumask_t phys_cpu_present_mask;
...@@ -168,6 +167,7 @@ void __init nlm_smp_setup(void) ...@@ -168,6 +167,7 @@ void __init nlm_smp_setup(void)
{ {
unsigned int boot_cpu; unsigned int boot_cpu;
int num_cpus, i, ncore; int num_cpus, i, ncore;
volatile u32 *cpu_ready = nlm_get_boot_data(BOOT_CPU_READY);
char buf[64]; char buf[64];
boot_cpu = hard_smp_processor_id(); boot_cpu = hard_smp_processor_id();
...@@ -181,10 +181,10 @@ void __init nlm_smp_setup(void) ...@@ -181,10 +181,10 @@ void __init nlm_smp_setup(void)
num_cpus = 1; num_cpus = 1;
for (i = 0; i < NR_CPUS; i++) { for (i = 0; i < NR_CPUS; i++) {
/* /*
* nlm_cpu_ready array is not set for the boot_cpu, * cpu_ready array is not set for the boot_cpu,
* it is only set for ASPs (see smpboot.S) * it is only set for ASPs (see smpboot.S)
*/ */
if (nlm_cpu_ready[i]) { if (cpu_ready[i]) {
cpumask_set_cpu(i, &phys_cpu_present_mask); cpumask_set_cpu(i, &phys_cpu_present_mask);
__cpu_number_map[i] = num_cpus; __cpu_number_map[i] = num_cpus;
__cpu_logical_map[num_cpus] = i; __cpu_logical_map[num_cpus] = i;
...@@ -254,21 +254,15 @@ static int nlm_parse_cpumask(cpumask_t *wakeup_mask) ...@@ -254,21 +254,15 @@ static int nlm_parse_cpumask(cpumask_t *wakeup_mask)
int __cpuinit nlm_wakeup_secondary_cpus(void) int __cpuinit nlm_wakeup_secondary_cpus(void)
{ {
unsigned long reset_vec; u32 *reset_data;
char *reset_data;
int threadmode; int threadmode;
/* Update reset entry point with CPU init code */
reset_vec = CKSEG1ADDR(RESET_VEC_PHYS);
memcpy((void *)reset_vec, (void *)nlm_reset_entry,
(nlm_reset_entry_end - nlm_reset_entry));
/* verify the mask and setup core config variables */ /* verify the mask and setup core config variables */
threadmode = nlm_parse_cpumask(&nlm_cpumask); threadmode = nlm_parse_cpumask(&nlm_cpumask);
/* Setup CPU init parameters */ /* Setup CPU init parameters */
reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS); reset_data = nlm_get_boot_data(BOOT_THREAD_MODE);
*(int *)(reset_data + BOOT_THREAD_MODE) = threadmode; *reset_data = threadmode;
#ifdef CONFIG_CPU_XLP #ifdef CONFIG_CPU_XLP
xlp_wakeup_secondary_cpus(); xlp_wakeup_secondary_cpus();
......
...@@ -50,197 +50,12 @@ ...@@ -50,197 +50,12 @@
#include <asm/netlogic/xlp-hal/cpucontrol.h> #include <asm/netlogic/xlp-hal/cpucontrol.h>
#define CP0_EBASE $15 #define CP0_EBASE $15
#define SYS_CPU_COHERENT_BASE(node) CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \
XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \
SYS_CPU_NONCOHERENT_MODE * 4
#define XLP_AX_WORKAROUND /* enable Ax silicon workarounds */
/* Enable XLP features and workarounds in the LSU */
.macro xlp_config_lsu
li t0, LSU_DEFEATURE
mfcr t1, t0
lui t2, 0xc080 /* SUE, Enable Unaligned Access, L2HPE */
or t1, t1, t2
#ifdef XLP_AX_WORKAROUND
li t2, ~0xe /* S1RCM */
and t1, t1, t2
#endif
mtcr t1, t0
li t0, ICU_DEFEATURE
mfcr t1, t0
ori t1, 0x1000 /* Enable Icache partitioning */
mtcr t1, t0
#ifdef XLP_AX_WORKAROUND
li t0, SCHED_DEFEATURE
lui t1, 0x0100 /* Disable BRU accepting ALU ops */
mtcr t1, t0
#endif
.endm
/*
* This is the code that will be copied to the reset entry point for
* XLR and XLP. The XLP cores start here when they are woken up. This
* is also the NMI entry point.
*/
.macro xlp_flush_l1_dcache
li t0, LSU_DEBUG_DATA0
li t1, LSU_DEBUG_ADDR
li t2, 0 /* index */
li t3, 0x1000 /* loop count */
1:
sll v0, t2, 5
mtcr zero, t0
ori v1, v0, 0x3 /* way0 | write_enable | write_active */
mtcr v1, t1
2:
mfcr v1, t1
andi v1, 0x1 /* wait for write_active == 0 */
bnez v1, 2b
nop
mtcr zero, t0
ori v1, v0, 0x7 /* way1 | write_enable | write_active */
mtcr v1, t1
3:
mfcr v1, t1
andi v1, 0x1 /* wait for write_active == 0 */
bnez v1, 3b
nop
addi t2, 1
bne t3, t2, 1b
nop
.endm
/*
* The cores can come start when they are woken up. This is also the NMI
* entry, so check that first.
*
* The data corresponding to reset/NMI is stored at RESET_DATA_PHYS
* location, this will have the thread mask (used when core is woken up)
* and the current NMI handler in case we reached here for an NMI.
*
* When a core or thread is newly woken up, it loops in a 'wait'. When
* the CPU really needs waking up, we send an NMI to it, with the NMI
* handler set to prom_boot_secondary_cpus
*/
.set noreorder .set noreorder
.set noat .set noat
.set arch=xlr /* for mfcr/mtcr, XLR is sufficient */ .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */
FEXPORT(nlm_reset_entry)
dmtc0 k0, $22, 6
dmtc0 k1, $22, 7
mfc0 k0, CP0_STATUS
li k1, 0x80000
and k1, k0, k1
beqz k1, 1f /* go to real reset entry */
nop
li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */
ld k0, BOOT_NMI_HANDLER(k1)
jr k0
nop
1: /* Entry point on core wakeup */
mfc0 t0, CP0_EBASE, 1
mfc0 t1, CP0_EBASE, 1
srl t1, 5
andi t1, 0x3 /* t1 <- node */
li t2, 0x40000
mul t3, t2, t1 /* t3 = node * 0x40000 */
srl t0, t0, 2
and t0, t0, 0x7 /* t0 <- core */
li t1, 0x1
sll t0, t1, t0
nor t0, t0, zero /* t0 <- ~(1 << core) */
li t2, SYS_CPU_COHERENT_BASE(0)
add t2, t2, t3 /* t2 <- SYS offset for node */
lw t1, 0(t2)
and t1, t1, t0
sw t1, 0(t2)
/* read back to ensure complete */
lw t1, 0(t2)
sync
/* Configure LSU on Non-0 Cores. */
xlp_config_lsu
/* FALL THROUGH */
/*
* Wake up sibling threads from the initial thread in
* a core.
*/
EXPORT(nlm_boot_siblings)
/* core L1D flush before enable threads */
xlp_flush_l1_dcache
/* Enable hw threads by writing to MAP_THREADMODE of the core */
li t0, CKSEG1ADDR(RESET_DATA_PHYS)
lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */
li t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE)
mfcr t2, t0
or t2, t2, t1
mtcr t2, t0
/*
* The new hardware thread starts at the next instruction
* For all the cases other than core 0 thread 0, we will
* jump to the secondary wait function.
*/
mfc0 v0, CP0_EBASE, 1
andi v0, 0x3ff /* v0 <- node/core */
/* Init MMU in the first thread after changing THREAD_MODE
* register (Ax Errata?)
*/
andi v1, v0, 0x3 /* v1 <- thread id */
bnez v1, 2f
nop
li t0, MMU_SETUP
li t1, 0
mtcr t1, t0
_ehb
2: beqz v0, 4f /* boot cpu (cpuid == 0)? */
nop
/* setup status reg */
move t1, zero
#ifdef CONFIG_64BIT
ori t1, ST0_KX
#endif
mtc0 t1, CP0_STATUS
/* mark CPU ready */
PTR_LA t1, nlm_cpu_ready
sll v1, v0, 2
PTR_ADDU t1, v1
li t2, 1
sw t2, 0(t1)
/* Wait until NMI hits */
3: wait
j 3b
nop
/*
* For the boot CPU, we have to restore registers and
* return
*/
4: dmfc0 t0, $4, 2 /* restore SP from UserLocal */
li t1, 0xfadebeef
dmtc0 t1, $4, 2 /* restore SP from UserLocal */
PTR_SUBU sp, t0, PT_SIZE
RESTORE_ALL
jr ra
nop
EXPORT(nlm_reset_entry_end)
FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */ FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */
xlp_config_lsu
dmtc0 sp, $4, 2 /* SP saved in UserLocal */ dmtc0 sp, $4, 2 /* SP saved in UserLocal */
SAVE_ALL SAVE_ALL
sync sync
...@@ -294,8 +109,9 @@ NESTED(nlm_rmiboot_preboot, 16, sp) ...@@ -294,8 +109,9 @@ NESTED(nlm_rmiboot_preboot, 16, sp)
andi t2, t0, 0x3 /* thread num */ andi t2, t0, 0x3 /* thread num */
sll t0, 2 /* offset in cpu array */ sll t0, 2 /* offset in cpu array */
PTR_LA t1, nlm_cpu_ready /* mark CPU ready */ li t3, CKSEG1ADDR(RESET_DATA_PHYS)
PTR_ADDU t1, t0 ADDIU t1, t3, BOOT_CPU_READY
ADDU t1, t0
li t3, 1 li t3, 1
sw t3, 0(t1) sw t3, 0(t1)
...@@ -321,7 +137,7 @@ NESTED(nlm_rmiboot_preboot, 16, sp) ...@@ -321,7 +137,7 @@ NESTED(nlm_rmiboot_preboot, 16, sp)
mtcr t1, t0 /* update core control */ mtcr t1, t0 /* update core control */
1: wait 1: wait
j 1b b 1b
nop nop
END(nlm_rmiboot_preboot) END(nlm_rmiboot_preboot)
__FINIT __FINIT
obj-y += setup.o nlm_hal.o obj-y += setup.o nlm_hal.o cop2-ex.o dt.o
obj-$(CONFIG_SMP) += wakeup.o obj-$(CONFIG_SMP) += wakeup.o
obj-$(CONFIG_USB) += usb-init.o obj-$(CONFIG_USB) += usb-init.o
/*
* 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) 2013 Broadcom Corporation.
*
* based on arch/mips/cavium-octeon/cpu.c
* Copyright (C) 2009 Wind River Systems,
* written by Ralf Baechle <ralf@linux-mips.org>
*/
#include <linux/init.h>
#include <linux/irqflags.h>
#include <linux/notifier.h>
#include <linux/prefetch.h>
#include <linux/sched.h>
#include <asm/cop2.h>
#include <asm/current.h>
#include <asm/mipsregs.h>
#include <asm/page.h>
#include <asm/netlogic/mips-extns.h>
/*
* 64 bit ops are done in inline assembly to support 32 bit
* compilation
*/
void nlm_cop2_save(struct nlm_cop2_state *r)
{
asm volatile(
".set push\n"
".set noat\n"
"dmfc2 $1, $0, 0\n"
"sd $1, 0(%1)\n"
"dmfc2 $1, $0, 1\n"
"sd $1, 8(%1)\n"
"dmfc2 $1, $0, 2\n"
"sd $1, 16(%1)\n"
"dmfc2 $1, $0, 3\n"
"sd $1, 24(%1)\n"
"dmfc2 $1, $1, 0\n"
"sd $1, 0(%2)\n"
"dmfc2 $1, $1, 1\n"
"sd $1, 8(%2)\n"
"dmfc2 $1, $1, 2\n"
"sd $1, 16(%2)\n"
"dmfc2 $1, $1, 3\n"
"sd $1, 24(%2)\n"
".set pop\n"
: "=m"(*r)
: "r"(r->tx), "r"(r->rx));
r->tx_msg_status = __read_32bit_c2_register($2, 0);
r->rx_msg_status = __read_32bit_c2_register($3, 0) & 0x0fffffff;
}
void nlm_cop2_restore(struct nlm_cop2_state *r)
{
u32 rstat;
asm volatile(
".set push\n"
".set noat\n"
"ld $1, 0(%1)\n"
"dmtc2 $1, $0, 0\n"
"ld $1, 8(%1)\n"
"dmtc2 $1, $0, 1\n"
"ld $1, 16(%1)\n"
"dmtc2 $1, $0, 2\n"
"ld $1, 24(%1)\n"
"dmtc2 $1, $0, 3\n"
"ld $1, 0(%2)\n"
"dmtc2 $1, $1, 0\n"
"ld $1, 8(%2)\n"
"dmtc2 $1, $1, 1\n"
"ld $1, 16(%2)\n"
"dmtc2 $1, $1, 2\n"
"ld $1, 24(%2)\n"
"dmtc2 $1, $1, 3\n"
".set pop\n"
: : "m"(*r), "r"(r->tx), "r"(r->rx));
__write_32bit_c2_register($2, 0, r->tx_msg_status);
rstat = __read_32bit_c2_register($3, 0) & 0xf0000000u;
__write_32bit_c2_register($3, 0, r->rx_msg_status | rstat);
}
static int nlm_cu2_call(struct notifier_block *nfb, unsigned long action,
void *data)
{
unsigned long flags;
unsigned int status;
switch (action) {
case CU2_EXCEPTION:
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
break;
local_irq_save(flags);
KSTK_STATUS(current) |= ST0_CU2;
status = read_c0_status();
write_c0_status(status | ST0_CU2);
nlm_cop2_restore(&(current->thread.cp2));
write_c0_status(status & ~ST0_CU2);
local_irq_restore(flags);
pr_info("COP2 access enabled for pid %d (%s)\n",
current->pid, current->comm);
return NOTIFY_BAD; /* Don't call default notifier */
}
return NOTIFY_OK; /* Let default notifier send signals */
}
static int __init nlm_cu2_setup(void)
{
return cu2_notifier(nlm_cu2_call, 0);
}
early_initcall(nlm_cu2_setup);
/*
* Copyright 2003-2013 Broadcom Corporation.
* All Rights Reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the Broadcom
* license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/kernel.h>
#include <linux/bootmem.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
#include <linux/of_device.h>
extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[], __dtb_start[];
void __init *xlp_dt_init(void *fdtp)
{
if (!fdtp) {
switch (current_cpu_data.processor_id & 0xff00) {
#ifdef CONFIG_DT_XLP_SVP
case PRID_IMP_NETLOGIC_XLP3XX:
fdtp = __dtb_xlp_svp_begin;
break;
#endif
#ifdef CONFIG_DT_XLP_EVP
case PRID_IMP_NETLOGIC_XLP8XX:
fdtp = __dtb_xlp_evp_begin;
break;
#endif
default:
/* Pick a built-in if any, and hope for the best */
fdtp = __dtb_start;
break;
}
}
initial_boot_params = fdtp;
return fdtp;
}
void __init device_tree_init(void)
{
unsigned long base, size;
if (!initial_boot_params)
return;
base = virt_to_phys((void *)initial_boot_params);
size = be32_to_cpu(initial_boot_params->totalsize);
/* Before we do anything, lets reserve the dt blob */
reserve_bootmem(base, size, BOOTMEM_DEFAULT);
unflatten_device_tree();
/* free the space reserved for the dt blob */
free_bootmem(base, size);
}
static struct of_device_id __initdata xlp_ids[] = {
{ .compatible = "simple-bus", },
{},
};
int __init xlp8xx_ds_publish_devices(void)
{
if (!of_have_populated_dt())
return 0;
return of_platform_bus_probe(NULL, xlp_ids, NULL);
}
device_initcall(xlp8xx_ds_publish_devices);
...@@ -33,19 +33,13 @@ ...@@ -33,19 +33,13 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/serial_8250.h> #include <linux/of_fdt.h>
#include <linux/pm.h>
#include <linux/bootmem.h>
#include <asm/idle.h> #include <asm/idle.h>
#include <asm/reboot.h> #include <asm/reboot.h>
#include <asm/time.h> #include <asm/time.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
#include <linux/of_device.h>
#include <asm/netlogic/haldefs.h> #include <asm/netlogic/haldefs.h>
#include <asm/netlogic/common.h> #include <asm/netlogic/common.h>
...@@ -57,7 +51,6 @@ uint64_t nlm_io_base; ...@@ -57,7 +51,6 @@ uint64_t nlm_io_base;
struct nlm_soc_info nlm_nodes[NLM_NR_NODES]; struct nlm_soc_info nlm_nodes[NLM_NR_NODES];
cpumask_t nlm_cpumask = CPU_MASK_CPU0; cpumask_t nlm_cpumask = CPU_MASK_CPU0;
unsigned int nlm_threads_per_core; unsigned int nlm_threads_per_core;
extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[], __dtb_start[];
static void nlm_linux_exit(void) static void nlm_linux_exit(void)
{ {
...@@ -68,41 +61,28 @@ static void nlm_linux_exit(void) ...@@ -68,41 +61,28 @@ static void nlm_linux_exit(void)
cpu_wait(); cpu_wait();
} }
void __init plat_mem_setup(void) static void nlm_fixup_mem(void)
{ {
void *fdtp; const int pref_backup = 512;
int i;
for (i = 0; i < boot_mem_map.nr_map; i++) {
if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
continue;
boot_mem_map.map[i].size -= pref_backup;
}
}
void __init plat_mem_setup(void)
{
panic_timeout = 5; panic_timeout = 5;
_machine_restart = (void (*)(char *))nlm_linux_exit; _machine_restart = (void (*)(char *))nlm_linux_exit;
_machine_halt = nlm_linux_exit; _machine_halt = nlm_linux_exit;
pm_power_off = nlm_linux_exit; pm_power_off = nlm_linux_exit;
/* /* memory and bootargs from DT */
* If no FDT pointer is passed in, use the built-in FDT. early_init_devtree(initial_boot_params);
* device_tree_init() does not handle CKSEG0 pointers in nlm_fixup_mem();
* 64-bit, so convert pointer.
*/
fdtp = (void *)(long)fw_arg0;
if (!fdtp) {
switch (current_cpu_data.processor_id & 0xff00) {
#ifdef CONFIG_DT_XLP_SVP
case PRID_IMP_NETLOGIC_XLP3XX:
fdtp = __dtb_xlp_svp_begin;
break;
#endif
#ifdef CONFIG_DT_XLP_EVP
case PRID_IMP_NETLOGIC_XLP8XX:
fdtp = __dtb_xlp_evp_begin;
break;
#endif
default:
/* Pick a built-in if any, and hope for the best */
fdtp = __dtb_start;
break;
}
}
fdtp = phys_to_virt(__pa(fdtp));
early_init_devtree(fdtp);
} }
const char *get_system_type(void) const char *get_system_type(void)
...@@ -131,9 +111,19 @@ void nlm_percpu_init(int hwcpuid) ...@@ -131,9 +111,19 @@ void nlm_percpu_init(int hwcpuid)
void __init prom_init(void) void __init prom_init(void)
{ {
void *reset_vec;
nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE); nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE);
nlm_init_boot_cpu();
xlp_mmu_init(); xlp_mmu_init();
nlm_node_init(0); nlm_node_init(0);
xlp_dt_init((void *)(long)fw_arg0);
/* Update reset entry point with CPU init code */
reset_vec = (void *)CKSEG1ADDR(RESET_VEC_PHYS);
memset(reset_vec, 0, RESET_VEC_SIZE);
memcpy(reset_vec, (void *)nlm_reset_entry,
(nlm_reset_entry_end - nlm_reset_entry));
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
cpumask_setall(&nlm_cpumask); cpumask_setall(&nlm_cpumask);
...@@ -145,36 +135,3 @@ void __init prom_init(void) ...@@ -145,36 +135,3 @@ void __init prom_init(void)
register_smp_ops(&nlm_smp_ops); register_smp_ops(&nlm_smp_ops);
#endif #endif
} }
void __init device_tree_init(void)
{
unsigned long base, size;
if (!initial_boot_params)
return;
base = virt_to_phys((void *)initial_boot_params);
size = be32_to_cpu(initial_boot_params->totalsize);
/* Before we do anything, lets reserve the dt blob */
reserve_bootmem(base, size, BOOTMEM_DEFAULT);
unflatten_device_tree();
/* free the space reserved for the dt blob */
free_bootmem(base, size);
}
static struct of_device_id __initdata xlp_ids[] = {
{ .compatible = "simple-bus", },
{},
};
int __init xlp8xx_ds_publish_devices(void)
{
if (!of_have_populated_dt())
return 0;
return of_platform_bus_probe(NULL, xlp_ids, NULL);
}
device_initcall(xlp8xx_ds_publish_devices);
...@@ -77,12 +77,28 @@ static int xlp_wakeup_core(uint64_t sysbase, int node, int core) ...@@ -77,12 +77,28 @@ static int xlp_wakeup_core(uint64_t sysbase, int node, int core)
return count != 0; return count != 0;
} }
static int wait_for_cpus(int cpu, int bootcpu)
{
volatile uint32_t *cpu_ready = nlm_get_boot_data(BOOT_CPU_READY);
int i, count, notready;
count = 0x20000000;
do {
notready = nlm_threads_per_core;
for (i = 0; i < nlm_threads_per_core; i++)
if (cpu_ready[cpu + i] || cpu == bootcpu)
--notready;
} while (notready != 0 && --count > 0);
return count != 0;
}
static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
{ {
struct nlm_soc_info *nodep; struct nlm_soc_info *nodep;
uint64_t syspcibase; uint64_t syspcibase;
uint32_t syscoremask; uint32_t syscoremask;
int core, n, cpu, count, val; int core, n, cpu;
for (n = 0; n < NLM_NR_NODES; n++) { for (n = 0; n < NLM_NR_NODES; n++) {
syspcibase = nlm_get_sys_pcibase(n); syspcibase = nlm_get_sys_pcibase(n);
...@@ -122,11 +138,8 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) ...@@ -122,11 +138,8 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
/* core is up */ /* core is up */
nodep->coremask |= 1u << core; nodep->coremask |= 1u << core;
/* spin until the first hw thread sets its ready */ /* spin until the hw threads sets their ready */
count = 0x20000000; wait_for_cpus(cpu, 0);
do {
val = *(volatile int *)&nlm_cpu_ready[cpu];
} while (val == 0 && --count > 0);
} }
} }
} }
...@@ -138,6 +151,7 @@ void xlp_wakeup_secondary_cpus() ...@@ -138,6 +151,7 @@ void xlp_wakeup_secondary_cpus()
* first wakeup core 0 threads * first wakeup core 0 threads
*/ */
xlp_boot_core0_siblings(); xlp_boot_core0_siblings();
wait_for_cpus(0, 0);
/* now get other cores out of reset */ /* now get other cores out of reset */
xlp_enable_secondary_cores(&nlm_cpumask); xlp_enable_secondary_cores(&nlm_cpumask);
......
...@@ -74,13 +74,13 @@ static irqreturn_t fmn_message_handler(int irq, void *data) ...@@ -74,13 +74,13 @@ static irqreturn_t fmn_message_handler(int irq, void *data)
struct nlm_fmn_msg msg; struct nlm_fmn_msg msg;
uint32_t mflags, bkt_status; uint32_t mflags, bkt_status;
mflags = nlm_cop2_enable(); mflags = nlm_cop2_enable_irqsave();
/* Disable message ring interrupt */ /* Disable message ring interrupt */
nlm_fmn_setup_intr(irq, 0); nlm_fmn_setup_intr(irq, 0);
while (1) { while (1) {
/* 8 bkts per core, [24:31] each bit represents one bucket /* 8 bkts per core, [24:31] each bit represents one bucket
* Bit is Zero if bucket is not empty */ * Bit is Zero if bucket is not empty */
bkt_status = (nlm_read_c2_status() >> 24) & 0xff; bkt_status = (nlm_read_c2_status0() >> 24) & 0xff;
if (bkt_status == 0xff) if (bkt_status == 0xff)
break; break;
for (bucket = 0; bucket < 8; bucket++) { for (bucket = 0; bucket < 8; bucket++) {
...@@ -97,16 +97,16 @@ static irqreturn_t fmn_message_handler(int irq, void *data) ...@@ -97,16 +97,16 @@ static irqreturn_t fmn_message_handler(int irq, void *data)
pr_warn("No msgring handler for stnid %d\n", pr_warn("No msgring handler for stnid %d\n",
src_stnid); src_stnid);
else { else {
nlm_cop2_restore(mflags); nlm_cop2_disable_irqrestore(mflags);
hndlr->action(bucket, src_stnid, size, code, hndlr->action(bucket, src_stnid, size, code,
&msg, hndlr->arg); &msg, hndlr->arg);
mflags = nlm_cop2_enable(); mflags = nlm_cop2_enable_irqsave();
} }
} }
}; };
/* Enable message ring intr, to any thread in core */ /* Enable message ring intr, to any thread in core */
nlm_fmn_setup_intr(irq, (1 << nlm_threads_per_core) - 1); nlm_fmn_setup_intr(irq, (1 << nlm_threads_per_core) - 1);
nlm_cop2_restore(mflags); nlm_cop2_disable_irqrestore(mflags);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -128,7 +128,7 @@ void xlr_percpu_fmn_init(void) ...@@ -128,7 +128,7 @@ void xlr_percpu_fmn_init(void)
bucket_sizes = xlr_board_fmn_config.bucket_size; bucket_sizes = xlr_board_fmn_config.bucket_size;
cpu_fmn_info = &xlr_board_fmn_config.cpu[id]; cpu_fmn_info = &xlr_board_fmn_config.cpu[id];
flags = nlm_cop2_enable(); flags = nlm_cop2_enable_irqsave();
/* Setup bucket sizes for the core. */ /* Setup bucket sizes for the core. */
nlm_write_c2_bucksize(0, bucket_sizes[id * 8 + 0]); nlm_write_c2_bucksize(0, bucket_sizes[id * 8 + 0]);
...@@ -166,7 +166,7 @@ void xlr_percpu_fmn_init(void) ...@@ -166,7 +166,7 @@ void xlr_percpu_fmn_init(void)
/* enable FMN interrupts on this CPU */ /* enable FMN interrupts on this CPU */
nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1); nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1);
nlm_cop2_restore(flags); nlm_cop2_disable_irqrestore(flags);
} }
...@@ -198,7 +198,7 @@ void nlm_setup_fmn_irq(void) ...@@ -198,7 +198,7 @@ void nlm_setup_fmn_irq(void)
/* setup irq only once */ /* setup irq only once */
setup_irq(IRQ_FMN, &fmn_irqaction); setup_irq(IRQ_FMN, &fmn_irqaction);
flags = nlm_cop2_enable(); flags = nlm_cop2_enable_irqsave();
nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1); nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1);
nlm_cop2_restore(flags); nlm_cop2_disable_irqrestore(flags);
} }
...@@ -196,6 +196,7 @@ void __init prom_init(void) ...@@ -196,6 +196,7 @@ void __init prom_init(void)
{ {
int *argv, *envp; /* passed as 32 bit ptrs */ int *argv, *envp; /* passed as 32 bit ptrs */
struct psb_info *prom_infop; struct psb_info *prom_infop;
void *reset_vec;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
int i; int i;
#endif #endif
...@@ -208,6 +209,12 @@ void __init prom_init(void) ...@@ -208,6 +209,12 @@ void __init prom_init(void)
nlm_prom_info = *prom_infop; nlm_prom_info = *prom_infop;
nlm_init_node(); nlm_init_node();
/* Update reset entry point with CPU init code */
reset_vec = (void *)CKSEG1ADDR(RESET_VEC_PHYS);
memset(reset_vec, 0, RESET_VEC_SIZE);
memcpy(reset_vec, (void *)nlm_reset_entry,
(nlm_reset_entry_end - nlm_reset_entry));
nlm_early_serial_setup(); nlm_early_serial_setup();
build_arcs_cmdline(argv); build_arcs_cmdline(argv);
prom_add_memory(); prom_add_memory();
......
...@@ -53,6 +53,7 @@ int __cpuinit xlr_wakeup_secondary_cpus(void) ...@@ -53,6 +53,7 @@ int __cpuinit xlr_wakeup_secondary_cpus(void)
{ {
struct nlm_soc_info *nodep; struct nlm_soc_info *nodep;
unsigned int i, j, boot_cpu; unsigned int i, j, boot_cpu;
volatile u32 *cpu_ready = nlm_get_boot_data(BOOT_CPU_READY);
/* /*
* In case of RMI boot, hit with NMI to get the cores * In case of RMI boot, hit with NMI to get the cores
...@@ -71,7 +72,7 @@ int __cpuinit xlr_wakeup_secondary_cpus(void) ...@@ -71,7 +72,7 @@ int __cpuinit xlr_wakeup_secondary_cpus(void)
nodep->coremask = 1; nodep->coremask = 1;
for (i = 1; i < NLM_CORES_PER_NODE; i++) { for (i = 1; i < NLM_CORES_PER_NODE; i++) {
for (j = 1000000; j > 0; j--) { for (j = 1000000; j > 0; j--) {
if (nlm_cpu_ready[i * NLM_THREADS_PER_CORE]) if (cpu_ready[i * NLM_THREADS_PER_CORE])
break; break;
udelay(10); udelay(10);
} }
......
...@@ -29,7 +29,7 @@ obj-$(CONFIG_LASAT) += pci-lasat.o ...@@ -29,7 +29,7 @@ obj-$(CONFIG_LASAT) += pci-lasat.o
obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o
obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o
obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o
obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o pci-malta.o
obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o
obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o
obj-$(CONFIG_PMC_MSP7120_FPGA) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_FPGA) += fixup-pmcmsp.o ops-pmcmsp.o
...@@ -52,12 +52,11 @@ obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ...@@ -52,12 +52,11 @@ obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o
obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o
obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o
obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o
obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o
obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += pci-octeon.o pcie-octeon.o obj-$(CONFIG_CAVIUM_OCTEON_SOC) += pci-octeon.o pcie-octeon.o
obj-$(CONFIG_CPU_XLR) += pci-xlr.o obj-$(CONFIG_CPU_XLR) += pci-xlr.o
obj-$(CONFIG_CPU_XLP) += pci-xlp.o obj-$(CONFIG_CPU_XLP) += pci-xlp.o
ifdef CONFIG_PCI_MSI ifdef CONFIG_PCI_MSI
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += msi-octeon.o obj-$(CONFIG_CAVIUM_OCTEON_SOC) += msi-octeon.o
endif endif
/*
* fixup-wrppmc.c: PPMC board specific PCI fixup
*
* 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) 2006, Wind River Inc. Rongkai.zhan (rongkai.zhan@windriver.com)
*/
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/gt64120.h>
/* PCI interrupt pins */
#define PCI_INTA 1
#define PCI_INTB 2
#define PCI_INTC 3
#define PCI_INTD 4
#define PCI_SLOT_MAXNR 32 /* Each PCI bus has 32 physical slots */
static char pci_irq_tab[PCI_SLOT_MAXNR][5] __initdata = {
/* 0 INTA INTB INTC INTD */
[0] = {0, 0, 0, 0, 0}, /* Slot 0: GT64120 PCI bridge */
[6] = {0, WRPPMC_PCI_INTA_IRQ, 0, 0, 0},
};
int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
return pci_irq_tab[slot][pin];
}
/* Do platform specific device initialization at pci_enable_device() time */
int pcibios_plat_dev_init(struct pci_dev *dev)
{
return 0;
}
...@@ -266,7 +266,7 @@ static int __init bcm63xx_register_pci(void) ...@@ -266,7 +266,7 @@ static int __init bcm63xx_register_pci(void)
/* setup PCI to local bus access, used by PCI device to target /* setup PCI to local bus access, used by PCI device to target
* local RAM while bus mastering */ * local RAM while bus mastering */
bcm63xx_int_cfg_writel(0, PCI_BASE_ADDRESS_3); bcm63xx_int_cfg_writel(0, PCI_BASE_ADDRESS_3);
if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6368())
val = MPI_SP0_REMAP_ENABLE_MASK; val = MPI_SP0_REMAP_ENABLE_MASK;
else else
val = 0; val = 0;
...@@ -338,6 +338,7 @@ static int __init bcm63xx_pci_init(void) ...@@ -338,6 +338,7 @@ static int __init bcm63xx_pci_init(void)
case BCM6328_CPU_ID: case BCM6328_CPU_ID:
case BCM6362_CPU_ID: case BCM6362_CPU_ID:
return bcm63xx_register_pcie(); return bcm63xx_register_pcie();
case BCM3368_CPU_ID:
case BCM6348_CPU_ID: case BCM6348_CPU_ID:
case BCM6358_CPU_ID: case BCM6358_CPU_ID:
case BCM6368_CPU_ID: case BCM6368_CPU_ID:
......
...@@ -217,6 +217,7 @@ static void pci_fixup_ioc3(struct pci_dev *d) ...@@ -217,6 +217,7 @@ static void pci_fixup_ioc3(struct pci_dev *d)
pci_disable_swapping(d); pci_disable_swapping(d);
} }
#ifdef CONFIG_NUMA
int pcibus_to_node(struct pci_bus *bus) int pcibus_to_node(struct pci_bus *bus)
{ {
struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
...@@ -224,6 +225,7 @@ int pcibus_to_node(struct pci_bus *bus) ...@@ -224,6 +225,7 @@ int pcibus_to_node(struct pci_bus *bus)
return bc->nasid; return bc->nasid;
} }
EXPORT_SYMBOL(pcibus_to_node); EXPORT_SYMBOL(pcibus_to_node);
#endif /* CONFIG_NUMA */
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
pci_fixup_ioc3); pci_fixup_ioc3);
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
# #
obj-y += msp_prom.o msp_setup.o msp_irq.o \ obj-y += msp_prom.o msp_setup.o msp_irq.o \
msp_time.o msp_serial.o msp_elb.o msp_time.o msp_serial.o msp_elb.o
obj-$(CONFIG_HAVE_GPIO_LIB) += gpio.o gpio_extended.o
obj-$(CONFIG_PMC_MSP7120_GW) += msp_hwbutton.o obj-$(CONFIG_PMC_MSP7120_GW) += msp_hwbutton.o
obj-$(CONFIG_IRQ_MSP_SLP) += msp_irq_slp.o obj-$(CONFIG_IRQ_MSP_SLP) += msp_irq_slp.o
obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o msp_irq_per.o obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o msp_irq_per.o
......
/*
* Generic PMC MSP71xx GPIO handling. These base gpio are controlled by two
* types of registers. The data register sets the output level when in output
* mode and when in input mode will contain the value at the input. The config
* register sets the various modes for each gpio.
*
* 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.
*
* @author Patrick Glass <patrickglass@gmail.com>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#define MSP71XX_CFG_OFFSET(gpio) (4 * (gpio))
#define CONF_MASK 0x0F
#define MSP71XX_GPIO_INPUT 0x01
#define MSP71XX_GPIO_OUTPUT 0x08
#define MSP71XX_GPIO_BASE 0x0B8400000L
#define to_msp71xx_gpio_chip(c) container_of(c, struct msp71xx_gpio_chip, chip)
static spinlock_t gpio_lock;
/*
* struct msp71xx_gpio_chip - container for gpio chip and registers
* @chip: chip structure for the specified gpio bank
* @data_reg: register for reading and writing the gpio pin value
* @config_reg: register to set the mode for the gpio pin bank
* @out_drive_reg: register to set the output drive mode for the gpio pin bank
*/
struct msp71xx_gpio_chip {
struct gpio_chip chip;
void __iomem *data_reg;
void __iomem *config_reg;
void __iomem *out_drive_reg;
};
/*
* msp71xx_gpio_get() - return the chip's gpio value
* @chip: chip structure which controls the specified gpio
* @offset: gpio whose value will be returned
*
* It will return 0 if gpio value is low and other if high.
*/
static int msp71xx_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct msp71xx_gpio_chip *msp_chip = to_msp71xx_gpio_chip(chip);
return __raw_readl(msp_chip->data_reg) & (1 << offset);
}
/*
* msp71xx_gpio_set() - set the output value for the gpio
* @chip: chip structure who controls the specified gpio
* @offset: gpio whose value will be assigned
* @value: logic level to assign to the gpio initially
*
* This will set the gpio bit specified to the desired value. It will set the
* gpio pin low if value is 0 otherwise it will be high.
*/
static void msp71xx_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct msp71xx_gpio_chip *msp_chip = to_msp71xx_gpio_chip(chip);
unsigned long flags;
u32 data;
spin_lock_irqsave(&gpio_lock, flags);
data = __raw_readl(msp_chip->data_reg);
if (value)
data |= (1 << offset);
else
data &= ~(1 << offset);
__raw_writel(data, msp_chip->data_reg);
spin_unlock_irqrestore(&gpio_lock, flags);
}
/*
* msp71xx_set_gpio_mode() - declare the mode for a gpio
* @chip: chip structure which controls the specified gpio
* @offset: gpio whose value will be assigned
* @mode: desired configuration for the gpio (see datasheet)
*
* It will set the gpio pin config to the @mode value passed in.
*/
static int msp71xx_set_gpio_mode(struct gpio_chip *chip,
unsigned offset, int mode)
{
struct msp71xx_gpio_chip *msp_chip = to_msp71xx_gpio_chip(chip);
const unsigned bit_offset = MSP71XX_CFG_OFFSET(offset);
unsigned long flags;
u32 cfg;
spin_lock_irqsave(&gpio_lock, flags);
cfg = __raw_readl(msp_chip->config_reg);
cfg &= ~(CONF_MASK << bit_offset);
cfg |= (mode << bit_offset);
__raw_writel(cfg, msp_chip->config_reg);
spin_unlock_irqrestore(&gpio_lock, flags);
return 0;
}
/*
* msp71xx_direction_output() - declare the direction mode for a gpio
* @chip: chip structure which controls the specified gpio
* @offset: gpio whose value will be assigned
* @value: logic level to assign to the gpio initially
*
* This call will set the mode for the @gpio to output. It will set the
* gpio pin low if value is 0 otherwise it will be high.
*/
static int msp71xx_direction_output(struct gpio_chip *chip,
unsigned offset, int value)
{
msp71xx_gpio_set(chip, offset, value);
return msp71xx_set_gpio_mode(chip, offset, MSP71XX_GPIO_OUTPUT);
}
/*
* msp71xx_direction_input() - declare the direction mode for a gpio
* @chip: chip structure which controls the specified gpio
* @offset: gpio whose to which the value will be assigned
*
* This call will set the mode for the @gpio to input.
*/
static int msp71xx_direction_input(struct gpio_chip *chip, unsigned offset)
{
return msp71xx_set_gpio_mode(chip, offset, MSP71XX_GPIO_INPUT);
}
/*
* msp71xx_set_output_drive() - declare the output drive for the gpio line
* @gpio: gpio pin whose output drive you wish to modify
* @value: zero for active drain 1 for open drain drive
*
* This call will set the output drive mode for the @gpio to output.
*/
int msp71xx_set_output_drive(unsigned gpio, int value)
{
unsigned long flags;
u32 data;
if (gpio > 15 || gpio < 0)
return -EINVAL;
spin_lock_irqsave(&gpio_lock, flags);
data = __raw_readl((void __iomem *)(MSP71XX_GPIO_BASE + 0x190));
if (value)
data |= (1 << gpio);
else
data &= ~(1 << gpio);
__raw_writel(data, (void __iomem *)(MSP71XX_GPIO_BASE + 0x190));
spin_unlock_irqrestore(&gpio_lock, flags);
return 0;
}
EXPORT_SYMBOL(msp71xx_set_output_drive);
#define MSP71XX_GPIO_BANK(name, dr, cr, base_gpio, num_gpio) \
{ \
.chip = { \
.label = name, \
.direction_input = msp71xx_direction_input, \
.direction_output = msp71xx_direction_output, \
.get = msp71xx_gpio_get, \
.set = msp71xx_gpio_set, \
.base = base_gpio, \
.ngpio = num_gpio \
}, \
.data_reg = (void __iomem *)(MSP71XX_GPIO_BASE + dr), \
.config_reg = (void __iomem *)(MSP71XX_GPIO_BASE + cr), \
.out_drive_reg = (void __iomem *)(MSP71XX_GPIO_BASE + 0x190), \
}
/*
* struct msp71xx_gpio_banks[] - container array of gpio banks
* @chip: chip structure for the specified gpio bank
* @data_reg: register for reading and writing the gpio pin value
* @config_reg: register to set the mode for the gpio pin bank
*
* This array structure defines the gpio banks for the PMC MIPS Processor.
* We specify the bank name, the data register, the config register, base
* starting gpio number, and the number of gpios exposed by the bank.
*/
static struct msp71xx_gpio_chip msp71xx_gpio_banks[] = {
MSP71XX_GPIO_BANK("GPIO_1_0", 0x170, 0x180, 0, 2),
MSP71XX_GPIO_BANK("GPIO_5_2", 0x174, 0x184, 2, 4),
MSP71XX_GPIO_BANK("GPIO_9_6", 0x178, 0x188, 6, 4),
MSP71XX_GPIO_BANK("GPIO_15_10", 0x17C, 0x18C, 10, 6),
};
void __init msp71xx_init_gpio(void)
{
int i;
spin_lock_init(&gpio_lock);
for (i = 0; i < ARRAY_SIZE(msp71xx_gpio_banks); i++)
gpiochip_add(&msp71xx_gpio_banks[i].chip);
}
/*
* Generic PMC MSP71xx EXTENDED (EXD) GPIO handling. The extended gpio is
* a set of hardware registers that have no need for explicit locking as
* it is handled by unique method of writing individual set/clr bits.
*
* 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.
*
* @author Patrick Glass <patrickglass@gmail.com>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/io.h>
#define MSP71XX_DATA_OFFSET(gpio) (2 * (gpio))
#define MSP71XX_READ_OFFSET(gpio) (MSP71XX_DATA_OFFSET(gpio) + 1)
#define MSP71XX_CFG_OUT_OFFSET(gpio) (MSP71XX_DATA_OFFSET(gpio) + 16)
#define MSP71XX_CFG_IN_OFFSET(gpio) (MSP71XX_CFG_OUT_OFFSET(gpio) + 1)
#define MSP71XX_EXD_GPIO_BASE 0x0BC000000L
#define to_msp71xx_exd_gpio_chip(c) \
container_of(c, struct msp71xx_exd_gpio_chip, chip)
/*
* struct msp71xx_exd_gpio_chip - container for gpio chip and registers
* @chip: chip structure for the specified gpio bank
* @reg: register for control and data of gpio pin
*/
struct msp71xx_exd_gpio_chip {
struct gpio_chip chip;
void __iomem *reg;
};
/*
* msp71xx_exd_gpio_get() - return the chip's gpio value
* @chip: chip structure which controls the specified gpio
* @offset: gpio whose value will be returned
*
* It will return 0 if gpio value is low and other if high.
*/
static int msp71xx_exd_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct msp71xx_exd_gpio_chip *msp71xx_chip =
to_msp71xx_exd_gpio_chip(chip);
const unsigned bit = MSP71XX_READ_OFFSET(offset);
return __raw_readl(msp71xx_chip->reg) & (1 << bit);
}
/*
* msp71xx_exd_gpio_set() - set the output value for the gpio
* @chip: chip structure who controls the specified gpio
* @offset: gpio whose value will be assigned
* @value: logic level to assign to the gpio initially
*
* This will set the gpio bit specified to the desired value. It will set the
* gpio pin low if value is 0 otherwise it will be high.
*/
static void msp71xx_exd_gpio_set(struct gpio_chip *chip,
unsigned offset, int value)
{
struct msp71xx_exd_gpio_chip *msp71xx_chip =
to_msp71xx_exd_gpio_chip(chip);
const unsigned bit = MSP71XX_DATA_OFFSET(offset);
__raw_writel(1 << (bit + (value ? 1 : 0)), msp71xx_chip->reg);
}
/*
* msp71xx_exd_direction_output() - declare the direction mode for a gpio
* @chip: chip structure which controls the specified gpio
* @offset: gpio whose value will be assigned
* @value: logic level to assign to the gpio initially
*
* This call will set the mode for the @gpio to output. It will set the
* gpio pin low if value is 0 otherwise it will be high.
*/
static int msp71xx_exd_direction_output(struct gpio_chip *chip,
unsigned offset, int value)
{
struct msp71xx_exd_gpio_chip *msp71xx_chip =
to_msp71xx_exd_gpio_chip(chip);
msp71xx_exd_gpio_set(chip, offset, value);
__raw_writel(1 << MSP71XX_CFG_OUT_OFFSET(offset), msp71xx_chip->reg);
return 0;
}
/*
* msp71xx_exd_direction_input() - declare the direction mode for a gpio
* @chip: chip structure which controls the specified gpio
* @offset: gpio whose to which the value will be assigned
*
* This call will set the mode for the @gpio to input.
*/
static int msp71xx_exd_direction_input(struct gpio_chip *chip, unsigned offset)
{
struct msp71xx_exd_gpio_chip *msp71xx_chip =
to_msp71xx_exd_gpio_chip(chip);
__raw_writel(1 << MSP71XX_CFG_IN_OFFSET(offset), msp71xx_chip->reg);
return 0;
}
#define MSP71XX_EXD_GPIO_BANK(name, exd_reg, base_gpio, num_gpio) \
{ \
.chip = { \
.label = name, \
.direction_input = msp71xx_exd_direction_input, \
.direction_output = msp71xx_exd_direction_output, \
.get = msp71xx_exd_gpio_get, \
.set = msp71xx_exd_gpio_set, \
.base = base_gpio, \
.ngpio = num_gpio, \
}, \
.reg = (void __iomem *)(MSP71XX_EXD_GPIO_BASE + exd_reg), \
}
/*
* struct msp71xx_exd_gpio_banks[] - container array of gpio banks
* @chip: chip structure for the specified gpio bank
* @reg: register for reading and writing the gpio pin value
*
* This array structure defines the extended gpio banks for the
* PMC MIPS Processor. We specify the bank name, the data/config
* register,the base starting gpio number, and the number of
* gpios exposed by the bank of gpios.
*/
static struct msp71xx_exd_gpio_chip msp71xx_exd_gpio_banks[] = {
MSP71XX_EXD_GPIO_BANK("GPIO_23_16", 0x188, 16, 8),
MSP71XX_EXD_GPIO_BANK("GPIO_27_24", 0x18C, 24, 4),
};
void __init msp71xx_init_gpio_extended(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(msp71xx_exd_gpio_banks); i++)
gpiochip_add(&msp71xx_exd_gpio_banks[i].chip);
}
...@@ -529,17 +529,8 @@ EXPORT_SYMBOL(asic_resource_get); ...@@ -529,17 +529,8 @@ EXPORT_SYMBOL(asic_resource_get);
*/ */
void platform_release_memory(void *ptr, int size) void platform_release_memory(void *ptr, int size)
{ {
unsigned long addr; free_reserved_area((unsigned long)ptr, (unsigned long)(ptr + size),
unsigned long end; -1, NULL);
addr = ((unsigned long)ptr + (PAGE_SIZE - 1)) & PAGE_MASK;
end = ((unsigned long)ptr + size) & PAGE_MASK;
for (; addr < end; addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(__va(addr)));
init_page_count(virt_to_page(__va(addr)));
free_page((unsigned long)__va(addr));
}
} }
EXPORT_SYMBOL(platform_release_memory); EXPORT_SYMBOL(platform_release_memory);
......
...@@ -104,7 +104,7 @@ static int __init plat_of_setup(void) ...@@ -104,7 +104,7 @@ static int __init plat_of_setup(void)
if (!of_have_populated_dt()) if (!of_have_populated_dt())
panic("device tree not present"); panic("device tree not present");
strncpy(of_ids[0].compatible, soc_info.compatible, len); strlcpy(of_ids[0].compatible, soc_info.compatible, len);
strncpy(of_ids[1].compatible, "palmbus", len); strncpy(of_ids[1].compatible, "palmbus", len);
if (of_platform_populate(NULL, of_ids, NULL, NULL)) if (of_platform_populate(NULL, of_ids, NULL, NULL))
......
...@@ -7,4 +7,5 @@ obj-y := ip27-berr.o ip27-irq.o ip27-init.o ip27-klconfig.o ip27-klnuma.o \ ...@@ -7,4 +7,5 @@ obj-y := ip27-berr.o ip27-irq.o ip27-init.o ip27-klconfig.o ip27-klnuma.o \
ip27-xtalk.o ip27-xtalk.o
obj-$(CONFIG_EARLY_PRINTK) += ip27-console.o obj-$(CONFIG_EARLY_PRINTK) += ip27-console.o
obj-$(CONFIG_PCI) += ip27-irq-pci.o
obj-$(CONFIG_SMP) += ip27-smp.o obj-$(CONFIG_SMP) += ip27-smp.o
/*
* ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
*
* Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
* Copyright (C) 1999 - 2001 Kanoj Sarcar
*/
#undef DEBUG
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timex.h>
#include <linux/smp.h>
#include <linux/random.h>
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/processor.h>
#include <asm/pci/bridge.h>
#include <asm/sn/addrs.h>
#include <asm/sn/agent.h>
#include <asm/sn/arch.h>
#include <asm/sn/hub.h>
#include <asm/sn/intr.h>
/*
* Linux has a controller-independent x86 interrupt architecture.
* every controller has a 'controller-template', that is used
* by the main code to do the right thing. Each driver-visible
* interrupt source is transparently wired to the appropriate
* controller. Thus drivers need not be aware of the
* interrupt-controller.
*
* Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
* PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
* (IO-APICs assumed to be messaging to Pentium local-APICs)
*
* the code is designed to be easily extended with new/different
* interrupt controllers, without having to do assembly magic.
*/
extern struct bridge_controller *irq_to_bridge[];
extern int irq_to_slot[];
/*
* use these macros to get the encoded nasid and widget id
* from the irq value
*/
#define IRQ_TO_BRIDGE(i) irq_to_bridge[(i)]
#define SLOT_FROM_PCI_IRQ(i) irq_to_slot[i]
static inline int alloc_level(int cpu, int irq)
{
struct hub_data *hub = hub_data(cpu_to_node(cpu));
struct slice_data *si = cpu_data[cpu].data;
int level;
level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE);
if (level >= LEVELS_PER_SLICE)
panic("Cpu %d flooded with devices", cpu);
__set_bit(level, hub->irq_alloc_mask);
si->level_to_irq[level] = irq;
return level;
}
static inline int find_level(cpuid_t *cpunum, int irq)
{
int cpu, i;
for_each_online_cpu(cpu) {
struct slice_data *si = cpu_data[cpu].data;
for (i = BASE_PCI_IRQ; i < LEVELS_PER_SLICE; i++)
if (si->level_to_irq[i] == irq) {
*cpunum = cpu;
return i;
}
}
panic("Could not identify cpu/level for irq %d", irq);
}
static int intr_connect_level(int cpu, int bit)
{
nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
struct slice_data *si = cpu_data[cpu].data;
set_bit(bit, si->irq_enable_mask);
if (!cputoslice(cpu)) {
REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
} else {
REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
}
return 0;
}
static int intr_disconnect_level(int cpu, int bit)
{
nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
struct slice_data *si = cpu_data[cpu].data;
clear_bit(bit, si->irq_enable_mask);
if (!cputoslice(cpu)) {
REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
} else {
REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
}
return 0;
}
/* Startup one of the (PCI ...) IRQs routes over a bridge. */
static unsigned int startup_bridge_irq(struct irq_data *d)
{
struct bridge_controller *bc;
bridgereg_t device;
bridge_t *bridge;
int pin, swlevel;
cpuid_t cpu;
pin = SLOT_FROM_PCI_IRQ(d->irq);
bc = IRQ_TO_BRIDGE(d->irq);
bridge = bc->base;
pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, pin);
/*
* "map" irq to a swlevel greater than 6 since the first 6 bits
* of INT_PEND0 are taken
*/
swlevel = find_level(&cpu, d->irq);
bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8));
bridge->b_int_enable |= (1 << pin);
bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */
/*
* Enable sending of an interrupt clear packt to the hub on a high to
* low transition of the interrupt pin.
*
* IRIX sets additional bits in the address which are documented as
* reserved in the bridge docs.
*/
bridge->b_int_mode |= (1UL << pin);
/*
* We assume the bridge to have a 1:1 mapping between devices
* (slots) and intr pins.
*/
device = bridge->b_int_device;
device &= ~(7 << (pin*3));
device |= (pin << (pin*3));
bridge->b_int_device = device;
bridge->b_wid_tflush;
intr_connect_level(cpu, swlevel);
return 0; /* Never anything pending. */
}
/* Shutdown one of the (PCI ...) IRQs routes over a bridge. */
static void shutdown_bridge_irq(struct irq_data *d)
{
struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq);
bridge_t *bridge = bc->base;
int pin, swlevel;
cpuid_t cpu;
pr_debug("bridge_shutdown: irq 0x%x\n", d->irq);
pin = SLOT_FROM_PCI_IRQ(d->irq);
/*
* map irq to a swlevel greater than 6 since the first 6 bits
* of INT_PEND0 are taken
*/
swlevel = find_level(&cpu, d->irq);
intr_disconnect_level(cpu, swlevel);
bridge->b_int_enable &= ~(1 << pin);
bridge->b_wid_tflush;
}
static inline void enable_bridge_irq(struct irq_data *d)
{
cpuid_t cpu;
int swlevel;
swlevel = find_level(&cpu, d->irq); /* Criminal offence */
intr_connect_level(cpu, swlevel);
}
static inline void disable_bridge_irq(struct irq_data *d)
{
cpuid_t cpu;
int swlevel;
swlevel = find_level(&cpu, d->irq); /* Criminal offence */
intr_disconnect_level(cpu, swlevel);
}
static struct irq_chip bridge_irq_type = {
.name = "bridge",
.irq_startup = startup_bridge_irq,
.irq_shutdown = shutdown_bridge_irq,
.irq_mask = disable_bridge_irq,
.irq_unmask = enable_bridge_irq,
};
void register_bridge_irq(unsigned int irq)
{
irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq);
}
int request_bridge_irq(struct bridge_controller *bc)
{
int irq = allocate_irqno();
int swlevel, cpu;
nasid_t nasid;
if (irq < 0)
return irq;
/*
* "map" irq to a swlevel greater than 6 since the first 6 bits
* of INT_PEND0 are taken
*/
cpu = bc->irq_cpu;
swlevel = alloc_level(cpu, irq);
if (unlikely(swlevel < 0)) {
free_irqno(irq);
return -EAGAIN;
}
/* Make sure it's not already pending when we connect it. */
nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
REMOTE_HUB_CLR_INTR(nasid, swlevel);
intr_connect_level(cpu, swlevel);
register_bridge_irq(irq);
return irq;
}
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/pci/bridge.h>
#include <asm/sn/addrs.h> #include <asm/sn/addrs.h>
#include <asm/sn/agent.h> #include <asm/sn/agent.h>
#include <asm/sn/arch.h> #include <asm/sn/arch.h>
...@@ -54,50 +53,6 @@ ...@@ -54,50 +53,6 @@
extern asmlinkage void ip27_irq(void); extern asmlinkage void ip27_irq(void);
extern struct bridge_controller *irq_to_bridge[];
extern int irq_to_slot[];
/*
* use these macros to get the encoded nasid and widget id
* from the irq value
*/
#define IRQ_TO_BRIDGE(i) irq_to_bridge[(i)]
#define SLOT_FROM_PCI_IRQ(i) irq_to_slot[i]
static inline int alloc_level(int cpu, int irq)
{
struct hub_data *hub = hub_data(cpu_to_node(cpu));
struct slice_data *si = cpu_data[cpu].data;
int level;
level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE);
if (level >= LEVELS_PER_SLICE)
panic("Cpu %d flooded with devices", cpu);
__set_bit(level, hub->irq_alloc_mask);
si->level_to_irq[level] = irq;
return level;
}
static inline int find_level(cpuid_t *cpunum, int irq)
{
int cpu, i;
for_each_online_cpu(cpu) {
struct slice_data *si = cpu_data[cpu].data;
for (i = BASE_PCI_IRQ; i < LEVELS_PER_SLICE; i++)
if (si->level_to_irq[i] == irq) {
*cpunum = cpu;
return i;
}
}
panic("Could not identify cpu/level for irq %d", irq);
}
/* /*
* Find first bit set * Find first bit set
*/ */
...@@ -204,175 +159,6 @@ static void ip27_hub_error(void) ...@@ -204,175 +159,6 @@ static void ip27_hub_error(void)
panic("CPU %d got a hub error interrupt", smp_processor_id()); panic("CPU %d got a hub error interrupt", smp_processor_id());
} }
static int intr_connect_level(int cpu, int bit)
{
nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
struct slice_data *si = cpu_data[cpu].data;
set_bit(bit, si->irq_enable_mask);
if (!cputoslice(cpu)) {
REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
} else {
REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
}
return 0;
}
static int intr_disconnect_level(int cpu, int bit)
{
nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
struct slice_data *si = cpu_data[cpu].data;
clear_bit(bit, si->irq_enable_mask);
if (!cputoslice(cpu)) {
REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
} else {
REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
}
return 0;
}
/* Startup one of the (PCI ...) IRQs routes over a bridge. */
static unsigned int startup_bridge_irq(struct irq_data *d)
{
struct bridge_controller *bc;
bridgereg_t device;
bridge_t *bridge;
int pin, swlevel;
cpuid_t cpu;
pin = SLOT_FROM_PCI_IRQ(d->irq);
bc = IRQ_TO_BRIDGE(d->irq);
bridge = bc->base;
pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, pin);
/*
* "map" irq to a swlevel greater than 6 since the first 6 bits
* of INT_PEND0 are taken
*/
swlevel = find_level(&cpu, d->irq);
bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8));
bridge->b_int_enable |= (1 << pin);
bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */
/*
* Enable sending of an interrupt clear packt to the hub on a high to
* low transition of the interrupt pin.
*
* IRIX sets additional bits in the address which are documented as
* reserved in the bridge docs.
*/
bridge->b_int_mode |= (1UL << pin);
/*
* We assume the bridge to have a 1:1 mapping between devices
* (slots) and intr pins.
*/
device = bridge->b_int_device;
device &= ~(7 << (pin*3));
device |= (pin << (pin*3));
bridge->b_int_device = device;
bridge->b_wid_tflush;
intr_connect_level(cpu, swlevel);
return 0; /* Never anything pending. */
}
/* Shutdown one of the (PCI ...) IRQs routes over a bridge. */
static void shutdown_bridge_irq(struct irq_data *d)
{
struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq);
bridge_t *bridge = bc->base;
int pin, swlevel;
cpuid_t cpu;
pr_debug("bridge_shutdown: irq 0x%x\n", d->irq);
pin = SLOT_FROM_PCI_IRQ(d->irq);
/*
* map irq to a swlevel greater than 6 since the first 6 bits
* of INT_PEND0 are taken
*/
swlevel = find_level(&cpu, d->irq);
intr_disconnect_level(cpu, swlevel);
bridge->b_int_enable &= ~(1 << pin);
bridge->b_wid_tflush;
}
static inline void enable_bridge_irq(struct irq_data *d)
{
cpuid_t cpu;
int swlevel;
swlevel = find_level(&cpu, d->irq); /* Criminal offence */
intr_connect_level(cpu, swlevel);
}
static inline void disable_bridge_irq(struct irq_data *d)
{
cpuid_t cpu;
int swlevel;
swlevel = find_level(&cpu, d->irq); /* Criminal offence */
intr_disconnect_level(cpu, swlevel);
}
static struct irq_chip bridge_irq_type = {
.name = "bridge",
.irq_startup = startup_bridge_irq,
.irq_shutdown = shutdown_bridge_irq,
.irq_mask = disable_bridge_irq,
.irq_unmask = enable_bridge_irq,
};
void register_bridge_irq(unsigned int irq)
{
irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq);
}
int request_bridge_irq(struct bridge_controller *bc)
{
int irq = allocate_irqno();
int swlevel, cpu;
nasid_t nasid;
if (irq < 0)
return irq;
/*
* "map" irq to a swlevel greater than 6 since the first 6 bits
* of INT_PEND0 are taken
*/
cpu = bc->irq_cpu;
swlevel = alloc_level(cpu, irq);
if (unlikely(swlevel < 0)) {
free_irqno(irq);
return -EAGAIN;
}
/* Make sure it's not already pending when we connect it. */
nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
REMOTE_HUB_CLR_INTR(nasid, swlevel);
intr_connect_level(cpu, swlevel);
register_bridge_irq(irq);
return irq;
}
asmlinkage void plat_irq_dispatch(void) asmlinkage void plat_irq_dispatch(void)
{ {
unsigned long pending = read_c0_cause() & read_c0_status(); unsigned long pending = read_c0_cause() & read_c0_status();
......
...@@ -147,7 +147,8 @@ config SIBYTE_CFE_CONSOLE ...@@ -147,7 +147,8 @@ config SIBYTE_CFE_CONSOLE
config SIBYTE_BUS_WATCHER config SIBYTE_BUS_WATCHER
bool "Support for Bus Watcher statistics" bool "Support for Bus Watcher statistics"
depends on SIBYTE_SB1xxx_SOC depends on SIBYTE_SB1xxx_SOC && \
(SIBYTE_BCM112X || SIBYTE_SB1250)
help help
Handle and keep statistics on the bus error interrupts (COR_ECC, Handle and keep statistics on the bus error interrupts (COR_ECC,
BAD_ECC, IO_BUS). BAD_ECC, IO_BUS).
......
...@@ -13,7 +13,6 @@ cflags-$(CONFIG_SIBYTE_BCM112X) += \ ...@@ -13,7 +13,6 @@ cflags-$(CONFIG_SIBYTE_BCM112X) += \
-I$(srctree)/arch/mips/include/asm/mach-sibyte \ -I$(srctree)/arch/mips/include/asm/mach-sibyte \
-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
platform-$(CONFIG_SIBYTE_SB1250) += sibyte/
cflags-$(CONFIG_SIBYTE_SB1250) += \ cflags-$(CONFIG_SIBYTE_SB1250) += \
-I$(srctree)/arch/mips/include/asm/mach-sibyte \ -I$(srctree)/arch/mips/include/asm/mach-sibyte \
-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
...@@ -31,7 +30,8 @@ cflags-$(CONFIG_SIBYTE_BCM1x80) += \ ...@@ -31,7 +30,8 @@ cflags-$(CONFIG_SIBYTE_BCM1x80) += \
# Sibyte BCM91120C (CRhine) board # Sibyte BCM91120C (CRhine) board
# Sibyte BCM91125C (CRhone) board # Sibyte BCM91125C (CRhone) board
# Sibyte BCM91125E (Rhone) board # Sibyte BCM91125E (Rhone) board
# Sibyte SWARM board # Sibyte BCM91250A (SWARM) board
# Sibyte BCM91250C2 (LittleSur) board
# Sibyte BCM91x80 (BigSur) board # Sibyte BCM91x80 (BigSur) board
# #
load-$(CONFIG_SIBYTE_CARMEL) := 0xffffffff80100000 load-$(CONFIG_SIBYTE_CARMEL) := 0xffffffff80100000
...@@ -41,3 +41,4 @@ load-$(CONFIG_SIBYTE_RHONE) := 0xffffffff80100000 ...@@ -41,3 +41,4 @@ load-$(CONFIG_SIBYTE_RHONE) := 0xffffffff80100000
load-$(CONFIG_SIBYTE_SENTOSA) := 0xffffffff80100000 load-$(CONFIG_SIBYTE_SENTOSA) := 0xffffffff80100000
load-$(CONFIG_SIBYTE_SWARM) := 0xffffffff80100000 load-$(CONFIG_SIBYTE_SWARM) := 0xffffffff80100000
load-$(CONFIG_SIBYTE_BIGSUR) := 0xffffffff80100000 load-$(CONFIG_SIBYTE_BIGSUR) := 0xffffffff80100000
load-$(CONFIG_SIBYTE_LITTLESUR) := 0xffffffff80100000
obj-y := cfe.o obj-y := cfe.o
obj-$(CONFIG_SIBYTE_BUS_WATCHER) += bus_watcher.o
obj-$(CONFIG_SIBYTE_CFE_CONSOLE) += cfe_console.o obj-$(CONFIG_SIBYTE_CFE_CONSOLE) += cfe_console.o
obj-$(CONFIG_SIBYTE_TBPROF) += sb_tbprof.o obj-$(CONFIG_SIBYTE_TBPROF) += sb_tbprof.o
...@@ -37,6 +37,9 @@ ...@@ -37,6 +37,9 @@
#include <asm/sibyte/sb1250_regs.h> #include <asm/sibyte/sb1250_regs.h>
#include <asm/sibyte/sb1250_int.h> #include <asm/sibyte/sb1250_int.h>
#include <asm/sibyte/sb1250_scd.h> #include <asm/sibyte/sb1250_scd.h>
#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
#include <asm/sibyte/bcm1480_regs.h>
#endif
struct bw_stats_struct { struct bw_stats_struct {
...@@ -81,9 +84,15 @@ void check_bus_watcher(void) ...@@ -81,9 +84,15 @@ void check_bus_watcher(void)
#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
/* Destructive read, clears register and interrupt */ /* Destructive read, clears register and interrupt */
status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS)); status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
#else #elif defined(CONFIG_SIBYTE_BCM112X) || defined(CONFIG_SIBYTE_SB1250)
/* Use non-destructive register */ /* Use non-destructive register */
status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS_DEBUG)); status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS_DEBUG));
#elif defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
/* Use non-destructive register */
/* Same as 1250 except BUS_ERR_STATUS_DEBUG is in a different place. */
status = csr_in32(IOADDR(A_BCM1480_BUS_ERR_STATUS_DEBUG));
#else
#error bus watcher being built for unknown Sibyte SOC!
#endif #endif
if (!(status & 0x7fffffff)) { if (!(status & 0x7fffffff)) {
printk("Using last values reaped by bus watcher driver\n"); printk("Using last values reaped by bus watcher driver\n");
...@@ -175,9 +184,6 @@ static irqreturn_t sibyte_bw_int(int irq, void *data) ...@@ -175,9 +184,6 @@ static irqreturn_t sibyte_bw_int(int irq, void *data)
#ifdef CONFIG_SIBYTE_BW_TRACE #ifdef CONFIG_SIBYTE_BW_TRACE
int i; int i;
#endif #endif
#ifndef CONFIG_PROC_FS
char bw_buf[1024];
#endif
#ifdef CONFIG_SIBYTE_BW_TRACE #ifdef CONFIG_SIBYTE_BW_TRACE
csr_out32(M_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG)); csr_out32(M_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/errno.h> #include <linux/errno.h>
......
obj-y := setup.o irq.o time.o obj-y := setup.o irq.o time.o
obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SIBYTE_BUS_WATCHER) += bus_watcher.o
...@@ -185,6 +185,7 @@ static void __init sni_pcimt_resource_init(void) ...@@ -185,6 +185,7 @@ static void __init sni_pcimt_resource_init(void)
extern struct pci_ops sni_pcimt_ops; extern struct pci_ops sni_pcimt_ops;
#ifdef CONFIG_PCI
static struct pci_controller sni_controller = { static struct pci_controller sni_controller = {
.pci_ops = &sni_pcimt_ops, .pci_ops = &sni_pcimt_ops,
.mem_resource = &sni_mem_resource, .mem_resource = &sni_mem_resource,
...@@ -193,6 +194,7 @@ static struct pci_controller sni_controller = { ...@@ -193,6 +194,7 @@ static struct pci_controller sni_controller = {
.io_offset = 0x00000000UL, .io_offset = 0x00000000UL,
.io_map_base = SNI_PORT_BASE .io_map_base = SNI_PORT_BASE
}; };
#endif
static void enable_pcimt_irq(struct irq_data *d) static void enable_pcimt_irq(struct irq_data *d)
{ {
......
...@@ -128,13 +128,6 @@ static struct resource pcit_io_resources[] = { ...@@ -128,13 +128,6 @@ static struct resource pcit_io_resources[] = {
} }
}; };
static struct resource sni_mem_resource = {
.start = 0x18000000UL,
.end = 0x1fbfffffUL,
.name = "PCIT PCI MEM",
.flags = IORESOURCE_MEM
};
static void __init sni_pcit_resource_init(void) static void __init sni_pcit_resource_init(void)
{ {
int i; int i;
...@@ -147,6 +140,14 @@ static void __init sni_pcit_resource_init(void) ...@@ -147,6 +140,14 @@ static void __init sni_pcit_resource_init(void)
extern struct pci_ops sni_pcit_ops; extern struct pci_ops sni_pcit_ops;
#ifdef CONFIG_PCI
static struct resource sni_mem_resource = {
.start = 0x18000000UL,
.end = 0x1fbfffffUL,
.name = "PCIT PCI MEM",
.flags = IORESOURCE_MEM
};
static struct pci_controller sni_pcit_controller = { static struct pci_controller sni_pcit_controller = {
.pci_ops = &sni_pcit_ops, .pci_ops = &sni_pcit_ops,
.mem_resource = &sni_mem_resource, .mem_resource = &sni_mem_resource,
...@@ -155,6 +156,7 @@ static struct pci_controller sni_pcit_controller = { ...@@ -155,6 +156,7 @@ static struct pci_controller sni_pcit_controller = {
.io_offset = 0x00000000UL, .io_offset = 0x00000000UL,
.io_map_base = SNI_PORT_BASE .io_map_base = SNI_PORT_BASE
}; };
#endif /* CONFIG_PCI */
static void enable_pcit_irq(struct irq_data *d) static void enable_pcit_irq(struct irq_data *d)
{ {
......
#
# 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 2006 Wind River System, Inc.
# Author: Rongkai.Zhan <rongkai.zhan@windriver.com>
#
# Makefile for the Wind River MIPS 4Kc PPMC Eval Board
#
obj-y += irq.o pci.o reset.o serial.o setup.o time.o
#
# Wind River PPMC Board (4KC + GT64120)
#
platform-$(CONFIG_WR_PPMC) += wrppmc/
cflags-$(CONFIG_WR_PPMC) += \
-I$(srctree)/arch/mips/include/asm/mach-wrppmc
load-$(CONFIG_WR_PPMC) += 0xffffffff80100000
/*
* irq.c: GT64120 Interrupt Controller
*
* Copyright (C) 2006, Wind River System Inc.
* Author: Rongkai.Zhan, <rongkai.zhan@windriver.com>
*
* 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/hardirq.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/gt64120.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
asmlinkage void plat_irq_dispatch(void)
{
unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
if (pending & STATUSF_IP7)
do_IRQ(WRPPMC_MIPS_TIMER_IRQ); /* CPU Compare/Count internal timer */
else if (pending & STATUSF_IP6)
do_IRQ(WRPPMC_UART16550_IRQ); /* UART 16550 port */
else if (pending & STATUSF_IP3)
do_IRQ(WRPPMC_PCI_INTA_IRQ); /* PCI INT_A */
else
spurious_interrupt();
}
/**
* Initialize GT64120 Interrupt Controller
*/
void gt64120_init_pic(void)
{
/* clear CPU Interrupt Cause Registers */
GT_WRITE(GT_INTRCAUSE_OFS, (0x1F << 21));
GT_WRITE(GT_HINTRCAUSE_OFS, 0x00);
/* Disable all interrupts from GT64120 bridge chip */
GT_WRITE(GT_INTRMASK_OFS, 0x00);
GT_WRITE(GT_HINTRMASK_OFS, 0x00);
GT_WRITE(GT_PCI0_ICMASK_OFS, 0x00);
GT_WRITE(GT_PCI0_HICMASK_OFS, 0x00);
}
void __init arch_init_irq(void)
{
/* IRQ 0 - 7 are for MIPS common irq_cpu controller */
mips_cpu_irq_init();
gt64120_init_pic();
}
/*
* pci.c: GT64120 PCI support.
*
* Copyright (C) 2006, Wind River System Inc. Rongkai.Zhan <rongkai.zhan@windriver.com>
*
* 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/ioport.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <asm/gt64120.h>
extern struct pci_ops gt64xxx_pci0_ops;
static struct resource pci0_io_resource = {
.name = "pci_0 io",
.start = GT_PCI_IO_BASE,
.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1,
.flags = IORESOURCE_IO,
};
static struct resource pci0_mem_resource = {
.name = "pci_0 memory",
.start = GT_PCI_MEM_BASE,
.end = GT_PCI_MEM_BASE + GT_PCI_MEM_SIZE - 1,
.flags = IORESOURCE_MEM,
};
static struct pci_controller hose_0 = {
.pci_ops = &gt64xxx_pci0_ops,
.io_resource = &pci0_io_resource,
.mem_resource = &pci0_mem_resource,
};
static int __init gt64120_pci_init(void)
{
(void) GT_READ(GT_PCI0_CMD_OFS); /* Huh??? -- Ralf */
(void) GT_READ(GT_PCI0_BARE_OFS);
/* reset the whole PCI I/O space range */
ioport_resource.start = GT_PCI_IO_BASE;
ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1;
register_pci_controller(&hose_0);
return 0;
}
arch_initcall(gt64120_pci_init);
/*
* 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) 1997 Ralf Baechle
*/
#include <linux/irqflags.h>
#include <linux/kernel.h>
#include <asm/cacheflush.h>
#include <asm/idle.h>
#include <asm/mipsregs.h>
#include <asm/processor.h>
void wrppmc_machine_restart(char *command)
{
/*
* Ouch, we're still alive ... This time we take the silver bullet ...
* ... and find that we leave the hardware in a state in which the
* kernel in the flush locks up somewhen during of after the PCI
* detection stuff.
*/
local_irq_disable();
set_c0_status(ST0_BEV | ST0_ERL);
change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
flush_cache_all();
write_c0_wired(0);
__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
}
void wrppmc_machine_halt(void)
{
local_irq_disable();
printk(KERN_NOTICE "You can safely turn off the power\n");
while (1) {
if (cpu_wait)
cpu_wait();
}
}
/*
* Registration of WRPPMC UART platform device.
*
* Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <asm/gt64120.h>
static struct resource wrppmc_uart_resource[] __initdata = {
{
.start = WRPPMC_UART16550_BASE,
.end = WRPPMC_UART16550_BASE + 7,
.flags = IORESOURCE_MEM,
},
{
.start = WRPPMC_UART16550_IRQ,
.end = WRPPMC_UART16550_IRQ,
.flags = IORESOURCE_IRQ,
},
};
static struct plat_serial8250_port wrppmc_serial8250_port[] = {
{
.irq = WRPPMC_UART16550_IRQ,
.uartclk = WRPPMC_UART16550_CLOCK,
.iotype = UPIO_MEM,
.flags = UPF_IOREMAP | UPF_SKIP_TEST,
.mapbase = WRPPMC_UART16550_BASE,
},
{},
};
static __init int wrppmc_uart_add(void)
{
struct platform_device *pdev;
int retval;
pdev = platform_device_alloc("serial8250", -1);
if (!pdev)
return -ENOMEM;
pdev->id = PLAT8250_DEV_PLATFORM;
pdev->dev.platform_data = wrppmc_serial8250_port;
retval = platform_device_add_resources(pdev, wrppmc_uart_resource,
ARRAY_SIZE(wrppmc_uart_resource));
if (retval)
goto err_free_device;
retval = platform_device_add(pdev);
if (retval)
goto err_free_device;
return 0;
err_free_device:
platform_device_put(pdev);
return retval;
}
device_initcall(wrppmc_uart_add);
/*
* setup.c: Setup pointers to hardware dependent routines.
*
* 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) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org)
* Copyright (C) 2006, Wind River System Inc. Rongkai.zhan <rongkai.zhan@windriver.com>
*/
#include <linux/init.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/pm.h>
#include <asm/io.h>
#include <asm/bootinfo.h>
#include <asm/reboot.h>
#include <asm/time.h>
#include <asm/gt64120.h>
unsigned long gt64120_base = KSEG1ADDR(0x14000000);
#ifdef WRPPMC_EARLY_DEBUG
static volatile unsigned char * wrppmc_led = \
(volatile unsigned char *)KSEG1ADDR(WRPPMC_LED_BASE);
/*
* PPMC LED control register:
* -) bit[0] controls DS1 LED (1 - OFF, 0 - ON)
* -) bit[1] controls DS2 LED (1 - OFF, 0 - ON)
* -) bit[2] controls DS4 LED (1 - OFF, 0 - ON)
*/
void wrppmc_led_on(int mask)
{
unsigned char value = *wrppmc_led;
value &= (0xF8 | mask);
*wrppmc_led = value;
}
/* If mask = 0, turn off all LEDs */
void wrppmc_led_off(int mask)
{
unsigned char value = *wrppmc_led;
value |= (0x7 & mask);
*wrppmc_led = value;
}
/*
* We assume that bootloader has initialized UART16550 correctly
*/
void __init wrppmc_early_putc(char ch)
{
static volatile unsigned char *wrppmc_uart = \
(volatile unsigned char *)KSEG1ADDR(WRPPMC_UART16550_BASE);
unsigned char value;
/* Wait until Transmit-Holding-Register is empty */
while (1) {
value = *(wrppmc_uart + 5);
if (value & 0x20)
break;
}
*wrppmc_uart = ch;
}
void __init wrppmc_early_printk(const char *fmt, ...)
{
static char pbuf[256] = {'\0', };
char *ch = pbuf;
va_list args;
unsigned int i;
memset(pbuf, 0, 256);
va_start(args, fmt);
i = vsprintf(pbuf, fmt, args);
va_end(args);
/* Print the string */
while (*ch != '\0') {
wrppmc_early_putc(*ch);
/* if print '\n', also print '\r' */
if (*ch++ == '\n')
wrppmc_early_putc('\r');
}
}
#endif /* WRPPMC_EARLY_DEBUG */
void __init prom_free_prom_memory(void)
{
}
void __init plat_mem_setup(void)
{
extern void wrppmc_machine_restart(char *command);
extern void wrppmc_machine_halt(void);
_machine_restart = wrppmc_machine_restart;
_machine_halt = wrppmc_machine_halt;
pm_power_off = wrppmc_machine_halt;
/* This makes the operations of 'in/out[bwl]' to the
* physical address ( < KSEG0) can work via KSEG1
*/
set_io_port_base(KSEG1);
}
const char *get_system_type(void)
{
return "Wind River PPMC (GT64120)";
}
/*
* Initializes basic routines and structures pointers, memory size (as
* given by the bios and saves the command line.
*/
void __init prom_init(void)
{
add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM);
add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA);
wrppmc_early_printk("prom_init: GT64120 SDRAM Bank 0: 0x%x - 0x%08lx\n",
WRPPMC_SDRAM_SCS0_BASE, (WRPPMC_SDRAM_SCS0_BASE + WRPPMC_SDRAM_SCS0_SIZE));
}
/*
* time.c: MIPS CPU Count/Compare timer hookup
*
* Author: Mark.Zhan, <rongkai.zhan@windriver.com>
*
* 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) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org)
* Copyright (C) 2006, Wind River System Inc.
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/gt64120.h>
#include <asm/time.h>
#define WRPPMC_CPU_CLK_FREQ 40000000 /* 40MHZ */
/*
* Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
*
* NOTE: We disable all GT64120 timers, and use MIPS processor internal
* timer as the source of kernel clock tick.
*/
void __init plat_time_init(void)
{
/* Disable GT64120 timers */
GT_WRITE(GT_TC_CONTROL_OFS, 0x00);
GT_WRITE(GT_TC0_OFS, 0x00);
GT_WRITE(GT_TC1_OFS, 0x00);
GT_WRITE(GT_TC2_OFS, 0x00);
GT_WRITE(GT_TC3_OFS, 0x00);
/* Use MIPS compare/count internal timer */
mips_hpt_frequency = WRPPMC_CPU_CLK_FREQ;
}
...@@ -160,7 +160,7 @@ config PDC_ADMA ...@@ -160,7 +160,7 @@ config PDC_ADMA
config PATA_OCTEON_CF config PATA_OCTEON_CF
tristate "OCTEON Boot Bus Compact Flash support" tristate "OCTEON Boot Bus Compact Flash support"
depends on CPU_CAVIUM_OCTEON depends on CAVIUM_OCTEON_SOC
help help
This option enables a polled compact flash driver for use with This option enables a polled compact flash driver for use with
compact flash cards attached to the OCTEON boot bus. compact flash cards attached to the OCTEON boot bus.
......
...@@ -167,7 +167,7 @@ config HW_RANDOM_OMAP ...@@ -167,7 +167,7 @@ config HW_RANDOM_OMAP
config HW_RANDOM_OCTEON config HW_RANDOM_OCTEON
tristate "Octeon Random Number Generator support" tristate "Octeon Random Number Generator support"
depends on HW_RANDOM && CPU_CAVIUM_OCTEON depends on HW_RANDOM && CAVIUM_OCTEON_SOC
default HW_RANDOM default HW_RANDOM
---help--- ---help---
This driver provides kernel-side support for the Random Number This driver provides kernel-side support for the Random Number
......
...@@ -349,21 +349,21 @@ config EDAC_OCTEON_PC ...@@ -349,21 +349,21 @@ config EDAC_OCTEON_PC
config EDAC_OCTEON_L2C config EDAC_OCTEON_L2C
tristate "Cavium Octeon Secondary Caches (L2C)" tristate "Cavium Octeon Secondary Caches (L2C)"
depends on EDAC_MM_EDAC && CPU_CAVIUM_OCTEON depends on EDAC_MM_EDAC && CAVIUM_OCTEON_SOC
help help
Support for error detection and correction on the Support for error detection and correction on the
Cavium Octeon family of SOCs. Cavium Octeon family of SOCs.
config EDAC_OCTEON_LMC config EDAC_OCTEON_LMC
tristate "Cavium Octeon DRAM Memory Controller (LMC)" tristate "Cavium Octeon DRAM Memory Controller (LMC)"
depends on EDAC_MM_EDAC && CPU_CAVIUM_OCTEON depends on EDAC_MM_EDAC && CAVIUM_OCTEON_SOC
help help
Support for error detection and correction on the Support for error detection and correction on the
Cavium Octeon family of SOCs. Cavium Octeon family of SOCs.
config EDAC_OCTEON_PCI config EDAC_OCTEON_PCI
tristate "Cavium Octeon PCI Controller" tristate "Cavium Octeon PCI Controller"
depends on EDAC_MM_EDAC && PCI && CPU_CAVIUM_OCTEON depends on EDAC_MM_EDAC && PCI && CAVIUM_OCTEON_SOC
help help
Support for error detection and correction on the Support for error detection and correction on the
Cavium Octeon family of SOCs. Cavium Octeon family of SOCs.
......
...@@ -739,7 +739,7 @@ config I2C_WMT ...@@ -739,7 +739,7 @@ config I2C_WMT
config I2C_OCTEON config I2C_OCTEON
tristate "Cavium OCTEON I2C bus support" tristate "Cavium OCTEON I2C bus support"
depends on CPU_CAVIUM_OCTEON depends on CAVIUM_OCTEON_SOC
help help
Say yes if you want to support the I2C serial bus on Cavium Say yes if you want to support the I2C serial bus on Cavium
OCTEON SOC. OCTEON SOC.
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
config OCTEON_MGMT_ETHERNET config OCTEON_MGMT_ETHERNET
tristate "Octeon Management port ethernet driver (CN5XXX, CN6XXX)" tristate "Octeon Management port ethernet driver (CN5XXX, CN6XXX)"
depends on CPU_CAVIUM_OCTEON depends on CAVIUM_OCTEON_SOC
select PHYLIB select PHYLIB
select MDIO_OCTEON select MDIO_OCTEON
default y default y
......
...@@ -135,7 +135,7 @@ config MDIO_GPIO ...@@ -135,7 +135,7 @@ config MDIO_GPIO
config MDIO_OCTEON config MDIO_OCTEON
tristate "Support for MDIO buses on Octeon SOCs" tristate "Support for MDIO buses on Octeon SOCs"
depends on CPU_CAVIUM_OCTEON depends on CAVIUM_OCTEON_SOC
default y default y
help help
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <linux/rio_drv.h> #include <linux/rio_drv.h>
#include <linux/rio_ids.h> #include <linux/rio_ids.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <asm/page.h>
#include "../rio.h" #include "../rio.h"
#define LOCAL_RTE_CONF_DESTID_SEL 0x010070 #define LOCAL_RTE_CONF_DESTID_SEL 0x010070
......
...@@ -266,7 +266,7 @@ config SPI_OC_TINY ...@@ -266,7 +266,7 @@ config SPI_OC_TINY
config SPI_OCTEON config SPI_OCTEON
tristate "Cavium OCTEON SPI controller" tristate "Cavium OCTEON SPI controller"
depends on CPU_CAVIUM_OCTEON depends on CAVIUM_OCTEON_SOC
help help
SPI host driver for the hardware found on some Cavium OCTEON SPI host driver for the hardware found on some Cavium OCTEON
SOCs. SOCs.
......
...@@ -144,7 +144,7 @@ config SSB_SFLASH ...@@ -144,7 +144,7 @@ config SSB_SFLASH
# Assumption: We are on embedded, if we compile the MIPS core. # Assumption: We are on embedded, if we compile the MIPS core.
config SSB_EMBEDDED config SSB_EMBEDDED
bool bool
depends on SSB_DRIVER_MIPS depends on SSB_DRIVER_MIPS && SSB_PCICORE_HOSTMODE
default y default y
config SSB_DRIVER_EXTIF config SSB_DRIVER_EXTIF
......
config OCTEON_ETHERNET config OCTEON_ETHERNET
tristate "Cavium Networks Octeon Ethernet support" tristate "Cavium Networks Octeon Ethernet support"
depends on CPU_CAVIUM_OCTEON && NETDEVICES depends on CAVIUM_OCTEON_SOC && NETDEVICES
select PHYLIB select PHYLIB
select MDIO_OCTEON select MDIO_OCTEON
help help
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <asm/byteorder.h>
#include "8250.h" #include "8250.h"
/* Offsets for the DesignWare specific registers */ /* Offsets for the DesignWare specific registers */
...@@ -57,6 +59,7 @@ struct dw8250_data { ...@@ -57,6 +59,7 @@ struct dw8250_data {
int last_lcr; int last_lcr;
int line; int line;
struct clk *clk; struct clk *clk;
u8 usr_reg;
}; };
static void dw8250_serial_out(struct uart_port *p, int offset, int value) static void dw8250_serial_out(struct uart_port *p, int offset, int value)
...@@ -77,6 +80,13 @@ static unsigned int dw8250_serial_in(struct uart_port *p, int offset) ...@@ -77,6 +80,13 @@ static unsigned int dw8250_serial_in(struct uart_port *p, int offset)
return readb(p->membase + offset); return readb(p->membase + offset);
} }
/* Read Back (rb) version to ensure register access ording. */
static void dw8250_serial_out_rb(struct uart_port *p, int offset, int value)
{
dw8250_serial_out(p, offset, value);
dw8250_serial_in(p, UART_LCR);
}
static void dw8250_serial_out32(struct uart_port *p, int offset, int value) static void dw8250_serial_out32(struct uart_port *p, int offset, int value)
{ {
struct dw8250_data *d = p->private_data; struct dw8250_data *d = p->private_data;
...@@ -104,7 +114,7 @@ static int dw8250_handle_irq(struct uart_port *p) ...@@ -104,7 +114,7 @@ static int dw8250_handle_irq(struct uart_port *p)
return 1; return 1;
} else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) { } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
/* Clear the USR and write the LCR again. */ /* Clear the USR and write the LCR again. */
(void)p->serial_in(p, DW_UART_USR); (void)p->serial_in(p, d->usr_reg);
p->serial_out(p, UART_LCR, d->last_lcr); p->serial_out(p, UART_LCR, d->last_lcr);
return 1; return 1;
...@@ -125,12 +135,60 @@ dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) ...@@ -125,12 +135,60 @@ dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
pm_runtime_put_sync_suspend(port->dev); pm_runtime_put_sync_suspend(port->dev);
} }
static int dw8250_probe_of(struct uart_port *p) static void dw8250_setup_port(struct uart_8250_port *up)
{
struct uart_port *p = &up->port;
u32 reg = readl(p->membase + DW_UART_UCV);
/*
* If the Component Version Register returns zero, we know that
* ADDITIONAL_FEATURES are not enabled. No need to go any further.
*/
if (!reg)
return;
dev_dbg_ratelimited(p->dev, "Designware UART version %c.%c%c\n",
(reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff);
reg = readl(p->membase + DW_UART_CPR);
if (!reg)
return;
/* Select the type based on fifo */
if (reg & DW_UART_CPR_FIFO_MODE) {
p->type = PORT_16550A;
p->flags |= UPF_FIXED_TYPE;
p->fifosize = DW_UART_CPR_FIFO_SIZE(reg);
up->tx_loadsz = p->fifosize;
up->capabilities = UART_CAP_FIFO;
}
if (reg & DW_UART_CPR_AFCE_MODE)
up->capabilities |= UART_CAP_AFE;
}
static int dw8250_probe_of(struct uart_port *p,
struct dw8250_data *data)
{ {
struct device_node *np = p->dev->of_node; struct device_node *np = p->dev->of_node;
u32 val; u32 val;
bool has_ucv = true;
if (!of_property_read_u32(np, "reg-io-width", &val)) {
if (of_device_is_compatible(np, "cavium,octeon-3860-uart")) {
#ifdef __BIG_ENDIAN
/*
* Low order bits of these 64-bit registers, when
* accessed as a byte, are 7 bytes further down in the
* address space in big endian mode.
*/
p->membase += 7;
#endif
p->serial_out = dw8250_serial_out_rb;
p->flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
p->type = PORT_OCTEON;
data->usr_reg = 0x27;
has_ucv = false;
} else if (!of_property_read_u32(np, "reg-io-width", &val)) {
switch (val) { switch (val) {
case 1: case 1:
break; break;
...@@ -144,6 +202,8 @@ static int dw8250_probe_of(struct uart_port *p) ...@@ -144,6 +202,8 @@ static int dw8250_probe_of(struct uart_port *p)
return -EINVAL; return -EINVAL;
} }
} }
if (has_ucv)
dw8250_setup_port(container_of(p, struct uart_8250_port, port));
if (!of_property_read_u32(np, "reg-shift", &val)) if (!of_property_read_u32(np, "reg-shift", &val))
p->regshift = val; p->regshift = val;
...@@ -168,6 +228,8 @@ static int dw8250_probe_acpi(struct uart_8250_port *up) ...@@ -168,6 +228,8 @@ static int dw8250_probe_acpi(struct uart_8250_port *up)
const struct acpi_device_id *id; const struct acpi_device_id *id;
struct uart_port *p = &up->port; struct uart_port *p = &up->port;
dw8250_setup_port(up);
id = acpi_match_device(p->dev->driver->acpi_match_table, p->dev); id = acpi_match_device(p->dev->driver->acpi_match_table, p->dev);
if (!id) if (!id)
return -ENODEV; return -ENODEV;
...@@ -196,38 +258,6 @@ static inline int dw8250_probe_acpi(struct uart_8250_port *up) ...@@ -196,38 +258,6 @@ static inline int dw8250_probe_acpi(struct uart_8250_port *up)
} }
#endif /* CONFIG_ACPI */ #endif /* CONFIG_ACPI */
static void dw8250_setup_port(struct uart_8250_port *up)
{
struct uart_port *p = &up->port;
u32 reg = readl(p->membase + DW_UART_UCV);
/*
* If the Component Version Register returns zero, we know that
* ADDITIONAL_FEATURES are not enabled. No need to go any further.
*/
if (!reg)
return;
dev_dbg_ratelimited(p->dev, "Designware UART version %c.%c%c\n",
(reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff);
reg = readl(p->membase + DW_UART_CPR);
if (!reg)
return;
/* Select the type based on fifo */
if (reg & DW_UART_CPR_FIFO_MODE) {
p->type = PORT_16550A;
p->flags |= UPF_FIXED_TYPE;
p->fifosize = DW_UART_CPR_FIFO_SIZE(reg);
up->tx_loadsz = p->fifosize;
up->capabilities = UART_CAP_FIFO;
}
if (reg & DW_UART_CPR_AFCE_MODE)
up->capabilities |= UART_CAP_AFE;
}
static int dw8250_probe(struct platform_device *pdev) static int dw8250_probe(struct platform_device *pdev)
{ {
struct uart_8250_port uart = {}; struct uart_8250_port uart = {};
...@@ -259,6 +289,7 @@ static int dw8250_probe(struct platform_device *pdev) ...@@ -259,6 +289,7 @@ static int dw8250_probe(struct platform_device *pdev)
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
data->usr_reg = DW_UART_USR;
data->clk = devm_clk_get(&pdev->dev, NULL); data->clk = devm_clk_get(&pdev->dev, NULL);
if (!IS_ERR(data->clk)) { if (!IS_ERR(data->clk)) {
clk_prepare_enable(data->clk); clk_prepare_enable(data->clk);
...@@ -270,10 +301,8 @@ static int dw8250_probe(struct platform_device *pdev) ...@@ -270,10 +301,8 @@ static int dw8250_probe(struct platform_device *pdev)
uart.port.serial_out = dw8250_serial_out; uart.port.serial_out = dw8250_serial_out;
uart.port.private_data = data; uart.port.private_data = data;
dw8250_setup_port(&uart);
if (pdev->dev.of_node) { if (pdev->dev.of_node) {
err = dw8250_probe_of(&uart.port); err = dw8250_probe_of(&uart.port, data);
if (err) if (err)
return err; return err;
} else if (ACPI_HANDLE(&pdev->dev)) { } else if (ACPI_HANDLE(&pdev->dev)) {
...@@ -362,6 +391,7 @@ static const struct dev_pm_ops dw8250_pm_ops = { ...@@ -362,6 +391,7 @@ static const struct dev_pm_ops dw8250_pm_ops = {
static const struct of_device_id dw8250_of_match[] = { static const struct of_device_id dw8250_of_match[] = {
{ .compatible = "snps,dw-apb-uart" }, { .compatible = "snps,dw-apb-uart" },
{ .compatible = "cavium,octeon-3860-uart" },
{ /* Sentinel */ } { /* Sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, dw8250_of_match); MODULE_DEVICE_TABLE(of, dw8250_of_match);
......
...@@ -283,7 +283,7 @@ config USB_EHCI_HCD_PLATFORM ...@@ -283,7 +283,7 @@ config USB_EHCI_HCD_PLATFORM
config USB_OCTEON_EHCI config USB_OCTEON_EHCI
bool "Octeon on-chip EHCI support" bool "Octeon on-chip EHCI support"
depends on CPU_CAVIUM_OCTEON depends on CAVIUM_OCTEON_SOC
default n default n
select USB_EHCI_BIG_ENDIAN_MMIO select USB_EHCI_BIG_ENDIAN_MMIO
help help
...@@ -488,7 +488,7 @@ config USB_OHCI_HCD_PLATFORM ...@@ -488,7 +488,7 @@ config USB_OHCI_HCD_PLATFORM
config USB_OCTEON_OHCI config USB_OCTEON_OHCI
bool "Octeon on-chip OHCI support" bool "Octeon on-chip OHCI support"
depends on CPU_CAVIUM_OCTEON depends on CAVIUM_OCTEON_SOC
default USB_OCTEON_EHCI default USB_OCTEON_EHCI
select USB_OHCI_BIG_ENDIAN_MMIO select USB_OHCI_BIG_ENDIAN_MMIO
select USB_OHCI_LITTLE_ENDIAN select USB_OHCI_LITTLE_ENDIAN
......
...@@ -1074,7 +1074,7 @@ config TXX9_WDT ...@@ -1074,7 +1074,7 @@ config TXX9_WDT
config OCTEON_WDT config OCTEON_WDT
tristate "Cavium OCTEON SOC family Watchdog Timer" tristate "Cavium OCTEON SOC family Watchdog Timer"
depends on CPU_CAVIUM_OCTEON depends on CAVIUM_OCTEON_SOC
default y default y
select EXPORT_UASM if OCTEON_WDT = m select EXPORT_UASM if OCTEON_WDT = m
help help
......
...@@ -208,7 +208,7 @@ static long sbwdog_ioctl(struct file *file, unsigned int cmd, ...@@ -208,7 +208,7 @@ static long sbwdog_ioctl(struct file *file, unsigned int cmd,
* get the remaining count from the ... count register * get the remaining count from the ... count register
* which is 1*8 before the config register * which is 1*8 before the config register
*/ */
ret = put_user(__raw_readq(user_dog - 8) / 1000000, p); ret = put_user((u32)__raw_readq(user_dog - 8) / 1000000, p);
break; break;
} }
return ret; return ret;
......
...@@ -62,6 +62,7 @@ header-y += auxvec.h ...@@ -62,6 +62,7 @@ header-y += auxvec.h
header-y += ax25.h header-y += ax25.h
header-y += b1lli.h header-y += b1lli.h
header-y += baycom.h header-y += baycom.h
header-y += bcm933xx_hcs.h
header-y += bfs_fs.h header-y += bfs_fs.h
header-y += binfmts.h header-y += binfmts.h
header-y += blkpg.h header-y += blkpg.h
......
/*
* Broadcom Cable Modem firmware format
*/
#ifndef __BCM933XX_HCS_H
#define __BCM933XX_HCS_H
#include <linux/types.h>
struct bcm_hcs {
__u16 magic;
__u16 control;
__u16 rev_maj;
__u16 rev_min;
__u32 build_date;
__u32 filelen;
__u32 ldaddress;
char filename[64];
__u16 hcs;
__u16 her_znaet_chto;
__u32 crc;
};
#endif /* __BCM933XX_HCS */
...@@ -475,18 +475,6 @@ unsigned int irq_create_of_mapping(struct device_node *controller, ...@@ -475,18 +475,6 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
domain = controller ? irq_find_host(controller) : irq_default_domain; domain = controller ? irq_find_host(controller) : irq_default_domain;
if (!domain) { if (!domain) {
#ifdef CONFIG_MIPS
/*
* Workaround to avoid breaking interrupt controller drivers
* that don't yet register an irq_domain. This is temporary
* code. ~~~gcl, Feb 24, 2012
*
* Scheduled for removal in Linux v3.6. That should be enough
* time.
*/
if (intsize > 0)
return intspec[0];
#endif
pr_warn("no irq domain found for %s !\n", pr_warn("no irq domain found for %s !\n",
of_node_full_name(controller)); of_node_full_name(controller));
return 0; return 0;
......
...@@ -1347,7 +1347,7 @@ config FAULT_INJECTION_STACKTRACE_FILTER ...@@ -1347,7 +1347,7 @@ config FAULT_INJECTION_STACKTRACE_FILTER
depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT
depends on !X86_64 depends on !X86_64
select STACKTRACE select STACKTRACE
select FRAME_POINTER if !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND
help help
Provide stacktrace filter for fault-injection capabilities Provide stacktrace filter for fault-injection capabilities
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册