Commit 3d430bdb authored by Linus Torvalds's avatar Linus Torvalds

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

Pull ARC updates from Vineet Gupta:
 "Sorry for the late pull request.  Current stuff was ready for a while
  but I was hoping to squeeze in support for almost ready ARC SDP
  platform (and avoid a 2nd pull request), however it seems there are
  still some loose ends which warrant more time.

   - Platform code reduction/moving-up (TB10X no longer needs any
     callbacks)
   - updated boot printing
   - kgdb update for arc gdb 7.5
   - bug fixes (some marked for stable)
   - more code refactoring/consolidation"

* tag 'arc-3.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc:
  ARC: boot: cpu feature print enhancements
  ARC: boot: consolidate cross-checking of h/w and s/w
  ARC: unbork FPU save/restore
  ARC: remove extraneous __KERNEL__ guards
  ARC: Update order of registers in KGDB to match GDB 7.5
  ARC: Remove unneeded Kconfig entry NO_DMA
  ARC: BUG() dumps stack after @msg (@msg now same as in generic BUG))
  ARC: refactoring: reduce the scope of some local vars
  ARC: remove gcc mpy heuristics
  ARC: RIP @running_on_hw
  ARC: Update comments about uncached address space
  ARC: rename kconfig option for unaligned emulation
  ARC: [nsimosci] Allow "headless" models to boot
  ARC: [arcfpga] Get rid of ARC_BOARD_ANGEL4 and ARC_BOARD_ML509
  ARC: [arcfpga] Remove more dead code
  ARC: [plat*] move code out of .init_machine into common
  ARC: [arcfpga] consolidate machine description, DT
  ARC: Allow SMP kernel to build/boot on UP-only infrastructure
parents dc303408 56372082
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
config ARC config ARC
def_bool y def_bool y
select BUILDTIME_EXTABLE_SORT select BUILDTIME_EXTABLE_SORT
select COMMON_CLK
select CLONE_BACKWARDS select CLONE_BACKWARDS
# ARC Busybox based initramfs absolutely relies on DEVTMPFS for /dev # ARC Busybox based initramfs absolutely relies on DEVTMPFS for /dev
select DEVTMPFS if !INITRAMFS_SOURCE="" select DEVTMPFS if !INITRAMFS_SOURCE=""
...@@ -73,9 +74,6 @@ config STACKTRACE_SUPPORT ...@@ -73,9 +74,6 @@ config STACKTRACE_SUPPORT
config HAVE_LATENCYTOP_SUPPORT config HAVE_LATENCYTOP_SUPPORT
def_bool y def_bool y
config NO_DMA
def_bool n
source "init/Kconfig" source "init/Kconfig"
source "kernel/Kconfig.freezer" source "kernel/Kconfig.freezer"
...@@ -354,7 +352,7 @@ config ARC_CURR_IN_REG ...@@ -354,7 +352,7 @@ config ARC_CURR_IN_REG
kernel mode. This saves memory access for each such access kernel mode. This saves memory access for each such access
config ARC_MISALIGN_ACCESS config ARC_EMUL_UNALIGNED
bool "Emulate unaligned memory access (userspace only)" bool "Emulate unaligned memory access (userspace only)"
select SYSCTL_ARCH_UNALIGN_NO_WARN select SYSCTL_ARCH_UNALIGN_NO_WARN
select SYSCTL_ARCH_UNALIGN_ALLOW select SYSCTL_ARCH_UNALIGN_ALLOW
......
...@@ -25,7 +25,6 @@ ifdef CONFIG_ARC_CURR_IN_REG ...@@ -25,7 +25,6 @@ ifdef CONFIG_ARC_CURR_IN_REG
LINUXINCLUDE += -include ${src}/arch/arc/include/asm/current.h LINUXINCLUDE += -include ${src}/arch/arc/include/asm/current.h
endif endif
upto_gcc42 := $(call cc-ifversion, -le, 0402, y)
upto_gcc44 := $(call cc-ifversion, -le, 0404, y) upto_gcc44 := $(call cc-ifversion, -le, 0404, y)
atleast_gcc44 := $(call cc-ifversion, -ge, 0404, y) atleast_gcc44 := $(call cc-ifversion, -ge, 0404, y)
atleast_gcc48 := $(call cc-ifversion, -ge, 0408, y) atleast_gcc48 := $(call cc-ifversion, -ge, 0408, y)
...@@ -60,25 +59,11 @@ ldflags-$(CONFIG_CPU_BIG_ENDIAN) += -EB ...@@ -60,25 +59,11 @@ ldflags-$(CONFIG_CPU_BIG_ENDIAN) += -EB
# --build-id w/o "-marclinux". Default arc-elf32-ld is OK # --build-id w/o "-marclinux". Default arc-elf32-ld is OK
ldflags-$(upto_gcc44) += -marclinux ldflags-$(upto_gcc44) += -marclinux
ARC_LIBGCC := -mA7
cflags-$(CONFIG_ARC_HAS_HW_MPY) += -multcost=16
ifndef CONFIG_ARC_HAS_HW_MPY ifndef CONFIG_ARC_HAS_HW_MPY
cflags-y += -mno-mpy cflags-y += -mno-mpy
# newlib for ARC700 assumes MPY to be always present, which is generally true
# However, if someone really doesn't want MPY, we need to use the 600 ver
# which coupled with -mno-mpy will use mpy emulation
# With gcc 4.4.7, -mno-mpy is enough to make any other related adjustments,
# e.g. increased cost of MPY. With gcc 4.2.1 this had to be explicitly hinted
ifeq ($(upto_gcc42),y)
ARC_LIBGCC := -marc600
cflags-y += -multcost=30
endif
endif endif
LIBGCC := $(shell $(CC) $(ARC_LIBGCC) $(cflags-y) --print-libgcc-file-name) LIBGCC := $(shell $(CC) $(cflags-y) --print-libgcc-file-name)
# Modules with short calls might break for calls into builtin-kernel # Modules with short calls might break for calls into builtin-kernel
KBUILD_CFLAGS_MODULE += -mlong-calls KBUILD_CFLAGS_MODULE += -mlong-calls
......
...@@ -24,11 +24,6 @@ aliases { ...@@ -24,11 +24,6 @@ aliases {
serial0 = &arcuart0; serial0 = &arcuart0;
}; };
memory {
device_type = "memory";
reg = <0x00000000 0x10000000>; /* 256M */
};
fpga { fpga {
compatible = "simple-bus"; compatible = "simple-bus";
#address-cells = <1>; #address-cells = <1>;
......
...@@ -20,18 +20,13 @@ chosen { ...@@ -20,18 +20,13 @@ chosen {
/* this is for console on PGU */ /* this is for console on PGU */
/* bootargs = "console=tty0 consoleblank=0"; */ /* bootargs = "console=tty0 consoleblank=0"; */
/* this is for console on serial */ /* this is for console on serial */
bootargs = "earlycon=uart8250,mmio32,0xc0000000,115200n8 console=ttyS0,115200n8 consoleblank=0 debug"; bootargs = "earlycon=uart8250,mmio32,0xc0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblank=0 debug";
}; };
aliases { aliases {
serial0 = &uart0; serial0 = &uart0;
}; };
memory {
device_type = "memory";
reg = <0x80000000 0x10000000>; /* 256M */
};
fpga { fpga {
compatible = "simple-bus"; compatible = "simple-bus";
#address-cells = <1>; #address-cells = <1>;
......
...@@ -23,7 +23,6 @@ CONFIG_MODULES=y ...@@ -23,7 +23,6 @@ CONFIG_MODULES=y
# CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set # CONFIG_IOSCHED_CFQ is not set
CONFIG_ARC_PLAT_FPGA_LEGACY=y CONFIG_ARC_PLAT_FPGA_LEGACY=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_PREEMPT=y
......
...@@ -20,7 +20,6 @@ CONFIG_MODULES=y ...@@ -20,7 +20,6 @@ CONFIG_MODULES=y
# CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set # CONFIG_IOSCHED_CFQ is not set
CONFIG_ARC_PLAT_FPGA_LEGACY=y CONFIG_ARC_PLAT_FPGA_LEGACY=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_PREEMPT=y
......
...@@ -21,7 +21,6 @@ CONFIG_MODULES=y ...@@ -21,7 +21,6 @@ CONFIG_MODULES=y
# CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set # CONFIG_IOSCHED_CFQ is not set
CONFIG_ARC_PLAT_FPGA_LEGACY=y CONFIG_ARC_PLAT_FPGA_LEGACY=y
CONFIG_ARC_BOARD_ML509=y
# CONFIG_ARC_IDE is not set # CONFIG_ARC_IDE is not set
# CONFIG_ARCTANGENT_EMAC is not set # CONFIG_ARCTANGENT_EMAC is not set
# CONFIG_ARC_HAS_RTSC is not set # CONFIG_ARC_HAS_RTSC is not set
......
...@@ -9,19 +9,16 @@ ...@@ -9,19 +9,16 @@
#ifndef _ASM_ARC_ARCREGS_H #ifndef _ASM_ARC_ARCREGS_H
#define _ASM_ARC_ARCREGS_H #define _ASM_ARC_ARCREGS_H
#ifdef __KERNEL__
/* Build Configuration Registers */ /* Build Configuration Registers */
#define ARC_REG_DCCMBASE_BCR 0x61 /* DCCM Base Addr */ #define ARC_REG_DCCMBASE_BCR 0x61 /* DCCM Base Addr */
#define ARC_REG_CRC_BCR 0x62 #define ARC_REG_CRC_BCR 0x62
#define ARC_REG_DVFB_BCR 0x64
#define ARC_REG_EXTARITH_BCR 0x65
#define ARC_REG_VECBASE_BCR 0x68 #define ARC_REG_VECBASE_BCR 0x68
#define ARC_REG_PERIBASE_BCR 0x69 #define ARC_REG_PERIBASE_BCR 0x69
#define ARC_REG_FP_BCR 0x6B /* Single-Precision FPU */ #define ARC_REG_FP_BCR 0x6B /* ARCompact: Single-Precision FPU */
#define ARC_REG_DPFP_BCR 0x6C /* Dbl Precision FPU */ #define ARC_REG_DPFP_BCR 0x6C /* ARCompact: Dbl Precision FPU */
#define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */ #define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */
#define ARC_REG_TIMERS_BCR 0x75 #define ARC_REG_TIMERS_BCR 0x75
#define ARC_REG_AP_BCR 0x76
#define ARC_REG_ICCM_BCR 0x78 #define ARC_REG_ICCM_BCR 0x78
#define ARC_REG_XY_MEM_BCR 0x79 #define ARC_REG_XY_MEM_BCR 0x79
#define ARC_REG_MAC_BCR 0x7a #define ARC_REG_MAC_BCR 0x7a
...@@ -31,6 +28,9 @@ ...@@ -31,6 +28,9 @@
#define ARC_REG_MIXMAX_BCR 0x7e #define ARC_REG_MIXMAX_BCR 0x7e
#define ARC_REG_BARREL_BCR 0x7f #define ARC_REG_BARREL_BCR 0x7f
#define ARC_REG_D_UNCACH_BCR 0x6A #define ARC_REG_D_UNCACH_BCR 0x6A
#define ARC_REG_BPU_BCR 0xc0
#define ARC_REG_ISA_CFG_BCR 0xc1
#define ARC_REG_SMART_BCR 0xFF
/* status32 Bits Positions */ /* status32 Bits Positions */
#define STATUS_AE_BIT 5 /* Exception active */ #define STATUS_AE_BIT 5 /* Exception active */
...@@ -191,14 +191,6 @@ ...@@ -191,14 +191,6 @@
#define PAGES_TO_KB(n_pages) ((n_pages) << (PAGE_SHIFT - 10)) #define PAGES_TO_KB(n_pages) ((n_pages) << (PAGE_SHIFT - 10))
#define PAGES_TO_MB(n_pages) (PAGES_TO_KB(n_pages) >> 10) #define PAGES_TO_MB(n_pages) (PAGES_TO_KB(n_pages) >> 10)
#ifdef CONFIG_ARC_FPU_SAVE_RESTORE
/* These DPFP regs need to be saved/restored across ctx-sw */
struct arc_fpu {
struct {
unsigned int l, h;
} aux_dpfp[2];
};
#endif
/* /*
*************************************************************** ***************************************************************
...@@ -212,27 +204,19 @@ struct bcr_identity { ...@@ -212,27 +204,19 @@ struct bcr_identity {
#endif #endif
}; };
#define EXTN_SWAP_VALID 0x1 struct bcr_isa {
#define EXTN_NORM_VALID 0x2
#define EXTN_MINMAX_VALID 0x2
#define EXTN_BARREL_VALID 0x2
struct bcr_extn {
#ifdef CONFIG_CPU_BIG_ENDIAN #ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad:20, crc:1, ext_arith:2, mul:2, barrel:2, minmax:2, unsigned int pad1:23, atomic1:1, ver:8;
norm:2, swap:1;
#else #else
unsigned int swap:1, norm:2, minmax:2, barrel:2, mul:2, ext_arith:2, unsigned int ver:8, atomic1:1, pad1:23;
crc:1, pad:20;
#endif #endif
}; };
/* DSP Options Ref Manual */ struct bcr_mpy {
struct bcr_extn_mac_mul {
#ifdef CONFIG_CPU_BIG_ENDIAN #ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad:16, type:8, ver:8; unsigned int pad:8, x1616:8, dsp:4, cycles:2, type:2, ver:8;
#else #else
unsigned int ver:8, type:8, pad:16; unsigned int ver:8, type:2, cycles:2, dsp:4, x1616:8, pad:8;
#endif #endif
}; };
...@@ -251,6 +235,7 @@ struct bcr_perip { ...@@ -251,6 +235,7 @@ struct bcr_perip {
unsigned int pad:8, sz:8, pad2:8, start:8; unsigned int pad:8, sz:8, pad2:8, start:8;
#endif #endif
}; };
struct bcr_iccm { struct bcr_iccm {
#ifdef CONFIG_CPU_BIG_ENDIAN #ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int base:16, pad:5, sz:3, ver:8; unsigned int base:16, pad:5, sz:3, ver:8;
...@@ -277,8 +262,8 @@ struct bcr_dccm { ...@@ -277,8 +262,8 @@ struct bcr_dccm {
#endif #endif
}; };
/* Both SP and DP FPU BCRs have same format */ /* ARCompact: Both SP and DP FPU BCRs have same format */
struct bcr_fp { struct bcr_fp_arcompact {
#ifdef CONFIG_CPU_BIG_ENDIAN #ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int fast:1, ver:8; unsigned int fast:1, ver:8;
#else #else
...@@ -286,6 +271,30 @@ struct bcr_fp { ...@@ -286,6 +271,30 @@ struct bcr_fp {
#endif #endif
}; };
struct bcr_timer {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad2:15, rtsc:1, pad1:6, t1:1, t0:1, ver:8;
#else
unsigned int ver:8, t0:1, t1:1, pad1:6, rtsc:1, pad2:15;
#endif
};
struct bcr_bpu_arcompact {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad2:19, fam:1, pad:2, ent:2, ver:8;
#else
unsigned int ver:8, ent:2, pad:2, fam:1, pad2:19;
#endif
};
struct bcr_generic {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad:24, ver:8;
#else
unsigned int ver:8, pad:24;
#endif
};
/* /*
******************************************************************* *******************************************************************
* Generic structures to hold build configuration used at runtime * Generic structures to hold build configuration used at runtime
...@@ -299,6 +308,10 @@ struct cpuinfo_arc_cache { ...@@ -299,6 +308,10 @@ struct cpuinfo_arc_cache {
unsigned int sz_k:8, line_len:8, assoc:4, ver:4, alias:1, vipt:1, pad:6; unsigned int sz_k:8, line_len:8, assoc:4, ver:4, alias:1, vipt:1, pad:6;
}; };
struct cpuinfo_arc_bpu {
unsigned int ver, full, num_cache, num_pred;
};
struct cpuinfo_arc_ccm { struct cpuinfo_arc_ccm {
unsigned int base_addr, sz; unsigned int base_addr, sz;
}; };
...@@ -306,21 +319,25 @@ struct cpuinfo_arc_ccm { ...@@ -306,21 +319,25 @@ struct cpuinfo_arc_ccm {
struct cpuinfo_arc { struct cpuinfo_arc {
struct cpuinfo_arc_cache icache, dcache; struct cpuinfo_arc_cache icache, dcache;
struct cpuinfo_arc_mmu mmu; struct cpuinfo_arc_mmu mmu;
struct cpuinfo_arc_bpu bpu;
struct bcr_identity core; struct bcr_identity core;
unsigned int timers; struct bcr_isa isa;
struct bcr_timer timers;
unsigned int vec_base; unsigned int vec_base;
unsigned int uncached_base; unsigned int uncached_base;
struct cpuinfo_arc_ccm iccm, dccm; struct cpuinfo_arc_ccm iccm, dccm;
struct bcr_extn extn; struct {
unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, pad1:3,
fpu_sp:1, fpu_dp:1, pad2:6,
debug:1, ap:1, smart:1, rtt:1, pad3:4,
pad4:8;
} extn;
struct bcr_mpy extn_mpy;
struct bcr_extn_xymem extn_xymem; struct bcr_extn_xymem extn_xymem;
struct bcr_extn_mac_mul extn_mac_mul;
struct bcr_fp fp, dpfp;
}; };
extern struct cpuinfo_arc cpuinfo_arc700[]; extern struct cpuinfo_arc cpuinfo_arc700[];
#endif /* __ASEMBLY__ */ #endif /* __ASEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_ARC_ARCREGS_H */ #endif /* _ASM_ARC_ARCREGS_H */
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
#ifndef _ASM_ARC_ATOMIC_H #ifndef _ASM_ARC_ATOMIC_H
#define _ASM_ARC_ATOMIC_H #define _ASM_ARC_ATOMIC_H
#ifdef __KERNEL__
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/types.h> #include <linux/types.h>
...@@ -170,5 +168,3 @@ ATOMIC_OP(and, &=, and) ...@@ -170,5 +168,3 @@ ATOMIC_OP(and, &=, and)
#endif #endif
#endif #endif
#endif
...@@ -13,8 +13,6 @@ ...@@ -13,8 +13,6 @@
#error only <linux/bitops.h> can be included directly #error only <linux/bitops.h> can be included directly
#endif #endif
#ifdef __KERNEL__
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/types.h> #include <linux/types.h>
...@@ -508,6 +506,4 @@ static inline __attribute__ ((const)) int __ffs(unsigned long word) ...@@ -508,6 +506,4 @@ static inline __attribute__ ((const)) int __ffs(unsigned long word)
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif #endif
...@@ -21,10 +21,9 @@ void show_kernel_fault_diag(const char *str, struct pt_regs *regs, ...@@ -21,10 +21,9 @@ void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
unsigned long address); unsigned long address);
void die(const char *str, struct pt_regs *regs, unsigned long address); void die(const char *str, struct pt_regs *regs, unsigned long address);
#define BUG() do { \ #define BUG() do { \
dump_stack(); \ pr_warn("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
pr_warn("Kernel BUG in %s: %s: %d!\n", \ dump_stack(); \
__FILE__, __func__, __LINE__); \
} while (0) } while (0)
#define HAVE_ARCH_BUG #define HAVE_ARCH_BUG
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#define CACHE_LINE_MASK (~(L1_CACHE_BYTES - 1)) #define CACHE_LINE_MASK (~(L1_CACHE_BYTES - 1))
/* /*
* ARC700 doesn't cache any access in top 256M. * ARC700 doesn't cache any access in top 1G (0xc000_0000 to 0xFFFF_FFFF)
* Ideal for wiring memory mapped peripherals as we don't need to do * Ideal for wiring memory mapped peripherals as we don't need to do
* explicit uncached accesses (LD.di/ST.di) hence more portable drivers * explicit uncached accesses (LD.di/ST.di) hence more portable drivers
*/ */
......
...@@ -12,8 +12,6 @@ ...@@ -12,8 +12,6 @@
#ifndef _ASM_ARC_CURRENT_H #ifndef _ASM_ARC_CURRENT_H
#define _ASM_ARC_CURRENT_H #define _ASM_ARC_CURRENT_H
#ifdef __KERNEL__
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#ifdef CONFIG_ARC_CURR_IN_REG #ifdef CONFIG_ARC_CURR_IN_REG
...@@ -27,6 +25,4 @@ register struct task_struct *curr_arc asm("r25"); ...@@ -27,6 +25,4 @@ register struct task_struct *curr_arc asm("r25");
#endif /* ! __ASSEMBLY__ */ #endif /* ! __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_ARC_CURRENT_H */ #endif /* _ASM_ARC_CURRENT_H */
...@@ -15,8 +15,6 @@ ...@@ -15,8 +15,6 @@
* -Conditionally disable interrupts (if they are not enabled, don't disable) * -Conditionally disable interrupts (if they are not enabled, don't disable)
*/ */
#ifdef __KERNEL__
#include <asm/arcregs.h> #include <asm/arcregs.h>
/* status32 Reg bits related to Interrupt Handling */ /* status32 Reg bits related to Interrupt Handling */
...@@ -169,6 +167,4 @@ static inline int arch_irqs_disabled(void) ...@@ -169,6 +167,4 @@ static inline int arch_irqs_disabled(void)
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* KERNEL */
#endif #endif
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* register API yet */ * register API yet */
#undef DBG_MAX_REG_NUM #undef DBG_MAX_REG_NUM
#define GDB_MAX_REGS 39 #define GDB_MAX_REGS 87
#define BREAK_INSTR_SIZE 2 #define BREAK_INSTR_SIZE 2
#define CACHE_FLUSH_IS_SAFE 1 #define CACHE_FLUSH_IS_SAFE 1
...@@ -33,23 +33,27 @@ static inline void arch_kgdb_breakpoint(void) ...@@ -33,23 +33,27 @@ static inline void arch_kgdb_breakpoint(void)
extern void kgdb_trap(struct pt_regs *regs); extern void kgdb_trap(struct pt_regs *regs);
enum arc700_linux_regnums { /* This is the numbering of registers according to the GDB. See GDB's
* arc-tdep.h for details.
*
* Registers are ordered for GDB 7.5. It is incompatible with GDB 6.8. */
enum arc_linux_regnums {
_R0 = 0, _R0 = 0,
_R1, _R2, _R3, _R4, _R5, _R6, _R7, _R8, _R9, _R10, _R11, _R12, _R13, _R1, _R2, _R3, _R4, _R5, _R6, _R7, _R8, _R9, _R10, _R11, _R12, _R13,
_R14, _R15, _R16, _R17, _R18, _R19, _R20, _R21, _R22, _R23, _R24, _R14, _R15, _R16, _R17, _R18, _R19, _R20, _R21, _R22, _R23, _R24,
_R25, _R26, _R25, _R26,
_BTA = 27, _FP = 27,
_LP_START = 28, __SP = 28,
_LP_END = 29, _R30 = 30,
_LP_COUNT = 30, _BLINK = 31,
_STATUS32 = 31, _LP_COUNT = 60,
_BLINK = 32, _STOP_PC = 64,
_FP = 33, _RET = 64,
__SP = 34, _LP_START = 65,
_EFA = 35, _LP_END = 66,
_RET = 36, _STATUS32 = 67,
_ORIG_R8 = 37, _ECR = 76,
_STOP_PC = 38 _BTA = 82,
}; };
#else #else
......
...@@ -14,12 +14,19 @@ ...@@ -14,12 +14,19 @@
#ifndef __ASM_ARC_PROCESSOR_H #ifndef __ASM_ARC_PROCESSOR_H
#define __ASM_ARC_PROCESSOR_H #define __ASM_ARC_PROCESSOR_H
#ifdef __KERNEL__
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <asm/ptrace.h> #include <asm/ptrace.h>
#ifdef CONFIG_ARC_FPU_SAVE_RESTORE
/* These DPFP regs need to be saved/restored across ctx-sw */
struct arc_fpu {
struct {
unsigned int l, h;
} aux_dpfp[2];
};
#endif
/* Arch specific stuff which needs to be saved per task. /* Arch specific stuff which needs to be saved per task.
* However these items are not so important so as to earn a place in * However these items are not so important so as to earn a place in
* struct thread_info * struct thread_info
...@@ -128,6 +135,4 @@ extern unsigned int get_wchan(struct task_struct *p); ...@@ -128,6 +135,4 @@ extern unsigned int get_wchan(struct task_struct *p);
*/ */
#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
#endif /* __KERNEL__ */
#endif /* __ASM_ARC_PROCESSOR_H */ #endif /* __ASM_ARC_PROCESSOR_H */
...@@ -29,7 +29,6 @@ struct cpuinfo_data { ...@@ -29,7 +29,6 @@ struct cpuinfo_data {
}; };
extern int root_mountflags, end_mem; extern int root_mountflags, end_mem;
extern int running_on_hw;
void setup_processor(void); void setup_processor(void);
void __init setup_arch_memory(void); void __init setup_arch_memory(void);
......
...@@ -59,7 +59,15 @@ struct plat_smp_ops { ...@@ -59,7 +59,15 @@ struct plat_smp_ops {
/* TBD: stop exporting it for direct population by platform */ /* TBD: stop exporting it for direct population by platform */
extern struct plat_smp_ops plat_smp_ops; extern struct plat_smp_ops plat_smp_ops;
#endif /* CONFIG_SMP */ #else /* CONFIG_SMP */
static inline void smp_init_cpus(void) {}
static inline const char *arc_platform_smp_cpuinfo(void)
{
return "";
}
#endif /* !CONFIG_SMP */
/* /*
* ARC700 doesn't support atomic Read-Modify-Write ops. * ARC700 doesn't support atomic Read-Modify-Write ops.
......
...@@ -17,8 +17,6 @@ ...@@ -17,8 +17,6 @@
#include <linux/types.h> #include <linux/types.h>
#ifdef __KERNEL__
#define __HAVE_ARCH_MEMSET #define __HAVE_ARCH_MEMSET
#define __HAVE_ARCH_MEMCPY #define __HAVE_ARCH_MEMCPY
#define __HAVE_ARCH_MEMCMP #define __HAVE_ARCH_MEMCMP
...@@ -36,5 +34,4 @@ extern char *strcpy(char *dest, const char *src); ...@@ -36,5 +34,4 @@ extern char *strcpy(char *dest, const char *src);
extern int strcmp(const char *cs, const char *ct); extern int strcmp(const char *cs, const char *ct);
extern __kernel_size_t strlen(const char *); extern __kernel_size_t strlen(const char *);
#endif /* __KERNEL__ */
#endif /* _ASM_ARC_STRING_H */ #endif /* _ASM_ARC_STRING_H */
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
#ifndef _ASM_ARC_SYSCALLS_H #ifndef _ASM_ARC_SYSCALLS_H
#define _ASM_ARC_SYSCALLS_H 1 #define _ASM_ARC_SYSCALLS_H 1
#ifdef __KERNEL__
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -22,6 +20,4 @@ int sys_arc_gettls(void); ...@@ -22,6 +20,4 @@ int sys_arc_gettls(void);
#include <asm-generic/syscalls.h> #include <asm-generic/syscalls.h>
#endif /* __KERNEL__ */
#endif #endif
...@@ -16,8 +16,6 @@ ...@@ -16,8 +16,6 @@
#ifndef _ASM_THREAD_INFO_H #ifndef _ASM_THREAD_INFO_H
#define _ASM_THREAD_INFO_H #define _ASM_THREAD_INFO_H
#ifdef __KERNEL__
#include <asm/page.h> #include <asm/page.h>
#ifdef CONFIG_16KSTACKS #ifdef CONFIG_16KSTACKS
...@@ -114,6 +112,4 @@ static inline __attribute_const__ struct thread_info *current_thread_info(void) ...@@ -114,6 +112,4 @@ static inline __attribute_const__ struct thread_info *current_thread_info(void)
* syscall, so all that reamins to be tested is _TIF_WORK_MASK * syscall, so all that reamins to be tested is _TIF_WORK_MASK
*/ */
#endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */ #endif /* _ASM_THREAD_INFO_H */
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include <asm-generic/unaligned.h> #include <asm-generic/unaligned.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#ifdef CONFIG_ARC_MISALIGN_ACCESS #ifdef CONFIG_ARC_EMUL_UNALIGNED
int misaligned_fixup(unsigned long address, struct pt_regs *regs, int misaligned_fixup(unsigned long address, struct pt_regs *regs,
struct callee_regs *cregs); struct callee_regs *cregs);
#else #else
......
...@@ -16,7 +16,7 @@ obj-$(CONFIG_MODULES) += arcksyms.o module.o ...@@ -16,7 +16,7 @@ obj-$(CONFIG_MODULES) += arcksyms.o module.o
obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_ARC_DW2_UNWIND) += unwind.o obj-$(CONFIG_ARC_DW2_UNWIND) += unwind.o
obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_ARC_MISALIGN_ACCESS) += unaligned.o obj-$(CONFIG_ARC_EMUL_UNALIGNED) += unaligned.o
obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_ARC_METAWARE_HLINK) += arc_hostlink.o obj-$(CONFIG_ARC_METAWARE_HLINK) += arc_hostlink.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o obj-$(CONFIG_PERF_EVENTS) += perf_event.o
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/disasm.h> #include <asm/disasm.h>
#if defined(CONFIG_KGDB) || defined(CONFIG_ARC_MISALIGN_ACCESS) || \ #if defined(CONFIG_KGDB) || defined(CONFIG_ARC_EMUL_UNALIGNED) || \
defined(CONFIG_KPROBES) defined(CONFIG_KPROBES)
/* disasm_instr: Analyses instruction at addr, stores /* disasm_instr: Analyses instruction at addr, stores
...@@ -535,4 +535,4 @@ int __kprobes disasm_next_pc(unsigned long pc, struct pt_regs *regs, ...@@ -535,4 +535,4 @@ int __kprobes disasm_next_pc(unsigned long pc, struct pt_regs *regs,
return instr.is_branch; return instr.is_branch;
} }
#endif /* CONFIG_KGDB || CONFIG_ARC_MISALIGN_ACCESS || CONFIG_KPROBES */ #endif /* CONFIG_KGDB || CONFIG_ARC_EMUL_UNALIGNED || CONFIG_KPROBES */
...@@ -91,16 +91,6 @@ stext: ...@@ -91,16 +91,6 @@ stext:
st r0, [@uboot_tag] st r0, [@uboot_tag]
st r2, [@uboot_arg] st r2, [@uboot_arg]
; Identify if running on ISS vs Silicon
; IDENTITY Reg [ 3 2 1 0 ]
; (chip-id) ^^^^^ ==> 0xffff for ISS
lr r0, [identity]
lsr r3, r0, 16
cmp r3, 0xffff
mov.z r4, 0
mov.nz r4, 1
st r4, [@running_on_hw]
; setup "current" tsk and optionally cache it in dedicated r25 ; setup "current" tsk and optionally cache it in dedicated r25
mov r9, @init_task mov r9, @init_task
SET_CURR_TASK_ON_CPU r9, r0 ; r9 = tsk, r0 = scratch SET_CURR_TASK_ON_CPU r9, r0 ; r9 = tsk, r0 = scratch
......
...@@ -244,25 +244,23 @@ static int arc_pmu_device_probe(struct platform_device *pdev) ...@@ -244,25 +244,23 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
pr_err("This core does not have performance counters!\n"); pr_err("This core does not have performance counters!\n");
return -ENODEV; return -ENODEV;
} }
BUG_ON(pct_bcr.c > ARC_PMU_MAX_HWEVENTS);
arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu), READ_BCR(ARC_REG_CC_BUILD, cc_bcr);
GFP_KERNEL); if (!cc_bcr.v) {
pr_err("Performance counters exist, but no countable conditions?\n");
return -ENODEV;
}
arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu), GFP_KERNEL);
if (!arc_pmu) if (!arc_pmu)
return -ENOMEM; return -ENOMEM;
arc_pmu->n_counters = pct_bcr.c; arc_pmu->n_counters = pct_bcr.c;
BUG_ON(arc_pmu->n_counters > ARC_PMU_MAX_HWEVENTS);
arc_pmu->counter_size = 32 + (pct_bcr.s << 4); arc_pmu->counter_size = 32 + (pct_bcr.s << 4);
pr_info("ARC PMU found with %d counters of size %d bits\n",
arc_pmu->n_counters, arc_pmu->counter_size);
READ_BCR(ARC_REG_CC_BUILD, cc_bcr);
if (!cc_bcr.v)
pr_err("Strange! Performance counters exist, but no countable conditions?\n");
pr_info("ARC PMU has %d countable conditions\n", cc_bcr.c); pr_info("ARC perf\t: %d counters (%d bits), %d countable conditions\n",
arc_pmu->n_counters, arc_pmu->counter_size, cc_bcr.c);
cc_name.str[8] = 0; cc_name.str[8] = 0;
for (i = 0; i < PERF_COUNT_HW_MAX; i++) for (i = 0; i < PERF_COUNT_HW_MAX; i++)
......
This diff is collapsed.
...@@ -101,7 +101,7 @@ void __weak arc_platform_smp_wait_to_boot(int cpu) ...@@ -101,7 +101,7 @@ void __weak arc_platform_smp_wait_to_boot(int cpu)
const char *arc_platform_smp_cpuinfo(void) const char *arc_platform_smp_cpuinfo(void)
{ {
return plat_smp_ops.info; return plat_smp_ops.info ? : "";
} }
/* /*
......
...@@ -530,16 +530,9 @@ EXPORT_SYMBOL(dma_cache_wback); ...@@ -530,16 +530,9 @@ EXPORT_SYMBOL(dma_cache_wback);
*/ */
void flush_icache_range(unsigned long kstart, unsigned long kend) void flush_icache_range(unsigned long kstart, unsigned long kend)
{ {
unsigned int tot_sz, off, sz; unsigned int tot_sz;
unsigned long phy, pfn;
/* printk("Kernel Cache Cohenercy: %lx to %lx\n",kstart, kend); */ WARN(kstart < TASK_SIZE, "%s() can't handle user vaddr", __func__);
/* This is not the right API for user virtual address */
if (kstart < TASK_SIZE) {
BUG_ON("Flush icache range for user virtual addr space");
return;
}
/* Shortcut for bigger flush ranges. /* Shortcut for bigger flush ranges.
* Here we don't care if this was kernel virtual or phy addr * Here we don't care if this was kernel virtual or phy addr
...@@ -572,6 +565,9 @@ void flush_icache_range(unsigned long kstart, unsigned long kend) ...@@ -572,6 +565,9 @@ void flush_icache_range(unsigned long kstart, unsigned long kend)
* straddles across 2 virtual pages and hence need for loop * straddles across 2 virtual pages and hence need for loop
*/ */
while (tot_sz > 0) { while (tot_sz > 0) {
unsigned int off, sz;
unsigned long phy, pfn;
off = kstart % PAGE_SIZE; off = kstart % PAGE_SIZE;
pfn = vmalloc_to_pfn((void *)kstart); pfn = vmalloc_to_pfn((void *)kstart);
phy = (pfn << PAGE_SHIFT) + off; phy = (pfn << PAGE_SHIFT) + off;
......
...@@ -609,14 +609,12 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) ...@@ -609,14 +609,12 @@ 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[cpu_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, ",
p_mmu->ver, TO_KB(p_mmu->pg_sz));
n += scnprintf(buf + n, len - n, n += scnprintf(buf + n, len - n,
"J-TLB %d (%dx%d), uDTLB %d, uITLB %d, %s\n", "MMU [v%x]\t: %dk PAGE, JTLB %d (%dx%d), uDTLB %d, uITLB %d %s\n",
p_mmu->ver, TO_KB(p_mmu->pg_sz),
p_mmu->num_tlb, p_mmu->sets, p_mmu->ways, p_mmu->num_tlb, p_mmu->sets, p_mmu->ways,
p_mmu->u_dtlb, p_mmu->u_itlb, p_mmu->u_dtlb, p_mmu->u_itlb,
IS_ENABLED(CONFIG_ARC_MMU_SASID) ? "SASID" : ""); IS_ENABLED(CONFIG_ARC_MMU_SASID) ? ",SASID" : "");
return buf; return buf;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
menuconfig ARC_PLAT_FPGA_LEGACY menuconfig ARC_PLAT_FPGA_LEGACY
bool "\"Legacy\" ARC FPGA dev Boards" bool "\"Legacy\" ARC FPGA dev Boards"
select ISS_SMP_EXTN if SMP select ARC_HAS_COH_CACHES if SMP
help help
Support for ARC development boards, provided by Synopsys. Support for ARC development boards, provided by Synopsys.
These are based on FPGA or ISS. e.g. These are based on FPGA or ISS. e.g.
...@@ -18,17 +18,6 @@ menuconfig ARC_PLAT_FPGA_LEGACY ...@@ -18,17 +18,6 @@ menuconfig ARC_PLAT_FPGA_LEGACY
if ARC_PLAT_FPGA_LEGACY if ARC_PLAT_FPGA_LEGACY
config ARC_BOARD_ANGEL4
bool "ARC Angel4"
default y
help
ARC Angel4 FPGA Ref Platform (Xilinx Virtex Based)
config ARC_BOARD_ML509
bool "ML509"
help
ARC ML509 FPGA Ref Platform (Xilinx Virtex-5 Based)
config ISS_SMP_EXTN config ISS_SMP_EXTN
bool "ARC SMP Extensions (ISS Models only)" bool "ARC SMP Extensions (ISS Models only)"
default n default n
......
/*
* Copyright (C) 2004, 2007-2010, 2011-2012 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.
*
* vineetg: Feb 2009
* -For AA4 board, IRQ assignments to peripherals
*/
#ifndef __PLAT_IRQ_H
#define __PLAT_IRQ_H
#define UART0_IRQ 5
#define UART1_IRQ 10
#define UART2_IRQ 11
#define IDE_IRQ 13
#define PCI_IRQ 14
#define PS2_IRQ 15
#ifdef CONFIG_SMP
#define IDU_INTERRUPT_0 16
#endif
#endif
/*
* Copyright (C) 2004, 2007-2010, 2011-2012 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.
*
* vineetg: Feb 2009
* -For AA4 board, System Memory Map for Peripherals etc
*/
#ifndef __PLAT_MEMMAP_H
#define __PLAT_MEMMAP_H
#define UART0_BASE 0xC0FC1000
#define UART1_BASE 0xC0FC1100
#define IDE_CONTROLLER_BASE 0xC0FC9000
#define AHB_PCI_HOST_BRG_BASE 0xC0FD0000
#define PGU_BASEADDR 0xC0FC8000
#define VLCK_ADDR 0xC0FCF028
#define BVCI_LAT_UNIT_BASE 0xC0FED000
#define PS2_BASE_ADDR 0xC0FCC000
#endif
...@@ -8,37 +8,9 @@ ...@@ -8,37 +8,9 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/types.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/console.h>
#include <linux/of_platform.h>
#include <asm/setup.h>
#include <asm/clk.h>
#include <asm/mach_desc.h> #include <asm/mach_desc.h>
#include <plat/memmap.h>
#include <plat/smp.h> #include <plat/smp.h>
#include <plat/irq.h>
static void __init plat_fpga_early_init(void)
{
pr_info("[plat-arcfpga]: registering early dev resources\n");
#ifdef CONFIG_ISS_SMP_EXTN
iss_model_init_early_smp();
#endif
}
static void __init plat_fpga_populate_dev(void)
{
/*
* Traverses flattened DeviceTree - registering platform devices
* (if any) complete with their resources
*/
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
/*----------------------- Machine Descriptions ------------------------------ /*----------------------- Machine Descriptions ------------------------------
* *
...@@ -48,41 +20,26 @@ static void __init plat_fpga_populate_dev(void) ...@@ -48,41 +20,26 @@ static void __init plat_fpga_populate_dev(void)
* callback set, by matching the DT compatible name. * callback set, by matching the DT compatible name.
*/ */
static const char *aa4_compat[] __initconst = { static const char *legacy_fpga_compat[] __initconst = {
"snps,arc-angel4", "snps,arc-angel4",
NULL,
};
MACHINE_START(ANGEL4, "angel4")
.dt_compat = aa4_compat,
.init_early = plat_fpga_early_init,
.init_machine = plat_fpga_populate_dev,
#ifdef CONFIG_ISS_SMP_EXTN
.init_smp = iss_model_init_smp,
#endif
MACHINE_END
static const char *ml509_compat[] __initconst = {
"snps,arc-ml509", "snps,arc-ml509",
NULL, NULL,
}; };
MACHINE_START(ML509, "ml509") MACHINE_START(LEGACY_FPGA, "legacy_fpga")
.dt_compat = ml509_compat, .dt_compat = legacy_fpga_compat,
.init_early = plat_fpga_early_init, #ifdef CONFIG_ISS_SMP_EXTN
.init_machine = plat_fpga_populate_dev, .init_early = iss_model_init_early_smp,
#ifdef CONFIG_SMP
.init_smp = iss_model_init_smp, .init_smp = iss_model_init_smp,
#endif #endif
MACHINE_END MACHINE_END
static const char *nsimosci_compat[] __initconst = { static const char *simulation_compat[] __initconst = {
"snps,nsim",
"snps,nsimosci", "snps,nsimosci",
NULL, NULL,
}; };
MACHINE_START(NSIMOSCI, "nsimosci") MACHINE_START(SIMULATION, "simulation")
.dt_compat = nsimosci_compat, .dt_compat = simulation_compat,
.init_early = NULL,
.init_machine = plat_fpga_populate_dev,
MACHINE_END MACHINE_END
...@@ -13,9 +13,10 @@ ...@@ -13,9 +13,10 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <plat/irq.h>
#include <plat/smp.h> #include <plat/smp.h>
#define IDU_INTERRUPT_0 16
static char smp_cpuinfo_buf[128]; static char smp_cpuinfo_buf[128];
/* /*
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
menuconfig ARC_PLAT_TB10X menuconfig ARC_PLAT_TB10X
bool "Abilis TB10x" bool "Abilis TB10x"
select COMMON_CLK
select PINCTRL select PINCTRL
select PINCTRL_TB10X select PINCTRL_TB10X
select PINMUX select PINMUX
......
...@@ -19,21 +19,9 @@ ...@@ -19,21 +19,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/of_platform.h>
#include <linux/clk-provider.h>
#include <linux/pinctrl/consumer.h>
#include <asm/mach_desc.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 const char *tb10x_compat[] __initdata = { static const char *tb10x_compat[] __initdata = {
"abilis,arc-tb10x", "abilis,arc-tb10x",
NULL, NULL,
...@@ -41,5 +29,4 @@ static const char *tb10x_compat[] __initdata = { ...@@ -41,5 +29,4 @@ static const char *tb10x_compat[] __initdata = {
MACHINE_START(TB10x, "tb10x") MACHINE_START(TB10x, "tb10x")
.dt_compat = tb10x_compat, .dt_compat = tb10x_compat,
.init_machine = tb10x_platform_init,
MACHINE_END MACHINE_END
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment