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

Merge tag 'arc-v3.10-rc1-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc

Pull ARC port updates from Vineet Gupta:
 "Support for two new platforms based on ARC700:
   - Abilis TB10x SoC [Chritisian/Pierrick]
   - Simulator only System-C Model [Mischa]

  ARC specific MM improvements:
   - Avoid full TLB flush (ASID increment) on munmap (even single page)
   - VIPT Cache Flushing improvements
     + Delayed dcache flush for non-aliasing dcache (big performance boost)
     + icache flush aliasing agnostic (no need to kill all possible aliases)

  Others:
   - Avoid needless rebuild of DTB files for every kernel build
   - Remove builtin cmdline as that is already provided by DeviceTree/bootargs
   - Fixing unaligned access emulation corner case
   - checkpatch fixes [Sachin]
   - Various fixlets [Noam]
   - Minor build failures/cleanups"

* tag 'arc-v3.10-rc1-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: (35 commits)
  ARC: [mm] Lazy D-cache flush (non aliasing VIPT)
  ARC: [mm] micro-optimize page size icache invalidate
  ARC: [mm] remove the pessimistic all-alias-invalidate icache helpers
  ARC: [mm] consolidate icache/dcache sync code
  ARC: [mm] optimise icache flush for kernel mappings
  ARC: [mm] optimise icache flush for user mappings
  ARC: [mm] optimize needless full mm TLB flush on munmap
  ARC: Add support for nSIM OSCI System C model
  ARC: [TB10x] Adapt device tree to new compatible string
  ARC: [TB10x] Add support for TB10x platform
  ARC: [TB10x] Device tree of TB100 and TB101 Development Kits
  ARC: Prepare interrupt code for external controllers
  ARC: Allow embedded arc-intc to be properly placed in DT intc hierarchy
  ARC: [cmdline] Don't overwrite u-boot provided bootargs
  ARC: [cmdline] Remove CONFIG_CMDLINE
  ARC: [plat-arcfpga] defconfig update
  ARC: unaligned access emulation broken if callee-reg dest of LD/ST
  ARC: unaligned access emulation error handling consolidation
  ARC: Debug/crash-printing Improvements
  ARC: fix typo with clock speed
  ...
...@@ -16,8 +16,6 @@ config ARC ...@@ -16,8 +16,6 @@ config ARC
select GENERIC_FIND_FIRST_BIT select GENERIC_FIND_FIRST_BIT
# for now, we don't need GENERIC_IRQ_PROBE, CONFIG_GENERIC_IRQ_CHIP # for now, we don't need GENERIC_IRQ_PROBE, CONFIG_GENERIC_IRQ_CHIP
select GENERIC_IRQ_SHOW select GENERIC_IRQ_SHOW
select GENERIC_KERNEL_EXECVE
select GENERIC_KERNEL_THREAD
select GENERIC_PENDING_IRQ if SMP select GENERIC_PENDING_IRQ if SMP
select GENERIC_SMP_IDLE_THREAD select GENERIC_SMP_IDLE_THREAD
select HAVE_ARCH_KGDB select HAVE_ARCH_KGDB
...@@ -61,9 +59,6 @@ config GENERIC_CALIBRATE_DELAY ...@@ -61,9 +59,6 @@ config GENERIC_CALIBRATE_DELAY
config GENERIC_HWEIGHT config GENERIC_HWEIGHT
def_bool y def_bool y
config BINFMT_ELF
def_bool y
config STACKTRACE_SUPPORT config STACKTRACE_SUPPORT
def_bool y def_bool y
select STACKTRACE select STACKTRACE
...@@ -82,6 +77,7 @@ menu "ARC Architecture Configuration" ...@@ -82,6 +77,7 @@ menu "ARC Architecture Configuration"
menu "ARC Platform/SoC/Board" menu "ARC Platform/SoC/Board"
source "arch/arc/plat-arcfpga/Kconfig" source "arch/arc/plat-arcfpga/Kconfig"
source "arch/arc/plat-tb10x/Kconfig"
#New platform adds here #New platform adds here
endmenu endmenu
...@@ -134,9 +130,6 @@ if SMP ...@@ -134,9 +130,6 @@ if SMP
config ARC_HAS_COH_CACHES config ARC_HAS_COH_CACHES
def_bool n def_bool n
config ARC_HAS_COH_LLSC
def_bool n
config ARC_HAS_COH_RTSC config ARC_HAS_COH_RTSC
def_bool n def_bool n
...@@ -304,6 +297,9 @@ config ARC_FPU_SAVE_RESTORE ...@@ -304,6 +297,9 @@ config ARC_FPU_SAVE_RESTORE
based on actual usage of FPU by a task. Thus our implemn does based on actual usage of FPU by a task. Thus our implemn does
this for all tasks in system. this for all tasks in system.
config ARC_CANT_LLSC
def_bool n
menuconfig ARC_CPU_REL_4_10 menuconfig ARC_CPU_REL_4_10
bool "Enable support for Rel 4.10 features" bool "Enable support for Rel 4.10 features"
default n default n
...@@ -314,9 +310,7 @@ menuconfig ARC_CPU_REL_4_10 ...@@ -314,9 +310,7 @@ menuconfig ARC_CPU_REL_4_10
config ARC_HAS_LLSC config ARC_HAS_LLSC
bool "Insn: LLOCK/SCOND (efficient atomic ops)" bool "Insn: LLOCK/SCOND (efficient atomic ops)"
default y default y
depends on ARC_CPU_770 depends on ARC_CPU_770 && !ARC_CANT_LLSC
# if SMP, enable LLSC ONLY if ARC implementation has coherent atomics
depends on !SMP || ARC_HAS_COH_LLSC
config ARC_HAS_SWAPE config ARC_HAS_SWAPE
bool "Insn: SWAPE (endian-swap)" bool "Insn: SWAPE (endian-swap)"
...@@ -415,13 +409,6 @@ config ARC_DBG_TLB_MISS_COUNT ...@@ -415,13 +409,6 @@ config ARC_DBG_TLB_MISS_COUNT
Counts number of I and D TLB Misses and exports them via Debugfs Counts number of I and D TLB Misses and exports them via Debugfs
The counters can be cleared via Debugfs as well The counters can be cleared via Debugfs as well
config CMDLINE
string "Kernel command line to built-in"
default "print-fatal-signals=1"
help
The default command line which will be appended to the optional
u-boot provided command line (see below)
config CMDLINE_UBOOT config CMDLINE_UBOOT
bool "Support U-boot kernel command line passing" bool "Support U-boot kernel command line passing"
default n default n
...@@ -430,8 +417,8 @@ config CMDLINE_UBOOT ...@@ -430,8 +417,8 @@ config CMDLINE_UBOOT
command line from the U-boot environment to the Linux kernel then command line from the U-boot environment to the Linux kernel then
switch this option on. switch this option on.
ARC U-boot will setup the cmdline in RAM/flash and set r2 to point ARC U-boot will setup the cmdline in RAM/flash and set r2 to point
to it. kernel startup code will copy the string into cmdline buffer to it. kernel startup code will append this to DeviceTree
and also append CONFIG_CMDLINE. /bootargs provided cmdline args.
config ARC_BUILTIN_DTB_NAME config ARC_BUILTIN_DTB_NAME
string "Built in DTB" string "Built in DTB"
...@@ -441,6 +428,10 @@ config ARC_BUILTIN_DTB_NAME ...@@ -441,6 +428,10 @@ config ARC_BUILTIN_DTB_NAME
source "kernel/Kconfig.preempt" source "kernel/Kconfig.preempt"
menu "Executable file formats"
source "fs/Kconfig.binfmt"
endmenu
endmenu # "ARC Architecture Configuration" endmenu # "ARC Architecture Configuration"
source "mm/Kconfig" source "mm/Kconfig"
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
UTS_MACHINE := arc UTS_MACHINE := arc
ifeq ($(CROSS_COMPILE),)
CROSS_COMPILE := arc-elf32-
endif
KBUILD_DEFCONFIG := fpga_defconfig KBUILD_DEFCONFIG := fpga_defconfig
cflags-y += -mA7 -fno-common -pipe -fno-builtin -D__linux__ cflags-y += -mA7 -fno-common -pipe -fno-builtin -D__linux__
...@@ -87,20 +91,23 @@ core-y += arch/arc/ ...@@ -87,20 +91,23 @@ core-y += arch/arc/
core-y += arch/arc/boot/dts/ core-y += arch/arc/boot/dts/
core-$(CONFIG_ARC_PLAT_FPGA_LEGACY) += arch/arc/plat-arcfpga/ core-$(CONFIG_ARC_PLAT_FPGA_LEGACY) += arch/arc/plat-arcfpga/
core-$(CONFIG_ARC_PLAT_TB10X) += arch/arc/plat-tb10x/
drivers-$(CONFIG_OPROFILE) += arch/arc/oprofile/ drivers-$(CONFIG_OPROFILE) += arch/arc/oprofile/
libs-y += arch/arc/lib/ $(LIBGCC) libs-y += arch/arc/lib/ $(LIBGCC)
boot := arch/arc/boot
#default target for make without any arguements. #default target for make without any arguements.
KBUILD_IMAGE := bootpImage KBUILD_IMAGE := bootpImage
all: $(KBUILD_IMAGE) all: $(KBUILD_IMAGE)
boot := arch/arc/boot
bootpImage: vmlinux bootpImage: vmlinux
uImage: vmlinux boot_targets += uImage uImage.bin uImage.gz
$(boot_targets): vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
%.dtb %.dtb.S %.dtb.o: scripts %.dtb %.dtb.S %.dtb.o: scripts
......
...@@ -3,7 +3,6 @@ targets := vmlinux.bin vmlinux.bin.gz uImage ...@@ -3,7 +3,6 @@ targets := vmlinux.bin vmlinux.bin.gz uImage
# uImage build relies on mkimage being availble on your host for ARC target # uImage build relies on mkimage being availble on your host for ARC target
# You will need to build u-boot for ARC, rename mkimage to arc-elf32-mkimage # You will need to build u-boot for ARC, rename mkimage to arc-elf32-mkimage
# and make sure it's reacable from your PATH # and make sure it's reacable from your PATH
MKIMAGE := $(srctree)/scripts/mkuboot.sh
OBJCOPYFLAGS= -O binary -R .note -R .note.gnu.build-id -R .comment -S OBJCOPYFLAGS= -O binary -R .note -R .note.gnu.build-id -R .comment -S
...@@ -12,7 +11,12 @@ LINUX_START_TEXT = $$(readelf -h vmlinux | \ ...@@ -12,7 +11,12 @@ LINUX_START_TEXT = $$(readelf -h vmlinux | \
UIMAGE_LOADADDR = $(CONFIG_LINUX_LINK_BASE) UIMAGE_LOADADDR = $(CONFIG_LINUX_LINK_BASE)
UIMAGE_ENTRYADDR = $(LINUX_START_TEXT) UIMAGE_ENTRYADDR = $(LINUX_START_TEXT)
UIMAGE_COMPRESSION = gzip
suffix-y := bin
suffix-$(CONFIG_KERNEL_GZIP) := gz
targets += uImage uImage.bin uImage.gz
extra-y += vmlinux.bin vmlinux.bin.gz
$(obj)/vmlinux.bin: vmlinux FORCE $(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy) $(call if_changed,objcopy)
...@@ -20,7 +24,12 @@ $(obj)/vmlinux.bin: vmlinux FORCE ...@@ -20,7 +24,12 @@ $(obj)/vmlinux.bin: vmlinux FORCE
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip) $(call if_changed,gzip)
$(obj)/uImage: $(obj)/vmlinux.bin.gz FORCE $(obj)/uImage.bin: $(obj)/vmlinux.bin FORCE
$(call if_changed,uimage) $(call if_changed,uimage,none)
$(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE
$(call if_changed,uimage,gzip)
PHONY += FORCE $(obj)/uImage: $(obj)/uImage.$(suffix-y)
@ln -sf $(notdir $<) $@
@echo ' Image $@ is ready'
...@@ -8,6 +8,8 @@ endif ...@@ -8,6 +8,8 @@ endif
obj-y += $(builtindtb-y).dtb.o obj-y += $(builtindtb-y).dtb.o
targets += $(builtindtb-y).dtb targets += $(builtindtb-y).dtb
.SECONDARY: $(obj)/$(builtindtb-y).dtb.S
dtbs: $(addprefix $(obj)/, $(builtindtb-y).dtb) dtbs: $(addprefix $(obj)/, $(builtindtb-y).dtb)
clean-files := *.dtb clean-files := *.dtb *.dtb.S
/*
* Abilis Systems TB100 SOC device tree
*
* Copyright (C) Abilis Systems 2013
*
* Author: Christian Ruppert <christian.ruppert@abilis.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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/include/ "abilis_tb10x.dtsi"
/* interrupt specifiers
* --------------------
* 0: rising, 1: low, 2: high, 3: falling,
*/
/ {
clock-frequency = <500000000>; /* 500 MHZ */
soc100 {
bus-frequency = <166666666>;
pll0: oscillator {
clock-frequency = <1000000000>;
};
cpu_clk: clkdiv_cpu {
clock-mult = <1>;
clock-div = <2>;
};
ahb_clk: clkdiv_ahb {
clock-mult = <1>;
clock-div = <6>;
};
iomux: iomux@FF10601c {
/* Port 1 */
pctl_tsin_s0: pctl-tsin-s0 { /* Serial TS-in 0 */
pingrp = "mis0_pins";
};
pctl_tsin_s1: pctl-tsin-s1 { /* Serial TS-in 1 */
pingrp = "mis1_pins";
};
pctl_gpio_a: pctl-gpio-a { /* GPIO bank A */
pingrp = "gpioa_pins";
};
pctl_tsin_p1: pctl-tsin-p1 { /* Parallel TS-in 1 */
pingrp = "mip1_pins";
};
/* Port 2 */
pctl_tsin_s2: pctl-tsin-s2 { /* Serial TS-in 2 */
pingrp = "mis2_pins";
};
pctl_tsin_s3: pctl-tsin-s3 { /* Serial TS-in 3 */
pingrp = "mis3_pins";
};
pctl_gpio_c: pctl-gpio-c { /* GPIO bank C */
pingrp = "gpioc_pins";
};
pctl_tsin_p3: pctl-tsin-p3 { /* Parallel TS-in 3 */
pingrp = "mip3_pins";
};
/* Port 3 */
pctl_tsin_s4: pctl-tsin-s4 { /* Serial TS-in 4 */
pingrp = "mis4_pins";
};
pctl_tsin_s5: pctl-tsin-s5 { /* Serial TS-in 5 */
pingrp = "mis5_pins";
};
pctl_gpio_e: pctl-gpio-e { /* GPIO bank E */
pingrp = "gpioe_pins";
};
pctl_tsin_p5: pctl-tsin-p5 { /* Parallel TS-in 5 */
pingrp = "mip5_pins";
};
/* Port 4 */
pctl_tsin_s6: pctl-tsin-s6 { /* Serial TS-in 6 */
pingrp = "mis6_pins";
};
pctl_tsin_s7: pctl-tsin-s7 { /* Serial TS-in 7 */
pingrp = "mis7_pins";
};
pctl_gpio_g: pctl-gpio-g { /* GPIO bank G */
pingrp = "gpiog_pins";
};
pctl_tsin_p7: pctl-tsin-p7 { /* Parallel TS-in 7 */
pingrp = "mip7_pins";
};
/* Port 5 */
pctl_gpio_j: pctl-gpio-j { /* GPIO bank J */
pingrp = "gpioj_pins";
};
pctl_gpio_k: pctl-gpio-k { /* GPIO bank K */
pingrp = "gpiok_pins";
};
pctl_ciplus: pctl-ciplus { /* CI+ interface */
pingrp = "ciplus_pins";
};
pctl_mcard: pctl-mcard { /* M-Card interface */
pingrp = "mcard_pins";
};
/* Port 6 */
pctl_tsout_p: pctl-tsout-p { /* Parallel TS-out */
pingrp = "mop_pins";
};
pctl_tsout_s0: pctl-tsout-s0 { /* Serial TS-out 0 */
pingrp = "mos0_pins";
};
pctl_tsout_s1: pctl-tsout-s1 { /* Serial TS-out 1 */
pingrp = "mos1_pins";
};
pctl_tsout_s2: pctl-tsout-s2 { /* Serial TS-out 2 */
pingrp = "mos2_pins";
};
pctl_tsout_s3: pctl-tsout-s3 { /* Serial TS-out 3 */
pingrp = "mos3_pins";
};
/* Port 7 */
pctl_uart0: pctl-uart0 { /* UART 0 */
pingrp = "uart0_pins";
};
pctl_uart1: pctl-uart1 { /* UART 1 */
pingrp = "uart1_pins";
};
pctl_gpio_l: pctl-gpio-l { /* GPIO bank L */
pingrp = "gpiol_pins";
};
pctl_gpio_m: pctl-gpio-m { /* GPIO bank M */
pingrp = "gpiom_pins";
};
/* Port 8 */
pctl_spi3: pctl-spi3 {
pingrp = "spi3_pins";
};
/* Port 9 */
pctl_spi1: pctl-spi1 {
pingrp = "spi1_pins";
};
pctl_gpio_n: pctl-gpio-n {
pingrp = "gpion_pins";
};
/* Unmuxed GPIOs */
pctl_gpio_b: pctl-gpio-b {
pingrp = "gpiob_pins";
};
pctl_gpio_d: pctl-gpio-d {
pingrp = "gpiod_pins";
};
pctl_gpio_f: pctl-gpio-f {
pingrp = "gpiof_pins";
};
pctl_gpio_h: pctl-gpio-h {
pingrp = "gpioh_pins";
};
pctl_gpio_i: pctl-gpio-i {
pingrp = "gpioi_pins";
};
};
gpioa: gpio@FF140000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF140000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <0>;
gpio-pins = <&pctl_gpio_a>;
};
gpiob: gpio@FF141000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF141000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <3>;
gpio-pins = <&pctl_gpio_b>;
};
gpioc: gpio@FF142000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF142000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <5>;
gpio-pins = <&pctl_gpio_c>;
};
gpiod: gpio@FF143000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF143000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <8>;
gpio-pins = <&pctl_gpio_d>;
};
gpioe: gpio@FF144000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF144000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <10>;
gpio-pins = <&pctl_gpio_e>;
};
gpiof: gpio@FF145000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF145000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <13>;
gpio-pins = <&pctl_gpio_f>;
};
gpiog: gpio@FF146000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF146000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <15>;
gpio-pins = <&pctl_gpio_g>;
};
gpioh: gpio@FF147000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF147000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <18>;
gpio-pins = <&pctl_gpio_h>;
};
gpioi: gpio@FF148000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF148000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <20>;
gpio-pins = <&pctl_gpio_i>;
};
gpioj: gpio@FF149000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF149000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <32>;
gpio-pins = <&pctl_gpio_j>;
};
gpiok: gpio@FF14a000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF14A000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <64>;
gpio-pins = <&pctl_gpio_k>;
};
gpiol: gpio@FF14b000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF14B000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <86>;
gpio-pins = <&pctl_gpio_l>;
};
gpiom: gpio@FF14c000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF14C000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <90>;
gpio-pins = <&pctl_gpio_m>;
};
gpion: gpio@FF14d000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF14D000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <94>;
gpio-pins = <&pctl_gpio_n>;
};
};
};
/*
* Abilis Systems TB100 Development Kit PCB device tree
*
* Copyright (C) Abilis Systems 2013
*
* Author: Christian Ruppert <christian.ruppert@abilis.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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/dts-v1/;
/include/ "abilis_tb100.dtsi"
/ {
chosen {
bootargs = "earlycon=uart8250,mmio32,0xff100000,9600n8 console=ttyS0,9600n8";
};
aliases { };
memory {
device_type = "memory";
reg = <0x80000000 0x08000000>; /* 128M */
};
soc100 {
uart@FF100000 {
pinctrl-names = "abilis,simple-default";
pinctrl-0 = <&pctl_uart0>;
};
ethernet@FE100000 {
phy-mode = "rgmii";
};
i2c0: i2c@FF120000 {
sda-hold-time = <432>;
};
i2c1: i2c@FF121000 {
sda-hold-time = <432>;
};
i2c2: i2c@FF122000 {
sda-hold-time = <432>;
};
i2c3: i2c@FF123000 {
sda-hold-time = <432>;
};
i2c4: i2c@FF124000 {
sda-hold-time = <432>;
};
leds {
compatible = "gpio-leds";
power {
label = "Power";
gpios = <&gpioi 0>;
linux,default-trigger = "default-on";
};
heartbeat {
label = "Heartbeat";
gpios = <&gpioi 1>;
linux,default-trigger = "heartbeat";
};
led2 {
label = "LED2";
gpios = <&gpioi 2>;
default-state = "off";
};
led3 {
label = "LED3";
gpios = <&gpioi 3>;
default-state = "off";
};
led4 {
label = "LED4";
gpios = <&gpioi 4>;
default-state = "off";
};
led5 {
label = "LED5";
gpios = <&gpioi 5>;
default-state = "off";
};
led6 {
label = "LED6";
gpios = <&gpioi 6>;
default-state = "off";
};
led7 {
label = "LED7";
gpios = <&gpioi 7>;
default-state = "off";
};
led8 {
label = "LED8";
gpios = <&gpioi 8>;
default-state = "off";
};
led9 {
label = "LED9";
gpios = <&gpioi 9>;
default-state = "off";
};
led10 {
label = "LED10";
gpios = <&gpioi 10>;
default-state = "off";
};
led11 {
label = "LED11";
gpios = <&gpioi 11>;
default-state = "off";
};
};
};
};
/*
* Abilis Systems TB101 SOC device tree
*
* Copyright (C) Abilis Systems 2013
*
* Author: Christian Ruppert <christian.ruppert@abilis.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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/include/ "abilis_tb10x.dtsi"
/* interrupt specifiers
* --------------------
* 0: rising, 1: low, 2: high, 3: falling,
*/
/ {
clock-frequency = <500000000>; /* 500 MHZ */
soc100 {
bus-frequency = <166666666>;
pll0: oscillator {
clock-frequency = <1000000000>;
};
cpu_clk: clkdiv_cpu {
clock-mult = <1>;
clock-div = <2>;
};
ahb_clk: clkdiv_ahb {
clock-mult = <1>;
clock-div = <6>;
};
iomux: iomux@FF10601c {
/* Port 1 */
pctl_tsin_s0: pctl-tsin-s0 { /* Serial TS-in 0 */
pingrp = "mis0_pins";
};
pctl_tsin_s1: pctl-tsin-s1 { /* Serial TS-in 1 */
pingrp = "mis1_pins";
};
pctl_gpio_a: pctl-gpio-a { /* GPIO bank A */
pingrp = "gpioa_pins";
};
pctl_tsin_p1: pctl-tsin-p1 { /* Parallel TS-in 1 */
pingrp = "mip1_pins";
};
/* Port 2 */
pctl_tsin_s2: pctl-tsin-s2 { /* Serial TS-in 2 */
pingrp = "mis2_pins";
};
pctl_tsin_s3: pctl-tsin-s3 { /* Serial TS-in 3 */
pingrp = "mis3_pins";
};
pctl_gpio_c: pctl-gpio-c { /* GPIO bank C */
pingrp = "gpioc_pins";
};
pctl_tsin_p3: pctl-tsin-p3 { /* Parallel TS-in 3 */
pingrp = "mip3_pins";
};
/* Port 3 */
pctl_tsin_s4: pctl-tsin-s4 { /* Serial TS-in 4 */
pingrp = "mis4_pins";
};
pctl_tsin_s5: pctl-tsin-s5 { /* Serial TS-in 5 */
pingrp = "mis5_pins";
};
pctl_gpio_e: pctl-gpio-e { /* GPIO bank E */
pingrp = "gpioe_pins";
};
pctl_tsin_p5: pctl-tsin-p5 { /* Parallel TS-in 5 */
pingrp = "mip5_pins";
};
/* Port 4 */
pctl_tsin_s6: pctl-tsin-s6 { /* Serial TS-in 6 */
pingrp = "mis6_pins";
};
pctl_tsin_s7: pctl-tsin-s7 { /* Serial TS-in 7 */
pingrp = "mis7_pins";
};
pctl_gpio_g: pctl-gpio-g { /* GPIO bank G */
pingrp = "gpiog_pins";
};
pctl_tsin_p7: pctl-tsin-p7 { /* Parallel TS-in 7 */
pingrp = "mip7_pins";
};
/* Port 5 */
pctl_gpio_j: pctl-gpio-j { /* GPIO bank J */
pingrp = "gpioj_pins";
};
pctl_gpio_k: pctl-gpio-k { /* GPIO bank K */
pingrp = "gpiok_pins";
};
pctl_ciplus: pctl-ciplus { /* CI+ interface */
pingrp = "ciplus_pins";
};
pctl_mcard: pctl-mcard { /* M-Card interface */
pingrp = "mcard_pins";
};
pctl_stc0: pctl-stc0 { /* Smart card I/F 0 */
pingrp = "stc0_pins";
};
pctl_stc1: pctl-stc1 { /* Smart card I/F 1 */
pingrp = "stc1_pins";
};
/* Port 6 */
pctl_tsout_p: pctl-tsout-p { /* Parallel TS-out */
pingrp = "mop_pins";
};
pctl_tsout_s0: pctl-tsout-s0 { /* Serial TS-out 0 */
pingrp = "mos0_pins";
};
pctl_tsout_s1: pctl-tsout-s1 { /* Serial TS-out 1 */
pingrp = "mos1_pins";
};
pctl_tsout_s2: pctl-tsout-s2 { /* Serial TS-out 2 */
pingrp = "mos2_pins";
};
pctl_tsout_s3: pctl-tsout-s3 { /* Serial TS-out 3 */
pingrp = "mos3_pins";
};
/* Port 7 */
pctl_uart0: pctl-uart0 { /* UART 0 */
pingrp = "uart0_pins";
};
pctl_uart1: pctl-uart1 { /* UART 1 */
pingrp = "uart1_pins";
};
pctl_gpio_l: pctl-gpio-l { /* GPIO bank L */
pingrp = "gpiol_pins";
};
pctl_gpio_m: pctl-gpio-m { /* GPIO bank M */
pingrp = "gpiom_pins";
};
/* Port 8 */
pctl_spi3: pctl-spi3 {
pingrp = "spi3_pins";
};
pctl_jtag: pctl-jtag {
pingrp = "jtag_pins";
};
/* Port 9 */
pctl_spi1: pctl-spi1 {
pingrp = "spi1_pins";
};
pctl_gpio_n: pctl-gpio-n {
pingrp = "gpion_pins";
};
/* Unmuxed GPIOs */
pctl_gpio_b: pctl-gpio-b {
pingrp = "gpiob_pins";
};
pctl_gpio_d: pctl-gpio-d {
pingrp = "gpiod_pins";
};
pctl_gpio_f: pctl-gpio-f {
pingrp = "gpiof_pins";
};
pctl_gpio_h: pctl-gpio-h {
pingrp = "gpioh_pins";
};
pctl_gpio_i: pctl-gpio-i {
pingrp = "gpioi_pins";
};
};
gpioa: gpio@FF140000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF140000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <0>;
gpio-pins = <&pctl_gpio_a>;
};
gpiob: gpio@FF141000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF141000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <3>;
gpio-pins = <&pctl_gpio_b>;
};
gpioc: gpio@FF142000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF142000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <5>;
gpio-pins = <&pctl_gpio_c>;
};
gpiod: gpio@FF143000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF143000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <8>;
gpio-pins = <&pctl_gpio_d>;
};
gpioe: gpio@FF144000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF144000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <10>;
gpio-pins = <&pctl_gpio_e>;
};
gpiof: gpio@FF145000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF145000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <13>;
gpio-pins = <&pctl_gpio_f>;
};
gpiog: gpio@FF146000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF146000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <15>;
gpio-pins = <&pctl_gpio_g>;
};
gpioh: gpio@FF147000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF147000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <18>;
gpio-pins = <&pctl_gpio_h>;
};
gpioi: gpio@FF148000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF148000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <20>;
gpio-pins = <&pctl_gpio_i>;
};
gpioj: gpio@FF149000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF149000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <32>;
gpio-pins = <&pctl_gpio_j>;
};
gpiok: gpio@FF14a000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF14A000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <64>;
gpio-pins = <&pctl_gpio_k>;
};
gpiol: gpio@FF14b000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF14B000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <86>;
gpio-pins = <&pctl_gpio_l>;
};
gpiom: gpio@FF14c000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF14C000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <90>;
gpio-pins = <&pctl_gpio_m>;
};
gpion: gpio@FF14d000 {
compatible = "abilis,tb10x-gpio";
interrupt-controller;
#interrupt-cells = <1>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <27 1>;
reg = <0xFF14D000 0x1000>;
gpio-controller;
#gpio-cells = <1>;
gpio-base = <94>;
gpio-pins = <&pctl_gpio_n>;
};
};
};
/*
* Abilis Systems TB101 Development Kit PCB device tree
*
* Copyright (C) Abilis Systems 2013
*
* Author: Christian Ruppert <christian.ruppert@abilis.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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/dts-v1/;
/include/ "abilis_tb101.dtsi"
/ {
chosen {
bootargs = "earlycon=uart8250,mmio32,0xff100000,9600n8 console=ttyS0,9600n8";
};
aliases { };
memory {
device_type = "memory";
reg = <0x80000000 0x08000000>; /* 128M */
};
soc100 {
uart@FF100000 {
pinctrl-names = "abilis,simple-default";
pinctrl-0 = <&pctl_uart0>;
};
ethernet@FE100000 {
phy-mode = "rgmii";
};
i2c0: i2c@FF120000 {
sda-hold-time = <432>;
};
i2c1: i2c@FF121000 {
sda-hold-time = <432>;
};
i2c2: i2c@FF122000 {
sda-hold-time = <432>;
};
i2c3: i2c@FF123000 {
sda-hold-time = <432>;
};
i2c4: i2c@FF124000 {
sda-hold-time = <432>;
};
leds {
compatible = "gpio-leds";
power {
label = "Power";
gpios = <&gpioi 0>;
linux,default-trigger = "default-on";
};
heartbeat {
label = "Heartbeat";
gpios = <&gpioi 1>;
linux,default-trigger = "heartbeat";
};
led2 {
label = "LED2";
gpios = <&gpioi 2>;
default-state = "off";
};
led3 {
label = "LED3";
gpios = <&gpioi 3>;
default-state = "off";
};
led4 {
label = "LED4";
gpios = <&gpioi 4>;
default-state = "off";
};
led5 {
label = "LED5";
gpios = <&gpioi 5>;
default-state = "off";
};
led6 {
label = "LED6";
gpios = <&gpioi 6>;
default-state = "off";
};
led7 {
label = "LED7";
gpios = <&gpioi 7>;
default-state = "off";
};
led8 {
label = "LED8";
gpios = <&gpioi 8>;
default-state = "off";
};
led9 {
label = "LED9";
gpios = <&gpioi 9>;
default-state = "off";
};
led10 {
label = "LED10";
gpios = <&gpioi 10>;
default-state = "off";
};
led11 {
label = "LED11";
gpios = <&gpioi 11>;
default-state = "off";
};
};
};
};
/*
* Abilis Systems TB10X SOC device tree
*
* Copyright (C) Abilis Systems 2013
*
* Author: Christian Ruppert <christian.ruppert@abilis.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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* interrupt specifiers
* --------------------
* 0: rising, 1: low, 2: high, 3: falling,
*/
/ {
compatible = "abilis,arc-tb10x";
#address-cells = <1>;
#size-cells = <1>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
device_type = "cpu";
compatible = "snps,arc770d";
reg = <0>;
};
};
soc100 {
#address-cells = <1>;
#size-cells = <1>;
device_type = "soc";
ranges = <0xfe000000 0xfe000000 0x02000000
0x000F0000 0x000F0000 0x00010000>;
compatible = "abilis,tb10x", "simple-bus";
pll0: oscillator {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-output-names = "pll0";
};
cpu_clk: clkdiv_cpu {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clocks = <&pll0>;
clock-output-names = "cpu_clk";
};
ahb_clk: clkdiv_ahb {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clocks = <&pll0>;
clock-output-names = "ahb_clk";
};
iomux: iomux@FF10601c {
#address-cells = <1>;
#size-cells = <1>;
compatible = "abilis,tb10x-iomux";
reg = <0xFF10601c 0x4>;
};
intc: interrupt-controller {
compatible = "snps,arc700-intc";
interrupt-controller;
#interrupt-cells = <1>;
};
tb10x_ictl: pic@fe002000 {
compatible = "abilis,tb10x_ictl";
reg = <0xFE002000 0x20>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29 30 31>;
};
uart@FF100000 {
compatible = "snps,dw-apb-uart",
"abilis,simple-pinctrl";
reg = <0xFF100000 0x100>;
clock-frequency = <166666666>;
interrupts = <25 1>;
reg-shift = <2>;
reg-io-width = <4>;
interrupt-parent = <&tb10x_ictl>;
};
ethernet@FE100000 {
compatible = "snps,dwmac-3.70a","snps,dwmac";
reg = <0xFE100000 0x1058>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <6 1>;
interrupt-names = "macirq";
clocks = <&ahb_clk>;
clock-names = "stmmaceth";
};
dma@FE000000 {
compatible = "snps,dma-spear1340";
reg = <0xFE000000 0x400>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <14 1>;
dma-channels = <6>;
dma-requests = <0>;
dma-masters = <1>;
#dma-cells = <3>;
chan_allocation_order = <0>;
chan_priority = <1>;
block_size = <0x7ff>;
data_width = <2 0 0 0>;
clocks = <&ahb_clk>;
clock-names = "hclk";
};
i2c0: i2c@FF120000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,designware-i2c";
reg = <0xFF120000 0x1000>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <12 1>;
clocks = <&ahb_clk>;
};
i2c1: i2c@FF121000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,designware-i2c";
reg = <0xFF121000 0x1000>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <12 1>;
clocks = <&ahb_clk>;
};
i2c2: i2c@FF122000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,designware-i2c";
reg = <0xFF122000 0x1000>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <12 1>;
clocks = <&ahb_clk>;
};
i2c3: i2c@FF123000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,designware-i2c";
reg = <0xFF123000 0x1000>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <12 1>;
clocks = <&ahb_clk>;
};
i2c4: i2c@FF124000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,designware-i2c";
reg = <0xFF124000 0x1000>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <12 1>;
clocks = <&ahb_clk>;
};
spi0: spi@0xFE010000 {
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
compatible = "abilis,tb100-spi";
num-cs = <1>;
reg = <0xFE010000 0x20>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <26 1>;
clocks = <&ahb_clk>;
};
spi1: spi@0xFE011000 {
#address-cells = <1>;
#size-cells = <0>;
cell-index = <1>;
compatible = "abilis,tb100-spi",
"abilis,simple-pinctrl";
num-cs = <2>;
reg = <0xFE011000 0x20>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <10 1>;
clocks = <&ahb_clk>;
};
tb10x_tsm: tb10x-tsm@ff316000 {
compatible = "abilis,tb100-tsm";
reg = <0xff316000 0x400>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <17 1>;
output-clkdiv = <4>;
global-packet-delay = <0x21>;
port-packet-delay = <0>;
};
tb10x_stream_proc: tb10x-stream-proc {
compatible = "abilis,tb100-streamproc";
reg = <0xfff00000 0x200>,
<0x000f0000 0x10000>,
<0xfff00200 0x105>,
<0xff10600c 0x1>,
<0xfe001018 0x1>;
reg-names = "mbox",
"sp_iccm",
"mbox_irq",
"cpuctrl",
"a6it_int_force";
interrupt-parent = <&tb10x_ictl>;
interrupts = <20 1>, <19 1>;
interrupt-names = "cmd_irq", "event_irq";
};
tb10x_mdsc0: tb10x-mdscr@FF300000 {
compatible = "abilis,tb100-mdscr";
reg = <0xFF300000 0x7000>;
tb100-mdscr-manage-tsin;
};
tb10x_mscr0: tb10x-mdscr@FF307000 {
compatible = "abilis,tb100-mdscr";
reg = <0xFF307000 0x7000>;
};
tb10x_scr0: tb10x-mdscr@ff30e000 {
compatible = "abilis,tb100-mdscr";
reg = <0xFF30e000 0x4000>;
tb100-mdscr-manage-tsin;
};
tb10x_scr1: tb10x-mdscr@ff312000 {
compatible = "abilis,tb100-mdscr";
reg = <0xFF312000 0x4000>;
tb100-mdscr-manage-tsin;
};
tb10x_wfb: tb10x-wfb@ff319000 {
compatible = "abilis,tb100-wfb";
reg = <0xff319000 0x1000>;
interrupt-parent = <&tb10x_ictl>;
interrupts = <16 1>;
};
};
};
/*
* Copyright (C) 2013 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.
*/
/dts-v1/;
/include/ "skeleton.dtsi"
/ {
compatible = "snps,nsimosci";
clock-frequency = <80000000>; /* 80 MHZ */
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;
chosen {
bootargs = "console=tty0 consoleblank=0";
};
aliases {
serial0 = &uart0;
};
memory {
device_type = "memory";
reg = <0x80000000 0x10000000>; /* 256M */
};
fpga {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
/* child and parent address space 1:1 mapped */
ranges;
intc: interrupt-controller {
compatible = "snps,arc700-intc";
interrupt-controller;
#interrupt-cells = <1>;
};
uart0: serial@c0000000 {
compatible = "snps,dw-apb-uart";
reg = <0xc0000000 0x2000>;
interrupts = <11>;
#clock-frequency = <80000000>;
clock-frequency = <3686400>;
baud = <115200>;
reg-shift = <2>;
reg-io-width = <4>;
status = "okay";
};
pgu0: pgu@c9000000 {
compatible = "snps,arcpgufb";
reg = <0xc9000000 0x400>;
};
ps2: ps2@c9001000 {
compatible = "snps,arc_ps2";
reg = <0xc9000400 0x14>;
interrupts = <13>;
interrupt-names = "arc_ps2_irq";
};
eth0: ethernet@c0003000 {
compatible = "snps,oscilan";
reg = <0xc0003000 0x44>;
interrupts = <7>, <8>;
interrupt-names = "rx", "tx";
};
};
};
...@@ -9,7 +9,7 @@ CONFIG_NAMESPACES=y ...@@ -9,7 +9,7 @@ CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set # CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set # CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="../arc_initramfs" CONFIG_INITRAMFS_SOURCE="../arc_initramfs/"
CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y CONFIG_EMBEDDED=y
# CONFIG_SLUB_DEBUG is not set # CONFIG_SLUB_DEBUG is not set
...@@ -24,6 +24,7 @@ CONFIG_ARC_PLAT_FPGA_LEGACY=y ...@@ -24,6 +24,7 @@ CONFIG_ARC_PLAT_FPGA_LEGACY=y
CONFIG_ARC_BOARD_ML509=y CONFIG_ARC_BOARD_ML509=y
# CONFIG_ARC_HAS_RTSC is not set # CONFIG_ARC_HAS_RTSC is not set
CONFIG_ARC_BUILTIN_DTB_NAME="angel4" CONFIG_ARC_BUILTIN_DTB_NAME="angel4"
CONFIG_PREEMPT=y
# CONFIG_COMPACTION is not set # CONFIG_COMPACTION is not set
# CONFIG_CROSS_MEMORY_ATTACH is not set # CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_NET=y CONFIG_NET=y
......
CONFIG_CROSS_COMPILE="arc-elf32-"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
# CONFIG_SWAP is not set
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"
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
# CONFIG_SLUB_DEBUG is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_KPROBES=y
CONFIG_MODULES=y
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARC_PLAT_FPGA_LEGACY=y
CONFIG_ARC_BOARD_ML509=y
# CONFIG_ARC_IDE is not set
# CONFIG_ARCTANGENT_EMAC is not set
# CONFIG_ARC_HAS_RTSC is not set
CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci"
# CONFIG_COMPACTION is not set
# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_UNIX_DIAG=y
CONFIG_NET_KEY=y
CONFIG_INET=y
# CONFIG_IPV6 is not set
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FIRMWARE_IN_KERNEL is not set
# CONFIG_BLK_DEV is not set
CONFIG_NETDEVICES=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
# CONFIG_MOUSE_PS2_ALPS is not set
# CONFIG_MOUSE_PS2_LOGIPS2PP is not set
# CONFIG_MOUSE_PS2_SYNAPTICS is not set
# CONFIG_MOUSE_PS2_TRACKPOINT is not set
CONFIG_MOUSE_PS2_TOUCHKIT=y
# CONFIG_SERIO_I8042 is not set
# CONFIG_SERIO_SERPORT is not set
CONFIG_SERIO_ARC_PS2=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_ARC=y
CONFIG_SERIAL_ARC_CONSOLE=y
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
CONFIG_FB=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
# CONFIG_HID is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_TMPFS=y
# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_NFS_FS=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_XZ_DEC=y
CONFIG_CROSS_COMPILE="arc-elf32-"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_DEFAULT_HOSTNAME="tb10x"
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="../tb10x-rootfs.cpio"
CONFIG_INITRAMFS_ROOT_UID=2100
CONFIG_INITRAMFS_ROOT_GID=501
# CONFIG_RD_GZIP is not set
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_AIO is not set
CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_FORCE_LOAD=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLOCK is not set
CONFIG_ARC_PLAT_TB10X=y
CONFIG_ARC_CACHE_LINE_SHIFT=5
# CONFIG_ARC_HAS_RTSC is not set
CONFIG_ARC_STACK_NONEXEC=y
CONFIG_HZ=250
CONFIG_ARC_BUILTIN_DTB_NAME="abilis_tb100_dvk"
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_COMPACTION is not set
# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
# CONFIG_IPV6 is not set
# CONFIG_WIRELESS is not set
# CONFIG_FIRMWARE_IN_KERNEL is not set
CONFIG_PROC_DEVICETREE=y
CONFIG_NETDEVICES=y
# CONFIG_NET_CADENCE is not set
# CONFIG_NET_VENDOR_BROADCOM is not set
# CONFIG_NET_VENDOR_INTEL is not set
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
# CONFIG_NET_VENDOR_SEEQ is not set
CONFIG_STMMAC_ETH=y
CONFIG_STMMAC_DEBUG_FS=y
CONFIG_STMMAC_DA=y
CONFIG_STMMAC_CHAINED=y
# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_WLAN is not set
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=1
CONFIG_SERIAL_8250_RUNTIME_UARTS=1
CONFIG_SERIAL_8250_DW=y
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
# CONFIG_I2C_COMPAT is not set
CONFIG_I2C_DESIGNWARE_PLATFORM=y
CONFIG_GPIO_SYSFS=y
# CONFIG_HWMON is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_ONESHOT=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_LEDS_TRIGGER_TRANSIENT=y
CONFIG_DMADEVICES=y
CONFIG_DW_DMAC=y
CONFIG_NET_DMA=y
CONFIG_ASYNC_TX_DMA=y
# CONFIG_IOMMU_SUPPORT is not set
# CONFIG_DNOTIFY is not set
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_CONFIGFS_FS=y
# CONFIG_MISC_FILESYSTEMS is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
# CONFIG_ENABLE_WARN_DEPRECATED is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_STRIP_ASM_SYMS=y
CONFIG_DEBUG_FS=y
CONFIG_HEADERS_CHECK=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
...@@ -20,12 +20,20 @@ ...@@ -20,12 +20,20 @@
#include <linux/mm.h> #include <linux/mm.h>
/*
* Semantically we need this because icache doesn't snoop dcache/dma.
* However ARC Cache flush requires paddr as well as vaddr, latter not available
* in the flush_icache_page() API. So we no-op it but do the equivalent work
* in update_mmu_cache()
*/
#define flush_icache_page(vma, page)
void flush_cache_all(void); void flush_cache_all(void);
void flush_icache_range(unsigned long start, unsigned long end); void flush_icache_range(unsigned long start, unsigned long end);
void flush_icache_page(struct vm_area_struct *vma, struct page *page); void __sync_icache_dcache(unsigned long paddr, unsigned long vaddr, int len);
void flush_icache_range_vaddr(unsigned long paddr, unsigned long u_vaddr, void __inv_icache_page(unsigned long paddr, unsigned long vaddr);
int len); void __flush_dcache_page(unsigned long paddr);
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
...@@ -58,7 +66,7 @@ void dma_cache_wback(unsigned long start, unsigned long sz); ...@@ -58,7 +66,7 @@ void dma_cache_wback(unsigned long start, unsigned long sz);
do { \ do { \
memcpy(dst, src, len); \ memcpy(dst, src, len); \
if (vma->vm_flags & VM_EXEC) \ if (vma->vm_flags & VM_EXEC) \
flush_icache_range_vaddr((unsigned long)(dst), vaddr, len);\ __sync_icache_dcache((unsigned long)(dst), vaddr, len); \
} while (0) } while (0)
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ #define copy_from_user_page(vma, page, vaddr, dst, src, len) \
......
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
#ifndef __ASM_ARC_IRQ_H #ifndef __ASM_ARC_IRQ_H
#define __ASM_ARC_IRQ_H #define __ASM_ARC_IRQ_H
#define NR_IRQS 32 #define NR_CPU_IRQS 32 /* number of interrupt lines of ARC770 CPU */
#define NR_IRQS 128 /* allow some CPU external IRQ handling */
/* Platform Independent IRQs */ /* Platform Independent IRQs */
#define TIMER0_IRQ 3 #define TIMER0_IRQ 3
......
...@@ -22,4 +22,14 @@ ...@@ -22,4 +22,14 @@
#define BASE_BAUD (arc_get_core_freq() / 16) #define BASE_BAUD (arc_get_core_freq() / 16)
/*
* This is definitely going to break early 8250 consoles on multi-platform
* images but hey, it won't add any code complexity for a debug feature of
* one broken driver.
*/
#ifdef CONFIG_ARC_PLAT_TB10X
#undef BASE_BAUD
#define BASE_BAUD (arc_get_core_freq() / 16 / 3)
#endif
#endif /* _ASM_ARC_SERIAL_H */ #endif /* _ASM_ARC_SERIAL_H */
...@@ -21,20 +21,28 @@ ...@@ -21,20 +21,28 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#define tlb_flush(tlb) local_flush_tlb_mm((tlb)->mm) #define tlb_flush(tlb) \
do { \
if (tlb->fullmm) \
flush_tlb_mm((tlb)->mm); \
} while (0)
/* /*
* This pair is called at time of munmap/exit to flush cache and TLB entries * This pair is called at time of munmap/exit to flush cache and TLB entries
* for mappings being torn down. * for mappings being torn down.
* 1) cache-flush part -implemented via tlb_start_vma( ) can be NOP (for now) * 1) cache-flush part -implemented via tlb_start_vma( ) can be NOP (for now)
* as we don't support aliasing configs in our VIPT D$. * as we don't support aliasing configs in our VIPT D$.
* 2) tlb-flush part - implemted via tlb_end_vma( ) can be NOP as well- * 2) tlb-flush part - implemted via tlb_end_vma( ) flushes the TLB range
* albiet for difft reasons - its better handled by moving to new ASID
* *
* Note, read http://lkml.org/lkml/2004/1/15/6 * Note, read http://lkml.org/lkml/2004/1/15/6
*/ */
#define tlb_start_vma(tlb, vma) #define tlb_start_vma(tlb, vma)
#define tlb_end_vma(tlb, vma)
#define tlb_end_vma(tlb, vma) \
do { \
if (!tlb->fullmm) \
flush_tlb_range(vma, vma->vm_start, vma->vm_end); \
} while (0)
#define __tlb_remove_tlb_entry(tlb, ptep, address) #define __tlb_remove_tlb_entry(tlb, ptep, address)
......
...@@ -11,9 +11,9 @@ ...@@ -11,9 +11,9 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/thread_info.h> #include <linux/thread_info.h>
#include <linux/kbuild.h> #include <linux/kbuild.h>
#include <linux/ptrace.h>
#include <asm/hardirq.h> #include <asm/hardirq.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/ptrace.h>
int main(void) int main(void)
{ {
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <asm/clk.h> #include <asm/clk.h>
unsigned long core_freq = 800000000; unsigned long core_freq = 80000000;
/* /*
* As of now we default to device-tree provided clock * As of now we default to device-tree provided clock
......
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/kprobes.h> #include <linux/kprobes.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/uaccess.h>
#include <asm/disasm.h> #include <asm/disasm.h>
#include <asm/uaccess.h>
#if defined(CONFIG_KGDB) || defined(CONFIG_ARC_MISALIGN_ACCESS) || \ #if defined(CONFIG_KGDB) || defined(CONFIG_ARC_MISALIGN_ACCESS) || \
defined(CONFIG_KPROBES) defined(CONFIG_KPROBES)
......
...@@ -393,12 +393,14 @@ ARC_ENTRY EV_TLBProtV ...@@ -393,12 +393,14 @@ ARC_ENTRY EV_TLBProtV
#ifdef CONFIG_ARC_MISALIGN_ACCESS #ifdef CONFIG_ARC_MISALIGN_ACCESS
SAVE_CALLEE_SAVED_USER SAVE_CALLEE_SAVED_USER
mov r3, sp ; callee_regs mov r3, sp ; callee_regs
#endif
bl do_misaligned_access bl do_misaligned_access
#ifdef CONFIG_ARC_MISALIGN_ACCESS ; TBD: optimize - do this only if a callee reg was involved
DISCARD_CALLEE_SAVED_USER ; either a dst of emulated LD/ST or src with address-writeback
RESTORE_CALLEE_SAVED_USER
#else
bl do_misaligned_error
#endif #endif
b ret_from_exception b ret_from_exception
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/irqchip.h>
#include "../../drivers/irqchip/irqchip.h"
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/mach_desc.h> #include <asm/mach_desc.h>
...@@ -26,7 +28,7 @@ ...@@ -26,7 +28,7 @@
* -Disable all IRQs (on CPU side) * -Disable all IRQs (on CPU side)
* -Optionally, setup the High priority Interrupts as Level 2 IRQs * -Optionally, setup the High priority Interrupts as Level 2 IRQs
*/ */
void __init arc_init_IRQ(void) void __cpuinit arc_init_IRQ(void)
{ {
int level_mask = 0; int level_mask = 0;
...@@ -97,15 +99,13 @@ static const struct irq_domain_ops arc_intc_domain_ops = { ...@@ -97,15 +99,13 @@ static const struct irq_domain_ops arc_intc_domain_ops = {
static struct irq_domain *root_domain; static struct irq_domain *root_domain;
void __init init_onchip_IRQ(void) static int __init
init_onchip_IRQ(struct device_node *intc, struct device_node *parent)
{ {
struct device_node *intc = NULL; if (parent)
panic("DeviceTree incore intc not a root irq controller\n");
intc = of_find_compatible_node(NULL, NULL, "snps,arc700-intc"); root_domain = irq_domain_add_legacy(intc, NR_CPU_IRQS, 0, 0,
if(!intc)
panic("DeviceTree Missing incore intc\n");
root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0,
&arc_intc_domain_ops, NULL); &arc_intc_domain_ops, NULL);
if (!root_domain) if (!root_domain)
...@@ -113,8 +113,12 @@ void __init init_onchip_IRQ(void) ...@@ -113,8 +113,12 @@ void __init init_onchip_IRQ(void)
/* with this we don't need to export root_domain */ /* with this we don't need to export root_domain */
irq_set_default_host(root_domain); irq_set_default_host(root_domain);
return 0;
} }
IRQCHIP_DECLARE(arc_intc, "snps,arc700-intc", init_onchip_IRQ);
/* /*
* Late Interrupt system init called from start_kernel for Boot CPU only * Late Interrupt system init called from start_kernel for Boot CPU only
* *
...@@ -123,12 +127,13 @@ void __init init_onchip_IRQ(void) ...@@ -123,12 +127,13 @@ void __init init_onchip_IRQ(void)
*/ */
void __init init_IRQ(void) void __init init_IRQ(void)
{ {
init_onchip_IRQ();
/* Any external intc can be setup here */ /* Any external intc can be setup here */
if (machine_desc->init_irq) if (machine_desc->init_irq)
machine_desc->init_irq(); machine_desc->init_irq();
/* process the entire interrupt tree in one go */
irqchip_init();
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* Master CPU can initialize it's side of IPI */ /* Master CPU can initialize it's side of IPI */
if (machine_desc->init_smp) if (machine_desc->init_smp)
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <linux/kprobes.h> #include <linux/kprobes.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/kdebug.h> #include <linux/kdebug.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
......
...@@ -47,7 +47,7 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, ...@@ -47,7 +47,7 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
} }
} }
#endif #endif
return 0; return 0;
} }
void module_arch_cleanup(struct module *mod) void module_arch_cleanup(struct module *mod)
...@@ -141,5 +141,5 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, ...@@ -141,5 +141,5 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
mod->arch.unw_info = unw; mod->arch.unw_info = unw;
} }
#endif #endif
return 0; return 0;
} }
...@@ -14,14 +14,13 @@ ...@@ -14,14 +14,13 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/of_fdt.h> #include <linux/of_fdt.h>
#include <linux/cache.h>
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/arcregs.h> #include <asm/arcregs.h>
#include <asm/tlb.h> #include <asm/tlb.h>
#include <asm/cache.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/arcregs.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/unwind.h> #include <asm/unwind.h>
#include <asm/clk.h> #include <asm/clk.h>
...@@ -32,14 +31,14 @@ ...@@ -32,14 +31,14 @@
int running_on_hw = 1; /* vs. on ISS */ int running_on_hw = 1; /* vs. on ISS */
char __initdata command_line[COMMAND_LINE_SIZE]; char __initdata command_line[COMMAND_LINE_SIZE];
struct machine_desc *machine_desc __initdata; struct machine_desc *machine_desc __cpuinitdata;
struct task_struct *_current_task[NR_CPUS]; /* For stack switching */ struct task_struct *_current_task[NR_CPUS]; /* For stack switching */
struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; struct cpuinfo_arc cpuinfo_arc700[NR_CPUS];
void __init read_arc_build_cfg_regs(void) void __cpuinit read_arc_build_cfg_regs(void)
{ {
struct bcr_perip uncached_space; struct bcr_perip uncached_space;
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
...@@ -238,7 +237,7 @@ char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) ...@@ -238,7 +237,7 @@ char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
return buf; return buf;
} }
void __init arc_chk_ccms(void) void __cpuinit arc_chk_ccms(void)
{ {
#if defined(CONFIG_ARC_HAS_DCCM) || defined(CONFIG_ARC_HAS_ICCM) #if defined(CONFIG_ARC_HAS_DCCM) || defined(CONFIG_ARC_HAS_ICCM)
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
...@@ -273,7 +272,7 @@ void __init arc_chk_ccms(void) ...@@ -273,7 +272,7 @@ void __init arc_chk_ccms(void)
* hardware has dedicated regs which need to be saved/restored on ctx-sw * hardware has dedicated regs which need to be saved/restored on ctx-sw
* (Single Precision uses core regs), thus kernel is kind of oblivious to it * (Single Precision uses core regs), thus kernel is kind of oblivious to it
*/ */
void __init arc_chk_fpu(void) void __cpuinit arc_chk_fpu(void)
{ {
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
...@@ -294,7 +293,7 @@ void __init arc_chk_fpu(void) ...@@ -294,7 +293,7 @@ void __init arc_chk_fpu(void)
* such as only for boot CPU etc * such as only for boot CPU etc
*/ */
void __init setup_processor(void) void __cpuinit setup_processor(void)
{ {
char str[512]; char str[512];
int cpu_id = smp_processor_id(); int cpu_id = smp_processor_id();
...@@ -319,23 +318,20 @@ void __init setup_processor(void) ...@@ -319,23 +318,20 @@ void __init setup_processor(void)
void __init setup_arch(char **cmdline_p) void __init setup_arch(char **cmdline_p)
{ {
/* This also populates @boot_command_line from /bootargs */
machine_desc = setup_machine_fdt(__dtb_start);
if (!machine_desc)
panic("Embedded DT invalid\n");
/* Append any u-boot provided cmdline */
#ifdef CONFIG_CMDLINE_UBOOT #ifdef CONFIG_CMDLINE_UBOOT
/* Make sure that a whitespace is inserted before */ /* Add a whitespace seperator between the 2 cmdlines */
strlcat(command_line, " ", sizeof(command_line)); strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
strlcat(boot_command_line, command_line, COMMAND_LINE_SIZE);
#endif #endif
/*
* Append .config cmdline to base command line, which might already
* contain u-boot "bootargs" (handled by head.S, if so configured)
*/
strlcat(command_line, CONFIG_CMDLINE, sizeof(command_line));
/* Save unparsed command line copy for /proc/cmdline */ /* Save unparsed command line copy for /proc/cmdline */
strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); *cmdline_p = boot_command_line;
*cmdline_p = command_line;
machine_desc = setup_machine_fdt(__dtb_start);
if (!machine_desc)
panic("Embedded DT invalid\n");
/* To force early parsing of things like mem=xxx */ /* To force early parsing of things like mem=xxx */
parse_early_param(); parse_early_param();
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/timex.h> #include <linux/timex.h>
......
...@@ -16,11 +16,12 @@ ...@@ -16,11 +16,12 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/kdebug.h> #include <linux/kdebug.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/ptrace.h> #include <linux/ptrace.h>
#include <linux/kprobes.h>
#include <linux/kgdb.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/kprobes.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <asm/kgdb.h> #include <asm/kprobes.h>
void __init trap_init(void) void __init trap_init(void)
{ {
...@@ -83,6 +84,7 @@ DO_ERROR_INFO(SIGILL, "Invalid Extn Insn", do_extension_fault, ILL_ILLOPC) ...@@ -83,6 +84,7 @@ 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(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", do_memory_error, BUS_ADRERR)
DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT) DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT)
DO_ERROR_INFO(SIGBUS, "Misaligned Access", do_misaligned_error, BUS_ADRALN)
#ifdef CONFIG_ARC_MISALIGN_ACCESS #ifdef CONFIG_ARC_MISALIGN_ACCESS
/* /*
...@@ -91,21 +93,11 @@ DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT) ...@@ -91,21 +93,11 @@ DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT)
int do_misaligned_access(unsigned long cause, unsigned long address, int do_misaligned_access(unsigned long cause, unsigned long address,
struct pt_regs *regs, struct callee_regs *cregs) struct pt_regs *regs, struct callee_regs *cregs)
{ {
if (misaligned_fixup(address, regs, cause, cregs) != 0) { if (misaligned_fixup(address, regs, cause, cregs) != 0)
siginfo_t info; return do_misaligned_error(cause, address, regs);
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRALN;
info.si_addr = (void __user *)address;
return handle_exception(cause, "Misaligned Access", regs,
&info);
}
return 0; return 0;
} }
#else
DO_ERROR_INFO(SIGSEGV, "Misaligned Access", do_misaligned_access, SEGV_ACCERR)
#endif #endif
/* /*
......
...@@ -26,7 +26,6 @@ static noinline void print_reg_file(long *reg_rev, int start_num) ...@@ -26,7 +26,6 @@ static noinline void print_reg_file(long *reg_rev, int start_num)
char buf[512]; char buf[512];
int n = 0, len = sizeof(buf); int n = 0, len = sizeof(buf);
/* weird loop because pt_regs regs rev r12..r0, r25..r13 */
for (i = start_num; i < start_num + 13; i++) { for (i = start_num; i < start_num + 13; i++) {
n += scnprintf(buf + n, len - n, "r%02u: 0x%08lx\t", n += scnprintf(buf + n, len - n, "r%02u: 0x%08lx\t",
i, (unsigned long)*reg_rev); i, (unsigned long)*reg_rev);
...@@ -34,13 +33,18 @@ static noinline void print_reg_file(long *reg_rev, int start_num) ...@@ -34,13 +33,18 @@ static noinline void print_reg_file(long *reg_rev, int start_num)
if (((i + 1) % 3) == 0) if (((i + 1) % 3) == 0)
n += scnprintf(buf + n, len - n, "\n"); n += scnprintf(buf + n, len - n, "\n");
/* because pt_regs has regs reversed: r12..r0, r25..r13 */
reg_rev--; reg_rev--;
} }
if (start_num != 0) if (start_num != 0)
n += scnprintf(buf + n, len - n, "\n\n"); n += scnprintf(buf + n, len - n, "\n\n");
pr_info("%s", buf); /* To continue printing callee regs on same line as scratch regs */
if (start_num == 0)
pr_info("%s", buf);
else
pr_cont("%s\n", buf);
} }
static void show_callee_regs(struct callee_regs *cregs) static void show_callee_regs(struct callee_regs *cregs)
...@@ -83,6 +87,10 @@ static void show_faulting_vma(unsigned long address, char *buf) ...@@ -83,6 +87,10 @@ static void show_faulting_vma(unsigned long address, char *buf)
dev_t dev = 0; dev_t dev = 0;
char *nm = buf; char *nm = buf;
/* can't use print_vma_addr() yet as it doesn't check for
* non-inclusive vma
*/
vma = find_vma(current->active_mm, address); vma = find_vma(current->active_mm, address);
/* check against the find_vma( ) behaviour which returns the next VMA /* check against the find_vma( ) behaviour which returns the next VMA
...@@ -98,10 +106,13 @@ static void show_faulting_vma(unsigned long address, char *buf) ...@@ -98,10 +106,13 @@ static void show_faulting_vma(unsigned long address, char *buf)
ino = inode->i_ino; ino = inode->i_ino;
} }
pr_info(" @off 0x%lx in [%s]\n" pr_info(" @off 0x%lx in [%s]\n"
" VMA: 0x%08lx to 0x%08lx\n\n", " VMA: 0x%08lx to 0x%08lx\n",
address - vma->vm_start, nm, vma->vm_start, vma->vm_end); vma->vm_start < TASK_UNMAPPED_BASE ?
} else address : address - vma->vm_start,
nm, vma->vm_start, vma->vm_end);
} else {
pr_info(" @No matching VMA found\n"); pr_info(" @No matching VMA found\n");
}
} }
static void show_ecr_verbose(struct pt_regs *regs) static void show_ecr_verbose(struct pt_regs *regs)
...@@ -110,7 +121,7 @@ static void show_ecr_verbose(struct pt_regs *regs) ...@@ -110,7 +121,7 @@ static void show_ecr_verbose(struct pt_regs *regs)
unsigned long address; unsigned long address;
cause_reg = current->thread.cause_code; cause_reg = current->thread.cause_code;
pr_info("\n[ECR]: 0x%08x => ", cause_reg); pr_info("\n[ECR ]: 0x%08x => ", cause_reg);
/* For Data fault, this is data address not instruction addr */ /* For Data fault, this is data address not instruction addr */
address = current->thread.fault_address; address = current->thread.fault_address;
...@@ -120,7 +131,7 @@ static void show_ecr_verbose(struct pt_regs *regs) ...@@ -120,7 +131,7 @@ static void show_ecr_verbose(struct pt_regs *regs)
/* For DTLB Miss or ProtV, display the memory involved too */ /* For DTLB Miss or ProtV, display the memory involved too */
if (vec == ECR_V_DTLB_MISS) { if (vec == ECR_V_DTLB_MISS) {
pr_cont("Invalid (%s) @ 0x%08lx by insn @ 0x%08lx\n", pr_cont("Invalid %s 0x%08lx by insn @ 0x%08lx\n",
(cause_code == 0x01) ? "Read From" : (cause_code == 0x01) ? "Read From" :
((cause_code == 0x02) ? "Write to" : "EX"), ((cause_code == 0x02) ? "Write to" : "EX"),
address, regs->ret); address, regs->ret);
...@@ -168,20 +179,23 @@ void show_regs(struct pt_regs *regs) ...@@ -168,20 +179,23 @@ void show_regs(struct pt_regs *regs)
if (current->thread.cause_code) if (current->thread.cause_code)
show_ecr_verbose(regs); show_ecr_verbose(regs);
pr_info("[EFA]: 0x%08lx\n", current->thread.fault_address); pr_info("[EFA ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n",
pr_info("[ERET]: 0x%08lx (PC of Faulting Instr)\n", regs->ret); current->thread.fault_address,
(void *)regs->blink, (void *)regs->ret);
show_faulting_vma(regs->ret, buf); /* faulting code, not data */ if (user_mode(regs))
show_faulting_vma(regs->ret, buf); /* faulting code, not data */
/* can't use print_vma_addr() yet as it doesn't check for pr_info("[STAT32]: 0x%08lx", regs->status32);
* non-inclusive vma
*/ #define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit : ""
if (!user_mode(regs))
pr_cont(" : %2s %2s %2s %2s %2s\n",
STS_BIT(regs, AE), STS_BIT(regs, A2), STS_BIT(regs, A1),
STS_BIT(regs, E2), STS_BIT(regs, E1));
/* print special regs */ pr_info("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n",
pr_info("status32: 0x%08lx\n", regs->status32); regs->bta, regs->sp, regs->fp);
pr_info(" SP: 0x%08lx\tFP: 0x%08lx\n", regs->sp, regs->fp);
pr_info("BTA: 0x%08lx\tBLINK: 0x%08lx\n",
regs->bta, regs->blink);
pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n",
regs->lp_start, regs->lp_end, regs->lp_count); regs->lp_start, regs->lp_end, regs->lp_count);
......
...@@ -72,16 +72,6 @@ ...@@ -72,16 +72,6 @@
#include <asm/cachectl.h> #include <asm/cachectl.h>
#include <asm/setup.h> #include <asm/setup.h>
#ifdef CONFIG_ARC_HAS_ICACHE
static void __ic_line_inv_no_alias(unsigned long, int);
static void __ic_line_inv_2_alias(unsigned long, int);
static void __ic_line_inv_4_alias(unsigned long, int);
/* Holds the ptr to flush routine, dependign on size due to aliasing issues */
static void (*___flush_icache_rtn) (unsigned long, int);
#endif
char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len) char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len)
{ {
int n = 0; int n = 0;
...@@ -109,7 +99,7 @@ char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len) ...@@ -109,7 +99,7 @@ char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len)
* the cpuinfo structure for later use. * the cpuinfo structure for later use.
* No Validation done here, simply read/convert the BCRs * No Validation done here, simply read/convert the BCRs
*/ */
void __init read_decode_cache_bcr(void) void __cpuinit read_decode_cache_bcr(void)
{ {
struct bcr_cache ibcr, dbcr; struct bcr_cache ibcr, dbcr;
struct cpuinfo_arc_cache *p_ic, *p_dc; struct cpuinfo_arc_cache *p_ic, *p_dc;
...@@ -141,7 +131,7 @@ void __init read_decode_cache_bcr(void) ...@@ -141,7 +131,7 @@ void __init read_decode_cache_bcr(void)
* 3. Enable the Caches, setup default flush mode for D-Cache * 3. Enable the Caches, setup default flush mode for D-Cache
* 3. Calculate the SHMLBA used by user space * 3. Calculate the SHMLBA used by user space
*/ */
void __init arc_cache_init(void) void __cpuinit arc_cache_init(void)
{ {
unsigned int temp; unsigned int temp;
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
...@@ -171,30 +161,6 @@ void __init arc_cache_init(void) ...@@ -171,30 +161,6 @@ void __init arc_cache_init(void)
} }
#endif #endif
/*
* if Cache way size is <= page size then no aliasing exhibited
* otherwise ratio determines num of aliases.
* e.g. 32K I$, 2 way set assoc, 8k pg size
* way-sz = 32k/2 = 16k
* way-pg-ratio = 16k/8k = 2, so 2 aliases possible
* (meaning 1 line could be in 2 possible locations).
*/
way_pg_ratio = ic->sz / ARC_ICACHE_WAYS / PAGE_SIZE;
switch (way_pg_ratio) {
case 0:
case 1:
___flush_icache_rtn = __ic_line_inv_no_alias;
break;
case 2:
___flush_icache_rtn = __ic_line_inv_2_alias;
break;
case 4:
___flush_icache_rtn = __ic_line_inv_4_alias;
break;
default:
panic("Unsupported I-Cache Sz\n");
}
#endif #endif
/* Enable/disable I-Cache */ /* Enable/disable I-Cache */
...@@ -391,75 +357,38 @@ static inline void __dc_line_op(unsigned long start, unsigned long sz, ...@@ -391,75 +357,38 @@ static inline void __dc_line_op(unsigned long start, unsigned long sz,
/* /*
* I-Cache Aliasing in ARC700 VIPT caches * I-Cache Aliasing in ARC700 VIPT caches
* *
* For fetching code from I$, ARC700 uses vaddr (embedded in program code) * ARC VIPT I-cache uses vaddr to index into cache and paddr to match the tag.
* to "index" into SET of cache-line and paddr from MMU to match the TAG * The orig Cache Management Module "CDU" only required paddr to invalidate a
* in the WAYS of SET. * certain line since it sufficed as index in Non-Aliasing VIPT cache-geometry.
* Infact for distinct V1,V2,P: all of {V1-P},{V2-P},{P-P} would end up fetching
* the exact same line.
* *
* However the CDU iterface (to flush/inv) lines from software, only takes * However for larger Caches (way-size > page-size) - i.e. in Aliasing config,
* paddr (to have simpler hardware interface). For simpler cases, using paddr * paddr alone could not be used to correctly index the cache.
* alone suffices.
* e.g. 2-way-set-assoc, 16K I$ (8k MMU pg sz, 32b cache line size):
* way_sz = cache_sz / num_ways = 16k/2 = 8k
* num_sets = way_sz / line_sz = 8k/32 = 256 => 8 bits
* Ignoring the bottom 5 bits corresp to the off within a 32b cacheline,
* bits req for calc set-index = bits 12:5 (0 based). Since this range fits
* inside the bottom 13 bits of paddr, which are same for vaddr and paddr
* (with 8k pg sz), paddr alone can be safely used by CDU to unambigously
* locate a cache-line.
*
* However for a difft sized cache, say 32k I$, above math yields need
* for 14 bits of vaddr to locate a cache line, which can't be provided by
* paddr, since the bit 13 (0 based) might differ between the two.
*
* This lack of extra bits needed for correct line addressing, defines the
* classical problem of Cache aliasing with VIPT architectures
* num_aliases = 1 << extra_bits
* e.g. 2-way-set-assoc, 32K I$ with 8k MMU pg sz => 2 aliases
* 2-way-set-assoc, 64K I$ with 8k MMU pg sz => 4 aliases
* 2-way-set-assoc, 16K I$ with 8k MMU pg sz => NO aliases
* *
* ------------------ * ------------------
* MMU v1/v2 (Fixed Page Size 8k) * MMU v1/v2 (Fixed Page Size 8k)
* ------------------ * ------------------
* The solution was to provide CDU with these additonal vaddr bits. These * The solution was to provide CDU with these additonal vaddr bits. These
* would be bits [x:13], x would depend on cache-geom. * would be bits [x:13], x would depend on cache-geometry, 13 comes from
* standard page size of 8k.
* H/w folks chose [17:13] to be a future safe range, and moreso these 5 bits * H/w folks chose [17:13] to be a future safe range, and moreso these 5 bits
* of vaddr could easily be "stuffed" in the paddr as bits [4:0] since the * of vaddr could easily be "stuffed" in the paddr as bits [4:0] since the
* orig 5 bits of paddr were anyways ignored by CDU line ops, as they * orig 5 bits of paddr were anyways ignored by CDU line ops, as they
* represent the offset within cache-line. The adv of using this "clumsy" * represent the offset within cache-line. The adv of using this "clumsy"
* interface for additional info was no new reg was needed in CDU. * interface for additional info was no new reg was needed in CDU programming
* model.
* *
* 17:13 represented the max num of bits passable, actual bits needed were * 17:13 represented the max num of bits passable, actual bits needed were
* fewer, based on the num-of-aliases possible. * fewer, based on the num-of-aliases possible.
* -for 2 alias possibility, only bit 13 needed (32K cache) * -for 2 alias possibility, only bit 13 needed (32K cache)
* -for 4 alias possibility, bits 14:13 needed (64K cache) * -for 4 alias possibility, bits 14:13 needed (64K cache)
* *
* Since vaddr was not available for all instances of I$ flush req by core
* kernel, the only safe way (non-optimal though) was to kill all possible
* lines which could represent an alias (even if they didnt represent one
* in execution).
* e.g. for 64K I$, 4 aliases possible, so we did
* flush start
* flush start | 0x01
* flush start | 0x2
* flush start | 0x3
*
* The penalty was invoking the operation itself, since tag match is anyways
* paddr based, a line which didn't represent an alias would not match the
* paddr, hence wont be killed
*
* Note that aliasing concerns are independent of line-sz for a given cache
* geometry (size + set_assoc) because the extra bits required by line-sz are
* reduced from the set calc.
* e.g. 2-way-set-assoc, 32K I$ with 8k MMU pg sz and using math above
* 32b line-sz: 9 bits set-index-calc, 5 bits offset-in-line => 1 extra bit
* 64b line-sz: 8 bits set-index-calc, 6 bits offset-in-line => 1 extra bit
*
* ------------------ * ------------------
* MMU v3 * MMU v3
* ------------------ * ------------------
* This ver of MMU supports var page sizes (1k-16k) - Linux will support * This ver of MMU supports variable page sizes (1k-16k): although Linux will
* 8k (default), 16k and 4k. * only support 8k (default), 16k and 4k.
* However from hardware perspective, smaller page sizes aggrevate aliasing * However from hardware perspective, smaller page sizes aggrevate aliasing
* meaning more vaddr bits needed to disambiguate the cache-line-op ; * meaning more vaddr bits needed to disambiguate the cache-line-op ;
* the existing scheme of piggybacking won't work for certain configurations. * the existing scheme of piggybacking won't work for certain configurations.
...@@ -468,115 +397,29 @@ static inline void __dc_line_op(unsigned long start, unsigned long sz, ...@@ -468,115 +397,29 @@ static inline void __dc_line_op(unsigned long start, unsigned long sz,
*/ */
/*********************************************************** /***********************************************************
* Machine specific helpers for per line I-Cache invalidate. * Machine specific helper for per line I-Cache invalidate.
* 3 routines to accpunt for 1, 2, 4 aliases possible
*/ */
static void __ic_line_inv_vaddr(unsigned long phy_start, unsigned long vaddr,
static void __ic_line_inv_no_alias(unsigned long start, int num_lines) unsigned long sz)
{
while (num_lines-- > 0) {
#if (CONFIG_ARC_MMU_VER > 2)
write_aux_reg(ARC_REG_IC_PTAG, start);
#endif
write_aux_reg(ARC_REG_IC_IVIL, start);
start += ARC_ICACHE_LINE_LEN;
}
}
static void __ic_line_inv_2_alias(unsigned long start, int num_lines)
{
while (num_lines-- > 0) {
#if (CONFIG_ARC_MMU_VER > 2)
/*
* MMU v3, CDU prog model (for line ops) now uses a new IC_PTAG
* reg to pass the "tag" bits and existing IVIL reg only looks
* at bits relevant for "index" (details above)
* Programming Notes:
* -when writing tag to PTAG reg, bit chopping can be avoided,
* CDU ignores non-tag bits.
* -Ideally "index" must be computed from vaddr, but it is not
* avail in these rtns. So to be safe, we kill the lines in all
* possible indexes corresp to num of aliases possible for
* given cache config.
*/
write_aux_reg(ARC_REG_IC_PTAG, start);
write_aux_reg(ARC_REG_IC_IVIL,
start & ~(0x1 << PAGE_SHIFT));
write_aux_reg(ARC_REG_IC_IVIL, start | (0x1 << PAGE_SHIFT));
#else
write_aux_reg(ARC_REG_IC_IVIL, start);
write_aux_reg(ARC_REG_IC_IVIL, start | 0x01);
#endif
start += ARC_ICACHE_LINE_LEN;
}
}
static void __ic_line_inv_4_alias(unsigned long start, int num_lines)
{
while (num_lines-- > 0) {
#if (CONFIG_ARC_MMU_VER > 2)
write_aux_reg(ARC_REG_IC_PTAG, start);
write_aux_reg(ARC_REG_IC_IVIL,
start & ~(0x3 << PAGE_SHIFT));
write_aux_reg(ARC_REG_IC_IVIL,
start & ~(0x2 << PAGE_SHIFT));
write_aux_reg(ARC_REG_IC_IVIL,
start & ~(0x1 << PAGE_SHIFT));
write_aux_reg(ARC_REG_IC_IVIL, start | (0x3 << PAGE_SHIFT));
#else
write_aux_reg(ARC_REG_IC_IVIL, start);
write_aux_reg(ARC_REG_IC_IVIL, start | 0x01);
write_aux_reg(ARC_REG_IC_IVIL, start | 0x02);
write_aux_reg(ARC_REG_IC_IVIL, start | 0x03);
#endif
start += ARC_ICACHE_LINE_LEN;
}
}
static void __ic_line_inv(unsigned long start, unsigned long sz)
{ {
unsigned long flags; unsigned long flags;
int num_lines, slack; int num_lines, slack;
unsigned int addr;
/* /*
* Ensure we properly floor/ceil the non-line aligned/sized requests * Ensure we properly floor/ceil the non-line aligned/sized requests:
* and have @start - aligned to cache line, and integral @num_lines
* However page sized flushes can be compile time optimised. * However page sized flushes can be compile time optimised.
* -@start will be cache-line aligned already (being page aligned) * -@phy_start will be cache-line aligned already (being page aligned)
* -@sz will be integral multiple of line size (being page sized). * -@sz will be integral multiple of line size (being page sized).
*/ */
if (!(__builtin_constant_p(sz) && sz == PAGE_SIZE)) { if (!(__builtin_constant_p(sz) && sz == PAGE_SIZE)) {
slack = start & ~ICACHE_LINE_MASK; slack = phy_start & ~ICACHE_LINE_MASK;
sz += slack; sz += slack;
start -= slack; phy_start -= slack;
} }
num_lines = DIV_ROUND_UP(sz, ARC_ICACHE_LINE_LEN); num_lines = DIV_ROUND_UP(sz, ARC_ICACHE_LINE_LEN);
local_irq_save(flags);
(*___flush_icache_rtn) (start, num_lines);
local_irq_restore(flags);
}
/* Unlike routines above, having vaddr for flush op (along with paddr),
* prevents the need to speculatively kill the lines in multiple sets
* based on ratio of way_sz : pg_sz
*/
static void __ic_line_inv_vaddr(unsigned long phy_start,
unsigned long vaddr, unsigned long sz)
{
unsigned long flags;
int num_lines, slack;
unsigned int addr;
slack = phy_start & ~ICACHE_LINE_MASK;
sz += slack;
phy_start -= slack;
num_lines = DIV_ROUND_UP(sz, ARC_ICACHE_LINE_LEN);
#if (CONFIG_ARC_MMU_VER > 2) #if (CONFIG_ARC_MMU_VER > 2)
vaddr &= ~ICACHE_LINE_MASK; vaddr &= ~ICACHE_LINE_MASK;
addr = phy_start; addr = phy_start;
...@@ -595,7 +438,7 @@ static void __ic_line_inv_vaddr(unsigned long phy_start, ...@@ -595,7 +438,7 @@ static void __ic_line_inv_vaddr(unsigned long phy_start,
write_aux_reg(ARC_REG_IC_IVIL, vaddr); write_aux_reg(ARC_REG_IC_IVIL, vaddr);
vaddr += ARC_ICACHE_LINE_LEN; vaddr += ARC_ICACHE_LINE_LEN;
#else #else
/* this paddr contains vaddrs bits as needed */ /* paddr contains stuffed vaddrs bits */
write_aux_reg(ARC_REG_IC_IVIL, addr); write_aux_reg(ARC_REG_IC_IVIL, addr);
#endif #endif
addr += ARC_ICACHE_LINE_LEN; addr += ARC_ICACHE_LINE_LEN;
...@@ -605,7 +448,6 @@ static void __ic_line_inv_vaddr(unsigned long phy_start, ...@@ -605,7 +448,6 @@ static void __ic_line_inv_vaddr(unsigned long phy_start,
#else #else
#define __ic_line_inv(start, sz)
#define __ic_line_inv_vaddr(pstart, vstart, sz) #define __ic_line_inv_vaddr(pstart, vstart, sz)
#endif /* CONFIG_ARC_HAS_ICACHE */ #endif /* CONFIG_ARC_HAS_ICACHE */
...@@ -615,10 +457,10 @@ static void __ic_line_inv_vaddr(unsigned long phy_start, ...@@ -615,10 +457,10 @@ static void __ic_line_inv_vaddr(unsigned long phy_start,
* Exported APIs * Exported APIs
*/ */
/* TBD: use pg_arch_1 to optimize this */
void flush_dcache_page(struct page *page) void flush_dcache_page(struct page *page)
{ {
__dc_line_op((unsigned long)page_address(page), PAGE_SIZE, OP_FLUSH); /* Make a note that dcache is not yet flushed for this page */
set_bit(PG_arch_1, &page->flags);
} }
EXPORT_SYMBOL(flush_dcache_page); EXPORT_SYMBOL(flush_dcache_page);
...@@ -642,8 +484,8 @@ void dma_cache_wback(unsigned long start, unsigned long sz) ...@@ -642,8 +484,8 @@ void dma_cache_wback(unsigned long start, unsigned long sz)
EXPORT_SYMBOL(dma_cache_wback); EXPORT_SYMBOL(dma_cache_wback);
/* /*
* This is API for making I/D Caches consistent when modifying code * This is API for making I/D Caches consistent when modifying
* (loadable modules, kprobes, etc) * kernel code (loadable modules, kprobes, kgdb...)
* This is called on insmod, with kernel virtual address for CODE of * This is called on insmod, with kernel virtual address for CODE of
* the module. ARC cache maintenance ops require PHY address thus we * the module. ARC cache maintenance ops require PHY address thus we
* need to convert vmalloc addr to PHY addr * need to convert vmalloc addr to PHY addr
...@@ -652,7 +494,6 @@ void flush_icache_range(unsigned long kstart, unsigned long kend) ...@@ -652,7 +494,6 @@ void flush_icache_range(unsigned long kstart, unsigned long kend)
{ {
unsigned int tot_sz, off, sz; unsigned int tot_sz, off, sz;
unsigned long phy, pfn; unsigned long phy, pfn;
unsigned long flags;
/* printk("Kernel Cache Cohenercy: %lx to %lx\n",kstart, kend); */ /* printk("Kernel Cache Cohenercy: %lx to %lx\n",kstart, kend); */
...@@ -673,8 +514,13 @@ void flush_icache_range(unsigned long kstart, unsigned long kend) ...@@ -673,8 +514,13 @@ void flush_icache_range(unsigned long kstart, unsigned long kend)
/* Case: Kernel Phy addr (0x8000_0000 onwards) */ /* Case: Kernel Phy addr (0x8000_0000 onwards) */
if (likely(kstart > PAGE_OFFSET)) { if (likely(kstart > PAGE_OFFSET)) {
__ic_line_inv(kstart, kend - kstart); /*
__dc_line_op(kstart, kend - kstart, OP_FLUSH); * The 2nd arg despite being paddr will be used to index icache
* This is OK since no alternate virtual mappings will exist
* given the callers for this case: kprobe/kgdb in built-in
* kernel code only.
*/
__sync_icache_dcache(kstart, kstart, kend - kstart);
return; return;
} }
...@@ -692,42 +538,41 @@ void flush_icache_range(unsigned long kstart, unsigned long kend) ...@@ -692,42 +538,41 @@ void flush_icache_range(unsigned long kstart, unsigned long kend)
pfn = vmalloc_to_pfn((void *)kstart); pfn = vmalloc_to_pfn((void *)kstart);
phy = (pfn << PAGE_SHIFT) + off; phy = (pfn << PAGE_SHIFT) + off;
sz = min_t(unsigned int, tot_sz, PAGE_SIZE - off); sz = min_t(unsigned int, tot_sz, PAGE_SIZE - off);
local_irq_save(flags); __sync_icache_dcache(phy, kstart, sz);
__dc_line_op(phy, sz, OP_FLUSH);
__ic_line_inv(phy, sz);
local_irq_restore(flags);
kstart += sz; kstart += sz;
tot_sz -= sz; tot_sz -= sz;
} }
} }
/* /*
* Optimised ver of flush_icache_range() with spec callers: ptrace/signals * General purpose helper to make I and D cache lines consistent.
* where vaddr is also available. This allows passing both vaddr and paddr * @paddr is phy addr of region
* bits to CDU for cache flush, short-circuting the current pessimistic algo * @vaddr is typically user or kernel vaddr (vmalloc)
* which kills all possible aliases. * Howver in one instance, flush_icache_range() by kprobe (for a breakpt in
* An added adv of knowing that vaddr is user-vaddr avoids various checks * builtin kernel code) @vaddr will be paddr only, meaning CDU operation will
* and handling for k-vaddr, k-paddr as done in orig ver above * use a paddr to index the cache (despite VIPT). This is fine since since a
* built-in kernel page will not have any virtual mappings (not even kernel)
* kprobe on loadable module is different as it will have kvaddr.
*/ */
void flush_icache_range_vaddr(unsigned long paddr, unsigned long u_vaddr, void __sync_icache_dcache(unsigned long paddr, unsigned long vaddr, int len)
int len)
{ {
__ic_line_inv_vaddr(paddr, u_vaddr, len); unsigned long flags;
local_irq_save(flags);
__ic_line_inv_vaddr(paddr, vaddr, len);
__dc_line_op(paddr, len, OP_FLUSH); __dc_line_op(paddr, len, OP_FLUSH);
local_irq_restore(flags);
} }
/* /* wrapper to compile time eliminate alignment checks in flush loop */
* XXX: This also needs to be optim using pg_arch_1 void __inv_icache_page(unsigned long paddr, unsigned long vaddr)
* This is called when a page-cache page is about to be mapped into a
* user process' address space. It offers an opportunity for a
* port to ensure d-cache/i-cache coherency if necessary.
*/
void flush_icache_page(struct vm_area_struct *vma, struct page *page)
{ {
if (!(vma->vm_flags & VM_EXEC)) __ic_line_inv_vaddr(paddr, vaddr, PAGE_SIZE);
return; }
__ic_line_inv((unsigned long)page_address(page), PAGE_SIZE); void __flush_dcache_page(unsigned long paddr)
{
__dc_line_op(paddr, PAGE_SIZE, OP_FLUSH_N_INV);
} }
void flush_icache_all(void) void flush_icache_all(void)
......
...@@ -27,7 +27,7 @@ int fixup_exception(struct pt_regs *regs) ...@@ -27,7 +27,7 @@ int fixup_exception(struct pt_regs *regs)
#ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE #ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
long arc_copy_from_user_noinline(void *to, const void __user * from, long arc_copy_from_user_noinline(void *to, const void __user *from,
unsigned long n) unsigned long n)
{ {
return __arc_copy_from_user(to, from, n); return __arc_copy_from_user(to, from, n);
...@@ -48,7 +48,7 @@ unsigned long arc_clear_user_noinline(void __user *to, ...@@ -48,7 +48,7 @@ unsigned long arc_clear_user_noinline(void __user *to,
} }
EXPORT_SYMBOL(arc_clear_user_noinline); EXPORT_SYMBOL(arc_clear_user_noinline);
long arc_strncpy_from_user_noinline (char *dst, const char __user *src, long arc_strncpy_from_user_noinline(char *dst, const char __user *src,
long count) long count)
{ {
return __arc_strncpy_from_user(dst, src, count); return __arc_strncpy_from_user(dst, src, count);
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/version.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/kdebug.h> #include <linux/kdebug.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
......
...@@ -10,9 +10,6 @@ ...@@ -10,9 +10,6 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#ifdef CONFIG_BLOCK_DEV_RAM
#include <linux/blk.h>
#endif
#include <linux/swap.h> #include <linux/swap.h>
#include <linux/module.h> #include <linux/module.h>
#include <asm/page.h> #include <asm/page.h>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/cache.h> #include <linux/cache.h>
void __iomem *ioremap(unsigned long paddr, unsigned long size) void __iomem *ioremap(unsigned long paddr, unsigned long size)
{ {
......
...@@ -418,23 +418,37 @@ void create_tlb(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) ...@@ -418,23 +418,37 @@ void create_tlb(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
local_irq_restore(flags); local_irq_restore(flags);
} }
/* arch hook called by core VM at the end of handle_mm_fault( ), /*
* when a new PTE is entered in Page Tables or an existing one * Called at the end of pagefault, for a userspace mapped page
* is modified. We aggresively pre-install a TLB entry * -pre-install the corresponding TLB entry into MMU
* -Finalize the delayed D-cache flush (wback+inv kernel mapping)
*/ */
void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned,
void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddress,
pte_t *ptep) pte_t *ptep)
{ {
unsigned long vaddr = vaddr_unaligned & PAGE_MASK;
create_tlb(vma, vaddr, ptep);
create_tlb(vma, vaddress, ptep); /* icache doesn't snoop dcache, thus needs to be made coherent here */
if (vma->vm_flags & VM_EXEC) {
struct page *page = pfn_to_page(pte_pfn(*ptep));
/* if page was dcache dirty, flush now */
int dirty = test_and_clear_bit(PG_arch_1, &page->flags);
if (dirty) {
unsigned long paddr = pte_val(*ptep) & PAGE_MASK;
__flush_dcache_page(paddr);
__inv_icache_page(paddr, vaddr);
}
}
} }
/* Read the Cache Build Confuration Registers, Decode them and save into /* Read the Cache Build Confuration Registers, Decode them and save into
* the cpuinfo structure for later use. * the cpuinfo structure for later use.
* No Validation is done here, simply read/convert the BCRs * No Validation is done here, simply read/convert the BCRs
*/ */
void __init read_decode_mmu_bcr(void) void __cpuinit read_decode_mmu_bcr(void)
{ {
unsigned int tmp; unsigned int tmp;
struct bcr_mmu_1_2 *mmu2; /* encoded MMU2 attr */ struct bcr_mmu_1_2 *mmu2; /* encoded MMU2 attr */
...@@ -466,7 +480,7 @@ void __init read_decode_mmu_bcr(void) ...@@ -466,7 +480,7 @@ void __init read_decode_mmu_bcr(void)
char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len)
{ {
int n = 0; int n = 0;
struct cpuinfo_arc_mmu *p_mmu = &cpuinfo_arc700[smp_processor_id()].mmu; struct cpuinfo_arc_mmu *p_mmu = &cpuinfo_arc700[cpu_id].mmu;
n += scnprintf(buf + n, len - n, "ARC700 MMU [v%x]\t: %dk PAGE, ", n += scnprintf(buf + n, len - n, "ARC700 MMU [v%x]\t: %dk PAGE, ",
p_mmu->ver, TO_KB(p_mmu->pg_sz)); p_mmu->ver, TO_KB(p_mmu->pg_sz));
...@@ -480,7 +494,7 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) ...@@ -480,7 +494,7 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len)
return buf; return buf;
} }
void __init arc_mmu_init(void) void __cpuinit arc_mmu_init(void)
{ {
char str[256]; char str[256];
struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu;
......
...@@ -224,3 +224,15 @@ MACHINE_START(ML509, "ml509") ...@@ -224,3 +224,15 @@ MACHINE_START(ML509, "ml509")
.init_smp = iss_model_init_smp, .init_smp = iss_model_init_smp,
#endif #endif
MACHINE_END MACHINE_END
static const char *nsimosci_compat[] __initdata = {
"snps,nsimosci",
NULL,
};
MACHINE_START(NSIMOSCI, "nsimosci")
.dt_compat = nsimosci_compat,
.init_early = NULL,
.init_machine = plat_fpga_populate_dev,
.init_irq = NULL,
MACHINE_END
# Abilis Systems TB10x platform kernel configuration file
#
# Author: Christian Ruppert <christian.ruppert@abilis.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.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
menuconfig ARC_PLAT_TB10X
bool "Abilis TB10x"
select COMMON_CLK
select PINCTRL
select PINMUX
select ARCH_REQUIRE_GPIOLIB
help
Support for platforms based on the TB10x home media gateway SOC by
Abilis Systems. TB10x is based on the ARC700 CPU architecture.
Say Y if you are building a kernel for one of the SOCs in this
series (e.g. TB100 or TB101). If in doubt say N.
if ARC_PLAT_TB10X
config GENERIC_GPIO
def_bool y
endif
# Abilis Systems TB10x platform Makefile
#
# Author: Christian Ruppert <christian.ruppert@abilis.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.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
KBUILD_CFLAGS += -Iarch/arc/plat-tb10x/include
obj-y += tb10x.o
/*
* Abilis Systems TB10x platform initialisation
*
* Copyright (C) Abilis Systems 2012
*
* Author: Christian Ruppert <christian.ruppert@abilis.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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/of_platform.h>
#include <linux/clk-provider.h>
#include <linux/pinctrl/consumer.h>
#include <asm/mach_desc.h>
static void __init tb10x_platform_init(void)
{
of_clk_init(NULL);
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
static void __init tb10x_platform_late_init(void)
{
struct device_node *dn;
/*
* Pinctrl documentation recommends setting up the iomux here for
* all modules which don't require control over the pins themselves.
* Modules which need this kind of assistance are compatible with
* "abilis,simple-pinctrl", i.e. we can easily iterate over them.
* TODO: Does this recommended method work cleanly with pins required
* by modules?
*/
for_each_compatible_node(dn, NULL, "abilis,simple-pinctrl") {
struct platform_device *pd = of_find_device_by_node(dn);
struct pinctrl *pctl;
pctl = pinctrl_get_select(&pd->dev, "abilis,simple-default");
if (IS_ERR(pctl)) {
int ret = PTR_ERR(pctl);
dev_err(&pd->dev, "Could not set up pinctrl: %d\n",
ret);
}
}
}
static const char *tb10x_compat[] __initdata = {
"abilis,arc-tb10x",
NULL,
};
MACHINE_START(TB10x, "tb10x")
.dt_compat = tb10x_compat,
.init_machine = tb10x_platform_init,
.init_late = tb10x_platform_late_init,
MACHINE_END
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册