Commit e2464688 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull MIPS updates from Ralf Baechle:
 "This is the main pull request for MIPS for 4.5 plus some 4.4 fixes.

  The executive summary:

   - ATH79 platform improvments, use DT bindings for the ATH79 USB PHY.
   - Avoid useless rebuilds for zboot.
   - jz4780: Add NEMC, BCH and NAND device tree nodes
   - Initial support for the MicroChip's DT platform.  As all the device
     drivers are missing this is still of limited use.
   - Some Loongson3 cleanups.
   - The unavoidable whitespace polishing.
   - Reduce clock skew when synchronizing the CPU cycle counters on CPU
     startup.
   - Add MIPS R6 fixes.
   - Lots of cleanups across arch/mips as fallout from KVM.
   - Lots of minor fixes and changes for IEEE 754-2008 support to the
     FPU emulator / fp-assist software.
   - Minor Ralink, BCM47xx and bcm963xx platform support improvments.
   - Support SMP on BCM63168"

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (84 commits)
  MIPS: zboot: Add support for serial debug using the PROM
  MIPS: zboot: Avoid useless rebuilds
  MIPS: BMIPS: Enable ARCH_WANT_OPTIONAL_GPIOLIB
  MIPS: bcm63xx: nvram: Remove unused bcm63xx_nvram_get_psi_size() function
  MIPS: bcm963xx: Update bcm_tag field image_sequence
  MIPS: bcm963xx: Move extended flash address to bcm_tag header file
  MIPS: bcm963xx: Move Broadcom BCM963xx image tag data structure
  MIPS: bcm63xx: nvram: Use nvram structure definition from header file
  MIPS: bcm963xx: Add Broadcom BCM963xx board nvram data structure
  MAINTAINERS: Add KVM for MIPS entry
  MIPS: KVM: Add missing newline to kvm_err()
  MIPS: Move KVM specific opcodes into asm/inst.h
  MIPS: KVM: Use cacheops.h definitions
  MIPS: Break down cacheops.h definitions
  MIPS: Use EXCCODE_ constants with set_except_vector()
  MIPS: Update trap codes
  MIPS: Move Cause.ExcCode trap codes to mipsregs.h
  MIPS: KVM: Make kvm_mips_{init,exit}() static
  MIPS: KVM: Refactor added offsetof()s
  MIPS: KVM: Convert EXPORT_SYMBOL to _GPL
  ...
