ARC changes for 4.14-rc1
- support for HSDK board hosting a Quad core HS38x4 based SoC running @ 1 GHz (and some prerrquisite changes such as ability to scoot the kernel code/data from start of memory map etc) - Quite a few updates for EZChip (Mellanox) platform - Fixes to fault/exception printing -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJZstaxAAoJEGnX8d3iisJe5I0QAIExIdU5/V/bgJ7EJJaa6qW4 VxB5HXzbwOuIx/3i/uv4AwBIoeZIzuRQnjwf2dzTJms5vjT2zR08DGYIBmtSAA23 ZUmpZVd865IItLCRM7WOerP6B6gaHaObzNlZoo2d8rVnz0fruc5Td4PDC1Esfs7D vA4aITbiG6FsJMYFeYR6IKJbM8D1CmB2Gm1gEPIifniJ9dy/V9Xi5ttvISpVJSNx QMb6PDHVEpkOBypUEJKeoClFZlkeqscejjXmZ3QrhoeHM//3hX8MdvyvFBmoCY4t YpmmrfmoCupwFFn7+XDwYqDyYvJk/H84n64tUcpM7PLqCuw4BaMhd3KTjkTwvsnN H5NAhqbHIW3r4a9esn53yvgY8zk9i6U7qmhKpEwkUQTtUZ7XrdfL1H1t08cqtxPX /eFBkeKNshJy8EU02MewtxvWXON3RoJC3qgHoLkrj+iq5HTQjaDEahbQNm+rnXFI EdRMBwPX2sXOvB/m/jQYjz6QM1QTl6zHy+tXbBpATIqgRxsp6SIInqGmq7fC032a K7zPWo2Vf2LLl4ifhFJaYwbrQotqDGe/F72K1C5RcWKLnhMPdLgZ4Lwf0NcJTeDt DjmqUFXwNdQ2Ydw0B9JxeTddVCzdLHPQqxOOvvBI0vvgsF8AFmAmx2QhMdQTsZJr 73mD3udrQN48yYzAIZQf =w8CJ -----END PGP SIGNATURE----- Merge tag 'arc-4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc Pull ARC updates from Vineet Gupta: - Support for HSDK board hosting a Quad core HS38x4 based SoC running @1GHz (and some prerrquisite changes such as ability to scoot the kernel code/data from start of memory map etc) - Quite a few updates for EZChip (Mellanox) platform - Fixes to fault/exception printing * tag 'arc-4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: (26 commits) ARC: Re-enable MMU upon Machine Check exception ARC: Show fault information passed to show_kernel_fault_diag() ARC: [plat-hsdk] initial port for HSDK board ARC: mm: Decouple RAM base address from kernel link address ARCv2: IOC: Tighten up the contraints (specifically base / size alignment) ARC: [plat-axs103] refactor the DT fudging code ARC: [plat-axs103] use clk driver #2: Add core pll node to DT to manage cpu clk ARC: [plat-axs103] use clk driver #1: Get rid of platform specific cpu clk setting ARCv2: SLC: provide a line based flush routine for debugging ARC: Hardcode ARCH_DMA_MINALIGN to max line length we may have ARC: [plat-eznps] handle extra aux regs #2: kernel/entry exit ARC: [plat-eznps] handle extra aux regs #1: save/restore on context switch ARC: [plat-eznps] avoid toggling of DPC register ARC: [plat-eznps] Update the init sequence of aux regs per cpu. ARC: [plat-eznps] new command line argument for HW scheduler at MTM ARC: set boot print log level to PR_INFO ARC: [plat-eznps] Handle user memory error same in simulation and silicon ARC: [plat-eznps] use schd.wft instruction instead of sleep at idle task ARC: create cpu specific version of arch_cpu_idle() ARC: [plat-eznps] spinlock aware for MTM ...
This commit is contained in:
commit
ee89252b9e
|
@ -2764,6 +2764,15 @@
|
|||
If the dependencies are under your control, you can
|
||||
turn on cpu0_hotplug.
|
||||
|
||||
nps_mtm_hs_ctr= [KNL,ARC]
|
||||
This parameter sets the maximum duration, in
|
||||
cycles, each HW thread of the CTOP can run
|
||||
without interruptions, before HW switches it.
|
||||
The actual maximum duration is 16 times this
|
||||
parameter's value.
|
||||
Format: integer between 1 and 255
|
||||
Default: 255
|
||||
|
||||
nptcg= [IA-64] Override max number of concurrent global TLB
|
||||
purges which is reported from either PAL_VM_SUMMARY or
|
||||
SAL PALO.
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
Synopsys DesignWare ARC HS Development Kit Device Tree Bindings
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
ARC HSDK Board with quad-core ARC HS38x4 in silicon.
|
||||
|
||||
Required root node properties:
|
||||
- compatible = "snps,hsdk";
|
|
@ -100,6 +100,7 @@ source "arch/arc/plat-tb10x/Kconfig"
|
|||
source "arch/arc/plat-axs10x/Kconfig"
|
||||
#New platform adds here
|
||||
source "arch/arc/plat-eznps/Kconfig"
|
||||
source "arch/arc/plat-hsdk/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
|
@ -418,7 +419,7 @@ endif # ISA_ARCV2
|
|||
endmenu # "ARC CPU Configuration"
|
||||
|
||||
config LINUX_LINK_BASE
|
||||
hex "Linux Link Address"
|
||||
hex "Kernel link address"
|
||||
default "0x80000000"
|
||||
help
|
||||
ARC700 divides the 32 bit phy address space into two equal halves
|
||||
|
@ -431,6 +432,14 @@ config LINUX_LINK_BASE
|
|||
If you don't know what the above means, leave this setting alone.
|
||||
This needs to match memory start address specified in Device Tree
|
||||
|
||||
config LINUX_RAM_BASE
|
||||
hex "RAM base address"
|
||||
default LINUX_LINK_BASE
|
||||
help
|
||||
By default Linux is linked at base of RAM. However in some special
|
||||
cases (such as HSDK), Linux can't be linked at start of DDR, hence
|
||||
this option.
|
||||
|
||||
config HIGHMEM
|
||||
bool "High Memory Support"
|
||||
select ARCH_DISCONTIGMEM_ENABLE
|
||||
|
|
|
@ -111,6 +111,7 @@ core-y += arch/arc/plat-sim/
|
|||
core-$(CONFIG_ARC_PLAT_TB10X) += arch/arc/plat-tb10x/
|
||||
core-$(CONFIG_ARC_PLAT_AXS10X) += arch/arc/plat-axs10x/
|
||||
core-$(CONFIG_ARC_PLAT_EZNPS) += arch/arc/plat-eznps/
|
||||
core-$(CONFIG_ARC_SOC_HSDK) += arch/arc/plat-hsdk/
|
||||
|
||||
ifdef CONFIG_ARC_PLAT_EZNPS
|
||||
KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include
|
||||
|
|
|
@ -99,7 +99,7 @@ mb_intc: dw-apb-ictl@0xe0012000 {
|
|||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
/* CONFIG_KERNEL_RAM_BASE_ADDRESS needs to match low mem start */
|
||||
/* CONFIG_LINUX_RAM_BASE needs to match low mem start */
|
||||
reg = <0x0 0x80000000 0x0 0x1b000000>; /* (512 - 32) MiB */
|
||||
};
|
||||
|
||||
|
|
|
@ -24,10 +24,17 @@ cpu_card {
|
|||
|
||||
ranges = <0x00000000 0x0 0xf0000000 0x10000000>;
|
||||
|
||||
core_clk: core_clk {
|
||||
input_clk: input-clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <90000000>;
|
||||
clock-frequency = <33333333>;
|
||||
};
|
||||
|
||||
core_clk: core-clk@80 {
|
||||
compatible = "snps,axs10x-arc-pll-clock";
|
||||
reg = <0x80 0x10>, <0x100 0x10>;
|
||||
#clock-cells = <0>;
|
||||
clocks = <&input_clk>;
|
||||
};
|
||||
|
||||
core_intc: archs-intc@cpu {
|
||||
|
@ -102,7 +109,7 @@ mb_intc: dw-apb-ictl@0xe0012000 {
|
|||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
/* CONFIG_KERNEL_RAM_BASE_ADDRESS needs to match low mem start */
|
||||
/* CONFIG_LINUX_RAM_BASE needs to match low mem start */
|
||||
reg = <0x0 0x80000000 0x0 0x20000000 /* 512 MiB low mem */
|
||||
0x1 0xc0000000 0x0 0x40000000>; /* 1 GiB highmem */
|
||||
};
|
||||
|
|
|
@ -24,10 +24,17 @@ cpu_card {
|
|||
|
||||
ranges = <0x00000000 0x0 0xf0000000 0x10000000>;
|
||||
|
||||
core_clk: core_clk {
|
||||
input_clk: input-clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <100000000>;
|
||||
clock-frequency = <33333333>;
|
||||
};
|
||||
|
||||
core_clk: core-clk@80 {
|
||||
compatible = "snps,axs10x-arc-pll-clock";
|
||||
reg = <0x80 0x10>, <0x100 0x10>;
|
||||
#clock-cells = <0>;
|
||||
clocks = <&input_clk>;
|
||||
};
|
||||
|
||||
core_intc: archs-intc@cpu {
|
||||
|
@ -108,7 +115,7 @@ mb_intc: dw-apb-ictl@0xe0012000 {
|
|||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
/* CONFIG_KERNEL_RAM_BASE_ADDRESS needs to match low mem start */
|
||||
/* CONFIG_LINUX_RAM_BASE needs to match low mem start */
|
||||
reg = <0x0 0x80000000 0x0 0x20000000 /* 512 MiB low mem */
|
||||
0x1 0xc0000000 0x0 0x40000000>; /* 1 GiB highmem */
|
||||
};
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Device Tree for ARC HS Development Kit
|
||||
*/
|
||||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/net/ti-dp83867.h>
|
||||
|
||||
/ {
|
||||
model = "snps,hsdk";
|
||||
compatible = "snps,hsdk";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
chosen {
|
||||
bootargs = "earlycon=uart8250,mmio32,0xf0005000,115200n8 console=ttyS0,115200n8 debug print-fatal-signals=1";
|
||||
};
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "snps,archs38";
|
||||
reg = <0>;
|
||||
clocks = <&core_clk>;
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "snps,archs38";
|
||||
reg = <1>;
|
||||
clocks = <&core_clk>;
|
||||
};
|
||||
|
||||
cpu@2 {
|
||||
device_type = "cpu";
|
||||
compatible = "snps,archs38";
|
||||
reg = <2>;
|
||||
clocks = <&core_clk>;
|
||||
};
|
||||
|
||||
cpu@3 {
|
||||
device_type = "cpu";
|
||||
compatible = "snps,archs38";
|
||||
reg = <3>;
|
||||
clocks = <&core_clk>;
|
||||
};
|
||||
};
|
||||
|
||||
core_clk: core-clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <500000000>;
|
||||
};
|
||||
|
||||
cpu_intc: cpu-interrupt-controller {
|
||||
compatible = "snps,archs-intc";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
};
|
||||
|
||||
idu_intc: idu-interrupt-controller {
|
||||
compatible = "snps,archs-idu-intc";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-parent = <&cpu_intc>;
|
||||
};
|
||||
|
||||
arcpct: pct {
|
||||
compatible = "snps,archs-pct";
|
||||
};
|
||||
|
||||
/* TIMER0 with interrupt for clockevent */
|
||||
timer {
|
||||
compatible = "snps,arc-timer";
|
||||
interrupts = <16>;
|
||||
interrupt-parent = <&cpu_intc>;
|
||||
clocks = <&core_clk>;
|
||||
};
|
||||
|
||||
/* 64-bit Global Free Running Counter */
|
||||
gfrc {
|
||||
compatible = "snps,archs-timer-gfrc";
|
||||
clocks = <&core_clk>;
|
||||
};
|
||||
|
||||
soc {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
interrupt-parent = <&idu_intc>;
|
||||
|
||||
ranges = <0x00000000 0xf0000000 0x10000000>;
|
||||
|
||||
serial: serial@5000 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
reg = <0x5000 0x100>;
|
||||
clock-frequency = <33330000>;
|
||||
interrupts = <6>;
|
||||
baud = <115200>;
|
||||
reg-shift = <2>;
|
||||
reg-io-width = <4>;
|
||||
};
|
||||
|
||||
gmacclk: gmacclk {
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <400000000>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
mmcclk_ciu: mmcclk-ciu {
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <100000000>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
mmcclk_biu: mmcclk-biu {
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <400000000>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
ethernet@8000 {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "snps,dwmac";
|
||||
reg = <0x8000 0x2000>;
|
||||
interrupts = <10>;
|
||||
interrupt-names = "macirq";
|
||||
phy-mode = "rgmii";
|
||||
snps,pbl = <32>;
|
||||
clocks = <&gmacclk>;
|
||||
clock-names = "stmmaceth";
|
||||
phy-handle = <&phy0>;
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "snps,dwmac-mdio";
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
|
||||
ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
|
||||
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ohci@60000 {
|
||||
compatible = "snps,hsdk-v1.0-ohci", "generic-ohci";
|
||||
reg = <0x60000 0x100>;
|
||||
interrupts = <15>;
|
||||
};
|
||||
|
||||
ehci@40000 {
|
||||
compatible = "snps,hsdk-v1.0-ehci", "generic-ehci";
|
||||
reg = <0x40000 0x100>;
|
||||
interrupts = <15>;
|
||||
};
|
||||
|
||||
mmc@a000 {
|
||||
compatible = "altr,socfpga-dw-mshc";
|
||||
reg = <0xa000 0x400>;
|
||||
num-slots = <1>;
|
||||
fifo-depth = <16>;
|
||||
card-detect-delay = <200>;
|
||||
clocks = <&mmcclk_biu>, <&mmcclk_ciu>;
|
||||
clock-names = "biu", "ciu";
|
||||
interrupts = <12>;
|
||||
bus-width = <4>;
|
||||
};
|
||||
};
|
||||
|
||||
memory@80000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
device_type = "memory";
|
||||
reg = <0x80000000 0x40000000>; /* 1 GiB */
|
||||
};
|
||||
};
|
|
@ -18,7 +18,7 @@ / {
|
|||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
/* CONFIG_LINUX_LINK_BASE needs to match low mem start */
|
||||
/* CONFIG_LINUX_RAM_BASE needs to match low mem start */
|
||||
reg = <0x0 0x80000000 0x0 0x20000000 /* 512 MB low mem */
|
||||
0x1 0x00000000 0x0 0x40000000>; /* 1 GB highmem */
|
||||
};
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
|
||||
CONFIG_SYSVIPC=y
|
||||
# CONFIG_CROSS_MEMORY_ATTACH is not set
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_NAMESPACES=y
|
||||
# CONFIG_UTS_NS is not set
|
||||
# CONFIG_PID_NS is not set
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/"
|
||||
CONFIG_EMBEDDED=y
|
||||
CONFIG_PERF_EVENTS=y
|
||||
# CONFIG_VM_EVENT_COUNTERS is not set
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_SLAB=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_ARC_SOC_HSDK=y
|
||||
CONFIG_ISA_ARCV2=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_LINUX_LINK_BASE=0x90000000
|
||||
CONFIG_LINUX_RAM_BASE=0x80000000
|
||||
CONFIG_ARC_BUILTIN_DTB_NAME="hsdk"
|
||||
CONFIG_PREEMPT=y
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
# CONFIG_STANDALONE is not set
|
||||
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
|
||||
# CONFIG_FIRMWARE_IN_KERNEL is not set
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_STMMAC_ETH=y
|
||||
CONFIG_MICREL_PHY=y
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
# CONFIG_INPUT_KEYBOARD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_8250_DW=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_UDL=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_OHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_DW=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
# CONFIG_ENABLE_WARN_DEPRECATED is not set
|
||||
# CONFIG_ENABLE_MUST_CHECK is not set
|
||||
CONFIG_STRIP_ASM_SYMS=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
# CONFIG_FTRACE is not set
|
||||
CONFIG_CRYPTO_ECHAINIV=y
|
|
@ -47,7 +47,8 @@
|
|||
: "r"(data), "r"(ptr)); \
|
||||
})
|
||||
|
||||
#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
|
||||
/* Largest line length for either L1 or L2 is 128 bytes */
|
||||
#define ARCH_DMA_MINALIGN 128
|
||||
|
||||
extern void arc_cache_init(void);
|
||||
extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len);
|
||||
|
@ -95,6 +96,8 @@ extern unsigned long perip_base, perip_end;
|
|||
#define ARC_REG_SLC_CTRL 0x903
|
||||
#define ARC_REG_SLC_FLUSH 0x904
|
||||
#define ARC_REG_SLC_INVALIDATE 0x905
|
||||
#define ARC_AUX_SLC_IVDL 0x910
|
||||
#define ARC_AUX_SLC_FLDL 0x912
|
||||
#define ARC_REG_SLC_RGN_START 0x914
|
||||
#define ARC_REG_SLC_RGN_START1 0x915
|
||||
#define ARC_REG_SLC_RGN_END 0x916
|
||||
|
|
|
@ -192,6 +192,12 @@
|
|||
PUSHAX lp_start
|
||||
PUSHAX erbta
|
||||
|
||||
#ifdef CONFIG_ARC_PLAT_EZNPS
|
||||
.word CTOP_INST_SCHD_RW
|
||||
PUSHAX CTOP_AUX_GPA1
|
||||
PUSHAX CTOP_AUX_EFLAGS
|
||||
#endif
|
||||
|
||||
lr r9, [ecr]
|
||||
st r9, [sp, PT_event] /* EV_Trap expects r9 to have ECR */
|
||||
.endm
|
||||
|
@ -208,6 +214,12 @@
|
|||
* by hardware and that is not good.
|
||||
*-------------------------------------------------------------*/
|
||||
.macro EXCEPTION_EPILOGUE
|
||||
#ifdef CONFIG_ARC_PLAT_EZNPS
|
||||
.word CTOP_INST_SCHD_RW
|
||||
POPAX CTOP_AUX_EFLAGS
|
||||
POPAX CTOP_AUX_GPA1
|
||||
#endif
|
||||
|
||||
POPAX erbta
|
||||
POPAX lp_start
|
||||
POPAX lp_end
|
||||
|
@ -265,6 +277,12 @@
|
|||
PUSHAX lp_end
|
||||
PUSHAX lp_start
|
||||
PUSHAX bta_l\LVL\()
|
||||
|
||||
#ifdef CONFIG_ARC_PLAT_EZNPS
|
||||
.word CTOP_INST_SCHD_RW
|
||||
PUSHAX CTOP_AUX_GPA1
|
||||
PUSHAX CTOP_AUX_EFLAGS
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
|
@ -277,6 +295,12 @@
|
|||
* by hardware and that is not good.
|
||||
*-------------------------------------------------------------*/
|
||||
.macro INTERRUPT_EPILOGUE LVL
|
||||
#ifdef CONFIG_ARC_PLAT_EZNPS
|
||||
.word CTOP_INST_SCHD_RW
|
||||
POPAX CTOP_AUX_EFLAGS
|
||||
POPAX CTOP_AUX_GPA1
|
||||
#endif
|
||||
|
||||
POPAX bta_l\LVL\()
|
||||
POPAX lp_start
|
||||
POPAX lp_end
|
||||
|
|
|
@ -47,9 +47,6 @@
|
|||
#define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | STATUS_AD_MASK | \
|
||||
(ARCV2_IRQ_DEF_PRIO << 1))
|
||||
|
||||
/* SLEEP needs default irq priority (<=) which can interrupt the doze */
|
||||
#define ISA_SLEEP_ARG (0x10 | ARCV2_IRQ_DEF_PRIO)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
|
|
|
@ -43,8 +43,6 @@
|
|||
|
||||
#define ISA_INIT_STATUS_BITS STATUS_IE_MASK
|
||||
|
||||
#define ISA_SLEEP_ARG 0x3
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/******************************************************************
|
||||
|
|
|
@ -85,7 +85,7 @@ typedef pte_t * pgtable_t;
|
|||
*/
|
||||
#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT)
|
||||
|
||||
#define ARCH_PFN_OFFSET virt_to_pfn(CONFIG_LINUX_LINK_BASE)
|
||||
#define ARCH_PFN_OFFSET virt_to_pfn(CONFIG_LINUX_RAM_BASE)
|
||||
|
||||
#ifdef CONFIG_FLATMEM
|
||||
#define pfn_valid(pfn) (((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
|
||||
|
|
|
@ -27,6 +27,13 @@ struct arc_fpu {
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARC_PLAT_EZNPS
|
||||
struct eznps_dp {
|
||||
unsigned int eflags;
|
||||
unsigned int gpa1;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Arch specific stuff which needs to be saved per task.
|
||||
* However these items are not so important so as to earn a place in
|
||||
* struct thread_info
|
||||
|
@ -38,6 +45,9 @@ struct thread_struct {
|
|||
#ifdef CONFIG_ARC_FPU_SAVE_RESTORE
|
||||
struct arc_fpu fpu;
|
||||
#endif
|
||||
#ifdef CONFIG_ARC_PLAT_EZNPS
|
||||
struct eznps_dp dp;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define INIT_THREAD { \
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
#ifdef CONFIG_ISA_ARCOMPACT
|
||||
struct pt_regs {
|
||||
|
||||
#ifdef CONFIG_ARC_PLAT_EZNPS
|
||||
unsigned long eflags; /* Extended FLAGS */
|
||||
unsigned long gpa1; /* General Purpose Aux */
|
||||
#endif
|
||||
|
||||
/* Real registers */
|
||||
unsigned long bta; /* bta_l1, bta_l2, erbta */
|
||||
|
||||
|
|
|
@ -247,9 +247,15 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)
|
|||
|
||||
__asm__ __volatile__(
|
||||
"1: ex %0, [%1] \n"
|
||||
#ifdef CONFIG_EZNPS_MTM_EXT
|
||||
" .word %3 \n"
|
||||
#endif
|
||||
" breq %0, %2, 1b \n"
|
||||
: "+&r" (val)
|
||||
: "r"(&(lock->slock)), "ir"(__ARCH_SPIN_LOCK_LOCKED__)
|
||||
#ifdef CONFIG_EZNPS_MTM_EXT
|
||||
, "i"(CTOP_INST_SCHD_RW)
|
||||
#endif
|
||||
: "memory");
|
||||
|
||||
/*
|
||||
|
@ -291,6 +297,12 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
|
|||
*/
|
||||
smp_mb();
|
||||
|
||||
/*
|
||||
* EX is not really required here, a simple STore of 0 suffices.
|
||||
* However this causes tasklist livelocks in SystemC based SMP virtual
|
||||
* platforms where the systemc core scheduler uses EX as a cue for
|
||||
* moving to next core. Do a git log of this file for details
|
||||
*/
|
||||
__asm__ __volatile__(
|
||||
" ex %0, [%1] \n"
|
||||
: "+r" (val)
|
||||
|
|
|
@ -26,10 +26,19 @@ extern void fpu_save_restore(struct task_struct *p, struct task_struct *n);
|
|||
|
||||
#endif /* !CONFIG_ARC_FPU_SAVE_RESTORE */
|
||||
|
||||
#ifdef CONFIG_ARC_PLAT_EZNPS
|
||||
extern void dp_save_restore(struct task_struct *p, struct task_struct *n);
|
||||
#define ARC_EZNPS_DP_PREV(p, n) dp_save_restore(p, n)
|
||||
#else
|
||||
#define ARC_EZNPS_DP_PREV(p, n)
|
||||
|
||||
#endif /* !CONFIG_ARC_PLAT_EZNPS */
|
||||
|
||||
struct task_struct *__switch_to(struct task_struct *p, struct task_struct *n);
|
||||
|
||||
#define switch_to(prev, next, last) \
|
||||
do { \
|
||||
ARC_EZNPS_DP_PREV(prev, next); \
|
||||
ARC_FPU_PREV(prev, next); \
|
||||
last = __switch_to(prev, next);\
|
||||
ARC_FPU_NEXT(next); \
|
||||
|
|
|
@ -29,8 +29,9 @@ static void __init arc_set_early_base_baud(unsigned long dt_root)
|
|||
{
|
||||
if (of_flat_dt_is_compatible(dt_root, "abilis,arc-tb10x"))
|
||||
arc_base_baud = 166666666; /* Fixed 166.6MHz clk (TB10x) */
|
||||
else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp"))
|
||||
arc_base_baud = 33333333; /* Fixed 33MHz clk (AXS10x) */
|
||||
else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp") ||
|
||||
of_flat_dt_is_compatible(dt_root, "snps,hsdk"))
|
||||
arc_base_baud = 33333333; /* Fixed 33MHz clk (AXS10x & HSDK) */
|
||||
else if (of_flat_dt_is_compatible(dt_root, "ezchip,arc-nps"))
|
||||
arc_base_baud = 800000000; /* Fixed 800MHz clk (NPS) */
|
||||
else
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
*
|
||||
* vineetg: Nov 2009 (Everything needed for TIF_RESTORE_SIGMASK)
|
||||
* -do_signal()invoked upon TIF_RESTORE_SIGMASK as well
|
||||
* -Wrappers for sys_{,rt_}sigsuspend() nolonger needed as they don't
|
||||
* -Wrappers for sys_{,rt_}sigsuspend() no longer needed as they don't
|
||||
* need ptregs anymore
|
||||
*
|
||||
* Vineetg: Oct 2009
|
||||
* -In a rare scenario, Process gets a Priv-V exception and gets scheduled
|
||||
* out. Since we don't do FAKE RTIE for Priv-V, CPU excpetion state remains
|
||||
* out. Since we don't do FAKE RTIE for Priv-V, CPU exception state remains
|
||||
* active (AE bit enabled). This causes a double fault for a subseq valid
|
||||
* exception. Thus FAKE RTIE needed in low level Priv-Violation handler.
|
||||
* Instr Error could also cause similar scenario, so same there as well.
|
||||
|
@ -59,7 +59,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/linkage.h> /* {EXTRY,EXIT} */
|
||||
#include <linux/linkage.h> /* {ENTRY,EXIT} */
|
||||
#include <asm/entry.h>
|
||||
#include <asm/irqflags.h>
|
||||
|
||||
|
@ -80,8 +80,8 @@
|
|||
.align 4
|
||||
|
||||
/* Each entry in the vector table must occupy 2 words. Since it is a jump
|
||||
* across sections (.vector to .text) we are gauranteed that 'j somewhere'
|
||||
* will use the 'j limm' form of the intrsuction as long as somewhere is in
|
||||
* across sections (.vector to .text) we are guaranteed that 'j somewhere'
|
||||
* will use the 'j limm' form of the instruction as long as somewhere is in
|
||||
* a section other than .vector.
|
||||
*/
|
||||
|
||||
|
@ -105,13 +105,13 @@ VECTOR handle_interrupt_level1 ; Other devices
|
|||
|
||||
; ******************** Exceptions **********************
|
||||
VECTOR EV_MachineCheck ; 0x100, Fatal Machine check (0x20)
|
||||
VECTOR EV_TLBMissI ; 0x108, Intruction TLB miss (0x21)
|
||||
VECTOR EV_TLBMissI ; 0x108, Instruction TLB miss (0x21)
|
||||
VECTOR EV_TLBMissD ; 0x110, Data TLB miss (0x22)
|
||||
VECTOR EV_TLBProtV ; 0x118, Protection Violation (0x23)
|
||||
; or Misaligned Access
|
||||
VECTOR EV_PrivilegeV ; 0x120, Privilege Violation (0x24)
|
||||
VECTOR EV_Trap ; 0x128, Trap exception (0x25)
|
||||
VECTOR EV_Extension ; 0x130, Extn Intruction Excp (0x26)
|
||||
VECTOR EV_Extension ; 0x130, Extn Instruction Excp (0x26)
|
||||
|
||||
.rept 24
|
||||
VECTOR reserved ; Reserved Exceptions
|
||||
|
@ -199,7 +199,7 @@ END(handle_interrupt_level2)
|
|||
|
||||
; ---------------------------------------------
|
||||
; User Mode Memory Bus Error Interrupt Handler
|
||||
; (Kernel mode memory errors handled via seperate exception vectors)
|
||||
; (Kernel mode memory errors handled via separate exception vectors)
|
||||
; ---------------------------------------------
|
||||
ENTRY(mem_service)
|
||||
|
||||
|
@ -273,7 +273,7 @@ ENTRY(EV_TLBProtV)
|
|||
;------ (5) Type of Protection Violation? ----------
|
||||
;
|
||||
; ProtV Hardware Exception is triggered for Access Faults of 2 types
|
||||
; -Access Violaton : 00_23_(00|01|02|03)_00
|
||||
; -Access Violation : 00_23_(00|01|02|03)_00
|
||||
; x r w r+w
|
||||
; -Unaligned Access : 00_23_04_00
|
||||
;
|
||||
|
@ -327,7 +327,7 @@ END(call_do_page_fault)
|
|||
|
||||
.Lrestore_regs:
|
||||
|
||||
# Interrpts are actually disabled from this point on, but will get
|
||||
# Interrupts are actually disabled from this point on, but will get
|
||||
# reenabled after we return from interrupt/exception.
|
||||
# But irq tracer needs to be told now...
|
||||
TRACE_ASM_IRQ_ENABLE
|
||||
|
@ -335,7 +335,7 @@ END(call_do_page_fault)
|
|||
lr r10, [status32]
|
||||
|
||||
; Restore REG File. In case multiple Events outstanding,
|
||||
; use the same priorty as rtie: EXCPN, L2 IRQ, L1 IRQ, None
|
||||
; use the same priority as rtie: EXCPN, L2 IRQ, L1 IRQ, None
|
||||
; Note that we use realtime STATUS32 (not pt_regs->status32) to
|
||||
; decide that.
|
||||
|
||||
|
|
|
@ -92,6 +92,12 @@ ENTRY(EV_MachineCheck)
|
|||
lr r0, [efa]
|
||||
mov r1, sp
|
||||
|
||||
; hardware auto-disables MMU, re-enable it to allow kernel vaddr
|
||||
; access for say stack unwinding of modules for crash dumps
|
||||
lr r3, [ARC_REG_PID]
|
||||
or r3, r3, MMU_ENABLE
|
||||
sr r3, [ARC_REG_PID]
|
||||
|
||||
lsr r3, r2, 8
|
||||
bmsk r3, r3, 7
|
||||
brne r3, ECR_C_MCHK_DUP_TLB, 1f
|
||||
|
|
|
@ -79,15 +79,40 @@ SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new)
|
|||
return uval;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ISA_ARCV2
|
||||
|
||||
void arch_cpu_idle(void)
|
||||
{
|
||||
/* sleep, but enable all interrupts before committing */
|
||||
/* Re-enable interrupts <= default irq priority before commiting SLEEP */
|
||||
const unsigned int arg = 0x10 | ARCV2_IRQ_DEF_PRIO;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"sleep %0 \n"
|
||||
:
|
||||
:"I"(ISA_SLEEP_ARG)); /* can't be "r" has to be embedded const */
|
||||
:"I"(arg)); /* can't be "r" has to be embedded const */
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_EZNPS_MTM_EXT) /* ARC700 variant in NPS */
|
||||
|
||||
void arch_cpu_idle(void)
|
||||
{
|
||||
/* only the calling HW thread needs to sleep */
|
||||
__asm__ __volatile__(
|
||||
".word %0 \n"
|
||||
:
|
||||
:"i"(CTOP_INST_HWSCHD_WFT_IE12));
|
||||
}
|
||||
|
||||
#else /* ARC700 */
|
||||
|
||||
void arch_cpu_idle(void)
|
||||
{
|
||||
/* sleep, but enable both set E1/E2 (levels of interrutps) before committing */
|
||||
__asm__ __volatile__("sleep 0x3 \n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
asmlinkage void ret_from_fork(void);
|
||||
|
||||
/*
|
||||
|
@ -209,6 +234,10 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long usp)
|
|||
*/
|
||||
regs->status32 = STATUS_U_MASK | STATUS_L_MASK | ISA_INIT_STATUS_BITS;
|
||||
|
||||
#ifdef CONFIG_EZNPS_MTM_EXT
|
||||
regs->eflags = 0;
|
||||
#endif
|
||||
|
||||
/* bogus seed values for debugging */
|
||||
regs->lp_start = 0x10;
|
||||
regs->lp_end = 0x80;
|
||||
|
|
|
@ -385,13 +385,13 @@ void setup_processor(void)
|
|||
read_arc_build_cfg_regs();
|
||||
arc_init_IRQ();
|
||||
|
||||
printk(arc_cpu_mumbojumbo(cpu_id, str, sizeof(str)));
|
||||
pr_info("%s", arc_cpu_mumbojumbo(cpu_id, str, sizeof(str)));
|
||||
|
||||
arc_mmu_init();
|
||||
arc_cache_init();
|
||||
|
||||
printk(arc_extn_mumbojumbo(cpu_id, str, sizeof(str)));
|
||||
printk(arc_platform_smp_cpuinfo());
|
||||
pr_info("%s", arc_extn_mumbojumbo(cpu_id, str, sizeof(str)));
|
||||
pr_info("%s", arc_platform_smp_cpuinfo());
|
||||
|
||||
arc_chk_core_config();
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ int name(unsigned long address, struct pt_regs *regs) \
|
|||
DO_ERROR_INFO(SIGILL, "Priv Op/Disabled Extn", do_privilege_fault, ILL_PRVOPC)
|
||||
DO_ERROR_INFO(SIGILL, "Invalid Extn Insn", do_extension_fault, ILL_ILLOPC)
|
||||
DO_ERROR_INFO(SIGILL, "Illegal Insn (or Seq)", insterror_is_error, ILL_ILLOPC)
|
||||
DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", do_memory_error, BUS_ADRERR)
|
||||
DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", __weak do_memory_error, BUS_ADRERR)
|
||||
DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT)
|
||||
DO_ERROR_INFO(SIGBUS, "Misaligned Access", do_misaligned_error, BUS_ADRALN)
|
||||
|
||||
|
@ -103,7 +103,7 @@ int do_misaligned_access(unsigned long address, struct pt_regs *regs,
|
|||
*/
|
||||
void do_machine_check_fault(unsigned long address, struct pt_regs *regs)
|
||||
{
|
||||
die("Machine Check Exception", regs, address);
|
||||
die("Unhandled Machine Check Exception", regs, address);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ static void show_ecr_verbose(struct pt_regs *regs)
|
|||
} else if (vec == ECR_V_ITLB_MISS) {
|
||||
pr_cont("Insn could not be fetched\n");
|
||||
} else if (vec == ECR_V_MACH_CHK) {
|
||||
pr_cont("%s\n", (cause_code == 0x0) ?
|
||||
pr_cont("Machine Check (%s)\n", (cause_code == 0x0) ?
|
||||
"Double Fault" : "Other Fatal Err");
|
||||
|
||||
} else if (vec == ECR_V_PROTV) {
|
||||
|
@ -233,6 +233,9 @@ void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
|
|||
{
|
||||
current->thread.fault_address = address;
|
||||
|
||||
/* Show fault description */
|
||||
pr_info("\n%s\n", str);
|
||||
|
||||
/* Caller and Callee regs */
|
||||
show_regs(regs);
|
||||
|
||||
|
|
|
@ -652,7 +652,7 @@ static void __ic_line_inv_vaddr(phys_addr_t paddr, unsigned long vaddr,
|
|||
|
||||
#endif /* CONFIG_ARC_HAS_ICACHE */
|
||||
|
||||
noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op)
|
||||
noinline void slc_op_rgn(phys_addr_t paddr, unsigned long sz, const int op)
|
||||
{
|
||||
#ifdef CONFIG_ISA_ARCV2
|
||||
/*
|
||||
|
@ -715,6 +715,58 @@ noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op)
|
|||
#endif
|
||||
}
|
||||
|
||||
noinline void slc_op_line(phys_addr_t paddr, unsigned long sz, const int op)
|
||||
{
|
||||
#ifdef CONFIG_ISA_ARCV2
|
||||
/*
|
||||
* SLC is shared between all cores and concurrent aux operations from
|
||||
* multiple cores need to be serialized using a spinlock
|
||||
* A concurrent operation can be silently ignored and/or the old/new
|
||||
* operation can remain incomplete forever (lockup in SLC_CTRL_BUSY loop
|
||||
* below)
|
||||
*/
|
||||
static DEFINE_SPINLOCK(lock);
|
||||
|
||||
const unsigned long SLC_LINE_MASK = ~(l2_line_sz - 1);
|
||||
unsigned int ctrl, cmd;
|
||||
unsigned long flags;
|
||||
int num_lines;
|
||||
|
||||
spin_lock_irqsave(&lock, flags);
|
||||
|
||||
ctrl = read_aux_reg(ARC_REG_SLC_CTRL);
|
||||
|
||||
/* Don't rely on default value of IM bit */
|
||||
if (!(op & OP_FLUSH)) /* i.e. OP_INV */
|
||||
ctrl &= ~SLC_CTRL_IM; /* clear IM: Disable flush before Inv */
|
||||
else
|
||||
ctrl |= SLC_CTRL_IM;
|
||||
|
||||
write_aux_reg(ARC_REG_SLC_CTRL, ctrl);
|
||||
|
||||
cmd = op & OP_INV ? ARC_AUX_SLC_IVDL : ARC_AUX_SLC_FLDL;
|
||||
|
||||
sz += paddr & ~SLC_LINE_MASK;
|
||||
paddr &= SLC_LINE_MASK;
|
||||
|
||||
num_lines = DIV_ROUND_UP(sz, l2_line_sz);
|
||||
|
||||
while (num_lines-- > 0) {
|
||||
write_aux_reg(cmd, paddr);
|
||||
paddr += l2_line_sz;
|
||||
}
|
||||
|
||||
/* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */
|
||||
read_aux_reg(ARC_REG_SLC_CTRL);
|
||||
|
||||
while (read_aux_reg(ARC_REG_SLC_CTRL) & SLC_CTRL_BUSY);
|
||||
|
||||
spin_unlock_irqrestore(&lock, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define slc_op(paddr, sz, op) slc_op_rgn(paddr, sz, op)
|
||||
|
||||
noinline static void slc_entire_op(const int op)
|
||||
{
|
||||
unsigned int ctrl, r = ARC_REG_SLC_CTRL;
|
||||
|
@ -1095,7 +1147,7 @@ SYSCALL_DEFINE3(cacheflush, uint32_t, start, uint32_t, sz, uint32_t, flags)
|
|||
*/
|
||||
noinline void __init arc_ioc_setup(void)
|
||||
{
|
||||
unsigned int ap_sz;
|
||||
unsigned int ioc_base, mem_sz;
|
||||
|
||||
/* Flush + invalidate + disable L1 dcache */
|
||||
__dc_disable();
|
||||
|
@ -1104,18 +1156,29 @@ noinline void __init arc_ioc_setup(void)
|
|||
if (read_aux_reg(ARC_REG_SLC_BCR))
|
||||
slc_entire_op(OP_FLUSH_N_INV);
|
||||
|
||||
/* IOC Aperture start: TDB: handle non default CONFIG_LINUX_LINK_BASE */
|
||||
write_aux_reg(ARC_REG_IO_COH_AP0_BASE, 0x80000);
|
||||
|
||||
/*
|
||||
* IOC Aperture size:
|
||||
* decoded as 2 ^ (SIZE + 2) KB: so setting 0x11 implies 512M
|
||||
* currently IOC Aperture covers entire DDR
|
||||
* TBD: fix for PGU + 1GB of low mem
|
||||
* TBD: fix for PAE
|
||||
*/
|
||||
ap_sz = order_base_2(arc_get_mem_sz()/1024) - 2;
|
||||
write_aux_reg(ARC_REG_IO_COH_AP0_SIZE, ap_sz);
|
||||
mem_sz = arc_get_mem_sz();
|
||||
|
||||
if (!is_power_of_2(mem_sz) || mem_sz < 4096)
|
||||
panic("IOC Aperture size must be power of 2 larger than 4KB");
|
||||
|
||||
/*
|
||||
* IOC Aperture size decoded as 2 ^ (SIZE + 2) KB,
|
||||
* so setting 0x11 implies 512MB, 0x12 implies 1GB...
|
||||
*/
|
||||
write_aux_reg(ARC_REG_IO_COH_AP0_SIZE, order_base_2(mem_sz >> 10) - 2);
|
||||
|
||||
/* for now assume kernel base is start of IOC aperture */
|
||||
ioc_base = CONFIG_LINUX_RAM_BASE;
|
||||
|
||||
if (ioc_base % mem_sz != 0)
|
||||
panic("IOC Aperture start must be aligned to the size of the aperture");
|
||||
|
||||
write_aux_reg(ARC_REG_IO_COH_AP0_BASE, ioc_base >> 12);
|
||||
write_aux_reg(ARC_REG_IO_COH_PARTIAL, 1);
|
||||
write_aux_reg(ARC_REG_IO_COH_ENABLE, 1);
|
||||
|
||||
|
@ -1207,7 +1270,7 @@ void __ref arc_cache_init(void)
|
|||
unsigned int __maybe_unused cpu = smp_processor_id();
|
||||
char str[256];
|
||||
|
||||
printk(arc_cache_mumbojumbo(0, str, sizeof(str)));
|
||||
pr_info("%s", arc_cache_mumbojumbo(0, str, sizeof(str)));
|
||||
|
||||
if (!cpu)
|
||||
arc_cache_init_master();
|
||||
|
|
|
@ -207,7 +207,7 @@ void do_page_fault(unsigned long address, struct pt_regs *regs)
|
|||
/* Are we prepared to handle this kernel fault?
|
||||
*
|
||||
* (The kernel has valid exception-points in the source
|
||||
* when it acesses user-memory. When it fails in one
|
||||
* when it accesses user-memory. When it fails in one
|
||||
* of those points, we find it in a table and do a jump
|
||||
* to some fixup code that loads an appropriate error
|
||||
* code)
|
||||
|
|
|
@ -26,7 +26,7 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD] __aligned(PAGE_SIZE);
|
|||
char empty_zero_page[PAGE_SIZE] __aligned(PAGE_SIZE);
|
||||
EXPORT_SYMBOL(empty_zero_page);
|
||||
|
||||
static const unsigned long low_mem_start = CONFIG_LINUX_LINK_BASE;
|
||||
static const unsigned long low_mem_start = CONFIG_LINUX_RAM_BASE;
|
||||
static unsigned long low_mem_sz;
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
|
@ -63,7 +63,7 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
|
|||
|
||||
if (!low_mem_sz) {
|
||||
if (base != low_mem_start)
|
||||
panic("CONFIG_LINUX_LINK_BASE != DT memory { }");
|
||||
panic("CONFIG_LINUX_RAM_BASE != DT memory { }");
|
||||
|
||||
low_mem_sz = size;
|
||||
in_use = 1;
|
||||
|
@ -161,7 +161,7 @@ void __init setup_arch_memory(void)
|
|||
* We can't use the helper free_area_init(zones[]) because it uses
|
||||
* PAGE_OFFSET to compute the @min_low_pfn which would be wrong
|
||||
* when our kernel doesn't start at PAGE_OFFSET, i.e.
|
||||
* PAGE_OFFSET != CONFIG_LINUX_LINK_BASE
|
||||
* PAGE_OFFSET != CONFIG_LINUX_RAM_BASE
|
||||
*/
|
||||
free_area_init_node(0, /* node-id */
|
||||
zones_size, /* num pages per zone */
|
||||
|
|
|
@ -821,7 +821,7 @@ void arc_mmu_init(void)
|
|||
char str[256];
|
||||
struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu;
|
||||
|
||||
printk(arc_mmu_mumbojumbo(0, str, sizeof(str)));
|
||||
pr_info("%s", arc_mmu_mumbojumbo(0, str, sizeof(str)));
|
||||
|
||||
/*
|
||||
* Can't be done in processor.h due to header include depenedencies
|
||||
|
@ -908,9 +908,6 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address,
|
|||
|
||||
local_irq_save(flags);
|
||||
|
||||
/* re-enable the MMU */
|
||||
write_aux_reg(ARC_REG_PID, MMU_ENABLE | read_aux_reg(ARC_REG_PID));
|
||||
|
||||
/* loop thru all sets of TLB */
|
||||
for (set = 0; set < mmu->sets; set++) {
|
||||
|
||||
|
|
|
@ -274,6 +274,13 @@ ex_saved_reg1:
|
|||
.macro COMMIT_ENTRY_TO_MMU
|
||||
#if (CONFIG_ARC_MMU_VER < 4)
|
||||
|
||||
#ifdef CONFIG_EZNPS_MTM_EXT
|
||||
/* verify if entry for this vaddr+ASID already exists */
|
||||
sr TLBProbe, [ARC_REG_TLBCOMMAND]
|
||||
lr r0, [ARC_REG_TLBINDEX]
|
||||
bbit0 r0, 31, 88f
|
||||
#endif
|
||||
|
||||
/* Get free TLB slot: Set = computed from vaddr, way = random */
|
||||
sr TLBGetIndex, [ARC_REG_TLBCOMMAND]
|
||||
|
||||
|
@ -287,6 +294,8 @@ ex_saved_reg1:
|
|||
#else
|
||||
sr TLBInsertEntry, [ARC_REG_TLBCOMMAND]
|
||||
#endif
|
||||
|
||||
88:
|
||||
.endm
|
||||
|
||||
|
||||
|
|
|
@ -80,22 +80,6 @@ static void __init axs10x_enable_gpio_intc_wire(void)
|
|||
iowrite32(1 << MB_TO_GPIO_IRQ, (void __iomem *) GPIO_INTEN);
|
||||
}
|
||||
|
||||
static inline void __init
|
||||
write_cgu_reg(uint32_t value, void __iomem *reg, void __iomem *lock_reg)
|
||||
{
|
||||
unsigned int loops = 128 * 1024, ctr;
|
||||
|
||||
iowrite32(value, reg);
|
||||
|
||||
ctr = loops;
|
||||
while (((ioread32(lock_reg) & 1) == 1) && ctr--) /* wait for unlock */
|
||||
cpu_relax();
|
||||
|
||||
ctr = loops;
|
||||
while (((ioread32(lock_reg) & 1) == 0) && ctr--) /* wait for re-lock */
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
static void __init axs10x_print_board_ver(unsigned int creg, const char *str)
|
||||
{
|
||||
union ver {
|
||||
|
@ -314,7 +298,6 @@ static void __init axs101_early_init(void)
|
|||
|
||||
#ifdef CONFIG_AXS103
|
||||
|
||||
#define AXC003_CGU 0xF0000000
|
||||
#define AXC003_CREG 0xF0001000
|
||||
#define AXC003_MST_AXI_TUNNEL 0
|
||||
#define AXC003_MST_HS38 1
|
||||
|
@ -324,131 +307,38 @@ static void __init axs101_early_init(void)
|
|||
#define CREG_CPU_TUN_IO_CTRL (AXC003_CREG + 0x494)
|
||||
|
||||
|
||||
union pll_reg {
|
||||
struct {
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
unsigned int pad:17, noupd:1, bypass:1, edge:1, high:6, low:6;
|
||||
#else
|
||||
unsigned int low:6, high:6, edge:1, bypass:1, noupd:1, pad:17;
|
||||
#endif
|
||||
};
|
||||
unsigned int val;
|
||||
};
|
||||
|
||||
static unsigned int __init axs103_get_freq(void)
|
||||
{
|
||||
union pll_reg idiv, fbdiv, odiv;
|
||||
unsigned int f = 33333333;
|
||||
|
||||
idiv.val = ioread32((void __iomem *)AXC003_CGU + 0x80 + 0);
|
||||
fbdiv.val = ioread32((void __iomem *)AXC003_CGU + 0x80 + 4);
|
||||
odiv.val = ioread32((void __iomem *)AXC003_CGU + 0x80 + 8);
|
||||
|
||||
if (idiv.bypass != 1)
|
||||
f = f / (idiv.low + idiv.high);
|
||||
|
||||
if (fbdiv.bypass != 1)
|
||||
f = f * (fbdiv.low + fbdiv.high);
|
||||
|
||||
if (odiv.bypass != 1)
|
||||
f = f / (odiv.low + odiv.high);
|
||||
|
||||
f = (f + 500000) / 1000000; /* Rounding */
|
||||
return f;
|
||||
}
|
||||
|
||||
static inline unsigned int __init encode_div(unsigned int id, int upd)
|
||||
{
|
||||
union pll_reg div;
|
||||
|
||||
div.val = 0;
|
||||
|
||||
div.noupd = !upd;
|
||||
div.bypass = id == 1 ? 1 : 0;
|
||||
div.edge = (id%2 == 0) ? 0 : 1; /* 0 = rising */
|
||||
div.low = (id%2 == 0) ? id >> 1 : (id >> 1)+1;
|
||||
div.high = id >> 1;
|
||||
|
||||
return div.val;
|
||||
}
|
||||
|
||||
noinline static void __init
|
||||
axs103_set_freq(unsigned int id, unsigned int fd, unsigned int od)
|
||||
{
|
||||
write_cgu_reg(encode_div(id, 0),
|
||||
(void __iomem *)AXC003_CGU + 0x80 + 0,
|
||||
(void __iomem *)AXC003_CGU + 0x110);
|
||||
|
||||
write_cgu_reg(encode_div(fd, 0),
|
||||
(void __iomem *)AXC003_CGU + 0x80 + 4,
|
||||
(void __iomem *)AXC003_CGU + 0x110);
|
||||
|
||||
write_cgu_reg(encode_div(od, 1),
|
||||
(void __iomem *)AXC003_CGU + 0x80 + 8,
|
||||
(void __iomem *)AXC003_CGU + 0x110);
|
||||
}
|
||||
|
||||
static void __init axs103_early_init(void)
|
||||
{
|
||||
int offset = fdt_path_offset(initial_boot_params, "/cpu_card/core_clk");
|
||||
const struct fdt_property *prop = fdt_get_property(initial_boot_params,
|
||||
offset,
|
||||
"clock-frequency",
|
||||
NULL);
|
||||
u32 freq = be32_to_cpu(*(u32*)(prop->data)) / 1000000, orig = freq;
|
||||
|
||||
#ifdef CONFIG_ARC_MCIP
|
||||
/*
|
||||
* AXS103 configurations for SMP/QUAD configurations share device tree
|
||||
* which defaults to 90 MHz. However recent failures of Quad config
|
||||
* which defaults to 100 MHz. However recent failures of Quad config
|
||||
* revealed P&R timing violations so clamp it down to safe 50 MHz
|
||||
* Instead of duplicating defconfig/DT for SMP/QUAD, add a small hack
|
||||
*
|
||||
* This hack is really hacky as of now. Fix it properly by getting the
|
||||
* number of cores as return value of platform's early SMP callback
|
||||
* of fudging the freq in DT
|
||||
*/
|
||||
#ifdef CONFIG_ARC_MCIP
|
||||
unsigned int num_cores = (read_aux_reg(ARC_REG_MCIP_BCR) >> 16) & 0x3F;
|
||||
if (num_cores > 2)
|
||||
freq = 50;
|
||||
#endif
|
||||
|
||||
switch (freq) {
|
||||
case 33:
|
||||
axs103_set_freq(1, 1, 1);
|
||||
break;
|
||||
case 50:
|
||||
axs103_set_freq(1, 30, 20);
|
||||
break;
|
||||
case 75:
|
||||
axs103_set_freq(2, 45, 10);
|
||||
break;
|
||||
case 90:
|
||||
axs103_set_freq(2, 54, 10);
|
||||
break;
|
||||
case 100:
|
||||
axs103_set_freq(1, 30, 10);
|
||||
break;
|
||||
case 125:
|
||||
axs103_set_freq(2, 45, 6);
|
||||
break;
|
||||
default:
|
||||
if (num_cores > 2) {
|
||||
u32 freq = 50, orig;
|
||||
/*
|
||||
* In this case, core_frequency derived from
|
||||
* DT "clock-frequency" might not match with board value.
|
||||
* Hence update it to match the board value.
|
||||
* TODO: use cpu node "cpu-freq" param instead of platform-specific
|
||||
* "/cpu_card/core_clk" as it works only if we use fixed-clock for cpu.
|
||||
*/
|
||||
freq = axs103_get_freq();
|
||||
break;
|
||||
}
|
||||
int off = fdt_path_offset(initial_boot_params, "/cpu_card/core_clk");
|
||||
const struct fdt_property *prop;
|
||||
|
||||
pr_info("Freq is %dMHz\n", freq);
|
||||
prop = fdt_get_property(initial_boot_params, off,
|
||||
"clock-frequency", NULL);
|
||||
orig = be32_to_cpu(*(u32*)(prop->data)) / 1000000;
|
||||
|
||||
/* Patching .dtb in-place with new core clock value */
|
||||
if (freq != orig ) {
|
||||
freq = cpu_to_be32(freq * 1000000);
|
||||
fdt_setprop_inplace(initial_boot_params, offset,
|
||||
"clock-frequency", &freq, sizeof(freq));
|
||||
/* Patching .dtb in-place with new core clock value */
|
||||
if (freq != orig ) {
|
||||
freq = cpu_to_be32(freq * 1000000);
|
||||
fdt_setprop_inplace(initial_boot_params, off,
|
||||
"clock-frequency", &freq, sizeof(freq));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Memory maps already config in pre-bootloader */
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ menuconfig ARC_PLAT_EZNPS
|
|||
help
|
||||
Support for EZchip development platforms,
|
||||
based on ARC700 cores.
|
||||
We handle few flavours:
|
||||
- Hardware Emulator AKA HE which is FPGA based chasis
|
||||
We handle few flavors:
|
||||
- Hardware Emulator AKA HE which is FPGA based chassis
|
||||
- Simulator based on MetaWare nSIM
|
||||
- NPS400 chip based on ASIC
|
||||
|
||||
|
@ -32,3 +32,25 @@ config EZNPS_MTM_EXT
|
|||
any of them seem like CPU from Linux point of view.
|
||||
All threads within same core share the execution unit of the
|
||||
core and HW scheduler round robin between them.
|
||||
|
||||
config EZNPS_MEM_ERROR_ALIGN
|
||||
bool "ARC-EZchip Memory error as an exception"
|
||||
depends on EZNPS_MTM_EXT
|
||||
default n
|
||||
help
|
||||
On the real chip of the NPS, user memory errors are handled
|
||||
as a machine check exception, which is fatal, whereas on
|
||||
simulator platform for NPS, is handled as a Level 2 interrupt
|
||||
(just a stock ARC700) which is recoverable. This option makes
|
||||
simulator behave like hardware.
|
||||
|
||||
config EZNPS_SHARED_AUX_REGS
|
||||
bool "ARC-EZchip Shared Auxiliary Registers Per Core"
|
||||
depends on ARC_PLAT_EZNPS
|
||||
default y
|
||||
help
|
||||
On the real chip of the NPS, auxiliary registers are shared between
|
||||
all the cpus of the core, whereas on simulator platform for NPS,
|
||||
each cpu has a different set of auxiliary registers. Configuration
|
||||
should be unset if auxiliary registers are not shared between the cpus
|
||||
of the core, so there will be a need to initialize them per cpu.
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
obj-y := entry.o platform.o
|
||||
obj-y := entry.o platform.o ctop.o
|
||||
obj-$(CONFIG_SMP) += smp.o
|
||||
obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright(c) 2015 EZchip Technologies.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions 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.
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in
|
||||
* the file called "COPYING".
|
||||
*/
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <asm/processor.h>
|
||||
#include <plat/ctop.h>
|
||||
|
||||
void dp_save_restore(struct task_struct *prev, struct task_struct *next)
|
||||
{
|
||||
struct eznps_dp *prev_task_dp = &prev->thread.dp;
|
||||
struct eznps_dp *next_task_dp = &next->thread.dp;
|
||||
|
||||
/* Here we save all Data Plane related auxiliary registers */
|
||||
prev_task_dp->eflags = read_aux_reg(CTOP_AUX_EFLAGS);
|
||||
write_aux_reg(CTOP_AUX_EFLAGS, next_task_dp->eflags);
|
||||
|
||||
prev_task_dp->gpa1 = read_aux_reg(CTOP_AUX_GPA1);
|
||||
write_aux_reg(CTOP_AUX_GPA1, next_task_dp->gpa1);
|
||||
}
|
|
@ -27,7 +27,7 @@
|
|||
.align 1024 ; HW requierment for restart first PC
|
||||
|
||||
ENTRY(res_service)
|
||||
#ifdef CONFIG_EZNPS_MTM_EXT
|
||||
#if defined(CONFIG_EZNPS_MTM_EXT) && defined(CONFIG_EZNPS_SHARED_AUX_REGS)
|
||||
; There is no work for HW thread id != 0
|
||||
lr r3, [CTOP_AUX_THREAD_ID]
|
||||
cmp r3, 0
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#define CTOP_AUX_LOGIC_CORE_ID (CTOP_AUX_BASE + 0x018)
|
||||
#define CTOP_AUX_MT_CTRL (CTOP_AUX_BASE + 0x020)
|
||||
#define CTOP_AUX_HW_COMPLY (CTOP_AUX_BASE + 0x024)
|
||||
#define CTOP_AUX_DPC (CTOP_AUX_BASE + 0x02C)
|
||||
#define CTOP_AUX_LPC (CTOP_AUX_BASE + 0x030)
|
||||
#define CTOP_AUX_EFLAGS (CTOP_AUX_BASE + 0x080)
|
||||
#define CTOP_AUX_IACK (CTOP_AUX_BASE + 0x088)
|
||||
|
@ -46,6 +47,7 @@
|
|||
#define CTOP_AUX_UDMC (CTOP_AUX_BASE + 0x300)
|
||||
|
||||
/* EZchip core instructions */
|
||||
#define CTOP_INST_HWSCHD_WFT_IE12 0x3E6F7344
|
||||
#define CTOP_INST_HWSCHD_OFF_R4 0x3C6F00BF
|
||||
#define CTOP_INST_HWSCHD_RESTORE_R4 0x3E6F7103
|
||||
#define CTOP_INST_SCHD_RW 0x3E6F7004
|
||||
|
|
|
@ -21,10 +21,22 @@
|
|||
#include <plat/mtm.h>
|
||||
#include <plat/smp.h>
|
||||
|
||||
#define MT_CTRL_HS_CNT 0xFF
|
||||
#define MT_HS_CNT_MIN 0x01
|
||||
#define MT_HS_CNT_MAX 0xFF
|
||||
#define MT_CTRL_ST_CNT 0xF
|
||||
#define NPS_NUM_HW_THREADS 0x10
|
||||
|
||||
static int mtm_hs_ctr = MT_HS_CNT_MAX;
|
||||
|
||||
#ifdef CONFIG_EZNPS_MEM_ERROR_ALIGN
|
||||
int do_memory_error(unsigned long address, struct pt_regs *regs)
|
||||
{
|
||||
die("Invalid Mem Access", regs, address);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void mtm_init_nat(int cpu)
|
||||
{
|
||||
struct nps_host_reg_mtm_cfg mtm_cfg;
|
||||
|
@ -98,6 +110,18 @@ void mtm_enable_core(unsigned int cpu)
|
|||
int i;
|
||||
struct nps_host_reg_aux_mt_ctrl mt_ctrl;
|
||||
struct nps_host_reg_mtm_cfg mtm_cfg;
|
||||
struct nps_host_reg_aux_dpc dpc;
|
||||
|
||||
/*
|
||||
* Initializing dpc register in each CPU.
|
||||
* Overwriting the init value of the DPC
|
||||
* register so that CMEM and FMT virtual address
|
||||
* spaces are accessible, and Data Plane HW
|
||||
* facilities are enabled.
|
||||
*/
|
||||
dpc.ien = 1;
|
||||
dpc.men = 1;
|
||||
write_aux_reg(CTOP_AUX_DPC, dpc.value);
|
||||
|
||||
if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
|
||||
return;
|
||||
|
@ -118,9 +142,7 @@ void mtm_enable_core(unsigned int cpu)
|
|||
/* Enable HW schedule, stall counter, mtm */
|
||||
mt_ctrl.value = 0;
|
||||
mt_ctrl.hsen = 1;
|
||||
mt_ctrl.hs_cnt = MT_CTRL_HS_CNT;
|
||||
mt_ctrl.sten = 1;
|
||||
mt_ctrl.st_cnt = MT_CTRL_ST_CNT;
|
||||
mt_ctrl.hs_cnt = mtm_hs_ctr;
|
||||
mt_ctrl.mten = 1;
|
||||
write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value);
|
||||
|
||||
|
@ -131,3 +153,23 @@ void mtm_enable_core(unsigned int cpu)
|
|||
*/
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
/* Verify and set the value of the mtm hs counter */
|
||||
static int __init set_mtm_hs_ctr(char *ctr_str)
|
||||
{
|
||||
long hs_ctr;
|
||||
int ret;
|
||||
|
||||
ret = kstrtol(ctr_str, 0, &hs_ctr);
|
||||
|
||||
if (ret || hs_ctr > MT_HS_CNT_MAX || hs_ctr < MT_HS_CNT_MIN) {
|
||||
pr_err("** Invalid @nps_mtm_hs_ctr [%d] needs to be [%d:%d] (incl)\n",
|
||||
hs_ctr, MT_HS_CNT_MIN, MT_HS_CNT_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mtm_hs_ctr = hs_ctr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_param("nps_mtm_hs_ctr", set_mtm_hs_ctr);
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com)
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
menuconfig ARC_SOC_HSDK
|
||||
bool "ARC HS Development Kit SOC"
|
|
@ -0,0 +1,9 @@
|
|||
#
|
||||
# Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com)
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
obj-y := platform.o
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* ARC HSDK Platform support code
|
||||
*
|
||||
* Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com)
|
||||
*
|
||||
* 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/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/arcregs.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mach_desc.h>
|
||||
|
||||
#define ARC_CCM_UNUSED_ADDR 0x60000000
|
||||
|
||||
static void __init hsdk_init_per_cpu(unsigned int cpu)
|
||||
{
|
||||
/*
|
||||
* By default ICCM is mapped to 0x7z while this area is used for
|
||||
* kernel virtual mappings, so move it to currently unused area.
|
||||
*/
|
||||
if (cpuinfo_arc700[cpu].iccm.sz)
|
||||
write_aux_reg(ARC_REG_AUX_ICCM, ARC_CCM_UNUSED_ADDR);
|
||||
|
||||
/*
|
||||
* By default DCCM is mapped to 0x8z while this area is used by kernel,
|
||||
* so move it to currently unused area.
|
||||
*/
|
||||
if (cpuinfo_arc700[cpu].dccm.sz)
|
||||
write_aux_reg(ARC_REG_AUX_DCCM, ARC_CCM_UNUSED_ADDR);
|
||||
}
|
||||
|
||||
#define ARC_PERIPHERAL_BASE 0xf0000000
|
||||
#define CREG_BASE (ARC_PERIPHERAL_BASE + 0x1000)
|
||||
#define CREG_PAE (CREG_BASE + 0x180)
|
||||
#define CREG_PAE_UPDATE (CREG_BASE + 0x194)
|
||||
|
||||
static void __init hsdk_init_early(void)
|
||||
{
|
||||
/*
|
||||
* PAE remapping for DMA clients does not work due to an RTL bug, so
|
||||
* CREG_PAE register must be programmed to all zeroes, otherwise it
|
||||
* will cause problems with DMA to/from peripherals even if PAE40 is
|
||||
* not used.
|
||||
*/
|
||||
|
||||
/* Default is 1, which means "PAE offset = 4GByte" */
|
||||
writel_relaxed(0, (void __iomem *) CREG_PAE);
|
||||
|
||||
/* Really apply settings made above */
|
||||
writel(1, (void __iomem *) CREG_PAE_UPDATE);
|
||||
}
|
||||
|
||||
static const char *hsdk_compat[] __initconst = {
|
||||
"snps,hsdk",
|
||||
NULL,
|
||||
};
|
||||
|
||||
MACHINE_START(SIMULATION, "hsdk")
|
||||
.dt_compat = hsdk_compat,
|
||||
.init_early = hsdk_init_early,
|
||||
.init_per_cpu = hsdk_init_per_cpu,
|
||||
MACHINE_END
|
Loading…
Reference in New Issue