mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 05:00:55 +07:00
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 ...
This commit is contained in:
commit
e2464688b5
@ -0,0 +1,67 @@
|
||||
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>;
|
||||
...
|
||||
};
|
@ -0,0 +1,31 @@
|
||||
* 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.
|
@ -0,0 +1,26 @@
|
||||
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>;
|
||||
};
|
61
Documentation/devicetree/bindings/net/ralink,rt2880-net.txt
Normal file
61
Documentation/devicetree/bindings/net/ralink,rt2880-net.txt
Normal file
@ -0,0 +1,61 @@
|
||||
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>;
|
||||
};
|
||||
|
||||
};
|
32
Documentation/devicetree/bindings/net/ralink,rt3050-esw.txt
Normal file
32
Documentation/devicetree/bindings/net/ralink,rt3050-esw.txt
Normal file
@ -0,0 +1,32 @@
|
||||
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>;
|
||||
};
|
18
Documentation/devicetree/bindings/phy/phy-ath79-usb.txt
Normal file
18
Documentation/devicetree/bindings/phy/phy-ath79-usb.txt
Normal file
@ -0,0 +1,18 @@
|
||||
* 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.
|
||||
|
22
MAINTAINERS
22
MAINTAINERS
@ -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
|
||||
|
7
arch/mips/boot/compressed/uart-prom.c
Normal file
7
arch/mips/boot/compressed/uart-prom.c
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
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";
|
||||
};
|
||||
};
|
||||
|
12
arch/mips/boot/dts/pic32/Makefile
Normal file
12
arch/mips/boot/dts/pic32/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
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
|
236
arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi
Normal file
236
arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi
Normal file
@ -0,0 +1,236 @@
|
||||
/*
|
||||
* 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";
|
||||
};
|
||||
};
|
||||
};
|
281
arch/mips/boot/dts/pic32/pic32mzda.dtsi
Normal file
281
arch/mips/boot/dts/pic32/pic32mzda.dtsi
Normal file
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* 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";
|
||||
};
|
||||
};
|
151
arch/mips/boot/dts/pic32/pic32mzda_sk.dts
Normal file
151
arch/mips/boot/dts/pic32/pic32mzda_sk.dts
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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>;
|
||||
|
89
arch/mips/configs/pic32mzda_defconfig
Normal file
89
arch/mips/configs/pic32mzda_defconfig
Normal file
@ -0,0 +1,89 @@
|
||||
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 */
|
||||
|
32
arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h
Normal file
32
arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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 */
|
22
arch/mips/include/asm/mach-pic32/irq.h
Normal file
22
arch/mips/include/asm/mach-pic32/irq.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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 */
|
44
arch/mips/include/asm/mach-pic32/pic32.h
Normal file
44
arch/mips/include/asm/mach-pic32/pic32.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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 */
|
24
arch/mips/include/asm/mach-pic32/spaces.h
Normal file
24
arch/mips/include/asm/mach-pic32/spaces.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 */
|
9
arch/mips/include/asm/mach-ralink/irq.h
Normal file
9
arch/mips/include/asm/mach-ralink/irq.h
Normal file
@ -0,0 +1,9 @@
|
||||
#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
|
38
arch/mips/include/asm/mach-ralink/mt7621.h
Normal file
38
arch/mips/include/asm/mach-ralink/mt7621.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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 (is_mips64) {
|
||||
/* 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 {
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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 =
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <linux/random.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/cacheops.h>
|
||||
#include <asm/cpu-info.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/tlbflush.h>
|
||||
@ -29,7 +30,6 @@
|
||||
#include <asm/r4kcache.h>
|
||||
#define CONFIG_MIPS_MT
|
||||
|
||||
#include "opcode.h"
|
||||
#include "interrupt.h"
|
||||
#include "commpage.h"
|
||||
|
||||
@ -1239,21 +1239,20 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc,
|
||||
er = EMULATE_FAIL;
|
||||
break;
|
||||
|
||||
case mfmcz_op:
|
||||
case mfmc0_op:
|
||||
#ifdef KVM_MIPS_DEBUG_COP0_COUNTERS
|
||||
cop0->stat[MIPS_CP0_STATUS][0]++;
|
||||
#endif
|
||||
if (rt != 0) {
|
||||
if (rt != 0)
|
||||
vcpu->arch.gprs[rt] =
|
||||
kvm_read_c0_guest_status(cop0);
|
||||
}
|
||||
/* EI */
|
||||
if (inst & 0x20) {
|
||||
kvm_debug("[%#lx] mfmcz_op: EI\n",
|
||||
kvm_debug("[%#lx] mfmc0_op: EI\n",
|
||||
vcpu->arch.pc);
|
||||
kvm_set_c0_guest_status(cop0, ST0_IE);
|
||||
} else {
|
||||
kvm_debug("[%#lx] mfmcz_op: DI\n",
|
||||
kvm_debug("[%#lx] mfmc0_op: DI\n",
|
||||
vcpu->arch.pc);
|
||||
kvm_clear_c0_guest_status(cop0, ST0_IE);
|
||||
}
|
||||
@ -1545,19 +1544,6 @@ int kvm_mips_sync_icache(unsigned long va, struct kvm_vcpu *vcpu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MIPS_CACHE_OP_INDEX_INV 0x0
|
||||
#define MIPS_CACHE_OP_INDEX_LD_TAG 0x1
|
||||
#define MIPS_CACHE_OP_INDEX_ST_TAG 0x2
|
||||
#define MIPS_CACHE_OP_IMP 0x3
|
||||
#define MIPS_CACHE_OP_HIT_INV 0x4
|
||||
#define MIPS_CACHE_OP_FILL_WB_INV 0x5
|
||||
#define MIPS_CACHE_OP_HIT_HB 0x6
|
||||
#define MIPS_CACHE_OP_FETCH_LOCK 0x7
|
||||
|
||||
#define MIPS_CACHE_ICACHE 0x0
|
||||
#define MIPS_CACHE_DCACHE 0x1
|
||||
#define MIPS_CACHE_SEC 0x3
|
||||
|
||||
enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
|
||||
uint32_t cause,
|
||||
struct kvm_run *run,
|
||||
@ -1582,8 +1568,8 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
|
||||
base = (inst >> 21) & 0x1f;
|
||||
op_inst = (inst >> 16) & 0x1f;
|
||||
offset = (int16_t)inst;
|
||||
cache = (inst >> 16) & 0x3;
|
||||
op = (inst >> 18) & 0x7;
|
||||
cache = op_inst & CacheOp_Cache;
|
||||
op = op_inst & CacheOp_Op;
|
||||
|
||||
va = arch->gprs[base] + offset;
|
||||
|
||||
@ -1595,14 +1581,14 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
|
||||
* invalidate the caches entirely by stepping through all the
|
||||
* ways/indexes
|
||||
*/
|
||||
if (op == MIPS_CACHE_OP_INDEX_INV) {
|
||||
if (op == Index_Writeback_Inv) {
|
||||
kvm_debug("@ %#lx/%#lx CACHE (cache: %#x, op: %#x, base[%d]: %#lx, offset: %#x\n",
|
||||
vcpu->arch.pc, vcpu->arch.gprs[31], cache, op, base,
|
||||
arch->gprs[base], offset);
|
||||
|
||||
if (cache == MIPS_CACHE_DCACHE)
|
||||
if (cache == Cache_D)
|
||||
r4k_blast_dcache();
|
||||
else if (cache == MIPS_CACHE_ICACHE)
|
||||
else if (cache == Cache_I)
|
||||
r4k_blast_icache();
|
||||
else {
|
||||
kvm_err("%s: unsupported CACHE INDEX operation\n",
|
||||
@ -1675,9 +1661,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
|
||||
|
||||
skip_fault:
|
||||
/* XXXKYMA: Only a subset of cache ops are supported, used by Linux */
|
||||
if (cache == MIPS_CACHE_DCACHE
|
||||
&& (op == MIPS_CACHE_OP_FILL_WB_INV
|
||||
|| op == MIPS_CACHE_OP_HIT_INV)) {
|
||||
if (op_inst == Hit_Writeback_Inv_D || op_inst == Hit_Invalidate_D) {
|
||||
flush_dcache_line(va);
|
||||
|
||||
#ifdef CONFIG_KVM_MIPS_DYN_TRANS
|
||||
@ -1687,7 +1671,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
|
||||
*/
|
||||
kvm_mips_trans_cache_va(inst, opc, vcpu);
|
||||
#endif
|
||||
} else if (op == MIPS_CACHE_OP_HIT_INV && cache == MIPS_CACHE_ICACHE) {
|
||||
} else if (op_inst == Hit_Invalidate_I) {
|
||||
flush_dcache_line(va);
|
||||
flush_icache_line(va);
|
||||
|
||||
@ -1781,7 +1765,7 @@ enum emulation_result kvm_mips_emulate_syscall(unsigned long cause,
|
||||
kvm_debug("Delivering SYSCALL @ pc %#lx\n", arch->pc);
|
||||
|
||||
kvm_change_c0_guest_cause(cop0, (0xff),
|
||||
(T_SYSCALL << CAUSEB_EXCCODE));
|
||||
(EXCCODE_SYS << CAUSEB_EXCCODE));
|
||||
|
||||
/* Set PC to the exception entry point */
|
||||
arch->pc = KVM_GUEST_KSEG0 + 0x180;
|
||||
@ -1828,7 +1812,7 @@ enum emulation_result kvm_mips_emulate_tlbmiss_ld(unsigned long cause,
|
||||
}
|
||||
|
||||
kvm_change_c0_guest_cause(cop0, (0xff),
|
||||
(T_TLB_LD_MISS << CAUSEB_EXCCODE));
|
||||
(EXCCODE_TLBL << CAUSEB_EXCCODE));
|
||||
|
||||
/* setup badvaddr, context and entryhi registers for the guest */
|
||||
kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
|
||||
@ -1874,7 +1858,7 @@ enum emulation_result kvm_mips_emulate_tlbinv_ld(unsigned long cause,
|
||||
}
|
||||
|
||||
kvm_change_c0_guest_cause(cop0, (0xff),
|
||||
(T_TLB_LD_MISS << CAUSEB_EXCCODE));
|
||||
(EXCCODE_TLBL << CAUSEB_EXCCODE));
|
||||
|
||||
/* setup badvaddr, context and entryhi registers for the guest */
|
||||
kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
|
||||
@ -1918,7 +1902,7 @@ enum emulation_result kvm_mips_emulate_tlbmiss_st(unsigned long cause,
|
||||
}
|
||||
|
||||
kvm_change_c0_guest_cause(cop0, (0xff),
|
||||
(T_TLB_ST_MISS << CAUSEB_EXCCODE));
|
||||
(EXCCODE_TLBS << CAUSEB_EXCCODE));
|
||||
|
||||
/* setup badvaddr, context and entryhi registers for the guest */
|
||||
kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
|
||||
@ -1962,7 +1946,7 @@ enum emulation_result kvm_mips_emulate_tlbinv_st(unsigned long cause,
|
||||
}
|
||||
|
||||
kvm_change_c0_guest_cause(cop0, (0xff),
|
||||
(T_TLB_ST_MISS << CAUSEB_EXCCODE));
|
||||
(EXCCODE_TLBS << CAUSEB_EXCCODE));
|
||||
|
||||
/* setup badvaddr, context and entryhi registers for the guest */
|
||||
kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
|
||||
@ -2033,7 +2017,8 @@ enum emulation_result kvm_mips_emulate_tlbmod(unsigned long cause,
|
||||
arch->pc = KVM_GUEST_KSEG0 + 0x180;
|
||||
}
|
||||
|
||||
kvm_change_c0_guest_cause(cop0, (0xff), (T_TLB_MOD << CAUSEB_EXCCODE));
|
||||
kvm_change_c0_guest_cause(cop0, (0xff),
|
||||
(EXCCODE_MOD << CAUSEB_EXCCODE));
|
||||
|
||||
/* setup badvaddr, context and entryhi registers for the guest */
|
||||
kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
|
||||
@ -2068,7 +2053,7 @@ enum emulation_result kvm_mips_emulate_fpu_exc(unsigned long cause,
|
||||
arch->pc = KVM_GUEST_KSEG0 + 0x180;
|
||||
|
||||
kvm_change_c0_guest_cause(cop0, (0xff),
|
||||
(T_COP_UNUSABLE << CAUSEB_EXCCODE));
|
||||
(EXCCODE_CPU << CAUSEB_EXCCODE));
|
||||
kvm_change_c0_guest_cause(cop0, (CAUSEF_CE), (0x1 << CAUSEB_CE));
|
||||
|
||||
return EMULATE_DONE;
|
||||
@ -2096,7 +2081,7 @@ enum emulation_result kvm_mips_emulate_ri_exc(unsigned long cause,
|
||||
kvm_debug("Delivering RI @ pc %#lx\n", arch->pc);
|
||||
|
||||
kvm_change_c0_guest_cause(cop0, (0xff),
|
||||
(T_RES_INST << CAUSEB_EXCCODE));
|
||||
(EXCCODE_RI << CAUSEB_EXCCODE));
|
||||
|
||||
/* Set PC to the exception entry point */
|
||||
arch->pc = KVM_GUEST_KSEG0 + 0x180;
|
||||
@ -2131,7 +2116,7 @@ enum emulation_result kvm_mips_emulate_bp_exc(unsigned long cause,
|
||||
kvm_debug("Delivering BP @ pc %#lx\n", arch->pc);
|
||||
|
||||
kvm_change_c0_guest_cause(cop0, (0xff),
|
||||
(T_BREAK << CAUSEB_EXCCODE));
|
||||
(EXCCODE_BP << CAUSEB_EXCCODE));
|
||||
|
||||
/* Set PC to the exception entry point */
|
||||
arch->pc = KVM_GUEST_KSEG0 + 0x180;
|
||||
@ -2166,7 +2151,7 @@ enum emulation_result kvm_mips_emulate_trap_exc(unsigned long cause,
|
||||
kvm_debug("Delivering TRAP @ pc %#lx\n", arch->pc);
|
||||
|
||||
kvm_change_c0_guest_cause(cop0, (0xff),
|
||||
(T_TRAP << CAUSEB_EXCCODE));
|
||||
(EXCCODE_TR << CAUSEB_EXCCODE));
|
||||
|
||||
/* Set PC to the exception entry point */
|
||||
arch->pc = KVM_GUEST_KSEG0 + 0x180;
|
||||
@ -2201,7 +2186,7 @@ enum emulation_result kvm_mips_emulate_msafpe_exc(unsigned long cause,
|
||||
kvm_debug("Delivering MSAFPE @ pc %#lx\n", arch->pc);
|
||||
|
||||
kvm_change_c0_guest_cause(cop0, (0xff),
|
||||
(T_MSAFPE << CAUSEB_EXCCODE));
|
||||
(EXCCODE_MSAFPE << CAUSEB_EXCCODE));
|
||||
|
||||
/* Set PC to the exception entry point */
|
||||
arch->pc = KVM_GUEST_KSEG0 + 0x180;
|
||||
@ -2236,7 +2221,7 @@ enum emulation_result kvm_mips_emulate_fpe_exc(unsigned long cause,
|
||||
kvm_debug("Delivering FPE @ pc %#lx\n", arch->pc);
|
||||
|
||||
kvm_change_c0_guest_cause(cop0, (0xff),
|
||||
(T_FPE << CAUSEB_EXCCODE));
|
||||
(EXCCODE_FPE << CAUSEB_EXCCODE));
|
||||
|
||||
/* Set PC to the exception entry point */
|
||||
arch->pc = KVM_GUEST_KSEG0 + 0x180;
|
||||
@ -2271,7 +2256,7 @@ enum emulation_result kvm_mips_emulate_msadis_exc(unsigned long cause,
|
||||
kvm_debug("Delivering MSADIS @ pc %#lx\n", arch->pc);
|
||||
|
||||
kvm_change_c0_guest_cause(cop0, (0xff),
|
||||
(T_MSADIS << CAUSEB_EXCCODE));
|
||||
(EXCCODE_MSADIS << CAUSEB_EXCCODE));
|
||||
|
||||
/* Set PC to the exception entry point */
|
||||
arch->pc = KVM_GUEST_KSEG0 + 0x180;
|
||||
@ -2480,25 +2465,25 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause,
|
||||
|
||||
if (usermode) {
|
||||
switch (exccode) {
|
||||
case T_INT:
|
||||
case T_SYSCALL:
|
||||
case T_BREAK:
|
||||
case T_RES_INST:
|
||||
case T_TRAP:
|
||||
case T_MSAFPE:
|
||||
case T_FPE:
|
||||
case T_MSADIS:
|
||||
case EXCCODE_INT:
|
||||
case EXCCODE_SYS:
|
||||
case EXCCODE_BP:
|
||||
case EXCCODE_RI:
|
||||
case EXCCODE_TR:
|
||||
case EXCCODE_MSAFPE:
|
||||
case EXCCODE_FPE:
|
||||
case EXCCODE_MSADIS:
|
||||
break;
|
||||
|
||||
case T_COP_UNUSABLE:
|
||||
case EXCCODE_CPU:
|
||||
if (((cause & CAUSEF_CE) >> CAUSEB_CE) == 0)
|
||||
er = EMULATE_PRIV_FAIL;
|
||||
break;
|
||||
|
||||
case T_TLB_MOD:
|
||||
case EXCCODE_MOD:
|
||||
break;
|
||||
|
||||
case T_TLB_LD_MISS:
|
||||
case EXCCODE_TLBL:
|
||||
/*
|
||||
* We we are accessing Guest kernel space, then send an
|
||||
* address error exception to the guest
|
||||
@ -2507,12 +2492,12 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause,
|
||||
kvm_debug("%s: LD MISS @ %#lx\n", __func__,
|
||||
badvaddr);
|
||||
cause &= ~0xff;
|
||||
cause |= (T_ADDR_ERR_LD << CAUSEB_EXCCODE);
|
||||
cause |= (EXCCODE_ADEL << CAUSEB_EXCCODE);
|
||||
er = EMULATE_PRIV_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case T_TLB_ST_MISS:
|
||||
case EXCCODE_TLBS:
|
||||
/*
|
||||
* We we are accessing Guest kernel space, then send an
|
||||
* address error exception to the guest
|
||||
@ -2521,26 +2506,26 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause,
|
||||
kvm_debug("%s: ST MISS @ %#lx\n", __func__,
|
||||
badvaddr);
|
||||
cause &= ~0xff;
|
||||
cause |= (T_ADDR_ERR_ST << CAUSEB_EXCCODE);
|
||||
cause |= (EXCCODE_ADES << CAUSEB_EXCCODE);
|
||||
er = EMULATE_PRIV_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case T_ADDR_ERR_ST:
|
||||
case EXCCODE_ADES:
|
||||
kvm_debug("%s: address error ST @ %#lx\n", __func__,
|
||||
badvaddr);
|
||||
if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) {
|
||||
cause &= ~0xff;
|
||||
cause |= (T_TLB_ST_MISS << CAUSEB_EXCCODE);
|
||||
cause |= (EXCCODE_TLBS << CAUSEB_EXCCODE);
|
||||
}
|
||||
er = EMULATE_PRIV_FAIL;
|
||||
break;
|
||||
case T_ADDR_ERR_LD:
|
||||
case EXCCODE_ADEL:
|
||||
kvm_debug("%s: address error LD @ %#lx\n", __func__,
|
||||
badvaddr);
|
||||
if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) {
|
||||
cause &= ~0xff;
|
||||
cause |= (T_TLB_LD_MISS << CAUSEB_EXCCODE);
|
||||
cause |= (EXCCODE_TLBL << CAUSEB_EXCCODE);
|
||||
}
|
||||
er = EMULATE_PRIV_FAIL;
|
||||
break;
|
||||
@ -2583,13 +2568,12 @@ enum emulation_result kvm_mips_handle_tlbmiss(unsigned long cause,
|
||||
* an entry into the guest TLB.
|
||||
*/
|
||||
index = kvm_mips_guest_tlb_lookup(vcpu,
|
||||
(va & VPN2_MASK) |
|
||||
(kvm_read_c0_guest_entryhi
|
||||
(vcpu->arch.cop0) & ASID_MASK));
|
||||
(va & VPN2_MASK) |
|
||||
(kvm_read_c0_guest_entryhi(vcpu->arch.cop0) & ASID_MASK));
|
||||
if (index < 0) {
|
||||
if (exccode == T_TLB_LD_MISS) {
|
||||
if (exccode == EXCCODE_TLBL) {
|
||||
er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu);
|
||||
} else if (exccode == T_TLB_ST_MISS) {
|
||||
} else if (exccode == EXCCODE_TLBS) {
|
||||
er = kvm_mips_emulate_tlbmiss_st(cause, opc, run, vcpu);
|
||||
} else {
|
||||
kvm_err("%s: invalid exc code: %d\n", __func__,
|
||||
@ -2604,10 +2588,10 @@ enum emulation_result kvm_mips_handle_tlbmiss(unsigned long cause,
|
||||
* exception to the guest
|
||||
*/
|
||||
if (!TLB_IS_VALID(*tlb, va)) {
|
||||
if (exccode == T_TLB_LD_MISS) {
|
||||
if (exccode == EXCCODE_TLBL) {
|
||||
er = kvm_mips_emulate_tlbinv_ld(cause, opc, run,
|
||||
vcpu);
|
||||
} else if (exccode == T_TLB_ST_MISS) {
|
||||
} else if (exccode == EXCCODE_TLBS) {
|
||||
er = kvm_mips_emulate_tlbinv_st(cause, opc, run,
|
||||
vcpu);
|
||||
} else {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
426
arch/mips/pci/pci-mt7620.c
Normal file
426
arch/mips/pci/pci-mt7620.c
Normal file
@ -0,0 +1,426 @@
|
||||
/*
|
||||
* Ralink MT7620A SoC PCI support
|
||||
*
|
||||
* Copyright (C) 2007-2013 Bruce Chang (Mediatek)
|
||||
* Copyright (C) 2013-2016 John Crispin <blogic@openwrt.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_pci.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/mach-ralink/ralink_regs.h>
|
||||
#include <asm/mach-ralink/mt7620.h>
|
||||
|
||||
#define RALINK_PCI_IO_MAP_BASE 0x10160000
|
||||
#define RALINK_PCI_MEMORY_BASE 0x0
|
||||
|
||||
#define RALINK_INT_PCIE0 4
|
||||
|
||||
#define RALINK_CLKCFG1 0x30
|
||||
#define RALINK_GPIOMODE 0x60
|
||||
|
||||
#define PPLL_CFG1 0x9c
|
||||
#define PDRV_SW_SET BIT(23)
|
||||
|
||||
#define PPLL_DRV 0xa0
|
||||
#define PDRV_SW_SET (1<<31)
|
||||
#define LC_CKDRVPD (1<<19)
|
||||
#define LC_CKDRVOHZ (1<<18)
|
||||
#define LC_CKDRVHZ (1<<17)
|
||||
#define LC_CKTEST (1<<16)
|
||||
|
||||
/* PCI Bridge registers */
|
||||
#define RALINK_PCI_PCICFG_ADDR 0x00
|
||||
#define PCIRST BIT(1)
|
||||
|
||||
#define RALINK_PCI_PCIENA 0x0C
|
||||
#define PCIINT2 BIT(20)
|
||||
|
||||
#define RALINK_PCI_CONFIG_ADDR 0x20
|
||||
#define RALINK_PCI_CONFIG_DATA_VIRT_REG 0x24
|
||||
#define RALINK_PCI_MEMBASE 0x28
|
||||
#define RALINK_PCI_IOBASE 0x2C
|
||||
|
||||
/* PCI RC registers */
|
||||
#define RALINK_PCI0_BAR0SETUP_ADDR 0x10
|
||||
#define RALINK_PCI0_IMBASEBAR0_ADDR 0x18
|
||||
#define RALINK_PCI0_ID 0x30
|
||||
#define RALINK_PCI0_CLASS 0x34
|
||||
#define RALINK_PCI0_SUBID 0x38
|
||||
#define RALINK_PCI0_STATUS 0x50
|
||||
#define PCIE_LINK_UP_ST BIT(0)
|
||||
|
||||
#define PCIEPHY0_CFG 0x90
|
||||
|
||||
#define RALINK_PCIEPHY_P0_CTL_OFFSET 0x7498
|
||||
#define RALINK_PCIE0_CLK_EN (1 << 26)
|
||||
|
||||
#define BUSY 0x80000000
|
||||
#define WAITRETRY_MAX 10
|
||||
#define WRITE_MODE (1UL << 23)
|
||||
#define DATA_SHIFT 0
|
||||
#define ADDR_SHIFT 8
|
||||
|
||||
|
||||
static void __iomem *bridge_base;
|
||||
static void __iomem *pcie_base;
|
||||
|
||||
static struct reset_control *rstpcie0;
|
||||
|
||||
static inline void bridge_w32(u32 val, unsigned reg)
|
||||
{
|
||||
iowrite32(val, bridge_base + reg);
|
||||
}
|
||||
|
||||
static inline u32 bridge_r32(unsigned reg)
|
||||
{
|
||||
return ioread32(bridge_base + reg);
|
||||
}
|
||||
|
||||
static inline void pcie_w32(u32 val, unsigned reg)
|
||||
{
|
||||
iowrite32(val, pcie_base + reg);
|
||||
}
|
||||
|
||||
static inline u32 pcie_r32(unsigned reg)
|
||||
{
|
||||
return ioread32(pcie_base + reg);
|
||||
}
|
||||
|
||||
static inline void pcie_m32(u32 clr, u32 set, unsigned reg)
|
||||
{
|
||||
u32 val = pcie_r32(reg);
|
||||
|
||||
val &= ~clr;
|
||||
val |= set;
|
||||
pcie_w32(val, reg);
|
||||
}
|
||||
|
||||
static int wait_pciephy_busy(void)
|
||||
{
|
||||
unsigned long reg_value = 0x0, retry = 0;
|
||||
|
||||
while (1) {
|
||||
reg_value = pcie_r32(PCIEPHY0_CFG);
|
||||
|
||||
if (reg_value & BUSY)
|
||||
mdelay(100);
|
||||
else
|
||||
break;
|
||||
if (retry++ > WAITRETRY_MAX) {
|
||||
printk(KERN_WARN "PCIE-PHY retry failed.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pcie_phy(unsigned long addr, unsigned long val)
|
||||
{
|
||||
wait_pciephy_busy();
|
||||
pcie_w32(WRITE_MODE | (val << DATA_SHIFT) | (addr << ADDR_SHIFT),
|
||||
PCIEPHY0_CFG);
|
||||
mdelay(1);
|
||||
wait_pciephy_busy();
|
||||
}
|
||||
|
||||
static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
int size, u32 *val)
|
||||
{
|
||||
unsigned int slot = PCI_SLOT(devfn);
|
||||
u8 func = PCI_FUNC(devfn);
|
||||
u32 address;
|
||||
u32 data;
|
||||
u32 num = 0;
|
||||
|
||||
if (bus)
|
||||
num = bus->number;
|
||||
|
||||
address = (((where & 0xF00) >> 8) << 24) | (num << 16) | (slot << 11) |
|
||||
(func << 8) | (where & 0xfc) | 0x80000000;
|
||||
bridge_w32(address, RALINK_PCI_CONFIG_ADDR);
|
||||
data = bridge_r32(RALINK_PCI_CONFIG_DATA_VIRT_REG);
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
*val = (data >> ((where & 3) << 3)) & 0xff;
|
||||
break;
|
||||
case 2:
|
||||
*val = (data >> ((where & 3) << 3)) & 0xffff;
|
||||
break;
|
||||
case 4:
|
||||
*val = data;
|
||||
break;
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
int size, u32 val)
|
||||
{
|
||||
unsigned int slot = PCI_SLOT(devfn);
|
||||
u8 func = PCI_FUNC(devfn);
|
||||
u32 address;
|
||||
u32 data;
|
||||
u32 num = 0;
|
||||
|
||||
if (bus)
|
||||
num = bus->number;
|
||||
|
||||
address = (((where & 0xF00) >> 8) << 24) | (num << 16) | (slot << 11) |
|
||||
(func << 8) | (where & 0xfc) | 0x80000000;
|
||||
bridge_w32(address, RALINK_PCI_CONFIG_ADDR);
|
||||
data = bridge_r32(RALINK_PCI_CONFIG_DATA_VIRT_REG);
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
data = (data & ~(0xff << ((where & 3) << 3))) |
|
||||
(val << ((where & 3) << 3));
|
||||
break;
|
||||
case 2:
|
||||
data = (data & ~(0xffff << ((where & 3) << 3))) |
|
||||
(val << ((where & 3) << 3));
|
||||
break;
|
||||
case 4:
|
||||
data = val;
|
||||
break;
|
||||
}
|
||||
|
||||
bridge_w32(data, RALINK_PCI_CONFIG_DATA_VIRT_REG);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
struct pci_ops mt7620_pci_ops = {
|
||||
.read = pci_config_read,
|
||||
.write = pci_config_write,
|
||||
};
|
||||
|
||||
static struct resource mt7620_res_pci_mem1;
|
||||
static struct resource mt7620_res_pci_io1;
|
||||
struct pci_controller mt7620_controller = {
|
||||
.pci_ops = &mt7620_pci_ops,
|
||||
.mem_resource = &mt7620_res_pci_mem1,
|
||||
.mem_offset = 0x00000000UL,
|
||||
.io_resource = &mt7620_res_pci_io1,
|
||||
.io_offset = 0x00000000UL,
|
||||
.io_map_base = 0xa0000000,
|
||||
};
|
||||
|
||||
static int mt7620_pci_hw_init(struct platform_device *pdev)
|
||||
{
|
||||
/* bypass PCIe DLL */
|
||||
pcie_phy(0x0, 0x80);
|
||||
pcie_phy(0x1, 0x04);
|
||||
|
||||
/* Elastic buffer control */
|
||||
pcie_phy(0x68, 0xB4);
|
||||
|
||||
/* put core into reset */
|
||||
pcie_m32(0, PCIRST, RALINK_PCI_PCICFG_ADDR);
|
||||
reset_control_assert(rstpcie0);
|
||||
|
||||
/* disable power and all clocks */
|
||||
rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
|
||||
rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
|
||||
|
||||
/* bring core out of reset */
|
||||
reset_control_deassert(rstpcie0);
|
||||
rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
|
||||
mdelay(100);
|
||||
|
||||
if (!(rt_sysc_r32(PPLL_CFG1) & PDRV_SW_SET)) {
|
||||
dev_err(&pdev->dev, "MT7620 PPLL unlock\n");
|
||||
reset_control_assert(rstpcie0);
|
||||
rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* power up the bus */
|
||||
rt_sysc_m32(LC_CKDRVHZ | LC_CKDRVOHZ, LC_CKDRVPD | PDRV_SW_SET,
|
||||
PPLL_DRV);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7628_pci_hw_init(struct platform_device *pdev)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
/* bring the core out of reset */
|
||||
rt_sysc_m32(BIT(16), 0, RALINK_GPIOMODE);
|
||||
reset_control_deassert(rstpcie0);
|
||||
|
||||
/* enable the pci clk */
|
||||
rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
|
||||
mdelay(100);
|
||||
|
||||
/* voodoo from the SDK driver */
|
||||
pcie_m32(~0xff, 0x5, RALINK_PCIEPHY_P0_CTL_OFFSET);
|
||||
|
||||
pci_config_read(NULL, 0, 0x70c, 4, &val);
|
||||
val &= ~(0xff) << 8;
|
||||
val |= 0x50 << 8;
|
||||
pci_config_write(NULL, 0, 0x70c, 4, val);
|
||||
|
||||
pci_config_read(NULL, 0, 0x70c, 4, &val);
|
||||
dev_err(&pdev->dev, "Port 0 N_FTS = %x\n", (unsigned int) val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7620_pci_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *bridge_res = platform_get_resource(pdev,
|
||||
IORESOURCE_MEM, 0);
|
||||
struct resource *pcie_res = platform_get_resource(pdev,
|
||||
IORESOURCE_MEM, 1);
|
||||
u32 val = 0;
|
||||
|
||||
rstpcie0 = devm_reset_control_get(&pdev->dev, "pcie0");
|
||||
if (IS_ERR(rstpcie0))
|
||||
return PTR_ERR(rstpcie0);
|
||||
|
||||
bridge_base = devm_ioremap_resource(&pdev->dev, bridge_res);
|
||||
if (!bridge_base)
|
||||
return -ENOMEM;
|
||||
|
||||
pcie_base = devm_ioremap_resource(&pdev->dev, pcie_res);
|
||||
if (!pcie_base)
|
||||
return -ENOMEM;
|
||||
|
||||
iomem_resource.start = 0;
|
||||
iomem_resource.end = ~0;
|
||||
ioport_resource.start = 0;
|
||||
ioport_resource.end = ~0;
|
||||
|
||||
/* bring up the pci core */
|
||||
switch (ralink_soc) {
|
||||
case MT762X_SOC_MT7620A:
|
||||
if (mt7620_pci_hw_init(pdev))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case MT762X_SOC_MT7628AN:
|
||||
if (mt7628_pci_hw_init(pdev))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(&pdev->dev, "pcie is not supported on this hardware\n");
|
||||
return -1;
|
||||
}
|
||||
mdelay(50);
|
||||
|
||||
/* enable write access */
|
||||
pcie_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR);
|
||||
mdelay(100);
|
||||
|
||||
/* check if there is a card present */
|
||||
if ((pcie_r32(RALINK_PCI0_STATUS) & PCIE_LINK_UP_ST) == 0) {
|
||||
reset_control_assert(rstpcie0);
|
||||
rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
|
||||
if (ralink_soc == MT762X_SOC_MT7620A)
|
||||
rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
|
||||
dev_err(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* setup ranges */
|
||||
bridge_w32(0xffffffff, RALINK_PCI_MEMBASE);
|
||||
bridge_w32(RALINK_PCI_IO_MAP_BASE, RALINK_PCI_IOBASE);
|
||||
|
||||
pcie_w32(0x7FFF0001, RALINK_PCI0_BAR0SETUP_ADDR);
|
||||
pcie_w32(RALINK_PCI_MEMORY_BASE, RALINK_PCI0_IMBASEBAR0_ADDR);
|
||||
pcie_w32(0x06040001, RALINK_PCI0_CLASS);
|
||||
|
||||
/* enable interrupts */
|
||||
pcie_m32(0, PCIINT2, RALINK_PCI_PCIENA);
|
||||
|
||||
/* voodoo from the SDK driver */
|
||||
pci_config_read(NULL, 0, 4, 4, &val);
|
||||
pci_config_write(NULL, 0, 4, 4, val | 0x7);
|
||||
|
||||
pci_load_of_ranges(&mt7620_controller, pdev->dev.of_node);
|
||||
register_pci_controller(&mt7620_controller);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
{
|
||||
u16 cmd;
|
||||
u32 val;
|
||||
int irq = 0;
|
||||
|
||||
if ((dev->bus->number == 0) && (slot == 0)) {
|
||||
pcie_w32(0x7FFF0001, RALINK_PCI0_BAR0SETUP_ADDR);
|
||||
pci_config_write(dev->bus, 0, PCI_BASE_ADDRESS_0, 4,
|
||||
RALINK_PCI_MEMORY_BASE);
|
||||
pci_config_read(dev->bus, 0, PCI_BASE_ADDRESS_0, 4, &val);
|
||||
} else if ((dev->bus->number == 1) && (slot == 0x0)) {
|
||||
irq = RALINK_INT_PCIE0;
|
||||
} else {
|
||||
dev_err(&dev->dev, "no irq found - bus=0x%x, slot = 0x%x\n",
|
||||
dev->bus->number, slot);
|
||||
return 0;
|
||||
}
|
||||
dev_err(&dev->dev, "card - bus=0x%x, slot = 0x%x irq=%d\n",
|
||||
dev->bus->number, slot, irq);
|
||||
|
||||
/* configure the cache line size to 0x14 */
|
||||
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x14);
|
||||
|
||||
/* configure latency timer to 0xff */
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xff);
|
||||
pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
||||
|
||||
/* setup the slot */
|
||||
cmd = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
|
||||
pci_write_config_word(dev, PCI_COMMAND, cmd);
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
||||
int pcibios_plat_dev_init(struct pci_dev *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mt7620_pci_ids[] = {
|
||||
{ .compatible = "mediatek,mt7620-pci" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mt7620_pci_ids);
|
||||
|
||||
static struct platform_driver mt7620_pci_driver = {
|
||||
.probe = mt7620_pci_probe,
|
||||
.driver = {
|
||||
.name = "mt7620-pci",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(mt7620_pci_ids),
|
||||
},
|
||||
};
|
||||
|
||||
static int __init mt7620_pci_init(void)
|
||||
{
|
||||
return platform_driver_register(&mt7620_pci_driver);
|
||||
}
|
||||
|
||||
arch_initcall(mt7620_pci_init);
|
51
arch/mips/pic32/Kconfig
Normal file
51
arch/mips/pic32/Kconfig
Normal file
@ -0,0 +1,51 @@
|
||||
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
|
6
arch/mips/pic32/Makefile
Normal file
6
arch/mips/pic32/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
#
|
||||
# Joshua Henderson, <joshua.henderson@microchip.com>
|
||||
# Copyright (C) 2015 Microchip Technology, Inc. All rights reserved.
|
||||
#
|
||||
obj-$(CONFIG_MACH_PIC32) += common/
|
||||
obj-$(CONFIG_PIC32MZDA) += pic32mzda/
|
7
arch/mips/pic32/Platform
Normal file
7
arch/mips/pic32/Platform
Normal file
@ -0,0 +1,7 @@
|
||||
#
|
||||
# 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
|
5
arch/mips/pic32/common/Makefile
Normal file
5
arch/mips/pic32/common/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# Joshua Henderson, <joshua.henderson@microchip.com>
|
||||
# Copyright (C) 2015 Microchip Technology, Inc. All rights reserved.
|
||||
#
|
||||
obj-y = reset.o irq.o
|
21
arch/mips/pic32/common/irq.c
Normal file
21
arch/mips/pic32/common/irq.c
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user