parents e1c10879 07d17f09
Microchip PIC32 Interrupt Controller
====================================
The Microchip PIC32 contains an Enhanced Vectored Interrupt Controller (EVIC).
It handles all internal and external interrupts. This controller exists outside
of the CPU and is the arbitrator of all interrupts (including interrupts from
the CPU itself) before they are presented to the CPU.
External interrupts have a software configurable edge polarity. Non external
interrupts have a type and polarity that is determined by the source of the
interrupt.
Required properties
-------------------
- compatible: Should be "microchip,pic32mzda-evic"
- reg: Specifies physical base address and size of register range.
- interrupt-controller: Identifies the node as an interrupt controller.
- #interrupt cells: Specifies the number of cells used to encode an interrupt
source connected to this controller. The value shall be 2 and interrupt
descriptor shall have the following format:
<hw_irq irq_type>
hw_irq - represents the hardware interrupt number as in the data sheet.
irq_type - is used to describe the type and polarity of an interrupt. For
internal interrupts use IRQ_TYPE_EDGE_RISING for non persistent interrupts and
IRQ_TYPE_LEVEL_HIGH for persistent interrupts. For external interrupts use
IRQ_TYPE_EDGE_RISING or IRQ_TYPE_EDGE_FALLING to select the desired polarity.
Optional properties
-------------------
- microchip,external-irqs: u32 array of external interrupts with software
polarity configuration. This array corresponds to the bits in the INTCON
SFR.
Example
-------
evic: interrupt-controller@1f810000 {
compatible = "microchip,pic32mzda-evic";
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x1f810000 0x1000>;
microchip,external-irqs = <3 8 13 18 23>;
};
Each device/peripheral must request its interrupt line with the associated type
and polarity.
Internal interrupt DTS snippet
------------------------------
device@1f800000 {
...
interrupts = <113 IRQ_TYPE_LEVEL_HIGH>;
...
};
External interrupt DTS snippet
------------------------------
device@1f800000 {
...
interrupts = <3 IRQ_TYPE_EDGE_RISING>;
...
};
* Microchip PIC32MZDA Platforms
PIC32MZDA Starter Kit
Required root node properties:
- compatible = "microchip,pic32mzda-sk", "microchip,pic32mzda"
CPU nodes:
----------
A "cpus" node is required. Required properties:
- #address-cells: Must be 1.
- #size-cells: Must be 0.
A CPU sub-node is also required. Required properties:
- device_type: Must be "cpu".
- compatible: Must be "mti,mips14KEc".
Example:
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "mti,mips14KEc";
};
};
Boot protocol
--------------
In accordance with Unified Hosting Interface Reference Manual (MD01069), the
bootloader must pass the following arguments to the kernel:
- $a0: -2.
- $a1: KSEG0 address of the flattened device-tree blob.
Mediatek Gigabit Switch
=======================
The mediatek gigabit switch can be found on Mediatek SoCs (mt7620, mt7621).
Required properties:
- compatible: Should be "mediatek,mt7620-gsw" or "mediatek,mt7621-gsw"
- reg: Address and length of the register set for the device
- interrupt-parent: Should be the phandle for the interrupt controller
that services interrupts for this device
- interrupts: Should contain the gigabit switches interrupt
- resets: Should contain the gigabit switches resets
- reset-names: Should contain the reset names "gsw"
Example:
gsw@10110000 {
compatible = "ralink,mt7620-gsw";
reg = <0x10110000 8000>;
resets = <&rstctrl 23>;
reset-names = "gsw";
interrupt-parent = <&intc>;
interrupts = <17>;
};
Ralink Frame Engine Ethernet controller
=======================================
The Ralink frame engine ethernet controller can be found on Ralink and
Mediatek SoCs (RT288x, RT3x5x, RT366x, RT388x, rt5350, mt7620, mt7621, mt76x8).
Depending on the SoC, there is a number of ports connected to the CPU port
directly and/or via a (gigabit-)switch.
* Ethernet controller node
Required properties:
- compatible: Should be one of "ralink,rt2880-eth", "ralink,rt3050-eth",
"ralink,rt3050-eth", "ralink,rt3883-eth", "ralink,rt5350-eth",
"mediatek,mt7620-eth", "mediatek,mt7621-eth"
- reg: Address and length of the register set for the device
- interrupt-parent: Should be the phandle for the interrupt controller
that services interrupts for this device
- interrupts: Should contain the frame engines interrupt
- resets: Should contain the frame engines resets
- reset-names: Should contain the reset names "fe". If a switch is present
"esw" is also required.
* Ethernet port node
Required properties:
- compatible: Should be "ralink,eth-port"
- reg: The number of the physical port
- phy-handle: reference to the node describing the phy
Example:
mdio-bus {
...
phy0: ethernet-phy@0 {
phy-mode = "mii";
reg = <0>;
};
};
ethernet@400000 {
compatible = "ralink,rt2880-eth";
reg = <0x00400000 10000>;
#address-cells = <1>;
#size-cells = <0>;
resets = <&rstctrl 18>;
reset-names = "fe";
interrupt-parent = <&cpuintc>;
interrupts = <5>;
port@0 {
compatible = "ralink,eth-port";
reg = <0>;
phy-handle = <&phy0>;
};
};
Ralink Fast Ethernet Embedded Switch
====================================
The ralink fast ethernet embedded switch can be found on Ralink and Mediatek
SoCs (RT3x5x, RT5350, MT76x8).
Required properties:
- compatible: Should be "ralink,rt3050-esw"
- reg: Address and length of the register set for the device
- interrupt-parent: Should be the phandle for the interrupt controller
that services interrupts for this device
- interrupts: Should contain the embedded switches interrupt
- resets: Should contain the embedded switches resets
- reset-names: Should contain the reset names "esw"
Optional properties:
- ralink,portmap: can be used to choose if the default switch setup is
llllw or wllll
- ralink,led_polarity: override the active high/low settings of the leds
Example:
esw@10110000 {
compatible = "ralink,rt3050-esw";
reg = <0x10110000 8000>;
resets = <&rstctrl 23>;
reset-names = "esw";
interrupt-parent = <&intc>;
interrupts = <17>;
};
* Atheros AR71XX/9XXX USB PHY
Required properties:
- compatible: "qca,ar7100-usb-phy"
- #phys-cells: should be 0
- reset-names: "usb-phy"[, "usb-suspend-override"]
- resets: references to the reset controllers
Example:
usb-phy {
compatible = "qca,ar7100-usb-phy";
reset-names = "usb-phy", "usb-suspend-override";
resets = <&rst 4>, <&rst 3>;
#phy-cells = <0>;
};
......@@ -1454,6 +1454,41 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
In such case C2/C3 won't be used again.
idle=nomwait: Disable mwait for CPU C-states
ieee754= [MIPS] Select IEEE Std 754 conformance mode
Format: { strict | legacy | 2008 | relaxed }
Default: strict
Choose which programs will be accepted for execution
based on the IEEE 754 NaN encoding(s) supported by
the FPU and the NaN encoding requested with the value
of an ELF file header flag individually set by each
binary. Hardware implementations are permitted to
support either or both of the legacy and the 2008 NaN
encoding mode.
Available settings are as follows:
strict accept binaries that request a NaN encoding
supported by the FPU
legacy only accept legacy-NaN binaries, if supported
by the FPU
2008 only accept 2008-NaN binaries, if supported
by the FPU
relaxed accept any binaries regardless of whether
supported by the FPU
The FPU emulator is always able to support both NaN
encodings, so if no FPU hardware is present or it has
been disabled with 'nofpu', then the settings of
'legacy' and '2008' strap the emulator accordingly,
'relaxed' straps the emulator for both legacy-NaN and
2008-NaN, whereas 'strict' enables legacy-NaN only on
legacy processors and both NaN encodings on MIPS32 or
MIPS64 CPUs.
The setting for ABS.fmt/NEG.fmt instruction execution
mode generally follows that for the NaN encoding,
except where unsupported by hardware.
ignore_loglevel [KNL]
Ignore loglevel setting - this will print /all/
kernel messages to the console. Useful for debugging.
......
......@@ -2420,6 +2420,8 @@ F: arch/mips/kernel/*bmips*
F: arch/mips/boot/dts/brcm/bcm*.dts*
F: drivers/irqchip/irq-bcm7*
F: drivers/irqchip/irq-brcmstb*
F: include/linux/bcm963xx_nvram.h
F: include/linux/bcm963xx_tag.h
BROADCOM TG3 GIGABIT ETHERNET DRIVER
M: Prashant Sreedharan <prashant@broadcom.com>
......@@ -6216,6 +6218,14 @@ F: arch/arm64/include/uapi/asm/kvm*
F: arch/arm64/include/asm/kvm*
F: arch/arm64/kvm/
KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
M: James Hogan <james.hogan@imgtec.com>
L: linux-mips@linux-mips.org
S: Supported
F: arch/mips/include/uapi/asm/kvm*
F: arch/mips/include/asm/kvm*
F: arch/mips/kvm/
KEXEC
M: Eric Biederman <ebiederm@xmission.com>
W: http://kernel.org/pub/linux/utils/kernel/kexec/
......@@ -6313,6 +6323,12 @@ S: Maintained
F: net/l3mdev
F: include/net/l3mdev.h
LANTIQ MIPS ARCHITECTURE
M: John Crispin <blogic@openwrt.org>
L: linux-mips@linux-mips.org
S: Maintained
F: arch/mips/lantiq
LAPB module
L: linux-x25@vger.kernel.org
S: Orphan
......@@ -8997,6 +9013,12 @@ L: linux-fbdev@vger.kernel.org
S: Maintained
F: drivers/video/fbdev/aty/aty128fb.c
RALINK MIPS ARCHITECTURE
M: John Crispin <blogic@openwrt.org>
L: linux-mips@linux-mips.org
S: Maintained
F: arch/mips/ralink
RALINK RT2X00 WIRELESS LAN DRIVER
P: rt2x00 project
M: Stanislaw Gruszka <sgruszka@redhat.com>
......
......@@ -21,6 +21,7 @@ platforms += mti-malta
platforms += mti-sead3
platforms += netlogic
platforms += paravirt
platforms += pic32
platforms += pistachio
platforms += pmcs-msp71xx
platforms += pnx833x
......
......@@ -169,6 +169,7 @@ config BMIPS_GENERIC
select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
select ARCH_WANT_OPTIONAL_GPIOLIB
help
Build a generic DT-based kernel image that boots on select
BCM33xx cable modem chips, BCM63xx DSL chips, and BCM7xxx set-top
......@@ -480,6 +481,14 @@ config MIPS_MALTA
This enables support for the MIPS Technologies Malta evaluation
board.
config MACH_PIC32
bool "Microchip PIC32 Family"
help
This enables support for the Microchip PIC32 family of platforms.
Microchip PIC32 is a family of general-purpose 32 bit MIPS core
microcontrollers.
config MIPS_SEAD3
bool "MIPS SEAD3 board"
select BOOT_ELF32
......@@ -979,6 +988,7 @@ source "arch/mips/jazz/Kconfig"
source "arch/mips/jz4740/Kconfig"
source "arch/mips/lantiq/Kconfig"
source "arch/mips/lasat/Kconfig"
source "arch/mips/pic32/Kconfig"
source "arch/mips/pistachio/Kconfig"
source "arch/mips/pmcs-msp71xx/Kconfig"
source "arch/mips/ralink/Kconfig"
......@@ -1755,6 +1765,10 @@ config SYS_SUPPORTS_ZBOOT_UART16550
bool
select SYS_SUPPORTS_ZBOOT
config SYS_SUPPORTS_ZBOOT_UART_PROM
bool
select SYS_SUPPORTS_ZBOOT
config CPU_LOONGSON2
bool
select CPU_SUPPORTS_32BIT_KERNEL
......@@ -2017,7 +2031,8 @@ config KVM_GUEST
bool "KVM Guest Kernel"
depends on BROKEN_ON_SMP
help
Select this option if building a guest kernel for KVM (Trap & Emulate) mode
Select this option if building a guest kernel for KVM (Trap & Emulate)
mode.
config KVM_GUEST_TIMER_FREQ
int "Count/Compare Timer Frequency (MHz)"
......
......@@ -166,16 +166,6 @@ cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
endif
cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
cflags-$(CONFIG_CPU_BMIPS) += -march=mips32 -Wa,-mips32 -Wa,--trap
#
# binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a
# as MIPS64 R1; older versions as just R1. This leaves the possibility open
# that GCC might generate R2 code for -march=loongson3a which then is rejected
# by GAS. The cc-option can't probe for this behaviour so -march=loongson3a
# can't easily be used safely within the kbuild framework.
#
cflags-$(CONFIG_CPU_LOONGSON3) += \
$(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \
-Wa,-mips64r2 -Wa,--trap
cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
......
......@@ -40,7 +40,7 @@
static int gpio2_get(struct gpio_chip *chip, unsigned offset)
{
return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
return !!alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
}
static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value)
......@@ -68,7 +68,7 @@ static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset)
static int gpio1_get(struct gpio_chip *chip, unsigned offset)
{
return alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE);
return !!alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE);
}
static void gpio1_set(struct gpio_chip *chip,
......@@ -119,7 +119,7 @@ struct gpio_chip alchemy_gpio_chip[] = {
static int alchemy_gpic_get(struct gpio_chip *chip, unsigned int off)
{
return au1300_gpio_get_value(off + AU1300_GPIO_BASE);
return !!au1300_gpio_get_value(off + AU1300_GPIO_BASE);
}
static void alchemy_gpic_set(struct gpio_chip *chip, unsigned int off, int v)
......
......@@ -37,7 +37,7 @@ static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
container_of(chip, struct ar7_gpio_chip, chip);
void __iomem *gpio_in = gpch->regs + AR7_GPIO_INPUT;
return readl(gpio_in) & (1 << gpio);
return !!(readl(gpio_in) & (1 << gpio));
}
static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
......
......@@ -23,7 +23,6 @@ void ath79_clocks_init(void);
unsigned long ath79_get_sys_clk_rate(const char *id);
void ath79_ddr_ctrl_init(void);
void ath79_ddr_wb_flush(unsigned int reg);
void ath79_gpio_init(void);
......
......@@ -26,9 +26,13 @@
#include "common.h"
#include "machtypes.h"
static void __init ath79_misc_intc_domain_init(
struct device_node *node, int irq);
static void ath79_misc_irq_handler(struct irq_desc *desc)
{
void __iomem *base = ath79_reset_base;
struct irq_domain *domain = irq_desc_get_handler_data(desc);
void __iomem *base = domain->host_data;
u32 pending;
pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
......@@ -42,15 +46,15 @@ static void ath79_misc_irq_handler(struct irq_desc *desc)
while (pending) {
int bit = __ffs(pending);
generic_handle_irq(ATH79_MISC_IRQ(bit));
generic_handle_irq(irq_linear_revmap(domain, bit));
pending &= ~BIT(bit);
}
}
static void ar71xx_misc_irq_unmask(struct irq_data *d)
{
unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
void __iomem *base = ath79_reset_base;
void __iomem *base = irq_data_get_irq_chip_data(d);
unsigned int irq = d->hwirq;
u32 t;
t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
......@@ -62,8 +66,8 @@ static void ar71xx_misc_irq_unmask(struct irq_data *d)
static void ar71xx_misc_irq_mask(struct irq_data *d)
{
unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
void __iomem *base = ath79_reset_base;
void __iomem *base = irq_data_get_irq_chip_data(d);
unsigned int irq = d->hwirq;
u32 t;
t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
......@@ -75,8 +79,8 @@ static void ar71xx_misc_irq_mask(struct irq_data *d)
static void ar724x_misc_irq_ack(struct irq_data *d)
{
unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
void __iomem *base = ath79_reset_base;
void __iomem *base = irq_data_get_irq_chip_data(d);
unsigned int irq = d->hwirq;
u32 t;
t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
......@@ -94,12 +98,6 @@ static struct irq_chip ath79_misc_irq_chip = {
static void __init ath79_misc_irq_init(void)
{
void __iomem *base = ath79_reset_base;
int i;
__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
if (soc_is_ar71xx() || soc_is_ar913x())
ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
else if (soc_is_ar724x() ||
......@@ -110,13 +108,7 @@ static void __init ath79_misc_irq_init(void)
else
BUG();
for (i = ATH79_MISC_IRQ_BASE;
i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) {
irq_set_chip_and_handler(i, &ath79_misc_irq_chip,
handle_level_irq);
}
irq_set_chained_handler(ATH79_CPU_IRQ(6), ath79_misc_irq_handler);
ath79_misc_intc_domain_init(NULL, ATH79_CPU_IRQ(6));
}
static void ar934x_ip2_irq_dispatch(struct irq_desc *desc)
......@@ -256,10 +248,10 @@ asmlinkage void plat_irq_dispatch(void)
}
}
#ifdef CONFIG_IRQCHIP
static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
{
irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq);
irq_set_chip_data(irq, d->host_data);
return 0;
}
......@@ -268,19 +260,14 @@ static const struct irq_domain_ops misc_irq_domain_ops = {
.map = misc_map,
};
static int __init ath79_misc_intc_of_init(
struct device_node *node, struct device_node *parent)
static void __init ath79_misc_intc_domain_init(
struct device_node *node, int irq)
{
void __iomem *base = ath79_reset_base;
struct irq_domain *domain;
int irq;
irq = irq_of_parse_and_map(node, 0);
if (!irq)
panic("Failed to get MISC IRQ");
domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT,
ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, NULL);
ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, base);
if (!domain)
panic("Failed to add MISC irqdomain");
......@@ -288,9 +275,19 @@ static int __init ath79_misc_intc_of_init(
__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain);
}
irq_set_chained_handler(irq, ath79_misc_irq_handler);
static int __init ath79_misc_intc_of_init(
struct device_node *node, struct device_node *parent)
{
int irq;
irq = irq_of_parse_and_map(node, 0);
if (!irq)
panic("Failed to get MISC IRQ");
ath79_misc_intc_domain_init(node, irq);
return 0;
}
......@@ -349,8 +346,6 @@ static int __init ar79_cpu_intc_of_init(
IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
ar79_cpu_intc_of_init);
#endif
void __init arch_init_irq(void)
{
if (mips_machtype == ATH79_MACH_GENERIC_OF) {
......
......@@ -36,10 +36,6 @@
#define ATH79_SYS_TYPE_LEN 64
#define AR71XX_BASE_FREQ 40000000
#define AR724X_BASE_FREQ 5000000
#define AR913X_BASE_FREQ 5000000
static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
static void ath79_restart(char *command)
......@@ -272,15 +268,10 @@ void __init device_tree_init(void)
unflatten_and_copy_device_tree();
}
static void __init ath79_generic_init(void)
{
/* Nothing to do */
}
MIPS_MACHINE(ATH79_MACH_GENERIC,
"Generic",
"Generic AR71XX/AR724X/AR913X based board",
ath79_generic_init);
NULL);
MIPS_MACHINE(ATH79_MACH_GENERIC_OF,
"DTB",
......
......@@ -666,9 +666,15 @@ static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
switch (bus->hosttype) {
case BCMA_HOSTTYPE_PCI:
memset(out, 0, sizeof(struct ssb_sprom));
snprintf(buf, sizeof(buf), "pci/%u/%u/",
bus->host_pci->bus->number + 1,
PCI_SLOT(bus->host_pci->devfn));
/* On BCM47XX all PCI buses share the same domain */
if (config_enabled(CONFIG_BCM47XX))
snprintf(buf, sizeof(buf), "pci/%u/%u/",
bus->host_pci->bus->number + 1,
PCI_SLOT(bus->host_pci->devfn));
else
snprintf(buf, sizeof(buf), "pci/%u/%u/",
pci_domain_nr(bus->host_pci->bus) + 1,
bus->host_pci->bus->number);
bcm47xx_sprom_apply_prefix_alias(buf, sizeof(buf));
prefix = buf;
break;
......
......@@ -10,6 +10,7 @@
#define pr_fmt(fmt) "bcm63xx_nvram: " fmt
#include <linux/bcm963xx_nvram.h>
#include <linux/init.h>
#include <linux/crc32.h>
#include <linux/export.h>
......@@ -18,51 +19,19 @@
#include <bcm63xx_nvram.h>
/*
* nvram structure
*/
struct bcm963xx_nvram {
u32 version;
u8 reserved1[256];
u8 name[16];
u32 main_tp_number;
u32 psi_size;
u32 mac_addr_count;
u8 mac_addr_base[ETH_ALEN];
u8 reserved2[2];
u32 checksum_old;
u8 reserved3[720];
u32 checksum_high;
};
#define BCM63XX_DEFAULT_PSI_SIZE 64
static struct bcm963xx_nvram nvram;
static int mac_addr_used;
void __init bcm63xx_nvram_init(void *addr)
{
unsigned int check_len;
u32 crc, expected_crc;
u8 hcs_mac_addr[ETH_ALEN] = { 0x00, 0x10, 0x18, 0xff, 0xff, 0xff };
/* extract nvram data */
memcpy(&nvram, addr, sizeof(nvram));
memcpy(&nvram, addr, BCM963XX_NVRAM_V5_SIZE);
/* check checksum before using data */
if (nvram.version <= 4) {
check_len = offsetof(struct bcm963xx_nvram, reserved3);
expected_crc = nvram.checksum_old;
nvram.checksum_old = 0;
} else {
check_len = sizeof(nvram);
expected_crc = nvram.checksum_high;
nvram.checksum_high = 0;
}
crc = crc32_le(~0, (u8 *)&nvram, check_len);
if (crc != expected_crc)
if (bcm963xx_nvram_checksum(&nvram, &expected_crc, &crc))
pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n",
expected_crc, crc);
......@@ -116,12 +85,3 @@ int bcm63xx_nvram_get_mac_address(u8 *mac)
return 0;
}
EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address);
int bcm63xx_nvram_get_psi_size(void)
{
if (nvram.psi_size > 0)
return nvram.psi_size;
return BCM63XX_DEFAULT_PSI_SIZE;
}
EXPORT_SYMBOL(bcm63xx_nvram_get_psi_size);
......@@ -105,6 +105,7 @@ static const struct bmips_quirk bmips_quirk_list[] = {
{ "brcm,bcm33843-viper", &bcm3384_viper_quirks },
{ "brcm,bcm6328", &bcm6328_quirks },
{ "brcm,bcm6368", &bcm6368_quirks },
{ "brcm,bcm63168", &bcm6368_quirks },
{ },
};
......
......@@ -29,20 +29,23 @@ KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
-DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS)
targets := head.o decompress.o string.o dbg.o uart-16550.o uart-alchemy.o
# decompressor objects (linked with vmlinuz)
vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o
ifdef CONFIG_DEBUG_ZBOOT
vmlinuzobjs-$(CONFIG_DEBUG_ZBOOT) += $(obj)/dbg.o
vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM) += $(obj)/uart-prom.o
vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY) += $(obj)/uart-alchemy.o
endif
ifdef CONFIG_KERNEL_XZ
vmlinuzobjs-y += $(obj)/../../lib/ashldi3.o
endif
vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o
$(obj)/ashldi3.o: KBUILD_CFLAGS += -I$(srctree)/arch/mips/lib
$(obj)/ashldi3.c: $(srctree)/arch/mips/lib/ashldi3.c
$(call cmd,shipped)
targets := $(notdir $(vmlinuzobjs-y))
targets += vmlinux.bin
OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
......@@ -60,7 +63,7 @@ targets += vmlinux.bin.z
$(obj)/vmlinux.bin.z: $(obj)/vmlinux.bin FORCE
$(call if_changed,$(tool_y))
targets += piggy.o
targets += piggy.o dummy.o
OBJCOPYFLAGS_piggy.o := --add-section=.image=$(obj)/vmlinux.bin.z \
--set-section-flags=.image=contents,alloc,load,readonly,data
$(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE
......
extern void prom_putchar(unsigned char ch);
void putc(char c)
{
prom_putchar(c);
}
......@@ -4,6 +4,7 @@ dts-dirs += ingenic
dts-dirs += lantiq
dts-dirs += mti
dts-dirs += netlogic
dts-dirs += pic32
dts-dirs += qca
dts-dirs += ralink
dts-dirs += xilfpga
......
......@@ -31,6 +31,7 @@ periph_clk: periph_clk {
};
aliases {
leds0 = &leds0;
uart0 = &uart0;
};
......@@ -81,5 +82,13 @@ reboot {
offset = <0x28>;
mask = <0x1>;
};
leds0: led-controller@10000800 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,bcm6328-leds";
reg = <0x10000800 0x24>;
status = "disabled";
};
};
};
......@@ -32,6 +32,7 @@ periph_clk: periph_clk {
};
aliases {
leds0 = &leds0;
uart0 = &uart0;
};
......@@ -50,6 +51,19 @@ ubus {
compatible = "simple-bus";
ranges;
periph_cntl: syscon@10000000 {
compatible = "syscon";
reg = <0x10000000 0x14>;
little-endian;
};
reboot: syscon-reboot@10000008 {
compatible = "syscon-reboot";
regmap = <&periph_cntl>;
offset = <0x8>;
mask = <0x1>;
};
periph_intc: periph_intc@10000020 {
compatible = "brcm,bcm3380-l2-intc";
reg = <0x10000024 0x4 0x1000002c 0x4>,
......@@ -62,6 +76,14 @@ periph_intc: periph_intc@10000020 {
interrupts = <2>;
};
leds0: led-controller@100000d0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,bcm6358-leds";
reg = <0x100000d0 0x8>;
status = "disabled";
};
uart0: serial@10000100 {
compatible = "brcm,bcm6345-uart";
reg = <0x10000100 0x18>;
......
......@@ -42,3 +42,67 @@ &uart3 {
&uart4 {
status = "okay";
};
&nemc {
status = "okay";
nandc: nand-controller@1 {
compatible = "ingenic,jz4780-nand";
reg = <1 0 0x1000000>;
#address-cells = <1>;
#size-cells = <0>;
ingenic,bch-controller = <&bch>;
ingenic,nemc-tAS = <10>;
ingenic,nemc-tAH = <5>;
ingenic,nemc-tBP = <10>;
ingenic,nemc-tAW = <15>;
ingenic,nemc-tSTRV = <100>;
nand@1 {
reg = <1>;
nand-ecc-step-size = <1024>;
nand-ecc-strength = <24>;
nand-ecc-mode = "hw";
nand-on-flash-bbt;
partitions {
compatible = "fixed-partitions";
#address-cells = <2>;
#size-cells = <2>;
partition@0 {
label = "u-boot-spl";
reg = <0x0 0x0 0x0 0x800000>;
};
partition@0x800000 {
label = "u-boot";
reg = <0x0 0x800000 0x0 0x200000>;
};
partition@0xa00000 {
label = "u-boot-env";
reg = <0x0 0xa00000 0x0 0x200000>;
};
partition@0xc00000 {
label = "boot";
reg = <0x0 0xc00000 0x0 0x4000000>;
};
partition@0x8c00000 {
label = "system";
reg = <0x0 0x4c00000 0x1 0xfb400000>;
};
};
};
};
};
&bch {
status = "okay";
};
......@@ -108,4 +108,30 @@ uart4: serial@10034000 {
status = "disabled";
};
nemc: nemc@13410000 {
compatible = "ingenic,jz4780-nemc";
reg = <0x13410000 0x10000>;
#address-cells = <2>;
#size-cells = <1>;
ranges = <1 0 0x1b000000 0x1000000
2 0 0x1a000000 0x1000000
3 0 0x19000000 0x1000000
4 0 0x18000000 0x1000000
5 0 0x17000000 0x1000000
6 0 0x16000000 0x1000000>;
clocks = <&cgu JZ4780_CLK_NEMC>;
status = "disabled";
};
bch: bch@134d0000 {
compatible = "ingenic,jz4780-bch";
reg = <0x134d0000 0x10000>;
clocks = <&cgu JZ4780_CLK_BCH>;
status = "disabled";
};
};
dtb-$(CONFIG_DTB_PIC32_MZDA_SK) += pic32mzda_sk.dtb
dtb-$(CONFIG_DTB_PIC32_NONE) += \
pic32mzda_sk.dtb
obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
# Force kbuild to make empty built-in.o if necessary
obj- += dummy.o
always := $(dtb-y)
clean-files := *.dtb *.dtb.S
/*
* Device Tree Source for PIC32MZDA clock data
*
* Purna Chandra Mandal <purna.mandal@microchip.com>
* Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
*
* Licensed under GPLv2 or later.
*/
/* all fixed rate clocks */
/ {
POSC:posc_clk { /* On-chip primary oscillator */
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
};
FRC:frc_clk { /* internal FRC oscillator */
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <8000000>;
};
BFRC:bfrc_clk { /* internal backup FRC oscillator */
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <8000000>;
};
LPRC:lprc_clk { /* internal low-power FRC oscillator */
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32000>;
};
/* UPLL provides clock to USBCORE */
UPLL:usb_phy_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
clock-output-names = "usbphy_clk";
};
TxCKI:txcki_clk { /* external clock input on TxCLKI pin */
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <4000000>;
status = "disabled";
};
/* external clock input on REFCLKIx pin */
REFIx:refix_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
status = "disabled";
};
/* PIC32 specific clks */
pic32_clktree {
#address-cells = <1>;
#size-cells = <1>;
reg = <0x1f801200 0x200>;
compatible = "microchip,pic32mzda-clk";
ranges = <0 0x1f801200 0x200>;
/* secondary oscillator; external input on SOSCI pin */
SOSC:sosc_clk@0 {
#clock-cells = <0>;
compatible = "microchip,pic32mzda-sosc";
clock-frequency = <32768>;
reg = <0x000 0x10>, /* enable reg */
<0x1d0 0x10>; /* status reg */
microchip,bit-mask = <0x02>; /* enable mask */
microchip,status-bit-mask = <0x10>; /* status-mask*/
};
FRCDIV:frcdiv_clk {
#clock-cells = <0>;
compatible = "microchip,pic32mzda-frcdivclk";
clocks = <&FRC>;
clock-output-names = "frcdiv_clk";
};
/* System PLL clock */
SYSPLL:spll_clk@020 {
#clock-cells = <0>;
compatible = "microchip,pic32mzda-syspll";
reg = <0x020 0x10>, /* SPLL register */
<0x1d0 0x10>; /* CLKSTAT register */
clocks = <&POSC>, <&FRC>;
clock-output-names = "sys_pll";
microchip,status-bit-mask = <0x80>; /* SPLLRDY */
};
/* system clock; mux with postdiv & slew */
SYSCLK:sys_clk@1c0 {
#clock-cells = <0>;
compatible = "microchip,pic32mzda-sysclk-v2";
reg = <0x1c0 0x04>; /* SLEWCON */
clocks = <&FRCDIV>, <&SYSPLL>, <&POSC>, <&SOSC>,
<&LPRC>, <&FRCDIV>;
microchip,clock-indices = <0>, <1>, <2>, <4>,
<5>, <7>;
clock-output-names = "sys_clk";
};
/* Peripheral bus1 clock */
PBCLK1:pb1_clk@140 {
reg = <0x140 0x10>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-pbclk";
clocks = <&SYSCLK>;
clock-output-names = "pb1_clk";
/* used by system modules, not gateable */
microchip,ignore-unused;
};
/* Peripheral bus2 clock */
PBCLK2:pb2_clk@150 {
reg = <0x150 0x10>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-pbclk";
clocks = <&SYSCLK>;
clock-output-names = "pb2_clk";
/* avoid gating even if unused */
microchip,ignore-unused;
};
/* Peripheral bus3 clock */
PBCLK3:pb3_clk@160 {
reg = <0x160 0x10>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-pbclk";
clocks = <&SYSCLK>;
clock-output-names = "pb3_clk";
};
/* Peripheral bus4 clock(I/O ports, GPIO) */
PBCLK4:pb4_clk@170 {
reg = <0x170 0x10>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-pbclk";
clocks = <&SYSCLK>;
clock-output-names = "pb4_clk";
};
/* Peripheral bus clock */
PBCLK5:pb5_clk@180 {
reg = <0x180 0x10>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-pbclk";
clocks = <&SYSCLK>;
clock-output-names = "pb5_clk";
};
/* Peripheral Bus6 clock; */
PBCLK6:pb6_clk@190 {
reg = <0x190 0x10>;
compatible = "microchip,pic32mzda-pbclk";
clocks = <&SYSCLK>;
#clock-cells = <0>;
};
/* Peripheral bus7 clock */
PBCLK7:pb7_clk@1a0 {
reg = <0x1a0 0x10>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-pbclk";
/* CPU is driven by this clock; so named */
clock-output-names = "cpu_clk";
clocks = <&SYSCLK>;
};
/* Reference Oscillator clock for SPI/I2S */
REFCLKO1:refo1_clk@80 {
reg = <0x080 0x20>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-refoclk";
clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
<&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
<5>, <7>, <8>, <9>;
clock-output-names = "refo1_clk";
};
/* Reference Oscillator clock for SQI */
REFCLKO2:refo2_clk@a0 {
reg = <0x0a0 0x20>;
#clock-cells = <0>;
compatible = "microchip,pic32mzda-refoclk";
clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
<&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
<5>, <7>, <8>, <9>;
clock-output-names = "refo2_clk";
};
/* Reference Oscillator clock, ADC */
REFCLKO3:refo3_clk@c0 {
reg = <0x0c0 0x20>;
compatible = "microchip,pic32mzda-refoclk";
clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
<&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
<5>, <7>, <8>, <9>;
#clock-cells = <0>;
clock-output-names = "refo3_clk";
};
/* Reference Oscillator clock */
REFCLKO4:refo4_clk@e0 {
reg = <0x0e0 0x20>;
compatible = "microchip,pic32mzda-refoclk";
clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
<&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
<5>, <7>, <8>, <9>;
#clock-cells = <0>;
clock-output-names = "refo4_clk";
};
/* Reference Oscillator clock, LCD */
REFCLKO5:refo5_clk@100 {
reg = <0x100 0x20>;
compatible = "microchip,pic32mzda-refoclk";
clocks = <&SYSCLK>,<&PBCLK1>,<&POSC>,<&FRC>,<&LPRC>,
<&SOSC>,<&SYSPLL>,<&REFIx>,<&BFRC>;
microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
<5>, <7>, <8>, <9>;
#clock-cells = <0>;
clock-output-names = "refo5_clk";
};
};
};
/*
* Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <dt-bindings/interrupt-controller/irq.h>
#include "pic32mzda-clk.dtsi"
/ {
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&evic>;
aliases {
gpio0 = &gpio0;
gpio1 = &gpio1;
gpio2 = &gpio2;
gpio3 = &gpio3;
gpio4 = &gpio4;
gpio5 = &gpio5;
gpio6 = &gpio6;
gpio7 = &gpio7;
gpio8 = &gpio8;
gpio9 = &gpio9;
serial0 = &uart1;
serial1 = &uart2;
serial2 = &uart3;
serial3 = &uart4;
serial4 = &uart5;
serial5 = &uart6;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
compatible = "mti,mips14KEc";
device_type = "cpu";
};
};
soc {
compatible = "microchip,pic32mzda-infra";
interrupts = <0 IRQ_TYPE_EDGE_RISING>;
};
evic: interrupt-controller@1f810000 {
compatible = "microchip,pic32mzda-evic";
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x1f810000 0x1000>;
microchip,external-irqs = <3 8 13 18 23>;
};
pic32_pinctrl: pinctrl@1f801400{
#address-cells = <1>;
#size-cells = <1>;
compatible = "microchip,pic32mzda-pinctrl";
reg = <0x1f801400 0x400>;
clocks = <&PBCLK1>;
};
/* PORTA */
gpio0: gpio0@1f860000 {
compatible = "microchip,pic32mzda-gpio";
reg = <0x1f860000 0x100>;
interrupts = <118 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
microchip,gpio-bank = <0>;
gpio-ranges = <&pic32_pinctrl 0 0 16>;
};
/* PORTB */
gpio1: gpio1@1f860100 {
compatible = "microchip,pic32mzda-gpio";
reg = <0x1f860100 0x100>;
interrupts = <119 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
microchip,gpio-bank = <1>;
gpio-ranges = <&pic32_pinctrl 0 16 16>;
};
/* PORTC */
gpio2: gpio2@1f860200 {
compatible = "microchip,pic32mzda-gpio";
reg = <0x1f860200 0x100>;
interrupts = <120 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
microchip,gpio-bank = <2>;
gpio-ranges = <&pic32_pinctrl 0 32 16>;
};
/* PORTD */
gpio3: gpio3@1f860300 {
compatible = "microchip,pic32mzda-gpio";
reg = <0x1f860300 0x100>;
interrupts = <121 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
microchip,gpio-bank = <3>;
gpio-ranges = <&pic32_pinctrl 0 48 16>;
};
/* PORTE */
gpio4: gpio4@1f860400 {
compatible = "microchip,pic32mzda-gpio";
reg = <0x1f860400 0x100>;
interrupts = <122 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
microchip,gpio-bank = <4>;
gpio-ranges = <&pic32_pinctrl 0 64 16>;
};
/* PORTF */
gpio5: gpio5@1f860500 {
compatible = "microchip,pic32mzda-gpio";
reg = <0x1f860500 0x100>;
interrupts = <123 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
microchip,gpio-bank = <5>;
gpio-ranges = <&pic32_pinctrl 0 80 16>;
};
/* PORTG */
gpio6: gpio6@1f860600 {
compatible = "microchip,pic32mzda-gpio";
reg = <0x1f860600 0x100>;
interrupts = <124 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
microchip,gpio-bank = <6>;
gpio-ranges = <&pic32_pinctrl 0 96 16>;
};
/* PORTH */
gpio7: gpio7@1f860700 {
compatible = "microchip,pic32mzda-gpio";
reg = <0x1f860700 0x100>;
interrupts = <125 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
microchip,gpio-bank = <7>;
gpio-ranges = <&pic32_pinctrl 0 112 16>;
};
/* PORTI does not exist */
/* PORTJ */
gpio8: gpio8@1f860800 {
compatible = "microchip,pic32mzda-gpio";
reg = <0x1f860800 0x100>;
interrupts = <126 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
microchip,gpio-bank = <8>;
gpio-ranges = <&pic32_pinctrl 0 128 16>;
};
/* PORTK */
gpio9: gpio9@1f860900 {
compatible = "microchip,pic32mzda-gpio";
reg = <0x1f860900 0x100>;
interrupts = <127 IRQ_TYPE_LEVEL_HIGH>;
#gpio-cells = <2>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
clocks = <&PBCLK4>;
microchip,gpio-bank = <9>;
gpio-ranges = <&pic32_pinctrl 0 144 16>;
};
sdhci: sdhci@1f8ec000 {
compatible = "microchip,pic32mzda-sdhci";
reg = <0x1f8ec000 0x100>;
interrupts = <191 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&REFCLKO4>, <&PBCLK5>;
clock-names = "base_clk", "sys_clk";
bus-width = <4>;
cap-sd-highspeed;
status = "disabled";
};
uart1: serial@1f822000 {
compatible = "microchip,pic32mzda-uart";
reg = <0x1f822000 0x50>;
interrupts = <112 IRQ_TYPE_LEVEL_HIGH>,
<113 IRQ_TYPE_LEVEL_HIGH>,
<114 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&PBCLK2>;
status = "disabled";
};
uart2: serial@1f822200 {
compatible = "microchip,pic32mzda-uart";
reg = <0x1f822200 0x50>;
interrupts = <145 IRQ_TYPE_LEVEL_HIGH>,
<146 IRQ_TYPE_LEVEL_HIGH>,
<147 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&PBCLK2>;
status = "disabled";
};
uart3: serial@1f822400 {
compatible = "microchip,pic32mzda-uart";
reg = <0x1f822400 0x50>;
interrupts = <157 IRQ_TYPE_LEVEL_HIGH>,
<158 IRQ_TYPE_LEVEL_HIGH>,
<159 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&PBCLK2>;
status = "disabled";
};
uart4: serial@1f822600 {
compatible = "microchip,pic32mzda-uart";
reg = <0x1f822600 0x50>;
interrupts = <170 IRQ_TYPE_LEVEL_HIGH>,
<171 IRQ_TYPE_LEVEL_HIGH>,
<172 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&PBCLK2>;
status = "disabled";
};
uart5: serial@1f822800 {
compatible = "microchip,pic32mzda-uart";
reg = <0x1f822800 0x50>;
interrupts = <179 IRQ_TYPE_LEVEL_HIGH>,
<180 IRQ_TYPE_LEVEL_HIGH>,
<181 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&PBCLK2>;
status = "disabled";
};
uart6: serial@1f822A00 {
compatible = "microchip,pic32mzda-uart";
reg = <0x1f822A00 0x50>;
interrupts = <188 IRQ_TYPE_LEVEL_HIGH>,
<189 IRQ_TYPE_LEVEL_HIGH>,
<190 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&PBCLK2>;
status = "disabled";
};
};
/*
* Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
*
* 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.
*
*/
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include "pic32mzda.dtsi"
/ {
compatible = "microchip,pic32mzda-sk", "microchip,pic32mzda";
model = "Microchip PIC32MZDA Starter Kit";
memory {
device_type = "memory";
reg = <0x08000000 0x08000000>;
};
chosen {
bootargs = "earlyprintk=ttyPIC1,115200n8r console=ttyPIC1,115200n8";
};
leds0 {
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 = <&user_leds_s0>;
led@1 {
label = "pic32mzda_sk:red:led1";
gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
};
led@2 {
label = "pic32mzda_sk:yellow:led2";
gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "mmc0";
};
led@3 {
label = "pic32mzda_sk:green:led3";
gpios = <&gpio7 2 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
};
keys0 {
compatible = "gpio-keys";
pinctrl-0 = <&user_buttons_s0>;
pinctrl-names = "default";
#address-cells = <1>;
#size-cells = <0>;
button@sw1 {
label = "ESC";
linux,code = <1>;
gpios = <&gpio1 12 0>;
};
button@sw2 {
label = "Home";
linux,code = <102>;
gpios = <&gpio1 13 0>;
};
button@sw3 {
label = "Menu";
linux,code = <139>;
gpios = <&gpio1 14 0>;
};
};
};
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
status = "okay";
};
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart4>;
status = "okay";
};
&sdhci {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sdhc1>;
status = "okay";
assigned-clocks = <&REFCLKO2>,<&REFCLKO4>,<&REFCLKO5>;
assigned-clock-rates = <50000000>,<25000000>,<40000000>;
};
&pic32_pinctrl {
pinctrl_sdhc1: sdhc1_pins0 {
pins = "A6", "D4", "G13", "G12", "G14", "A7", "A0";
microchip,digital;
};
user_leds_s0: user_leds_s0 {
pins = "H0", "H1", "H2";
output-low;
microchip,digital;
};
user_buttons_s0: user_buttons_s0 {
pins = "B12", "B13", "B14";
microchip,digital;
input-enable;
bias-pull-up;
};
pinctrl_uart2: pinctrl_uart2 {
uart2-tx {
pins = "G9";
function = "U2TX";
microchip,digital;
output-high;
};
uart2-rx {
pins = "B0";
function = "U2RX";
microchip,digital;
input-enable;
};
};
pinctrl_uart4: uart4-0 {
uart4-tx {
pins = "C3";
function = "U4TX";
microchip,digital;
output-high;
};
uart4-rx {
pins = "E8";
function = "U4RX";
microchip,digital;
input-enable;
};
};
};
......@@ -125,6 +125,21 @@ rst: reset-controller@1806001c {
};
};
usb@1b000100 {
compatible = "qca,ar7100-ehci", "generic-ehci";
reg = <0x1b000100 0x100>;
interrupts = <3>;
resets = <&rst 5>;
has-transaction-translator;
phy-names = "usb";
phys = <&usb_phy>;
status = "disabled";
};
spi@1f000000 {
compatible = "qca,ar9132-spi", "qca,ar7100-spi";
reg = <0x1f000000 0x10>;
......@@ -138,4 +153,15 @@ spi@1f000000 {
#size-cells = <0>;
};
};
usb_phy: usb-phy {
compatible = "qca,ar7100-usb-phy";
reset-names = "usb-phy", "usb-suspend-override";
resets = <&rst 4>, <&rst 3>;
#phy-cells = <0>;
status = "disabled";
};
};
......@@ -35,6 +35,10 @@ pll-controller@18050000 {
};
};
usb@1b000100 {
status = "okay";
};
spi@1f000000 {
status = "okay";
num-cs = <1>;
......@@ -65,6 +69,10 @@ partition@2 {
};
};
usb-phy {
status = "okay";
};
gpio-keys {
compatible = "gpio-keys-polled";
#address-cells = <1>;
......
CONFIG_MACH_PIC32=y
CONFIG_DTB_PIC32_MZDA_SK=y
CONFIG_HZ_100=y
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_SECCOMP is not set
CONFIG_SYSVIPC=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_RELAY=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_SLAB=y
CONFIG_JUMP_LABEL=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_BLK_DEV_BSGLIB=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_SGI_PARTITION=y
CONFIG_BINFMT_MISC=m
# CONFIG_SUSPEND is not set
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_FIRMWARE_IN_KERNEL is not set
# CONFIG_ALLOW_DEV_COREDUMP is not set
CONFIG_BLK_DEV_LOOP=m
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_SCAN_ASYNC=y
# CONFIG_SCSI_LOWLEVEL is not set
CONFIG_INPUT_LEDS=m
CONFIG_INPUT_POLLDEV=y
CONFIG_INPUT_MOUSEDEV=m
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=m
# CONFIG_KEYBOARD_ATKBD is not set
CONFIG_KEYBOARD_GPIO=m
CONFIG_KEYBOARD_GPIO_POLLED=m
# CONFIG_MOUSE_PS2 is not set
# CONFIG_SERIO is not set
CONFIG_SERIAL_PIC32=y
CONFIG_SERIAL_PIC32_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_RAW_DRIVER=m
CONFIG_GPIO_SYSFS=y
# CONFIG_HWMON is not set
CONFIG_HIDRAW=y
# CONFIG_USB_SUPPORT is not set
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_MICROCHIP_PIC32=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_ONESHOT=m
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_GPIO=m
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
# CONFIG_MIPS_PLATFORM_DEVICES is not set
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=m
CONFIG_FSCACHE=m
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_SQUASHFS=m
CONFIG_SQUASHFS_XATTR=y
CONFIG_SQUASHFS_LZ4=y
CONFIG_SQUASHFS_LZO=y
CONFIG_SQUASHFS_XZ=y
......@@ -11,55 +11,77 @@
#ifndef __ASM_CACHEOPS_H
#define __ASM_CACHEOPS_H
/*
* Most cache ops are split into a 2 bit field identifying the cache, and a 3
* bit field identifying the cache operation.
*/
#define CacheOp_Cache 0x03
#define CacheOp_Op 0x1c
#define Cache_I 0x00
#define Cache_D 0x01
#define Cache_T 0x02
#define Cache_S 0x03
#define Index_Writeback_Inv 0x00
#define Index_Load_Tag 0x04
#define Index_Store_Tag 0x08
#define Hit_Invalidate 0x10
#define Hit_Writeback_Inv 0x14 /* not with Cache_I though */
#define Hit_Writeback 0x18
/*
* Cache Operations available on all MIPS processors with R4000-style caches
*/
#define Index_Invalidate_I 0x00
#define Index_Writeback_Inv_D 0x01
#define Index_Load_Tag_I 0x04
#define Index_Load_Tag_D 0x05
#define Index_Store_Tag_I 0x08
#define Index_Store_Tag_D 0x09
#define Hit_Invalidate_I 0x10
#define Hit_Invalidate_D 0x11
#define Hit_Writeback_Inv_D 0x15
#define Index_Invalidate_I (Cache_I | Index_Writeback_Inv)
#define Index_Writeback_Inv_D (Cache_D | Index_Writeback_Inv)
#define Index_Load_Tag_I (Cache_I | Index_Load_Tag)
#define Index_Load_Tag_D (Cache_D | Index_Load_Tag)
#define Index_Store_Tag_I (Cache_I | Index_Store_Tag)
#define Index_Store_Tag_D (Cache_D | Index_Store_Tag)
#define Hit_Invalidate_I (Cache_I | Hit_Invalidate)
#define Hit_Invalidate_D (Cache_D | Hit_Invalidate)
#define Hit_Writeback_Inv_D (Cache_D | Hit_Writeback_Inv)
/*
* R4000-specific cacheops
*/
#define Create_Dirty_Excl_D 0x0d
#define Fill 0x14
#define Hit_Writeback_I 0x18
#define Hit_Writeback_D 0x19
#define Create_Dirty_Excl_D (Cache_D | 0x0c)
#define Fill (Cache_I | 0x14)
#define Hit_Writeback_I (Cache_I | Hit_Writeback)
#define Hit_Writeback_D (Cache_D | Hit_Writeback)
/*
* R4000SC and R4400SC-specific cacheops
*/
#define Index_Invalidate_SI 0x02
#define Index_Writeback_Inv_SD 0x03
#define Index_Load_Tag_SI 0x06
#define Index_Load_Tag_SD 0x07
#define Index_Store_Tag_SI 0x0A
#define Index_Store_Tag_SD 0x0B
#define Create_Dirty_Excl_SD 0x0f
#define Hit_Invalidate_SI 0x12
#define Hit_Invalidate_SD 0x13
#define Hit_Writeback_Inv_SD 0x17
#define Hit_Writeback_SD 0x1b
#define Hit_Set_Virtual_SI 0x1e
#define Hit_Set_Virtual_SD 0x1f
#define Cache_SI 0x02
#define Cache_SD 0x03
#define Index_Invalidate_SI (Cache_SI | Index_Writeback_Inv)
#define Index_Writeback_Inv_SD (Cache_SD | Index_Writeback_Inv)
#define Index_Load_Tag_SI (Cache_SI | Index_Load_Tag)
#define Index_Load_Tag_SD (Cache_SD | Index_Load_Tag)
#define Index_Store_Tag_SI (Cache_SI | Index_Store_Tag)
#define Index_Store_Tag_SD (Cache_SD | Index_Store_Tag)
#define Create_Dirty_Excl_SD (Cache_SD | 0x0c)
#define Hit_Invalidate_SI (Cache_SI | Hit_Invalidate)
#define Hit_Invalidate_SD (Cache_SD | Hit_Invalidate)
#define Hit_Writeback_Inv_SD (Cache_SD | Hit_Writeback_Inv)
#define Hit_Writeback_SD (Cache_SD | Hit_Writeback)
#define Hit_Set_Virtual_SI (Cache_SI | 0x1c)
#define Hit_Set_Virtual_SD (Cache_SD | 0x1c)
/*
* R5000-specific cacheops
*/
#define R5K_Page_Invalidate_S 0x17
#define R5K_Page_Invalidate_S (Cache_S | 0x14)
/*
* RM7000-specific cacheops
*/
#define Page_Invalidate_T 0x16
#define Index_Store_Tag_T 0x0a
#define Index_Load_Tag_T 0x06
#define Page_Invalidate_T (Cache_T | 0x14)
#define Index_Store_Tag_T (Cache_T | Index_Store_Tag)
#define Index_Load_Tag_T (Cache_T | Index_Load_Tag)
/*
* R10000-specific cacheops
......@@ -67,22 +89,22 @@
* Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused.
* Most of the _S cacheops are identical to the R4000SC _SD cacheops.
*/
#define Index_Writeback_Inv_S 0x03
#define Index_Load_Tag_S 0x07
#define Index_Store_Tag_S 0x0B
#define Hit_Invalidate_S 0x13
#define Index_Writeback_Inv_S (Cache_S | Index_Writeback_Inv)
#define Index_Load_Tag_S (Cache_S | Index_Load_Tag)
#define Index_Store_Tag_S (Cache_S | Index_Store_Tag)
#define Hit_Invalidate_S (Cache_S | Hit_Invalidate)
#define Cache_Barrier 0x14
#define Hit_Writeback_Inv_S 0x17
#define Index_Load_Data_I 0x18
#define Index_Load_Data_D 0x19
#define Index_Load_Data_S 0x1b
#define Index_Store_Data_I 0x1c
#define Index_Store_Data_D 0x1d
#define Index_Store_Data_S 0x1f
#define Hit_Writeback_Inv_S (Cache_S | Hit_Writeback_Inv)
#define Index_Load_Data_I (Cache_I | 0x18)
#define Index_Load_Data_D (Cache_D | 0x18)
#define Index_Load_Data_S (Cache_S | 0x18)
#define Index_Store_Data_I (Cache_I | 0x1c)
#define Index_Store_Data_D (Cache_D | 0x1c)
#define Index_Store_Data_S (Cache_S | 0x1c)
/*
* Loongson2-specific cacheops
*/
#define Hit_Invalidate_I_Loongson2 0x00
#define Hit_Invalidate_I_Loongson2 (Cache_I | 0x00)
#endif /* __ASM_CACHEOPS_H */
......@@ -414,4 +414,11 @@
# define cpu_has_small_pages (cpu_data[0].options & MIPS_CPU_SP)
#endif
#ifndef cpu_has_nan_legacy
#define cpu_has_nan_legacy (cpu_data[0].options & MIPS_CPU_NAN_LEGACY)
#endif
#ifndef cpu_has_nan_2008
#define cpu_has_nan_2008 (cpu_data[0].options & MIPS_CPU_NAN_2008)
#endif
#endif /* __ASM_CPU_FEATURES_H */
......@@ -386,6 +386,8 @@ enum cpu_type_enum {
#define MIPS_CPU_BP_GHIST 0x8000000000ull /* R12K+ Branch Prediction Global History */
#define MIPS_CPU_SP 0x10000000000ull /* Small (1KB) page support */
#define MIPS_CPU_FTLB 0x20000000000ull /* CPU has Fixed-page-size TLB */
#define MIPS_CPU_NAN_LEGACY 0x40000000000ull /* Legacy NaN implemented */
#define MIPS_CPU_NAN_2008 0x80000000000ull /* 2008 NaN implemented */
/*
* CPU ASE encodings
......
......@@ -12,7 +12,6 @@
#include <linux/fs.h>
#include <uapi/linux/elf.h>
#include <asm/cpu-info.h>
#include <asm/current.h>
/* ELF header e_flags defines. */
......@@ -44,6 +43,7 @@
#define EF_MIPS_OPTIONS_FIRST 0x00000080
#define EF_MIPS_32BITMODE 0x00000100
#define EF_MIPS_FP64 0x00000200
#define EF_MIPS_NAN2008 0x00000400
#define EF_MIPS_ABI 0x0000f000
#define EF_MIPS_ARCH 0xf0000000
......@@ -305,7 +305,7 @@ do { \
\
current->thread.abi = &mips_abi; \
\
current->thread.fpu.fcr31 = boot_cpu_data.fpu_csr31; \
mips_set_personality_nan(state); \
} while (0)
#endif /* CONFIG_32BIT */
......@@ -367,7 +367,7 @@ do { \
else \
current->thread.abi = &mips_abi; \
\
current->thread.fpu.fcr31 = boot_cpu_data.fpu_csr31; \
mips_set_personality_nan(state); \
\
p = personality(current->personality); \
if (p != PER_LINUX32 && p != PER_LINUX) \
......@@ -432,6 +432,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
int uses_interp);
struct arch_elf_state {
int nan_2008;
int fp_abi;
int interp_fp_abi;
int overall_fp_mode;
......@@ -440,17 +441,23 @@ struct arch_elf_state {
#define MIPS_ABI_FP_UNKNOWN (-1) /* Unknown FP ABI (kernel internal) */
#define INIT_ARCH_ELF_STATE { \
.nan_2008 = -1, \
.fp_abi = MIPS_ABI_FP_UNKNOWN, \
.interp_fp_abi = MIPS_ABI_FP_UNKNOWN, \
.overall_fp_mode = -1, \
}
/* Whether to accept legacy-NaN and 2008-NaN user binaries. */
extern bool mips_use_nan_legacy;
extern bool mips_use_nan_2008;
extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf,
bool is_interp, struct arch_elf_state *state);
extern int arch_check_elf(void *ehdr, bool has_interpreter,
extern int arch_check_elf(void *ehdr, bool has_interpreter, void *interp_ehdr,
struct arch_elf_state *state);
extern void mips_set_personality_nan(struct arch_elf_state *state);
extern void mips_set_personality_fp(struct arch_elf_state *state);
#endif /* _ASM_ELF_H */
......@@ -79,7 +79,7 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
/*
* Break instruction with special math emu break code set
*/
#define BREAK_MATH (0x0000000d | (BRK_MEMU << 16))
#define BREAK_MATH(micromips) (((micromips) ? 0x7 : 0xd) | (BRK_MEMU << 16))
#define SIGNALLING_NAN 0x7ff800007ff80000LL
......
......@@ -275,6 +275,7 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
*/
#define ioremap_cachable(offset, size) \
__ioremap_mode((offset), (size), _page_cachable_default)
#define ioremap_cache ioremap_cachable
/*
* These two are MIPS specific ioremap variant. ioremap_cacheable_cow
......
......@@ -84,41 +84,11 @@ static inline void arch_local_irq_restore(unsigned long flags)
: "memory");
}
static inline void __arch_local_irq_restore(unsigned long flags)
{
__asm__ __volatile__(
" .set push \n"
" .set noreorder \n"
" .set noat \n"
#if defined(CONFIG_IRQ_MIPS_CPU)
/*
* Slow, but doesn't suffer from a relatively unlikely race
* condition we're having since days 1.
*/
" beqz %[flags], 1f \n"
" di \n"
" ei \n"
"1: \n"
#else
/*
* Fast, dangerous. Life is fun, life is good.
*/
" mfc0 $1, $12 \n"
" ins $1, %[flags], 0, 1 \n"
" mtc0 $1, $12 \n"
#endif
" " __stringify(__irq_disable_hazard) " \n"
" .set pop \n"
: [flags] "=r" (flags)
: "0" (flags)
: "memory");
}
#else
/* Functions that require preempt_{dis,en}able() are in mips-atomic.c */
void arch_local_irq_disable(void);
unsigned long arch_local_irq_save(void);
void arch_local_irq_restore(unsigned long flags);
void __arch_local_irq_restore(unsigned long flags);
#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
static inline void arch_local_irq_enable(void)
......
......@@ -58,7 +58,7 @@
#define KVM_MAX_VCPUS 1
#define KVM_USER_MEM_SLOTS 8
/* memory slots that does not exposed to userspace */
#define KVM_PRIVATE_MEM_SLOTS 0
#define KVM_PRIVATE_MEM_SLOTS 0
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
#define KVM_HALT_POLL_NS_DEFAULT 500000
......@@ -92,14 +92,6 @@
#define KVM_INVALID_INST 0xdeadbeef
#define KVM_INVALID_ADDR 0xdeadbeef
#define KVM_MALTA_GUEST_RTC_ADDR 0xb8000070UL
#define GUEST_TICKS_PER_JIFFY (40000000/HZ)
#define MS_TO_NS(x) (x * 1E6L)
#define CAUSEB_DC 27
#define CAUSEF_DC (_ULCAST_(1) << 27)
extern atomic_t kvm_mips_instance;
extern kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn);
extern void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn);
......@@ -289,34 +281,6 @@ enum mips_mmu_types {
MMU_TYPE_R8000
};
/*
* Trap codes
*/
#define T_INT 0 /* Interrupt pending */
#define T_TLB_MOD 1 /* TLB modified fault */
#define T_TLB_LD_MISS 2 /* TLB miss on load or ifetch */
#define T_TLB_ST_MISS 3 /* TLB miss on a store */
#define T_ADDR_ERR_LD 4 /* Address error on a load or ifetch */
#define T_ADDR_ERR_ST 5 /* Address error on a store */
#define T_BUS_ERR_IFETCH 6 /* Bus error on an ifetch */
#define T_BUS_ERR_LD_ST 7 /* Bus error on a load or store */
#define T_SYSCALL 8 /* System call */
#define T_BREAK 9 /* Breakpoint */
#define T_RES_INST 10 /* Reserved instruction exception */
#define T_COP_UNUSABLE 11 /* Coprocessor unusable */
#define T_OVFLOW 12 /* Arithmetic overflow */
/*
* Trap definitions added for r4000 port.
*/
#define T_TRAP 13 /* Trap instruction */
#define T_VCEI 14 /* Virtual coherency exception */
#define T_MSAFPE 14 /* MSA floating point exception */
#define T_FPE 15 /* Floating point exception */
#define T_MSADIS 21 /* MSA disabled exception */
#define T_WATCH 23 /* Watch address reference */
#define T_VCED 31 /* Virtual coherency data */
/* Resume Flags */
#define RESUME_FLAG_DR (1<<0) /* Reload guest nonvolatile state? */
#define RESUME_FLAG_HOST (1<<1) /* Resume host? */
......@@ -686,7 +650,6 @@ extern void kvm_mips_dump_host_tlbs(void);
extern void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu);
extern void kvm_mips_flush_host_tlb(int skip_kseg0);
extern int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long entryhi);
extern int kvm_mips_host_tlb_inv_index(struct kvm_vcpu *vcpu, int index);
extern int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu,
unsigned long entryhi);
......
......@@ -115,6 +115,7 @@ static inline int soc_is_qca955x(void)
return soc_is_qca9556() || soc_is_qca9558();
}
void ath79_ddr_wb_flush(unsigned int reg);
void ath79_ddr_set_pci_windows(void);
extern void __iomem *ath79_pll_base;
......
......@@ -30,6 +30,4 @@ u8 *bcm63xx_nvram_get_name(void);
*/
int bcm63xx_nvram_get_mac_address(u8 *mac);
int bcm63xx_nvram_get_psi_size(void);
#endif /* BCM63XX_NVRAM_H */
/*
* Joshua Henderson <joshua.henderson@microchip.com>
* Copyright (C) 2015 Microchip Technology Inc. All rights reserved.
*
* 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.
*/
#ifndef __ASM_MACH_PIC32_CPU_FEATURE_OVERRIDES_H
#define __ASM_MACH_PIC32_CPU_FEATURE_OVERRIDES_H
/*
* CPU feature overrides for PIC32 boards
*/
#ifdef CONFIG_CPU_MIPS32
#define cpu_has_vint 1
#define cpu_has_veic 0
#define cpu_has_tlb 1
#define cpu_has_4kex 1
#define cpu_has_4k_cache 1
#define cpu_has_fpu 0
#define cpu_has_counter 1
#define cpu_has_llsc 1
#define cpu_has_nofpuex 0
#define cpu_icache_snoops_remote_store 1
#endif
#ifdef CONFIG_CPU_MIPS64
#error This platform does not support 64bit.
#endif
#endif /* __ASM_MACH_PIC32_CPU_FEATURE_OVERRIDES_H */
/*
* Joshua Henderson <joshua.henderson@microchip.com>
* Copyright (C) 2015 Microchip Technology 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.
*/
#ifndef __ASM_MACH_PIC32_IRQ_H
#define __ASM_MACH_PIC32_IRQ_H
#define NR_IRQS 256
#define MIPS_CPU_IRQ_BASE 0
#include_next <irq.h>
#endif /* __ASM_MACH_PIC32_IRQ_H */
/*
* Joshua Henderson <joshua.henderson@microchip.com>
* Copyright (C) 2015 Microchip Technology 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.
*/
#ifndef _ASM_MACH_PIC32_H
#define _ASM_MACH_PIC32_H
#include <linux/io.h>
/*
* PIC32 register offsets for SET/CLR/INV where supported.
*/
#define PIC32_CLR(_reg) ((_reg) + 0x04)
#define PIC32_SET(_reg) ((_reg) + 0x08)
#define PIC32_INV(_reg) ((_reg) + 0x0C)
/*
* PIC32 Base Register Offsets
*/
#define PIC32_BASE_CONFIG 0x1f800000
#define PIC32_BASE_OSC 0x1f801200
#define PIC32_BASE_RESET 0x1f801240
#define PIC32_BASE_PPS 0x1f801400
#define PIC32_BASE_UART 0x1f822000
#define PIC32_BASE_PORT 0x1f860000
#define PIC32_BASE_DEVCFG2 0x1fc4ff44
/*
* Register unlock sequence required for some register access.
*/
void pic32_syskey_unlock_debug(const char *fn, const ulong ln);
#define pic32_syskey_unlock() \
pic32_syskey_unlock_debug(__func__, __LINE__)
#endif /* _ASM_MACH_PIC32_H */
/*
* Joshua Henderson <joshua.henderson@microchip.com>
* Copyright (C) 2015 Microchip Technology 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.
*/
#ifndef _ASM_MACH_PIC32_SPACES_H
#define _ASM_MACH_PIC32_SPACES_H
#ifdef CONFIG_PIC32MZDA
#define PHYS_OFFSET _AC(0x08000000, UL)
#define UNCAC_BASE _AC(0xa8000000, UL)
#endif
#include <asm/mach-generic/spaces.h>
#endif /* __ASM_MACH_PIC32_SPACES_H */
#ifndef __ASM_MACH_RALINK_IRQ_H
#define __ASM_MACH_RALINK_IRQ_H
#define GIC_NUM_INTRS 64
#define NR_IRQS 256
#include_next <irq.h>
#endif
/*
* 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.
*
* Copyright (C) 2015 John Crispin <blogic@openwrt.org>
*/
#ifndef _MT7621_REGS_H_
#define _MT7621_REGS_H_
#define MT7621_PALMBUS_BASE 0x1C000000
#define MT7621_PALMBUS_SIZE 0x03FFFFFF
#define MT7621_SYSC_BASE 0x1E000000
#define SYSC_REG_CHIP_NAME0 0x00
#define SYSC_REG_CHIP_NAME1 0x04
#define SYSC_REG_CHIP_REV 0x0c
#define SYSC_REG_SYSTEM_CONFIG0 0x10
#define SYSC_REG_SYSTEM_CONFIG1 0x14
#define CHIP_REV_PKG_MASK 0x1
#define CHIP_REV_PKG_SHIFT 16
#define CHIP_REV_VER_MASK 0xf
#define CHIP_REV_VER_SHIFT 8
#define CHIP_REV_ECO_MASK 0xf
#define MT7621_DRAM_BASE 0x0
#define MT7621_DDR2_SIZE_MIN 32
#define MT7621_DDR2_SIZE_MAX 256
#define MT7621_CHIP_NAME0 0x3637544D
#define MT7621_CHIP_NAME1 0x20203132
#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
#endif
/*
* Ralink MT7621 specific CPU feature overrides
*
* Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
* Copyright (C) 2015 Felix Fietkau <nbd@openwrt.org>
*
* This file was derived from: include/asm-mips/cpu-features.h
* Copyright (C) 2003, 2004 Ralf Baechle
* Copyright (C) 2004 Maciej W. Rozycki
*
* 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.
*
*/
#ifndef _MT7621_CPU_FEATURE_OVERRIDES_H
#define _MT7621_CPU_FEATURE_OVERRIDES_H
#define cpu_has_tlb 1
#define cpu_has_4kex 1
#define cpu_has_3k_cache 0
#define cpu_has_4k_cache 1
#define cpu_has_tx39_cache 0
#define cpu_has_sb1_cache 0
#define cpu_has_fpu 0
#define cpu_has_32fpr 0
#define cpu_has_counter 1
#define cpu_has_watch 1
#define cpu_has_divec 1
#define cpu_has_prefetch 1
#define cpu_has_ejtag 1
#define cpu_has_llsc 1
#define cpu_has_mips16 1
#define cpu_has_mdmx 0
#define cpu_has_mips3d 0
#define cpu_has_smartmips 0
#define cpu_has_mips32r1 1
#define cpu_has_mips32r2 1
#define cpu_has_mips64r1 0
#define cpu_has_mips64r2 0
#define cpu_has_dsp 1
#define cpu_has_dsp2 0
#define cpu_has_mipsmt 1
#define cpu_has_64bits 0
#define cpu_has_64bit_zero_reg 0
#define cpu_has_64bit_gp_regs 0
#define cpu_has_64bit_addresses 0
#define cpu_dcache_line_size() 32
#define cpu_icache_line_size() 32
#define cpu_has_dc_aliases 0
#define cpu_has_vtag_icache 0
#define cpu_has_rixi 0
#define cpu_has_tlbinv 0
#define cpu_has_userlocal 1
#endif /* _MT7621_CPU_FEATURE_OVERRIDES_H */
......@@ -243,6 +243,10 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80)
#define CM_GCR_BASE_CMDEFTGT_IOCU0 2
#define CM_GCR_BASE_CMDEFTGT_IOCU1 3
/* GCR_RESET_EXT_BASE register fields */
#define CM_GCR_RESET_EXT_BASE_EVARESET BIT(31)
#define CM_GCR_RESET_EXT_BASE_UEB BIT(30)
/* GCR_ACCESS register fields */
#define CM_GCR_ACCESS_ACCESSEN_SHF 0
#define CM_GCR_ACCESS_ACCESSEN_MSK (_ULCAST_(0xff) << 0)
......
......@@ -52,7 +52,7 @@ do { \
__this_cpu_inc(mipsr2emustats.M); \
err = __get_user(nir, (u32 __user *)regs->cp0_epc); \
if (!err) { \
if (nir == BREAK_MATH) \
if (nir == BREAK_MATH(0)) \
__this_cpu_inc(mipsr2bdemustats.M); \
} \
preempt_enable(); \
......
......@@ -394,6 +394,8 @@
#define CAUSEF_IV (_ULCAST_(1) << 23)
#define CAUSEB_PCI 26
#define CAUSEF_PCI (_ULCAST_(1) << 26)
#define CAUSEB_DC 27
#define CAUSEF_DC (_ULCAST_(1) << 27)
#define CAUSEB_CE 28
#define CAUSEF_CE (_ULCAST_(3) << 28)
#define CAUSEB_TI 30
......@@ -401,6 +403,38 @@
#define CAUSEB_BD 31
#define CAUSEF_BD (_ULCAST_(1) << 31)
/*
* Cause.ExcCode trap codes.
*/
#define EXCCODE_INT 0 /* Interrupt pending */
#define EXCCODE_MOD 1 /* TLB modified fault */
#define EXCCODE_TLBL 2 /* TLB miss on load or ifetch */
#define EXCCODE_TLBS 3 /* TLB miss on a store */
#define EXCCODE_ADEL 4 /* Address error on a load or ifetch */
#define EXCCODE_ADES 5 /* Address error on a store */
#define EXCCODE_IBE 6 /* Bus error on an ifetch */
#define EXCCODE_DBE 7 /* Bus error on a load or store */
#define EXCCODE_SYS 8 /* System call */
#define EXCCODE_BP 9 /* Breakpoint */
#define EXCCODE_RI 10 /* Reserved instruction exception */
#define EXCCODE_CPU 11 /* Coprocessor unusable */
#define EXCCODE_OV 12 /* Arithmetic overflow */
#define EXCCODE_TR 13 /* Trap instruction */
#define EXCCODE_MSAFPE 14 /* MSA floating point exception */
#define EXCCODE_FPE 15 /* Floating point exception */
#define EXCCODE_TLBRI 19 /* TLB Read-Inhibit exception */
#define EXCCODE_TLBXI 20 /* TLB Execution-Inhibit exception */
#define EXCCODE_MSADIS 21 /* MSA disabled exception */
#define EXCCODE_MDMX 22 /* MDMX unusable exception */
#define EXCCODE_WATCH 23 /* Watch address reference */
#define EXCCODE_MCHECK 24 /* Machine check */
#define EXCCODE_THREAD 25 /* Thread exceptions (MT) */
#define EXCCODE_DSPDIS 26 /* DSP disabled exception */
#define EXCCODE_GE 27 /* Virtualized guest exception (VZ) */
/* Implementation specific trap codes used by MIPS cores */
#define MIPS_EXCCODE_TLBPAR 16 /* TLB parity error exception */
/*
* Bits in the coprocessor 0 config register.
*/
......
......@@ -33,7 +33,7 @@
#define PAGE_SHIFT 16
#endif
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE - 1))
#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
/*
* This is used for calculating the real page sizes
......
......@@ -353,7 +353,7 @@ static inline pte_t pte_mkdirty(pte_t pte)
static inline pte_t pte_mkyoung(pte_t pte)
{
pte_val(pte) |= _PAGE_ACCESSED;
#ifdef CONFIG_CPU_MIPSR2
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
if (!(pte_val(pte) & _PAGE_NO_READ))
pte_val(pte) |= _PAGE_SILENT_READ;
else
......@@ -542,7 +542,7 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd)
{
pmd_val(pmd) |= _PAGE_ACCESSED;
#ifdef CONFIG_CPU_MIPSR2
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
if (!(pmd_val(pmd) & _PAGE_NO_READ))
pmd_val(pmd) |= _PAGE_SILENT_READ;
else
......
......@@ -116,7 +116,8 @@ enum cop_op {
dmtc_op = 0x05, ctc_op = 0x06,
mthc0_op = 0x06, mthc_op = 0x07,
bc_op = 0x08, bc1eqz_op = 0x09,
bc1nez_op = 0x0d, cop_op = 0x10,
mfmc0_op = 0x0b, bc1nez_op = 0x0d,
wrpgpr_op = 0x0e, cop_op = 0x10,
copm_op = 0x18
};
......@@ -529,7 +530,7 @@ enum MIPS6e_i8_func {
};
/*
* (microMIPS & MIPS16e) NOP instruction.
* (microMIPS) NOP instruction.
*/
#define MM_NOP16 0x0c00
......@@ -679,7 +680,7 @@ struct fp0_format { /* FPU multiply and add format (MIPS32) */
;))))))
};
struct mm_fp0_format { /* FPU multipy and add format (microMIPS) */
struct mm_fp0_format { /* FPU multiply and add format (microMIPS) */
__BITFIELD_FIELD(unsigned int opcode : 6,
__BITFIELD_FIELD(unsigned int ft : 5,
__BITFIELD_FIELD(unsigned int fs : 5,
......@@ -799,6 +800,13 @@ struct mm_x_format { /* Scaled indexed load format (microMIPS) */
;)))))
};
struct mm_a_format { /* ADDIUPC format (microMIPS) */
__BITFIELD_FIELD(unsigned int opcode : 6,
__BITFIELD_FIELD(unsigned int rs : 3,
__BITFIELD_FIELD(signed int simmediate : 23,
;)))
};
/*
* microMIPS instruction formats (16-bit length)
*/
......@@ -940,6 +948,7 @@ union mips_instruction {
struct mm_i_format mm_i_format;
struct mm_m_format mm_m_format;
struct mm_x_format mm_x_format;
struct mm_a_format mm_a_format;
struct mm_b0_format mm_b0_format;
struct mm_b1_format mm_b1_format;
struct mm16_m_format mm16_m_format ;
......
......@@ -190,7 +190,7 @@ static inline void check_daddi(void)
printk("Checking for the daddi bug... ");
local_irq_save(flags);
handler = set_except_vector(12, handle_daddi_ov);
handler = set_except_vector(EXCCODE_OV, handle_daddi_ov);
/*
* The following code fails to trigger an overflow exception
* when executed on R4000 rev. 2.2 or 3.0 (PRId 00000422 or
......@@ -214,7 +214,7 @@ static inline void check_daddi(void)
".set pop"
: "=r" (v), "=&r" (tmp)
: "I" (0xffffffffffffdb9aUL), "I" (0x1234));
set_except_vector(12, handler);
set_except_vector(EXCCODE_OV, handler);
local_irq_restore(flags);
if (daddi_ov) {
......@@ -225,14 +225,14 @@ static inline void check_daddi(void)
printk("yes, workaround... ");
local_irq_save(flags);
handler = set_except_vector(12, handle_daddi_ov);
handler = set_except_vector(EXCCODE_OV, handle_daddi_ov);
asm volatile(
"addiu %1, $0, %2\n\t"
"dsrl %1, %1, 1\n\t"
"daddi %0, %1, %3"
: "=r" (v), "=&r" (tmp)
: "I" (0xffffffffffffdb9aUL), "I" (0x1234));
set_except_vector(12, handler);
set_except_vector(EXCCODE_OV, handler);
local_irq_restore(flags);
if (daddi_ov) {
......
......@@ -98,6 +98,161 @@ static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c)
c->fpu_msk31 = ~(fcsr0 ^ fcsr1) & ~mask;
}
/*
* Determine the IEEE 754 NaN encodings and ABS.fmt/NEG.fmt execution modes
* supported by FPU hardware.
*/
static void cpu_set_fpu_2008(struct cpuinfo_mips *c)
{
if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
unsigned long sr, fir, fcsr, fcsr0, fcsr1;
sr = read_c0_status();
__enable_fpu(FPU_AS_IS);
fir = read_32bit_cp1_register(CP1_REVISION);
if (fir & MIPS_FPIR_HAS2008) {
fcsr = read_32bit_cp1_register(CP1_STATUS);
fcsr0 = fcsr & ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
write_32bit_cp1_register(CP1_STATUS, fcsr0);
fcsr0 = read_32bit_cp1_register(CP1_STATUS);
fcsr1 = fcsr | FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
write_32bit_cp1_register(CP1_STATUS, fcsr1);
fcsr1 = read_32bit_cp1_register(CP1_STATUS);
write_32bit_cp1_register(CP1_STATUS, fcsr);
if (!(fcsr0 & FPU_CSR_NAN2008))
c->options |= MIPS_CPU_NAN_LEGACY;
if (fcsr1 & FPU_CSR_NAN2008)
c->options |= MIPS_CPU_NAN_2008;
if ((fcsr0 ^ fcsr1) & FPU_CSR_ABS2008)
c->fpu_msk31 &= ~FPU_CSR_ABS2008;
else
c->fpu_csr31 |= fcsr & FPU_CSR_ABS2008;
if ((fcsr0 ^ fcsr1) & FPU_CSR_NAN2008)
c->fpu_msk31 &= ~FPU_CSR_NAN2008;
else
c->fpu_csr31 |= fcsr & FPU_CSR_NAN2008;
} else {
c->options |= MIPS_CPU_NAN_LEGACY;
}
write_c0_status(sr);
} else {
c->options |= MIPS_CPU_NAN_LEGACY;
}
}
/*
* IEEE 754 conformance mode to use. Affects the NaN encoding and the
* ABS.fmt/NEG.fmt execution mode.
*/
static enum { STRICT, LEGACY, STD2008, RELAXED } ieee754 = STRICT;
/*
* Set the IEEE 754 NaN encodings and the ABS.fmt/NEG.fmt execution modes
* to support by the FPU emulator according to the IEEE 754 conformance
* mode selected. Note that "relaxed" straps the emulator so that it
* allows 2008-NaN binaries even for legacy processors.
*/
static void cpu_set_nofpu_2008(struct cpuinfo_mips *c)
{
c->options &= ~(MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY);
c->fpu_csr31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
c->fpu_msk31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
switch (ieee754) {
case STRICT:
if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
} else {
c->options |= MIPS_CPU_NAN_LEGACY;
c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
}
break;
case LEGACY:
c->options |= MIPS_CPU_NAN_LEGACY;
c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
break;
case STD2008:
c->options |= MIPS_CPU_NAN_2008;
c->fpu_csr31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
break;
case RELAXED:
c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
break;
}
}
/*
* Override the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode
* according to the "ieee754=" parameter.
*/
static void cpu_set_nan_2008(struct cpuinfo_mips *c)
{
switch (ieee754) {
case STRICT:
mips_use_nan_legacy = !!cpu_has_nan_legacy;
mips_use_nan_2008 = !!cpu_has_nan_2008;
break;
case LEGACY:
mips_use_nan_legacy = !!cpu_has_nan_legacy;
mips_use_nan_2008 = !cpu_has_nan_legacy;
break;
case STD2008:
mips_use_nan_legacy = !cpu_has_nan_2008;
mips_use_nan_2008 = !!cpu_has_nan_2008;
break;
case RELAXED:
mips_use_nan_legacy = true;
mips_use_nan_2008 = true;
break;
}
}
/*
* IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode override
* settings:
*
* strict: accept binaries that request a NaN encoding supported by the FPU
* legacy: only accept legacy-NaN binaries
* 2008: only accept 2008-NaN binaries
* relaxed: accept any binaries regardless of whether supported by the FPU
*/
static int __init ieee754_setup(char *s)
{
if (!s)
return -1;
else if (!strcmp(s, "strict"))
ieee754 = STRICT;
else if (!strcmp(s, "legacy"))
ieee754 = LEGACY;
else if (!strcmp(s, "2008"))
ieee754 = STD2008;
else if (!strcmp(s, "relaxed"))
ieee754 = RELAXED;
else
return -1;
if (!(boot_cpu_data.options & MIPS_CPU_FPU))
cpu_set_nofpu_2008(&boot_cpu_data);
cpu_set_nan_2008(&boot_cpu_data);
return 0;
}
early_param("ieee754", ieee754_setup);
/*
* Set the FIR feature flags for the FPU emulator.
*/
......@@ -113,6 +268,8 @@ static void cpu_set_nofpu_id(struct cpuinfo_mips *c)
if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W;
if (c->options & MIPS_CPU_NAN_2008)
value |= MIPS_FPIR_HAS2008;
c->fpu_id = value;
}
......@@ -137,6 +294,8 @@ static void cpu_set_fpu_opts(struct cpuinfo_mips *c)
}
cpu_set_fpu_fcsr_mask(c);
cpu_set_fpu_2008(c);
cpu_set_nan_2008(c);
}
/*
......@@ -147,6 +306,8 @@ static void cpu_set_nofpu_opts(struct cpuinfo_mips *c)
c->options &= ~MIPS_CPU_FPU;
c->fpu_msk31 = mips_nofpu_msk31;
cpu_set_nofpu_2008(c);
cpu_set_nan_2008(c);
cpu_set_nofpu_id(c);
}
......
......@@ -11,6 +11,12 @@
#include <linux/elf.h>
#include <linux/sched.h>
#include <asm/cpu-info.h>
/* Whether to accept legacy-NaN and 2008-NaN user binaries. */
bool mips_use_nan_legacy;
bool mips_use_nan_2008;
/* FPU modes */
enum {
FP_FRE,
......@@ -68,15 +74,23 @@ static struct mode_req none_req = { true, true, false, true, true };
int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
bool is_interp, struct arch_elf_state *state)
{
struct elf32_hdr *ehdr32 = _ehdr;
union {
struct elf32_hdr e32;
struct elf64_hdr e64;
} *ehdr = _ehdr;
struct elf32_phdr *phdr32 = _phdr;
struct elf64_phdr *phdr64 = _phdr;
struct mips_elf_abiflags_v0 abiflags;
bool elf32;
u32 flags;
int ret;
elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32;
flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags;
/* Lets see if this is an O32 ELF */
if (ehdr32->e_ident[EI_CLASS] == ELFCLASS32) {
if (ehdr32->e_flags & EF_MIPS_FP64) {
if (elf32) {
if (flags & EF_MIPS_FP64) {
/*
* Set MIPS_ABI_FP_OLD_64 for EF_MIPS_FP64. We will override it
* later if needed
......@@ -120,13 +134,50 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
return 0;
}
int arch_check_elf(void *_ehdr, bool has_interpreter,
int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr,
struct arch_elf_state *state)
{
struct elf32_hdr *ehdr = _ehdr;
union {
struct elf32_hdr e32;
struct elf64_hdr e64;
} *ehdr = _ehdr;
union {
struct elf32_hdr e32;
struct elf64_hdr e64;
} *iehdr = _interp_ehdr;
struct mode_req prog_req, interp_req;
int fp_abi, interp_fp_abi, abi0, abi1, max_abi;
bool is_mips64;
bool elf32;
u32 flags;
elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32;
flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags;
/*
* Determine the NaN personality, reject the binary if not allowed.
* Also ensure that any interpreter matches the executable.
*/
if (flags & EF_MIPS_NAN2008) {
if (mips_use_nan_2008)
state->nan_2008 = 1;
else
return -ENOEXEC;
} else {
if (mips_use_nan_legacy)
state->nan_2008 = 0;
else
return -ENOEXEC;
}
if (has_interpreter) {
bool ielf32;
u32 iflags;
ielf32 = iehdr->e32.e_ident[EI_CLASS] == ELFCLASS32;
iflags = ielf32 ? iehdr->e32.e_flags : iehdr->e64.e_flags;
if ((flags ^ iflags) & EF_MIPS_NAN2008)
return -ELIBBAD;
}
if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
return 0;
......@@ -142,21 +193,18 @@ int arch_check_elf(void *_ehdr, bool has_interpreter,
abi0 = abi1 = fp_abi;
}
is_mips64 = (ehdr->e_ident[EI_CLASS] == ELFCLASS64) ||
(ehdr->e_flags & EF_MIPS_ABI2);
if (elf32 && !(flags & EF_MIPS_ABI2)) {
/* Default to a mode capable of running code expecting FR=0 */
state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0;
if (is_mips64) {
/* Allow all ABIs we know about */
max_abi = MIPS_ABI_FP_64A;
} else {
/* MIPS64 code always uses FR=1, thus the default is easy */
state->overall_fp_mode = FP_FR1;
/* Disallow access to the various FPXX & FP64 ABIs */
max_abi = MIPS_ABI_FP_SOFT;
} else {
/* Default to a mode capable of running code expecting FR=0 */
state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0;
/* Allow all ABIs we know about */
max_abi = MIPS_ABI_FP_64A;
}
if ((abi0 > max_abi && abi0 != MIPS_ABI_FP_UNKNOWN) ||
......@@ -254,3 +302,27 @@ void mips_set_personality_fp(struct arch_elf_state *state)
BUG();
}
}
/*
* Select the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode
* in FCSR according to the ELF NaN personality.
*/
void mips_set_personality_nan(struct arch_elf_state *state)
{
struct cpuinfo_mips *c = &boot_cpu_data;
struct task_struct *t = current;
t->thread.fpu.fcr31 = c->fpu_csr31;
switch (state->nan_2008) {
case 0:
break;
case 1:
if (!(c->fpu_msk31 & FPU_CSR_NAN2008))
t->thread.fpu.fcr31 |= FPU_CSR_NAN2008;
if (!(c->fpu_msk31 & FPU_CSR_ABS2008))
t->thread.fpu.fcr31 |= FPU_CSR_ABS2008;
break;
default:
BUG();
}
}
......@@ -21,7 +21,7 @@ static struct txx9_pio_reg __iomem *txx9_pioptr;
static int txx9_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
return __raw_readl(&txx9_pioptr->din) & (1 << offset);
return !!(__raw_readl(&txx9_pioptr->din) & (1 << offset));
}
static void txx9_gpio_set_raw(unsigned int offset, int value)
......
......@@ -548,9 +548,6 @@ static const struct pt_regs_offset regoffset_table[] = {
REG_OFFSET_NAME(c0_badvaddr, cp0_badvaddr),
REG_OFFSET_NAME(c0_cause, cp0_cause),
REG_OFFSET_NAME(c0_epc, cp0_epc),
#ifdef CONFIG_MIPS_MT_SMTC
REG_OFFSET_NAME(c0_tcstatus, cp0_tcstatus),
#endif
#ifdef CONFIG_CPU_CAVIUM_OCTEON
REG_OFFSET_NAME(mpl0, mpl[0]),
REG_OFFSET_NAME(mpl1, mpl[1]),
......
......@@ -623,7 +623,7 @@ static void __init request_crashkernel(struct resource *res)
#define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
#define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
#define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_EXTEND)
#define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
static void __init arch_mem_init(char **cmdline_p)
{
......
......@@ -202,6 +202,9 @@ static void boot_core(unsigned core)
/* Ensure its coherency is disabled */
write_gcr_co_coherence(0);
/* Start it with the legacy memory map and exception base */
write_gcr_co_reset_ext_base(CM_GCR_RESET_EXT_BASE_UEB);
/* Ensure the core can access the GCRs */
access = read_gcr_access();
access |= 1 << (CM_GCR_ACCESS_ACCESSEN_SHF + core);
......
......@@ -17,34 +17,22 @@
#include <asm/barrier.h>
#include <asm/mipsregs.h>
static atomic_t count_start_flag = ATOMIC_INIT(0);
static unsigned int initcount = 0;
static atomic_t count_count_start = ATOMIC_INIT(0);
static atomic_t count_count_stop = ATOMIC_INIT(0);
static atomic_t count_reference = ATOMIC_INIT(0);
#define COUNTON 100
#define NR_LOOPS 5
#define NR_LOOPS 3
void synchronise_count_master(int cpu)
{
int i;
unsigned long flags;
unsigned int initcount;
printk(KERN_INFO "Synchronize counters for CPU %u: ", cpu);
local_irq_save(flags);
/*
* Notify the slaves that it's time to start
*/
atomic_set(&count_reference, read_c0_count());
atomic_set(&count_start_flag, cpu);
smp_wmb();
/* Count will be initialised to current timer for all CPU's */
initcount = read_c0_count();
/*
* We loop a few times to get a primed instruction cache,
* then the last pass is more or less synchronised and
......@@ -63,9 +51,13 @@ void synchronise_count_master(int cpu)
atomic_set(&count_count_stop, 0);
smp_wmb();
/* this lets the slaves write their count register */
/* Let the slave writes its count register */
atomic_inc(&count_count_start);
/* Count will be initialised to current timer */
if (i == 1)
initcount = read_c0_count();
/*
* Everyone initialises count in the last loop:
*/
......@@ -73,7 +65,7 @@ void synchronise_count_master(int cpu)
write_c0_count(initcount);
/*
* Wait for all slaves to leave the synchronization point:
* Wait for slave to leave the synchronization point:
*/
while (atomic_read(&count_count_stop) != 1)
mb();
......@@ -83,7 +75,6 @@ void synchronise_count_master(int cpu)
}
/* Arrange for an interrupt in a short while */
write_c0_compare(read_c0_count() + COUNTON);
atomic_set(&count_start_flag, 0);
local_irq_restore(flags);
......@@ -98,19 +89,12 @@ void synchronise_count_master(int cpu)
void synchronise_count_slave(int cpu)
{
int i;
unsigned int initcount;
/*
* Not every cpu is online at the time this gets called,
* so we first wait for the master to say everyone is ready
*/
while (atomic_read(&count_start_flag) != cpu)
mb();
/* Count will be initialised to next expire for all CPU's */
initcount = atomic_read(&count_reference);
for (i = 0; i < NR_LOOPS; i++) {
atomic_inc(&count_count_start);
while (atomic_read(&count_count_start) != 2)
......
......@@ -2250,7 +2250,7 @@ void __init trap_init(void)
* Only some CPUs have the watch exceptions.
*/
if (cpu_has_watch)
set_except_vector(23, handle_watch);
set_except_vector(EXCCODE_WATCH, handle_watch);
/*
* Initialise interrupt handlers
......@@ -2277,27 +2277,27 @@ void __init trap_init(void)
if (board_be_init)
board_be_init();
set_except_vector(0, using_rollback_handler() ? rollback_handle_int
: handle_int);
set_except_vector(1, handle_tlbm);
set_except_vector(2, handle_tlbl);
set_except_vector(3, handle_tlbs);
set_except_vector(EXCCODE_INT, using_rollback_handler() ?
rollback_handle_int : handle_int);
set_except_vector(EXCCODE_MOD, handle_tlbm);
set_except_vector(EXCCODE_TLBL, handle_tlbl);
set_except_vector(EXCCODE_TLBS, handle_tlbs);
set_except_vector(4, handle_adel);
set_except_vector(5, handle_ades);
set_except_vector(EXCCODE_ADEL, handle_adel);
set_except_vector(EXCCODE_ADES, handle_ades);
set_except_vector(6, handle_ibe);
set_except_vector(7, handle_dbe);
set_except_vector(EXCCODE_IBE, handle_ibe);
set_except_vector(EXCCODE_DBE, handle_dbe);
set_except_vector(8, handle_sys);
set_except_vector(9, handle_bp);
set_except_vector(10, rdhwr_noopt ? handle_ri :
set_except_vector(EXCCODE_SYS, handle_sys);
set_except_vector(EXCCODE_BP, handle_bp);
set_except_vector(EXCCODE_RI, rdhwr_noopt ? handle_ri :
(cpu_has_vtag_icache ?
handle_ri_rdhwr_vivt : handle_ri_rdhwr));
set_except_vector(11, handle_cpu);
set_except_vector(12, handle_ov);
set_except_vector(13, handle_tr);
set_except_vector(14, handle_msa_fpe);
set_except_vector(EXCCODE_CPU, handle_cpu);
set_except_vector(EXCCODE_OV, handle_ov);
set_except_vector(EXCCODE_TR, handle_tr);
set_except_vector(EXCCODE_MSAFPE, handle_msa_fpe);
if (current_cpu_type() == CPU_R6000 ||
current_cpu_type() == CPU_R6000A) {
......@@ -2318,25 +2318,25 @@ void __init trap_init(void)
board_nmi_handler_setup();
if (cpu_has_fpu && !cpu_has_nofpuex)
set_except_vector(15, handle_fpe);
set_except_vector(EXCCODE_FPE, handle_fpe);
set_except_vector(16, handle_ftlb);
set_except_vector(MIPS_EXCCODE_TLBPAR, handle_ftlb);
if (cpu_has_rixiex) {
set_except_vector(19, tlb_do_page_fault_0);
set_except_vector(20, tlb_do_page_fault_0);
set_except_vector(EXCCODE_TLBRI, tlb_do_page_fault_0);
set_except_vector(EXCCODE_TLBXI, tlb_do_page_fault_0);
}
set_except_vector(21, handle_msa);
set_except_vector(22, handle_mdmx);
set_except_vector(EXCCODE_MSADIS, handle_msa);
set_except_vector(EXCCODE_MDMX, handle_mdmx);
if (cpu_has_mcheck)
set_except_vector(24, handle_mcheck);
set_except_vector(EXCCODE_MCHECK, handle_mcheck);
if (cpu_has_mipsmt)
set_except_vector(25, handle_mt);
set_except_vector(EXCCODE_THREAD, handle_mt);
set_except_vector(26, handle_dsp);
set_except_vector(EXCCODE_DSPDIS, handle_dsp);
if (board_cache_error_setup)
board_cache_error_setup();
......
......@@ -11,4 +11,4 @@
#include <linux/kvm_host.h>
struct kvm_mips_callbacks *kvm_mips_callbacks;
EXPORT_SYMBOL(kvm_mips_callbacks);
EXPORT_SYMBOL_GPL(kvm_mips_callbacks);
......@@ -86,10 +86,8 @@ int kvm_mips_trans_mfc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
} else {
mfc0_inst = LW_TEMPLATE;
mfc0_inst |= ((rt & 0x1f) << 16);
mfc0_inst |=
offsetof(struct mips_coproc,
reg[rd][sel]) + offsetof(struct kvm_mips_commpage,
cop0);
mfc0_inst |= offsetof(struct kvm_mips_commpage,
cop0.reg[rd][sel]);
}
if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) {
......@@ -123,9 +121,7 @@ int kvm_mips_trans_mtc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
sel = inst & 0x7;
mtc0_inst |= ((rt & 0x1f) << 16);
mtc0_inst |=
offsetof(struct mips_coproc,
reg[rd][sel]) + offsetof(struct kvm_mips_commpage, cop0);
mtc0_inst |= offsetof(struct kvm_mips_commpage, cop0.reg[rd][sel]);
if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) {
kseg0_opc =
......
This diff is collapsed.
......@@ -128,7 +128,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
&& (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
&& (kvm_read_c0_guest_status(cop0) & IE_IRQ5)) {
allowed = 1;
exccode = T_INT;
exccode = EXCCODE_INT;
}
break;
......@@ -137,7 +137,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
&& (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
&& (kvm_read_c0_guest_status(cop0) & IE_IRQ0)) {
allowed = 1;
exccode = T_INT;
exccode = EXCCODE_INT;
}
break;
......@@ -146,7 +146,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
&& (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
&& (kvm_read_c0_guest_status(cop0) & IE_IRQ1)) {
allowed = 1;
exccode = T_INT;
exccode = EXCCODE_INT;
}
break;
......@@ -155,7 +155,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
&& (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
&& (kvm_read_c0_guest_status(cop0) & IE_IRQ2)) {
allowed = 1;
exccode = T_INT;
exccode = EXCCODE_INT;
}
break;
......
......@@ -335,7 +335,7 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra)
/* Now restore the host state just enough to run the handlers */
/* Swtich EBASE to the one used by Linux */
/* Switch EBASE to the one used by Linux */
/* load up the host EBASE */
mfc0 v0, CP0_STATUS
......@@ -490,11 +490,11 @@ __kvm_mips_return_to_guest:
REG_ADDU t3, t1, t2
LONG_L k0, (t3)
andi k0, k0, 0xff
mtc0 k0,CP0_ENTRYHI
mtc0 k0, CP0_ENTRYHI
ehb
/* Disable RDHWR access */
mtc0 zero, CP0_HWRENA
mtc0 zero, CP0_HWRENA
/* load the guest context from VCPU and return */
LONG_L $0, VCPU_R0(k1)
......@@ -606,11 +606,11 @@ __kvm_mips_return_to_host:
/* Restore RDHWR access */
PTR_LI k0, 0x2000000F
mtc0 k0, CP0_HWRENA
mtc0 k0, CP0_HWRENA
/* Restore RA, which is the address we will return to */
LONG_L ra, PT_R31(k1)
j ra
LONG_L ra, PT_R31(k1)
j ra
nop
VECTOR_END(MIPSX(GuestExceptionEnd))
......
......@@ -229,7 +229,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
kzalloc(npages * sizeof(unsigned long), GFP_KERNEL);
if (!kvm->arch.guest_pmap) {
kvm_err("Failed to allocate guest PMAP");
kvm_err("Failed to allocate guest PMAP\n");
return;
}
......@@ -1264,8 +1264,8 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
}
switch (exccode) {
case T_INT:
kvm_debug("[%d]T_INT @ %p\n", vcpu->vcpu_id, opc);
case EXCCODE_INT:
kvm_debug("[%d]EXCCODE_INT @ %p\n", vcpu->vcpu_id, opc);
++vcpu->stat.int_exits;
trace_kvm_exit(vcpu, INT_EXITS);
......@@ -1276,8 +1276,8 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
ret = RESUME_GUEST;
break;
case T_COP_UNUSABLE:
kvm_debug("T_COP_UNUSABLE: @ PC: %p\n", opc);
case EXCCODE_CPU:
kvm_debug("EXCCODE_CPU: @ PC: %p\n", opc);
++vcpu->stat.cop_unusable_exits;
trace_kvm_exit(vcpu, COP_UNUSABLE_EXITS);
......@@ -1287,13 +1287,13 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
ret = RESUME_HOST;
break;
case T_TLB_MOD:
case EXCCODE_MOD:
++vcpu->stat.tlbmod_exits;
trace_kvm_exit(vcpu, TLBMOD_EXITS);
ret = kvm_mips_callbacks->handle_tlb_mod(vcpu);
break;
case T_TLB_ST_MISS:
case EXCCODE_TLBS:
kvm_debug("TLB ST fault: cause %#x, status %#lx, PC: %p, BadVaddr: %#lx\n",
cause, kvm_read_c0_guest_status(vcpu->arch.cop0), opc,
badvaddr);
......@@ -1303,7 +1303,7 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
ret = kvm_mips_callbacks->handle_tlb_st_miss(vcpu);
break;
case T_TLB_LD_MISS:
case EXCCODE_TLBL:
kvm_debug("TLB LD fault: cause %#x, PC: %p, BadVaddr: %#lx\n",
cause, opc, badvaddr);
......@@ -1312,55 +1312,55 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
ret = kvm_mips_callbacks->handle_tlb_ld_miss(vcpu);
break;
case T_ADDR_ERR_ST:
case EXCCODE_ADES:
++vcpu->stat.addrerr_st_exits;
trace_kvm_exit(vcpu, ADDRERR_ST_EXITS);
ret = kvm_mips_callbacks->handle_addr_err_st(vcpu);
break;
case T_ADDR_ERR_LD:
case EXCCODE_ADEL:
++vcpu->stat.addrerr_ld_exits;
trace_kvm_exit(vcpu, ADDRERR_LD_EXITS);
ret = kvm_mips_callbacks->handle_addr_err_ld(vcpu);
break;
case T_SYSCALL:
case EXCCODE_SYS:
++vcpu->stat.syscall_exits;
trace_kvm_exit(vcpu, SYSCALL_EXITS);
ret = kvm_mips_callbacks->handle_syscall(vcpu);
break;
case T_RES_INST:
case EXCCODE_RI:
++vcpu->stat.resvd_inst_exits;
trace_kvm_exit(vcpu, RESVD_INST_EXITS);
ret = kvm_mips_callbacks->handle_res_inst(vcpu);
break;
case T_BREAK:
case EXCCODE_BP:
++vcpu->stat.break_inst_exits;
trace_kvm_exit(vcpu, BREAK_INST_EXITS);
ret = kvm_mips_callbacks->handle_break(vcpu);
break;
case T_TRAP:
case EXCCODE_TR:
++vcpu->stat.trap_inst_exits;
trace_kvm_exit(vcpu, TRAP_INST_EXITS);
ret = kvm_mips_callbacks->handle_trap(vcpu);
break;
case T_MSAFPE:
case EXCCODE_MSAFPE:
++vcpu->stat.msa_fpe_exits;
trace_kvm_exit(vcpu, MSA_FPE_EXITS);
ret = kvm_mips_callbacks->handle_msa_fpe(vcpu);
break;
case T_FPE:
case EXCCODE_FPE:
++vcpu->stat.fpe_exits;
trace_kvm_exit(vcpu, FPE_EXITS);
ret = kvm_mips_callbacks->handle_fpe(vcpu);
break;
case T_MSADIS:
case EXCCODE_MSADIS:
++vcpu->stat.msa_disabled_exits;
trace_kvm_exit(vcpu, MSA_DISABLED_EXITS);
ret = kvm_mips_callbacks->handle_msa_disabled(vcpu);
......@@ -1620,7 +1620,7 @@ static struct notifier_block kvm_mips_csr_die_notifier = {
.notifier_call = kvm_mips_csr_die_notify,
};
int __init kvm_mips_init(void)
static int __init kvm_mips_init(void)
{
int ret;
......@@ -1646,7 +1646,7 @@ int __init kvm_mips_init(void)
return 0;
}
void __exit kvm_mips_exit(void)
static void __exit kvm_mips_exit(void)
{
kvm_exit();
......
/*
* 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 MIPS Technologies, Inc. All rights reserved.
* Authors: Sanjay Lal <sanjayl@kymasys.com>
*/
/* Define opcode values not defined in <asm/isnt.h> */
#ifndef __KVM_MIPS_OPCODE_H__
#define __KVM_MIPS_OPCODE_H__
/* COP0 Ops */
#define mfmcz_op 0x0b /* 01011 */
#define wrpgpr_op 0x0e /* 01110 */
/* COP0 opcodes (only if COP0 and CO=1): */
#define wait_op 0x20 /* 100000 */
#endif /* __KVM_MIPS_OPCODE_H__ */
......@@ -35,17 +35,17 @@
#define PRIx64 "llx"
atomic_t kvm_mips_instance;
EXPORT_SYMBOL(kvm_mips_instance);
EXPORT_SYMBOL_GPL(kvm_mips_instance);
/* These function pointers are initialized once the KVM module is loaded */
kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn);
EXPORT_SYMBOL(kvm_mips_gfn_to_pfn);
EXPORT_SYMBOL_GPL(kvm_mips_gfn_to_pfn);
void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn);
EXPORT_SYMBOL(kvm_mips_release_pfn_clean);
EXPORT_SYMBOL_GPL(kvm_mips_release_pfn_clean);
bool (*kvm_mips_is_error_pfn)(kvm_pfn_t pfn);
EXPORT_SYMBOL(kvm_mips_is_error_pfn);
EXPORT_SYMBOL_GPL(kvm_mips_is_error_pfn);
uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu)
{
......@@ -111,7 +111,7 @@ void kvm_mips_dump_host_tlbs(void)
mtc0_tlbw_hazard();
local_irq_restore(flags);
}
EXPORT_SYMBOL(kvm_mips_dump_host_tlbs);
EXPORT_SYMBOL_GPL(kvm_mips_dump_host_tlbs);
void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu)
{
......@@ -139,7 +139,7 @@ void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu)
(tlb.tlb_lo1 >> 3) & 7, tlb.tlb_mask);
}
}
EXPORT_SYMBOL(kvm_mips_dump_guest_tlbs);
EXPORT_SYMBOL_GPL(kvm_mips_dump_guest_tlbs);
static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn)
{
......@@ -191,7 +191,7 @@ unsigned long kvm_mips_translate_guest_kseg0_to_hpa(struct kvm_vcpu *vcpu,
return (kvm->arch.guest_pmap[gfn] << PAGE_SHIFT) + offset;
}
EXPORT_SYMBOL(kvm_mips_translate_guest_kseg0_to_hpa);
EXPORT_SYMBOL_GPL(kvm_mips_translate_guest_kseg0_to_hpa);
/* XXXKYMA: Must be called with interrupts disabled */
/* set flush_dcache_mask == 0 if no dcache flush required */
......@@ -308,7 +308,7 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr,
return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1,
flush_dcache_mask);
}
EXPORT_SYMBOL(kvm_mips_handle_kseg0_tlb_fault);
EXPORT_SYMBOL_GPL(kvm_mips_handle_kseg0_tlb_fault);
int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr,
struct kvm_vcpu *vcpu)
......@@ -351,7 +351,7 @@ int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr,
return 0;
}
EXPORT_SYMBOL(kvm_mips_handle_commpage_tlb_fault);
EXPORT_SYMBOL_GPL(kvm_mips_handle_commpage_tlb_fault);
int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
struct kvm_mips_tlb *tlb,
......@@ -401,7 +401,7 @@ int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1,
tlb->tlb_mask);
}
EXPORT_SYMBOL(kvm_mips_handle_mapped_seg_tlb_fault);
EXPORT_SYMBOL_GPL(kvm_mips_handle_mapped_seg_tlb_fault);
int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi)
{
......@@ -422,7 +422,7 @@ int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi)
return index;
}
EXPORT_SYMBOL(kvm_mips_guest_tlb_lookup);
EXPORT_SYMBOL_GPL(kvm_mips_guest_tlb_lookup);
int kvm_mips_host_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long vaddr)
{
......@@ -458,7 +458,7 @@ int kvm_mips_host_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long vaddr)
return idx;
}
EXPORT_SYMBOL(kvm_mips_host_tlb_lookup);
EXPORT_SYMBOL_GPL(kvm_mips_host_tlb_lookup);
int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va)
{
......@@ -505,44 +505,7 @@ int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va)
return 0;
}
EXPORT_SYMBOL(kvm_mips_host_tlb_inv);
/* XXXKYMA: Fix Guest USER/KERNEL no longer share the same ASID */
int kvm_mips_host_tlb_inv_index(struct kvm_vcpu *vcpu, int index)
{
unsigned long flags, old_entryhi;
if (index >= current_cpu_data.tlbsize)
BUG();
local_irq_save(flags);
old_entryhi = read_c0_entryhi();
write_c0_entryhi(UNIQUE_ENTRYHI(index));
mtc0_tlbw_hazard();
write_c0_index(index);
mtc0_tlbw_hazard();
write_c0_entrylo0(0);
mtc0_tlbw_hazard();
write_c0_entrylo1(0);
mtc0_tlbw_hazard();
tlb_write_indexed();
mtc0_tlbw_hazard();
tlbw_use_hazard();
write_c0_entryhi(old_entryhi);
mtc0_tlbw_hazard();
tlbw_use_hazard();
local_irq_restore(flags);
return 0;
}
EXPORT_SYMBOL_GPL(kvm_mips_host_tlb_inv);
void kvm_mips_flush_host_tlb(int skip_kseg0)
{
......@@ -594,7 +557,7 @@ void kvm_mips_flush_host_tlb(int skip_kseg0)
local_irq_restore(flags);
}
EXPORT_SYMBOL(kvm_mips_flush_host_tlb);
EXPORT_SYMBOL_GPL(kvm_mips_flush_host_tlb);
void kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu,
struct kvm_vcpu *vcpu)
......@@ -642,7 +605,7 @@ void kvm_local_flush_tlb_all(void)
local_irq_restore(flags);
}
EXPORT_SYMBOL(kvm_local_flush_tlb_all);
EXPORT_SYMBOL_GPL(kvm_local_flush_tlb_all);
/**
* kvm_mips_migrate_count() - Migrate timer.
......@@ -673,8 +636,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
local_irq_save(flags);
if (((vcpu->arch.
guest_kernel_asid[cpu] ^ asid_cache(cpu)) & ASID_VERSION_MASK)) {
if ((vcpu->arch.guest_kernel_asid[cpu] ^ asid_cache(cpu)) &
ASID_VERSION_MASK) {
kvm_get_new_mmu_context(&vcpu->arch.guest_kernel_mm, cpu, vcpu);
vcpu->arch.guest_kernel_asid[cpu] =
vcpu->arch.guest_kernel_mm.context.asid[cpu];
......@@ -739,7 +702,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
local_irq_restore(flags);
}
EXPORT_SYMBOL(kvm_arch_vcpu_load);
EXPORT_SYMBOL_GPL(kvm_arch_vcpu_load);
/* ASID can change if another task is scheduled during preemption */
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
......@@ -768,7 +731,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
local_irq_restore(flags);
}
EXPORT_SYMBOL(kvm_arch_vcpu_put);
EXPORT_SYMBOL_GPL(kvm_arch_vcpu_put);
uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu)
{
......@@ -813,4 +776,4 @@ uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu)
return inst;
}
EXPORT_SYMBOL(kvm_get_inst);
EXPORT_SYMBOL_GPL(kvm_get_inst);
......@@ -16,7 +16,6 @@
#include <linux/kvm_host.h>
#include "opcode.h"
#include "interrupt.h"
static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva)
......
......@@ -57,7 +57,6 @@ notrace void arch_local_irq_disable(void)
}
EXPORT_SYMBOL(arch_local_irq_disable);
notrace unsigned long arch_local_irq_save(void)
{
unsigned long flags;
......@@ -111,31 +110,4 @@ notrace void arch_local_irq_restore(unsigned long flags)
}
EXPORT_SYMBOL(arch_local_irq_restore);
notrace void __arch_local_irq_restore(unsigned long flags)
{
unsigned long __tmp1;
preempt_disable();
__asm__ __volatile__(
" .set push \n"
" .set noreorder \n"
" .set noat \n"
" mfc0 $1, $12 \n"
" andi %[flags], 1 \n"
" ori $1, 0x1f \n"
" xori $1, 0x1f \n"
" or %[flags], $1 \n"
" mtc0 %[flags], $12 \n"
" " __stringify(__irq_disable_hazard) " \n"
" .set pop \n"
: [flags] "=r" (__tmp1)
: "0" (flags)
: "memory");
preempt_enable();
}
EXPORT_SYMBOL(__arch_local_irq_restore);
#endif /* !CONFIG_CPU_MIPSR2 */
#endif /* !CONFIG_CPU_MIPSR2 && !CONFIG_CPU_MIPSR6 */
......@@ -22,6 +22,27 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
endif
endif
cflags-$(CONFIG_CPU_LOONGSON3) += -Wa,--trap
#
# binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a
# as MIPS64 R2; older versions as just R1. This leaves the possibility open
# that GCC might generate R2 code for -march=loongson3a which then is rejected
# by GAS. The cc-option can't probe for this behaviour so -march=loongson3a
# can't easily be used safely within the kbuild framework.
#
ifeq ($(call cc-ifversion, -ge, 0409, y), y)
ifeq ($(call ld-ifversion, -ge, 22500000, y), y)
cflags-$(CONFIG_CPU_LOONGSON3) += \
$(call cc-option,-march=loongson3a -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
else
cflags-$(CONFIG_CPU_LOONGSON3) += \
$(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
endif
else
cflags-$(CONFIG_CPU_LOONGSON3) += \
$(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
endif
#
# Loongson Machines' Support
#
......
......@@ -13,6 +13,9 @@
#define SMBUS_PCI_REG64 0x64
#define SMBUS_PCI_REGB4 0xb4
#define HPET_MIN_CYCLES 64
#define HPET_MIN_PROG_DELTA (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1))
static DEFINE_SPINLOCK(hpet_lock);
DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device);
......@@ -161,8 +164,9 @@ static int hpet_next_event(unsigned long delta,
cnt += delta;
hpet_write(HPET_T0_CMP, cnt);
res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0;
return res;
res = (int)(cnt - hpet_read(HPET_COUNTER));
return res < HPET_MIN_CYCLES ? -ETIME : 0;
}
static irqreturn_t hpet_irq_handler(int irq, void *data)
......@@ -237,7 +241,7 @@ void __init setup_hpet_timer(void)
cd->cpumask = cpumask_of(cpu);
clockevent_set_clock(cd, HPET_FREQ);
cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
cd->min_delta_ns = 5000;
cd->min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, cd);
clockevents_register_device(cd);
setup_irq(HPET_T0_IRQ, &hpet_irq);
......
......@@ -30,13 +30,13 @@
#include "smp.h"
DEFINE_PER_CPU(int, cpu_state);
DEFINE_PER_CPU(uint32_t, core0_c0count);
static void *ipi_set0_regs[16];
static void *ipi_clear0_regs[16];
static void *ipi_status0_regs[16];
static void *ipi_en0_regs[16];
static void *ipi_mailbox_buf[16];
static uint32_t core0_c0count[NR_CPUS];
/* read a 32bit value from ipi register */
#define loongson3_ipi_read32(addr) readl(addr)
......@@ -275,12 +275,14 @@ void loongson3_ipi_interrupt(struct pt_regs *regs)
if (action & SMP_ASK_C0COUNT) {
BUG_ON(cpu != 0);
c0count = read_c0_count();
for (i = 1; i < num_possible_cpus(); i++)
per_cpu(core0_c0count, i) = c0count;
c0count = c0count ? c0count : 1;
for (i = 1; i < nr_cpu_ids; i++)
core0_c0count[i] = c0count;
__wbflush(); /* Let others see the result ASAP */
}
}
#define MAX_LOOPS 1111
#define MAX_LOOPS 800
/*
* SMP init and finish on secondary CPUs
*/
......@@ -305,16 +307,20 @@ static void loongson3_init_secondary(void)
cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
i = 0;
__this_cpu_write(core0_c0count, 0);
core0_c0count[cpu] = 0;
loongson3_send_ipi_single(0, SMP_ASK_C0COUNT);
while (!__this_cpu_read(core0_c0count)) {
while (!core0_c0count[cpu]) {
i++;
cpu_relax();
}
if (i > MAX_LOOPS)
i = MAX_LOOPS;
initcount = __this_cpu_read(core0_c0count) + i;
if (cpu_data[cpu].package)
initcount = core0_c0count[cpu] + i;
else /* Local access is faster for loops */
initcount = core0_c0count[cpu] + i/2;
write_c0_count(initcount);
}
......
......@@ -1266,6 +1266,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
*/
sig = mips_dsemul(xcp, ir,
contpc);
if (sig < 0)
break;
if (sig)
xcp->cp0_epc = bcpc;
/*
......@@ -1319,6 +1321,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
* instruction in the dslot
*/
sig = mips_dsemul(xcp, ir, contpc);
if (sig < 0)
break;
if (sig)
xcp->cp0_epc = bcpc;
/* SIGILL forces out of the emulation loop. */
......
......@@ -23,27 +23,39 @@
union ieee754dp ieee754dp_neg(union ieee754dp x)
{
unsigned int oldrm;
union ieee754dp y;
oldrm = ieee754_csr.rm;
ieee754_csr.rm = FPU_CSR_RD;
y = ieee754dp_sub(ieee754dp_zero(0), x);
ieee754_csr.rm = oldrm;
if (ieee754_csr.abs2008) {
y = x;
DPSIGN(y) = !DPSIGN(x);
} else {
unsigned int oldrm;
oldrm = ieee754_csr.rm;
ieee754_csr.rm = FPU_CSR_RD;
y = ieee754dp_sub(ieee754dp_zero(0), x);
ieee754_csr.rm = oldrm;
}
return y;
}
union ieee754dp ieee754dp_abs(union ieee754dp x)
{
unsigned int oldrm;
union ieee754dp y;
oldrm = ieee754_csr.rm;
ieee754_csr.rm = FPU_CSR_RD;
if (DPSIGN(x))
y = ieee754dp_sub(ieee754dp_zero(0), x);
else
y = ieee754dp_add(ieee754dp_zero(0), x);
ieee754_csr.rm = oldrm;
if (ieee754_csr.abs2008) {
y = x;
DPSIGN(y) = 0;
} else {
unsigned int oldrm;
oldrm = ieee754_csr.rm;
ieee754_csr.rm = FPU_CSR_RD;
if (DPSIGN(x))
y = ieee754dp_sub(ieee754dp_zero(0), x);
else
y = ieee754dp_add(ieee754dp_zero(0), x);
ieee754_csr.rm = oldrm;
}
return y;
}
......@@ -38,10 +38,13 @@ int ieee754dp_tint(union ieee754dp x)
switch (xc) {
case IEEE754_CLASS_SNAN:
case IEEE754_CLASS_QNAN:
case IEEE754_CLASS_INF:
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754si_indef();
case IEEE754_CLASS_INF:
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754si_overflow(xs);
case IEEE754_CLASS_ZERO:
return 0;
......@@ -53,7 +56,7 @@ int ieee754dp_tint(union ieee754dp x)
/* Set invalid. We will only use overflow for floating
point overflow */
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754si_indef();
return ieee754si_overflow(xs);
}
/* oh gawd */
if (xe > DP_FBITS) {
......@@ -93,7 +96,7 @@ int ieee754dp_tint(union ieee754dp x)
if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {
/* This can happen after rounding */
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754si_indef();
return ieee754si_overflow(xs);
}
if (round || sticky)
ieee754_setcx(IEEE754_INEXACT);
......
......@@ -38,10 +38,13 @@ s64 ieee754dp_tlong(union ieee754dp x)
switch (xc) {
case IEEE754_CLASS_SNAN:
case IEEE754_CLASS_QNAN:
case IEEE754_CLASS_INF:
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754di_indef();
case IEEE754_CLASS_INF:
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754di_overflow(xs);
case IEEE754_CLASS_ZERO:
return 0;
......@@ -56,7 +59,7 @@ s64 ieee754dp_tlong(union ieee754dp x)
/* Set invalid. We will only use overflow for floating
point overflow */
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754di_indef();
return ieee754di_overflow(xs);
}
/* oh gawd */
if (xe > DP_FBITS) {
......@@ -97,7 +100,7 @@ s64 ieee754dp_tlong(union ieee754dp x)
if ((xm >> 63) != 0) {
/* This can happen after rounding */
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754di_indef();
return ieee754di_overflow(xs);
}
if (round || sticky)
ieee754_setcx(IEEE754_INEXACT);
......
......@@ -31,17 +31,41 @@ struct emuframe {
unsigned long epc;
};
/*
* Set up an emulation frame for instruction IR, from a delay slot of
* a branch jumping to CPC. Return 0 if successful, -1 if no emulation
* required, otherwise a signal number causing a frame setup failure.
*/
int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
{
int isa16 = get_isa16_mode(regs->cp0_epc);
mips_instruction break_math;
struct emuframe __user *fr;
int err;
if ((get_isa16_mode(regs->cp0_epc) && ((ir >> 16) == MM_NOP16)) ||
(ir == 0)) {
/* NOP is easy */
regs->cp0_epc = cpc;
clear_delay_slot(regs);
return 0;
/* NOP is easy */
if (ir == 0)
return -1;
/* microMIPS instructions */
if (isa16) {
union mips_instruction insn = { .word = ir };
/* NOP16 aka MOVE16 $0, $0 */
if ((ir >> 16) == MM_NOP16)
return -1;
/* ADDIUPC */
if (insn.mm_a_format.opcode == mm_addiupc_op) {
unsigned int rs;
s32 v;
rs = (((insn.mm_a_format.rs + 0x1e) & 0xf) + 2);
v = regs->cp0_epc & ~3;
v += insn.mm_a_format.simmediate << 2;
regs->regs[rs] = (long)v;
return -1;
}
}
pr_debug("dsemul %lx %lx\n", regs->cp0_epc, cpc);
......@@ -55,14 +79,10 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
* Algorithmics used a system call instruction, and
* borrowed that vector. MIPS/Linux version is a bit
* more heavyweight in the interests of portability and
* multiprocessor support. For Linux we generate a
* an unaligned access and force an address error exception.
*
* For embedded systems (stand-alone) we prefer to use a
* non-existing CP1 instruction. This prevents us from emulating
* branches, but gives us a cleaner interface to the exception
* handler (single entry point).
* multiprocessor support. For Linux we use a BREAK 514
* instruction causing a breakpoint exception.
*/
break_math = BREAK_MATH(isa16);
/* Ensure that the two instructions are in the same cache line */
fr = (struct emuframe __user *)
......@@ -72,14 +92,18 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe))))
return SIGBUS;
if (get_isa16_mode(regs->cp0_epc)) {
err = __put_user(ir >> 16, (u16 __user *)(&fr->emul));
err |= __put_user(ir & 0xffff, (u16 __user *)((long)(&fr->emul) + 2));
err |= __put_user(BREAK_MATH >> 16, (u16 __user *)(&fr->badinst));
err |= __put_user(BREAK_MATH & 0xffff, (u16 __user *)((long)(&fr->badinst) + 2));
if (isa16) {
err = __put_user(ir >> 16,
(u16 __user *)(&fr->emul));
err |= __put_user(ir & 0xffff,
(u16 __user *)((long)(&fr->emul) + 2));
err |= __put_user(break_math >> 16,
(u16 __user *)(&fr->badinst));
err |= __put_user(break_math & 0xffff,
(u16 __user *)((long)(&fr->badinst) + 2));
} else {
err = __put_user(ir, &fr->emul);
err |= __put_user((mips_instruction)BREAK_MATH, &fr->badinst);
err |= __put_user(break_math, &fr->badinst);
}
err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie);
......@@ -90,8 +114,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
return SIGBUS;
}
regs->cp0_epc = ((unsigned long) &fr->emul) |
get_isa16_mode(regs->cp0_epc);
regs->cp0_epc = (unsigned long)&fr->emul | isa16;
flush_cache_sigtramp((unsigned long)&fr->emul);
......@@ -100,6 +123,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
int do_dsemulret(struct pt_regs *xcp)
{
int isa16 = get_isa16_mode(xcp->cp0_epc);
struct emuframe __user *fr;
unsigned long epc;
u32 insn, cookie;
......@@ -122,16 +146,19 @@ int do_dsemulret(struct pt_regs *xcp)
* - Is the instruction pointed to by the EPC an BREAK_MATH?
* - Is the following memory word the BD_COOKIE?
*/
if (get_isa16_mode(xcp->cp0_epc)) {
err = __get_user(instr[0], (u16 __user *)(&fr->badinst));
err |= __get_user(instr[1], (u16 __user *)((long)(&fr->badinst) + 2));
if (isa16) {
err = __get_user(instr[0],
(u16 __user *)(&fr->badinst));
err |= __get_user(instr[1],
(u16 __user *)((long)(&fr->badinst) + 2));
insn = (instr[0] << 16) | instr[1];
} else {
err = __get_user(insn, &fr->badinst);
}
err |= __get_user(cookie, &fr->cookie);
if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) {
if (unlikely(err ||
insn != BREAK_MATH(isa16) || cookie != BD_COOKIE)) {
MIPS_FPU_EMU_INC_STATS(errors);
return 0;
}
......
......@@ -59,7 +59,8 @@ const union ieee754dp __ieee754dp_spcvals[] = {
DPCNST(1, 3, 0x4000000000000ULL), /* - 10.0 */
DPCNST(0, DP_EMAX + 1, 0x0000000000000ULL), /* + infinity */
DPCNST(1, DP_EMAX + 1, 0x0000000000000ULL), /* - infinity */
DPCNST(0, DP_EMAX + 1, 0x7FFFFFFFFFFFFULL), /* + indef quiet Nan */
DPCNST(0, DP_EMAX + 1, 0x7FFFFFFFFFFFFULL), /* + ind legacy qNaN */
DPCNST(0, DP_EMAX + 1, 0x8000000000000ULL), /* + indef 2008 qNaN */
DPCNST(0, DP_EMAX, 0xFFFFFFFFFFFFFULL), /* + max */
DPCNST(1, DP_EMAX, 0xFFFFFFFFFFFFFULL), /* - max */
DPCNST(0, DP_EMIN, 0x0000000000000ULL), /* + min normal */
......@@ -82,7 +83,8 @@ const union ieee754sp __ieee754sp_spcvals[] = {
SPCNST(1, 3, 0x200000), /* - 10.0 */
SPCNST(0, SP_EMAX + 1, 0x000000), /* + infinity */
SPCNST(1, SP_EMAX + 1, 0x000000), /* - infinity */
SPCNST(0, SP_EMAX + 1, 0x3FFFFF), /* + indef quiet Nan */
SPCNST(0, SP_EMAX + 1, 0x3FFFFF), /* + indef legacy quiet NaN */
SPCNST(0, SP_EMAX + 1, 0x400000), /* + indef 2008 quiet NaN */
SPCNST(0, SP_EMAX, 0x7FFFFF), /* + max normal */
SPCNST(1, SP_EMAX, 0x7FFFFF), /* - max normal */
SPCNST(0, SP_EMIN, 0x000000), /* + min normal */
......
......@@ -221,15 +221,16 @@ union ieee754dp ieee754dp_dump(char *s, union ieee754dp x);
#define IEEE754_SPCVAL_NTEN 5 /* -10.0 */
#define IEEE754_SPCVAL_PINFINITY 6 /* +inf */
#define IEEE754_SPCVAL_NINFINITY 7 /* -inf */
#define IEEE754_SPCVAL_INDEF 8 /* quiet NaN */
#define IEEE754_SPCVAL_PMAX 9 /* +max norm */
#define IEEE754_SPCVAL_NMAX 10 /* -max norm */
#define IEEE754_SPCVAL_PMIN 11 /* +min norm */
#define IEEE754_SPCVAL_NMIN 12 /* -min norm */
#define IEEE754_SPCVAL_PMIND 13 /* +min denorm */
#define IEEE754_SPCVAL_NMIND 14 /* -min denorm */
#define IEEE754_SPCVAL_P1E31 15 /* + 1.0e31 */
#define IEEE754_SPCVAL_P1E63 16 /* + 1.0e63 */
#define IEEE754_SPCVAL_INDEF_LEG 8 /* legacy quiet NaN */
#define IEEE754_SPCVAL_INDEF_2008 9 /* IEEE 754-2008 quiet NaN */
#define IEEE754_SPCVAL_PMAX 10 /* +max norm */
#define IEEE754_SPCVAL_NMAX 11 /* -max norm */
#define IEEE754_SPCVAL_PMIN 12 /* +min norm */
#define IEEE754_SPCVAL_NMIN 13 /* -min norm */
#define IEEE754_SPCVAL_PMIND 14 /* +min denorm */
#define IEEE754_SPCVAL_NMIND 15 /* -min denorm */
#define IEEE754_SPCVAL_P1E31 16 /* + 1.0e31 */
#define IEEE754_SPCVAL_P1E63 17 /* + 1.0e63 */
extern const union ieee754dp __ieee754dp_spcvals[];
extern const union ieee754sp __ieee754sp_spcvals[];
......@@ -243,7 +244,8 @@ extern const union ieee754sp __ieee754sp_spcvals[];
#define ieee754dp_zero(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
#define ieee754dp_one(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
#define ieee754dp_ten(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
#define ieee754dp_indef() (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
#define ieee754dp_indef() (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF_LEG + \
ieee754_csr.nan2008])
#define ieee754dp_max(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
#define ieee754dp_min(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
#define ieee754dp_mind(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
......@@ -254,7 +256,8 @@ extern const union ieee754sp __ieee754sp_spcvals[];
#define ieee754sp_zero(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
#define ieee754sp_one(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
#define ieee754sp_ten(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
#define ieee754sp_indef() (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
#define ieee754sp_indef() (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF_LEG + \
ieee754_csr.nan2008])
#define ieee754sp_max(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
#define ieee754sp_min(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
#define ieee754sp_mind(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
......@@ -266,12 +269,25 @@ extern const union ieee754sp __ieee754sp_spcvals[];
*/
static inline int ieee754si_indef(void)
{
return INT_MAX;
return ieee754_csr.nan2008 ? 0 : INT_MAX;
}
static inline s64 ieee754di_indef(void)
{
return S64_MAX;
return ieee754_csr.nan2008 ? 0 : S64_MAX;
}
/*
* Overflow integer value
*/
static inline int ieee754si_overflow(int xs)
{
return ieee754_csr.nan2008 && xs ? INT_MIN : INT_MAX;
}
static inline s64 ieee754di_overflow(int xs)
{
return ieee754_csr.nan2008 && xs ? S64_MIN : S64_MAX;
}
/* result types for xctx.rt */
......
......@@ -37,8 +37,11 @@ static inline int ieee754dp_isnan(union ieee754dp x)
static inline int ieee754dp_issnan(union ieee754dp x)
{
int qbit;
assert(ieee754dp_isnan(x));
return (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1);
qbit = (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1);
return ieee754_csr.nan2008 ^ qbit;
}
......@@ -51,7 +54,12 @@ union ieee754dp __cold ieee754dp_nanxcpt(union ieee754dp r)
assert(ieee754dp_issnan(r));
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754dp_indef();
if (ieee754_csr.nan2008)
DPMANT(r) |= DP_MBIT(DP_FBITS - 1);
else
r = ieee754dp_indef();
return r;
}
static u64 ieee754dp_get_rounding(int sn, u64 xm)
......
......@@ -63,10 +63,10 @@ static inline int ieee754_class_nan(int xc)
if (ve == SP_EMAX+1+SP_EBIAS) { \
if (vm == 0) \
vc = IEEE754_CLASS_INF; \
else if (vm & SP_MBIT(SP_FBITS-1)) \
vc = IEEE754_CLASS_SNAN; \
else \
else if (ieee754_csr.nan2008 ^ !(vm & SP_MBIT(SP_FBITS - 1))) \
vc = IEEE754_CLASS_QNAN; \
else \
vc = IEEE754_CLASS_SNAN; \
} else if (ve == SP_EMIN-1+SP_EBIAS) { \
if (vm) { \
ve = SP_EMIN; \
......@@ -97,10 +97,10 @@ static inline int ieee754_class_nan(int xc)
if (ve == DP_EMAX+1+DP_EBIAS) { \
if (vm == 0) \
vc = IEEE754_CLASS_INF; \
else if (vm & DP_MBIT(DP_FBITS-1)) \
vc = IEEE754_CLASS_SNAN; \
else \
else if (ieee754_csr.nan2008 ^ !(vm & DP_MBIT(DP_FBITS - 1))) \
vc = IEEE754_CLASS_QNAN; \
else \
vc = IEEE754_CLASS_SNAN; \
} else if (ve == DP_EMIN-1+DP_EBIAS) { \
if (vm) { \
ve = DP_EMIN; \
......
......@@ -37,8 +37,11 @@ static inline int ieee754sp_isnan(union ieee754sp x)
static inline int ieee754sp_issnan(union ieee754sp x)
{
int qbit;
assert(ieee754sp_isnan(x));
return SPMANT(x) & SP_MBIT(SP_FBITS - 1);
qbit = (SPMANT(x) & SP_MBIT(SP_FBITS - 1)) == SP_MBIT(SP_FBITS - 1);
return ieee754_csr.nan2008 ^ qbit;
}
......@@ -51,7 +54,12 @@ union ieee754sp __cold ieee754sp_nanxcpt(union ieee754sp r)
assert(ieee754sp_issnan(r));
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754sp_indef();
if (ieee754_csr.nan2008)
SPMANT(r) |= SP_MBIT(SP_FBITS - 1);
else
r = ieee754sp_indef();
return r;
}
static unsigned ieee754sp_get_rounding(int sn, unsigned xm)
......
......@@ -44,13 +44,16 @@ union ieee754sp ieee754sp_fdp(union ieee754dp x)
switch (xc) {
case IEEE754_CLASS_SNAN:
return ieee754sp_nanxcpt(ieee754sp_nan_fdp(xs, xm));
x = ieee754dp_nanxcpt(x);
EXPLODEXDP;
/* Fall through. */
case IEEE754_CLASS_QNAN:
y = ieee754sp_nan_fdp(xs, xm);
EXPLODEYSP;
if (!ieee754_class_nan(yc))
y = ieee754sp_indef();
if (!ieee754_csr.nan2008) {
EXPLODEYSP;
if (!ieee754_class_nan(yc))
y = ieee754sp_indef();
}
return y;
case IEEE754_CLASS_INF:
......
......@@ -23,27 +23,39 @@
union ieee754sp ieee754sp_neg(union ieee754sp x)
{
unsigned int oldrm;
union ieee754sp y;
oldrm = ieee754_csr.rm;
ieee754_csr.rm = FPU_CSR_RD;
y = ieee754sp_sub(ieee754sp_zero(0), x);
ieee754_csr.rm = oldrm;
if (ieee754_csr.abs2008) {
y = x;
SPSIGN(y) = !SPSIGN(x);
} else {
unsigned int oldrm;
oldrm = ieee754_csr.rm;
ieee754_csr.rm = FPU_CSR_RD;
y = ieee754sp_sub(ieee754sp_zero(0), x);
ieee754_csr.rm = oldrm;
}
return y;
}
union ieee754sp ieee754sp_abs(union ieee754sp x)
{
unsigned int oldrm;
union ieee754sp y;
oldrm = ieee754_csr.rm;
ieee754_csr.rm = FPU_CSR_RD;
if (SPSIGN(x))
y = ieee754sp_sub(ieee754sp_zero(0), x);
else
y = ieee754sp_add(ieee754sp_zero(0), x);
ieee754_csr.rm = oldrm;
if (ieee754_csr.abs2008) {
y = x;
SPSIGN(y) = 0;
} else {
unsigned int oldrm;
oldrm = ieee754_csr.rm;
ieee754_csr.rm = FPU_CSR_RD;
if (SPSIGN(x))
y = ieee754sp_sub(ieee754sp_zero(0), x);
else
y = ieee754sp_add(ieee754sp_zero(0), x);
ieee754_csr.rm = oldrm;
}
return y;
}
......@@ -38,10 +38,13 @@ int ieee754sp_tint(union ieee754sp x)
switch (xc) {
case IEEE754_CLASS_SNAN:
case IEEE754_CLASS_QNAN:
case IEEE754_CLASS_INF:
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754si_indef();
case IEEE754_CLASS_INF:
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754si_overflow(xs);
case IEEE754_CLASS_ZERO:
return 0;
......@@ -56,7 +59,7 @@ int ieee754sp_tint(union ieee754sp x)
/* Set invalid. We will only use overflow for floating
point overflow */
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754si_indef();
return ieee754si_overflow(xs);
}
/* oh gawd */
if (xe > SP_FBITS) {
......@@ -97,7 +100,7 @@ int ieee754sp_tint(union ieee754sp x)
if ((xm >> 31) != 0) {
/* This can happen after rounding */
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754si_indef();
return ieee754si_overflow(xs);
}
if (round || sticky)
ieee754_setcx(IEEE754_INEXACT);
......
......@@ -39,10 +39,13 @@ s64 ieee754sp_tlong(union ieee754sp x)
switch (xc) {
case IEEE754_CLASS_SNAN:
case IEEE754_CLASS_QNAN:
case IEEE754_CLASS_INF:
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754di_indef();
case IEEE754_CLASS_INF:
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754di_overflow(xs);
case IEEE754_CLASS_ZERO:
return 0;
......@@ -57,7 +60,7 @@ s64 ieee754sp_tlong(union ieee754sp x)
/* Set invalid. We will only use overflow for floating
point overflow */
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754di_indef();
return ieee754di_overflow(xs);
}
/* oh gawd */
if (xe > SP_FBITS) {
......@@ -94,7 +97,7 @@ s64 ieee754sp_tlong(union ieee754sp x)
if ((xm >> 63) != 0) {
/* This can happen after rounding */
ieee754_setcx(IEEE754_INVALID_OPERATION);
return ieee754di_indef();
return ieee754di_overflow(xs);
}
if (round || sticky)
ieee754_setcx(IEEE754_INEXACT);
......
......@@ -241,7 +241,7 @@ static void output_pgtable_bits_defines(void)
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT);
#endif
#ifdef CONFIG_CPU_MIPSR2
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
if (cpu_has_rixi) {
#ifdef _PAGE_NO_EXEC_SHIFT
pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT);
......
......@@ -43,6 +43,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o
obj-$(CONFIG_LANTIQ) += fixup-lantiq.o
obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o
obj-$(CONFIG_SOC_MT7620) += pci-mt7620.o
obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o
obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o
obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
......
This diff is collapsed.
if MACH_PIC32
choice
prompt "Machine Type"
config PIC32MZDA
bool "Microchip PIC32MZDA Platform"
select BOOT_ELF32
select BOOT_RAW
select CEVT_R4K
select CSRC_R4K
select DMA_NONCOHERENT
select SYS_HAS_CPU_MIPS32_R2
select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select ARCH_REQUIRE_GPIOLIB
select HAVE_MACH_CLKDEV
select COMMON_CLK
select CLKDEV_LOOKUP
select LIBFDT
select USE_OF
select PINCTRL
select PIC32_EVIC
help
Support for the Microchip PIC32MZDA microcontroller.
This is a 32-bit microcontroller with support for external or
internally packaged DDR2 memory up to 128MB.
For more information, see <http://www.microchip.com/>.
endchoice
choice
prompt "Devicetree selection"
default DTB_PIC32_NONE
help
Select the devicetree.
config DTB_PIC32_NONE
bool "None"
config DTB_PIC32_MZDA_SK
bool "PIC32MZDA Starter Kit"
depends on PIC32MZDA
select BUILTIN_DTB
endchoice
endif # MACH_PIC32
#
# Joshua Henderson, <joshua.henderson@microchip.com>
# Copyright (C) 2015 Microchip Technology, Inc. All rights reserved.
#
obj-$(CONFIG_MACH_PIC32) += common/
obj-$(CONFIG_PIC32MZDA) += pic32mzda/
#
# PIC32MZDA
#
platform-$(CONFIG_PIC32MZDA) += pic32/
cflags-$(CONFIG_PIC32MZDA) += -I$(srctree)/arch/mips/include/asm/mach-pic32
load-$(CONFIG_PIC32MZDA) += 0xffffffff88000000
all-$(CONFIG_PIC32MZDA) := $(COMPRESSION_FNAME).bin
#
# Joshua Henderson, <joshua.henderson@microchip.com>
# Copyright (C) 2015 Microchip Technology, Inc. All rights reserved.
#
obj-y = reset.o irq.o
/*
* Joshua Henderson <joshua.henderson@microchip.com>
* Copyright (C) 2015 Microchip Technology 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.
*/
#include <linux/init.h>
#include <linux/irqchip.h>
#include <asm/irq.h>
void __init arch_init_irq(void)
{
irqchip_init();
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment