diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 0cb97207db4c082a64633486e2a45edb208c6014..545fc3e243cdf0b8c1d05237b84fde3432e2309a 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -160,7 +160,7 @@ config TARGET_TB100
 	bool "Support tb100"
 
 config TARGET_NSIM
-	bool "Support standalone nSIM & Free nSIM"
+	bool "Support ARC simulation & prototyping platforms"
 
 config TARGET_AXS101
 	bool "Support Synopsys Designware SDP board AXS101"
@@ -184,10 +184,10 @@ config TARGET_IOT_DEVKIT
 endchoice
 
 source "board/abilis/tb100/Kconfig"
-source "board/synopsys/Kconfig"
 source "board/synopsys/axs10x/Kconfig"
 source "board/synopsys/emsdp/Kconfig"
 source "board/synopsys/hsdk/Kconfig"
 source "board/synopsys/iot_devkit/Kconfig"
+source "board/synopsys/nsim/Kconfig"
 
 endmenu
diff --git a/arch/arc/config.mk b/arch/arc/config.mk
index 18005d999301fd59288edbded22b504d892c8d56..6fa29adae81f77eb6d1afa43143afe91212b96df 100644
--- a/arch/arc/config.mk
+++ b/arch/arc/config.mk
@@ -22,26 +22,6 @@ ifdef CONFIG_ARC_MMU_VER
 CONFIG_MMU = 1
 endif
 
-ifdef CONFIG_CPU_ARC750D
-PLATFORM_CPPFLAGS += -mcpu=arc700
-endif
-
-ifdef CONFIG_CPU_ARC770D
-PLATFORM_CPPFLAGS += -mcpu=arc700 -mlock -mswape
-endif
-
-ifdef CONFIG_CPU_ARCEM6
-PLATFORM_CPPFLAGS += -mcpu=arcem
-endif
-
-ifdef CONFIG_CPU_ARCHS34
-PLATFORM_CPPFLAGS += -mcpu=archs
-endif
-
-ifdef CONFIG_CPU_ARCHS38
-PLATFORM_CPPFLAGS += -mcpu=archs
-endif
-
 PLATFORM_CPPFLAGS += -ffixed-r25 -D__ARC__ -gdwarf-2 -mno-sdata
 PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections -fno-common
 
diff --git a/arch/arc/dts/nsim.dts b/arch/arc/dts/nsim.dts
index 243ecb178e46319f1c36b03c806e7e22fc107b86..c2899ef2ea64d317e6f4e1692b30e43785775c85 100644
--- a/arch/arc/dts/nsim.dts
+++ b/arch/arc/dts/nsim.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
+ * Copyright (C) 2015-2016, 2020 Synopsys, Inc. (www.synopsys.com)
  */
 /dts-v1/;
 
@@ -10,7 +10,7 @@
 	model = "snps,nsim";
 
 	aliases {
-		console = &arcuart0;
+		console = &uart0;
 	};
 
 	cpu_card {
@@ -22,10 +22,36 @@
 		};
 	};
 
-	arcuart0: serial@0xc0fc1000 {
-		compatible = "snps,arc-uart";
-		reg = <0xc0fc1000 0x100>;
+	uart0: serial@f0000000 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0xf0000000 0x1000>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
 		clock-frequency = <70000000>;
 	};
 
+	virtio0: virtio@f0100000 {
+		compatible = "virtio,mmio";
+		reg = <0xf0100000 0x2000>;
+	};
+
+	virtio1: virtio@f0102000 {
+		compatible = "virtio,mmio";
+		reg = <0xf0102000 0x2000>;
+	};
+
+	virtio2: virtio@f0104000 {
+		compatible = "virtio,mmio";
+		reg = <0xf0104000 0x2000>;
+	};
+
+	virtio3: virtio@f0106000 {
+		compatible = "virtio,mmio";
+		reg = <0xf0106000 0x2000>;
+	};
+
+	virtio4: virtio@f0108000 {
+		compatible = "virtio,mmio";
+		reg = <0xf0108000 0x2000>;
+	};
 };
diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h
index fa844b54f4eeb14eceeef62c0db9f75f2d341f00..70d050590de4d4b544cd69dfb41b9b4975d9cf29 100644
--- a/arch/arc/include/asm/io.h
+++ b/arch/arc/include/asm/io.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
- * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
+ * Copyright (C) 2013-2014, 2020 Synopsys, Inc. All rights reserved.
  */
 
 #ifndef __ASM_ARC_IO_H
@@ -54,135 +54,98 @@ static inline void sync(void)
 	/* Not yet implemented */
 }
 
-static inline u8 __raw_readb(const volatile void __iomem *addr)
-{
-	u8 b;
+#define __arch_getb(a)		(*(unsigned char *)(a))
+#define __arch_getw(a)		(*(unsigned short *)(a))
+#define __arch_getl(a)		(*(unsigned int *)(a))
+#define __arch_getq(a)		(*(unsigned long long *)(a))
 
-	__asm__ __volatile__("ldb%U1	%0, %1\n"
-			     : "=r" (b)
-			     : "m" (*(volatile u8 __force *)addr)
-			     : "memory");
-	return b;
-}
+#define __arch_putb(v, a)	(*(unsigned char *)(a) = (v))
+#define __arch_putw(v, a)	(*(unsigned short *)(a) = (v))
+#define __arch_putl(v, a)	(*(unsigned int *)(a) = (v))
+#define __arch_putq(v, a)	(*(unsigned long long *)(a) = (v))
 
-static inline u16 __raw_readw(const volatile void __iomem *addr)
-{
-	u16 s;
+#define __raw_writeb(v, a)	__arch_putb(v, a)
+#define __raw_writew(v, a)	__arch_putw(v, a)
+#define __raw_writel(v, a)	__arch_putl(v, a)
+#define __raw_writeq(v, a)	__arch_putq(v, a)
 
-	__asm__ __volatile__("ldw%U1	%0, %1\n"
-			     : "=r" (s)
-			     : "m" (*(volatile u16 __force *)addr)
-			     : "memory");
-	return s;
-}
+#define __raw_readb(a)		__arch_getb(a)
+#define __raw_readw(a)		__arch_getw(a)
+#define __raw_readl(a)		__arch_getl(a)
+#define __raw_readq(a)		__arch_getq(a)
 
-static inline u32 __raw_readl(const volatile void __iomem *addr)
+static inline void __raw_writesb(unsigned long addr, const void *data,
+				 int bytelen)
 {
-	u32 w;
+	u8 *buf = (uint8_t *)data;
 
-	__asm__ __volatile__("ld%U1	%0, %1\n"
-			     : "=r" (w)
-			     : "m" (*(volatile u32 __force *)addr)
-			     : "memory");
-	return w;
+	while (bytelen--)
+		__arch_putb(*buf++, addr);
 }
 
-static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
+static inline void __raw_writesw(unsigned long addr, const void *data,
+				 int wordlen)
 {
-	__asm__ __volatile__("stb%U1	%0, %1\n"
-			     :
-			     : "r" (b), "m" (*(volatile u8 __force *)addr)
-			     : "memory");
-}
+	u16 *buf = (uint16_t *)data;
 
-static inline void __raw_writew(u16 s, volatile void __iomem *addr)
-{
-	__asm__ __volatile__("stw%U1	%0, %1\n"
-			     :
-			     : "r" (s), "m" (*(volatile u16 __force *)addr)
-			     : "memory");
+	while (wordlen--)
+		__arch_putw(*buf++, addr);
 }
 
-static inline void __raw_writel(u32 w, volatile void __iomem *addr)
+static inline void __raw_writesl(unsigned long addr, const void *data,
+				 int longlen)
 {
-	__asm__ __volatile__("st%U1	%0, %1\n"
-			     :
-			     : "r" (w), "m" (*(volatile u32 __force *)addr)
-			     : "memory");
-}
+	u32 *buf = (uint32_t *)data;
 
-static inline int __raw_readsb(unsigned int addr, void *data, int bytelen)
-{
-	__asm__ __volatile__ ("1:ld.di	r8, [r0]\n"
-			      "sub.f	r2, r2, 1\n"
-			      "bnz.d	1b\n"
-			      "stb.ab	r8, [r1, 1]\n"
-			      :
-			      : "r" (addr), "r" (data), "r" (bytelen)
-			      : "r8");
-	return bytelen;
+	while (longlen--)
+		__arch_putl(*buf++, addr);
 }
 
-static inline int __raw_readsw(unsigned int addr, void *data, int wordlen)
+static inline void __raw_readsb(unsigned long addr, void *data, int bytelen)
 {
-	__asm__ __volatile__ ("1:ld.di	r8, [r0]\n"
-			      "sub.f	r2, r2, 1\n"
-			      "bnz.d	1b\n"
-			      "stw.ab	r8, [r1, 2]\n"
-			      :
-			      : "r" (addr), "r" (data), "r" (wordlen)
-			      : "r8");
-	return wordlen;
-}
+	u8 *buf = (uint8_t *)data;
 
-static inline int __raw_readsl(unsigned int addr, void *data, int longlen)
-{
-	__asm__ __volatile__ ("1:ld.di	r8, [r0]\n"
-			      "sub.f	r2, r2, 1\n"
-			      "bnz.d	1b\n"
-			      "st.ab	r8, [r1, 4]\n"
-			      :
-			      : "r" (addr), "r" (data), "r" (longlen)
-			      : "r8");
-	return longlen;
+	while (bytelen--)
+		*buf++ = __arch_getb(addr);
 }
 
-static inline int __raw_writesb(unsigned int addr, void *data, int bytelen)
+static inline void __raw_readsw(unsigned long addr, void *data, int wordlen)
 {
-	__asm__ __volatile__ ("1:ldb.ab	r8, [r1, 1]\n"
-			      "sub.f	r2, r2, 1\n"
-			      "bnz.d	1b\n"
-			      "st.di	r8, [r0, 0]\n"
-			      :
-			      : "r" (addr), "r" (data), "r" (bytelen)
-			      : "r8");
-	return bytelen;
-}
+	u16 *buf = (uint16_t *)data;
 
-static inline int __raw_writesw(unsigned int addr, void *data, int wordlen)
-{
-	__asm__ __volatile__ ("1:ldw.ab	r8, [r1, 2]\n"
-			      "sub.f	r2, r2, 1\n"
-			      "bnz.d	1b\n"
-			      "st.ab.di	r8, [r0, 0]\n"
-			      :
-			      : "r" (addr), "r" (data), "r" (wordlen)
-			      : "r8");
-	return wordlen;
+	while (wordlen--)
+		*buf++ = __arch_getw(addr);
 }
 
-static inline int __raw_writesl(unsigned int addr, void *data, int longlen)
+static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
 {
-	__asm__ __volatile__ ("1:ld.ab	r8, [r1, 4]\n"
-			      "sub.f	r2, r2, 1\n"
-			      "bnz.d	1b\n"
-			      "st.ab.di	r8, [r0, 0]\n"
-			      :
-			      : "r" (addr), "r" (data), "r" (longlen)
-			      : "r8");
-	return longlen;
+	u32 *buf = (uint32_t *)data;
+
+	while (longlen--)
+		*buf++ = __arch_getl(addr);
 }
 
+/*
+ * Relaxed I/O memory access primitives. These follow the Device memory
+ * ordering rules but do not guarantee any ordering relative to Normal memory
+ * accesses.
+ */
+#define readb_relaxed(c)	({ u8  __r = __raw_readb(c); __r; })
+#define readw_relaxed(c)	({ u16 __r = le16_to_cpu((__force __le16) \
+						__raw_readw(c)); __r; })
+#define readl_relaxed(c)	({ u32 __r = le32_to_cpu((__force __le32) \
+						__raw_readl(c)); __r; })
+#define readq_relaxed(c)	({ u64 __r = le64_to_cpu((__force __le64) \
+						__raw_readq(c)); __r; })
+
+#define writeb_relaxed(v, c)	((void)__raw_writeb((v), (c)))
+#define writew_relaxed(v, c)	((void)__raw_writew((__force u16) \
+						    cpu_to_le16(v), (c)))
+#define writel_relaxed(v, c)	((void)__raw_writel((__force u32) \
+						    cpu_to_le32(v), (c)))
+#define writeq_relaxed(v, c)	((void)__raw_writeq((__force u64) \
+						    cpu_to_le64(v), (c)))
+
 /*
  * MMIO can also get buffered/optimized in micro-arch, so barriers needed
  * Based on ARM model for the typical use case
@@ -195,32 +158,15 @@ static inline int __raw_writesl(unsigned int addr, void *data, int longlen)
  *
  * http://lkml.kernel.org/r/20150622133656.GG1583@arm.com
  */
-#define readb(c)		({ u8  __v = readb_relaxed(c); __iormb(); __v; })
-#define readw(c)		({ u16 __v = readw_relaxed(c); __iormb(); __v; })
-#define readl(c)		({ u32 __v = readl_relaxed(c); __iormb(); __v; })
-
-#define writeb(v,c)		({ __iowmb(); writeb_relaxed(v,c); })
-#define writew(v,c)		({ __iowmb(); writew_relaxed(v,c); })
-#define writel(v,c)		({ __iowmb(); writel_relaxed(v,c); })
-
-/*
- * Relaxed API for drivers which can handle barrier ordering themselves
- *
- * Also these are defined to perform little endian accesses.
- * To provide the typical device register semantics of fixed endian,
- * swap the byte order for Big Endian
- *
- * http://lkml.kernel.org/r/201603100845.30602.arnd@arndb.de
- */
-#define readb_relaxed(c)	__raw_readb(c)
-#define readw_relaxed(c) ({ u16 __r = le16_to_cpu((__force __le16) \
-					__raw_readw(c)); __r; })
-#define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \
-					__raw_readl(c)); __r; })
-
-#define writeb_relaxed(v,c)	__raw_writeb(v,c)
-#define writew_relaxed(v,c)	__raw_writew((__force u16) cpu_to_le16(v),c)
-#define writel_relaxed(v,c)	__raw_writel((__force u32) cpu_to_le32(v),c)
+#define readb(c)	({ u8  __v = readb_relaxed(c); __iormb(); __v; })
+#define readw(c)	({ u16 __v = readw_relaxed(c); __iormb(); __v; })
+#define readl(c)	({ u32 __v = readl_relaxed(c); __iormb(); __v; })
+#define readq(c)	({ u64 __v = readq_relaxed(c); __iormb(); __v; })
+
+#define writeb(v, c)	({ __iowmb(); writeb_relaxed(v, c); })
+#define writew(v, c)	({ __iowmb(); writew_relaxed(v, c); })
+#define writel(v, c)	({ __iowmb(); writel_relaxed(v, c); })
+#define writeq(v, c)	({ __iowmb(); writeq_relaxed(v, c); })
 
 #define out_arch(type, endian, a, v)	__raw_write##type(cpu_to_##endian(v), a)
 #define in_arch(type, endian, a)	endian##_to_cpu(__raw_read##type(a))
diff --git a/board/abilis/tb100/config.mk b/board/abilis/tb100/config.mk
new file mode 100644
index 0000000000000000000000000000000000000000..9e8dee49bd3578702762762c3fba3689c4cb60d0
--- /dev/null
+++ b/board/abilis/tb100/config.mk
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2020 Synopsys, Inc. All rights reserved.
+
+PLATFORM_CPPFLAGS += -mcpu=arc700 -mlock -mswape
diff --git a/board/synopsys/Kconfig b/board/synopsys/Kconfig
deleted file mode 100644
index 27e5509b26e566f1d78374d89badcec20480556e..0000000000000000000000000000000000000000
--- a/board/synopsys/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-if TARGET_NSIM
-
-config SYS_VENDOR
-	default "synopsys"
-
-config SYS_CONFIG_NAME
-	default "nsim"
-
-endif
diff --git a/board/synopsys/axs10x/config.mk b/board/synopsys/axs10x/config.mk
index 81ff498f818921be1de12eeabfc6ead10a60a4d4..ccac5442908e5032d754770a826aa041c6ff3164 100644
--- a/board/synopsys/axs10x/config.mk
+++ b/board/synopsys/axs10x/config.mk
@@ -2,6 +2,12 @@
 #
 # Copyright (C) 2018 Synopsys, Inc. All rights reserved.
 
+ifdef CONFIG_TARGET_AXS103
+  PLATFORM_CPPFLAGS += -mcpu=archs
+else
+  PLATFORM_CPPFLAGS += -mcpu=arc700 -mlock -mswape
+endif
+
 bsp-generate: u-boot u-boot.bin
 ifdef CONFIG_ISA_ARCV2
 	$(Q)python3 $(srctree)/board/$(BOARDDIR)/headerize-axs.py \
diff --git a/board/synopsys/emsdp/config.mk b/board/synopsys/emsdp/config.mk
index 67fd7bf82a3a1607646d587dcc9fa24443a7f722..5bd10442aff417944fa17db1faf372d5a09a8dcb 100644
--- a/board/synopsys/emsdp/config.mk
+++ b/board/synopsys/emsdp/config.mk
@@ -1,2 +1,2 @@
-PLATFORM_CPPFLAGS += -mlittle-endian -mnorm -mswap -mmpy-option=3 \
+PLATFORM_CPPFLAGS += -mcpu=arcem -mlittle-endian -mnorm -mswap -mmpy-option=3 \
                      -mbarrel-shifter -mfpu=fpuda_all -mcode-density
diff --git a/board/synopsys/hsdk/config.mk b/board/synopsys/hsdk/config.mk
index 9e280f921a1b435f120f6047b683225abaa61c67..5ae22fa2b75e4233e1d47d97b90fd94cb30f351d 100644
--- a/board/synopsys/hsdk/config.mk
+++ b/board/synopsys/hsdk/config.mk
@@ -2,6 +2,10 @@
 #
 # Copyright (C) 2018 Synopsys, Inc. All rights reserved.
 
+PLATFORM_CPPFLAGS += -mcpu=hs38_linux -mlittle-endian -matomic -mll64 \
+                     -mdiv-rem -mswap -mnorm -mmpy-option=9 -mbarrel-shifter \
+                     -mfpu=fpud_all
+
 bsp-generate: u-boot u-boot.bin
 	$(Q)python3 $(srctree)/board/$(BOARDDIR)/headerize-hsdk.py \
 		--arc-id 0x52 --image $(srctree)/u-boot.bin \
diff --git a/board/synopsys/iot_devkit/config.mk b/board/synopsys/iot_devkit/config.mk
index 120733538a407aafae3a3609dfa6fb92841ad412..bd8f09ec7a7ed3288aabb2147ecb873fa0b6555d 100644
--- a/board/synopsys/iot_devkit/config.mk
+++ b/board/synopsys/iot_devkit/config.mk
@@ -1,2 +1,3 @@
-PLATFORM_CPPFLAGS += -mlittle-endian -mcode-density -mdiv-rem -mswap -mnorm -mmpy-option=6 -mbarrel-shifter
+PLATFORM_CPPFLAGS += -mcpu=arcem -mlittle-endian -mcode-density -mdiv-rem \
+                     -mswap -mnorm -mmpy-option=6 -mbarrel-shifter
 LDSCRIPT = $(srctree)/board/synopsys/iot_devkit/u-boot.lds
diff --git a/board/synopsys/nsim/Kconfig b/board/synopsys/nsim/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..b6966b2991efed1505b66e62470a615a1905f1d8
--- /dev/null
+++ b/board/synopsys/nsim/Kconfig
@@ -0,0 +1,21 @@
+if TARGET_NSIM
+
+config SYS_BOARD
+	default "nsim"
+
+config SYS_VENDOR
+	default "synopsys"
+
+config SYS_CONFIG_NAME
+	default "nsim"
+
+config NSIM_BOARD_CPPFLAGS
+	string "board arc-specific compiler options"
+	help
+	  For nSIM we allow to set custom arc-specific compiler options
+	  (like -mcpu=) instead of hardcoding them in its makefile as nSIM
+	  target is used for representing targets without fixed CPU version
+	  like FPGA-based boards and software simulators.
+	  This variable takes space separated compiler options list.
+
+endif
diff --git a/board/synopsys/nsim/MAINTAINERS b/board/synopsys/nsim/MAINTAINERS
new file mode 100644
index 0000000000000000000000000000000000000000..ad23c8338ec5773f5e65ca5e60192965f316ad8c
--- /dev/null
+++ b/board/synopsys/nsim/MAINTAINERS
@@ -0,0 +1,6 @@
+ARC SIMULATION & PROTOTYPING PLATFORMS
+M:	Alexey Brodkin <abrodkin@synopsys.com>
+S:	Maintained
+F:	arch/arc/dts/nsim.dts
+F:	board/synopsys/nsim/
+F:	configs/nsim_*_defconfig
diff --git a/board/synopsys/nsim/Makefile b/board/synopsys/nsim/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..6aaffffa73807d6896a3740abff1f2d58b77a54b
--- /dev/null
+++ b/board/synopsys/nsim/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2020 Synopsys, Inc. All rights reserved.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	+= nsim.o
diff --git a/board/synopsys/nsim/config.mk b/board/synopsys/nsim/config.mk
new file mode 100644
index 0000000000000000000000000000000000000000..40f9578a25aa6e200f2593de1da8925ed9464cba
--- /dev/null
+++ b/board/synopsys/nsim/config.mk
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2020 Synopsys, Inc. All rights reserved.
+
+# CONFIG_NSIM_BOARD_CPPFLAGS is a string variable which comes from defconfig
+# with double quotes. We use echo to remove them so CONFIG_NSIM_BOARD_CPPFLAGS
+# won't be treated by compiler as a single option.
+PLATFORM_CPPFLAGS += $(shell echo $(CONFIG_NSIM_BOARD_CPPFLAGS))
diff --git a/board/synopsys/nsim/nsim.c b/board/synopsys/nsim/nsim.c
new file mode 100644
index 0000000000000000000000000000000000000000..f384f707f670cd1b997e981ad7cee719b4527ce5
--- /dev/null
+++ b/board/synopsys/nsim/nsim.c
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Synopsys, Inc. All rights reserved.
+ */
+
+#include <common.h>
+#include <dm/device.h>
+#include <virtio_types.h>
+#include <virtio.h>
+
+int board_early_init_r(void)
+{
+	/*
+	 * Make sure virtio bus is enumerated so that peripherals
+	 * on the virtio bus can be discovered by their drivers
+	 */
+	virtio_init();
+
+	return 0;
+}
+
+int checkboard(void)
+{
+	printf("Board: ARC virtual or prototyping platform\n");
+	return 0;
+};
diff --git a/configs/nsim_700_defconfig b/configs/nsim_700_defconfig
index 5633113b090f36da8b421158190418c60c6f61b2..5e89769784362f85a6ac7213f7e95f24bb6dd4c0 100644
--- a/configs/nsim_700_defconfig
+++ b/configs/nsim_700_defconfig
@@ -1,21 +1,23 @@
 CONFIG_ARC=y
 CONFIG_TARGET_NSIM=y
+CONFIG_NSIM_BOARD_CPPFLAGS="-mcpu=arc700 -mlock -mswape"
 CONFIG_SYS_TEXT_BASE=0x81000000
-CONFIG_DEBUG_UART_BASE=0xc0fc1000
+CONFIG_DEBUG_UART_BASE=0xf0000000
 CONFIG_DEBUG_UART_CLOCK=70000000
 CONFIG_SYS_CLK_FREQ=70000000
 CONFIG_DEBUG_UART=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="console=ttyARC0,115200n8"
+CONFIG_BOOTARGS="console=ttyS0,115200n8"
 CONFIG_SYS_PROMPT="nsim# "
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="nsim"
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
 CONFIG_DM=y
 CONFIG_DM_SERIAL=y
-CONFIG_DEBUG_ARC_SERIAL=y
-CONFIG_ARC_SERIAL=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
 CONFIG_USE_PRIVATE_LIBGCC=y
diff --git a/configs/nsim_700be_defconfig b/configs/nsim_700be_defconfig
index 40f7ec7e1f4aaa36295e122dbba183dc7df7e5f3..03912712486b21f53594affa6700c77a61e8f7f4 100644
--- a/configs/nsim_700be_defconfig
+++ b/configs/nsim_700be_defconfig
@@ -1,22 +1,24 @@
 CONFIG_ARC=y
 CONFIG_CPU_BIG_ENDIAN=y
 CONFIG_TARGET_NSIM=y
+CONFIG_NSIM_BOARD_CPPFLAGS="-mcpu=arc700 -mlock -mswape"
 CONFIG_SYS_TEXT_BASE=0x81000000
-CONFIG_DEBUG_UART_BASE=0xc0fc1000
+CONFIG_DEBUG_UART_BASE=0xf0000000
 CONFIG_DEBUG_UART_CLOCK=70000000
 CONFIG_SYS_CLK_FREQ=70000000
 CONFIG_DEBUG_UART=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="console=ttyARC0,115200n8"
+CONFIG_BOOTARGS="console=ttyS0,115200n8"
 CONFIG_SYS_PROMPT="nsim# "
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="nsim"
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
 CONFIG_DM=y
 CONFIG_DM_SERIAL=y
-CONFIG_DEBUG_ARC_SERIAL=y
-CONFIG_ARC_SERIAL=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
 CONFIG_USE_PRIVATE_LIBGCC=y
diff --git a/configs/nsim_hs38_defconfig b/configs/nsim_hs38_defconfig
index 2820a6fca33cb9a8299601451f5d6560e552bc50..910c2ce2242438a82a48865f29662ff1c66e13a6 100644
--- a/configs/nsim_hs38_defconfig
+++ b/configs/nsim_hs38_defconfig
@@ -1,22 +1,32 @@
 CONFIG_ARC=y
 CONFIG_ISA_ARCV2=y
 CONFIG_TARGET_NSIM=y
+CONFIG_NSIM_BOARD_CPPFLAGS="-mcpu=archs"
 CONFIG_SYS_TEXT_BASE=0x81000000
-CONFIG_DEBUG_UART_BASE=0xc0fc1000
+CONFIG_DEBUG_UART_BASE=0xf0000000
 CONFIG_DEBUG_UART_CLOCK=70000000
 CONFIG_SYS_CLK_FREQ=70000000
 CONFIG_DEBUG_UART=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="console=ttyARC0,115200n8"
+CONFIG_BOOTARGS="console=ttyS0,115200n8"
+CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_SYS_PROMPT="nsim# "
+CONFIG_CMD_DM=y
 # CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="nsim"
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_DM=y
+CONFIG_BLK=y
+CONFIG_HAVE_BLOCK_DEVICE=y
+CONFIG_DM_ETH=y
 CONFIG_DM_SERIAL=y
-CONFIG_DEBUG_ARC_SERIAL=y
-CONFIG_ARC_SERIAL=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_NET=y
+CONFIG_VIRTIO_BLK=y
 CONFIG_USE_PRIVATE_LIBGCC=y
diff --git a/configs/nsim_hs38be_defconfig b/configs/nsim_hs38be_defconfig
index e533fae2b17c433b0bfd87585ed6efc5b6fd9691..72472afb2b1199eeb221a2b195febc725fec6c35 100644
--- a/configs/nsim_hs38be_defconfig
+++ b/configs/nsim_hs38be_defconfig
@@ -2,22 +2,24 @@ CONFIG_ARC=y
 CONFIG_ISA_ARCV2=y
 CONFIG_CPU_BIG_ENDIAN=y
 CONFIG_TARGET_NSIM=y
+CONFIG_NSIM_BOARD_CPPFLAGS="-mcpu=archs"
 CONFIG_SYS_TEXT_BASE=0x81000000
-CONFIG_DEBUG_UART_BASE=0xc0fc1000
+CONFIG_DEBUG_UART_BASE=0xf0000000
 CONFIG_DEBUG_UART_CLOCK=70000000
 CONFIG_SYS_CLK_FREQ=70000000
 CONFIG_DEBUG_UART=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="console=ttyARC0,115200n8"
+CONFIG_BOOTARGS="console=ttyS0,115200n8"
 CONFIG_SYS_PROMPT="nsim# "
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_DEFAULT_DEVICE_TREE="nsim"
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
 CONFIG_DM=y
 CONFIG_DM_SERIAL=y
-CONFIG_DEBUG_ARC_SERIAL=y
-CONFIG_ARC_SERIAL=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
 CONFIG_USE_PRIVATE_LIBGCC=y
diff --git a/drivers/clk/clk-hsdk-cgu.c b/drivers/clk/clk-hsdk-cgu.c
index 56ef08c032b99b500aa629b065b1df012bf09820..4637b9fdf15562b8263a0e3e908be75c67bca0db 100644
--- a/drivers/clk/clk-hsdk-cgu.c
+++ b/drivers/clk/clk-hsdk-cgu.c
@@ -46,17 +46,21 @@
  *            |        |-->|CGU_TUN_IDIV_ROM|----------->
  *            |        |-->|CGU_TUN_IDIV_PWM|----------->
  *            |
- *            |   ------------
- *            |-->| HDMI PLL |
- *            |   ------------
- *            |        |
- *            |        |-->|CGU_HDMI_IDIV_APB|------>
- *            |
  *            |   -----------
  *            |-->| DDR PLL |
  *                -----------
  *                     |
  *                     |---------------------------->
+ *
+ *   ------------------
+ *   | 27.00 MHz xtal |
+ *   ------------------
+ *            |
+ *            |   ------------
+ *            |-->| HDMI PLL |
+ *                ------------
+ *                     |
+ *                     |-->|CGU_HDMI_IDIV_APB|------>
  */
 
 #define CGU_ARC_IDIV		0x080
@@ -117,7 +121,8 @@
 #define CREG_CORE_IF_CLK_DIV_2		0x1
 
 #define MIN_PLL_RATE			100000000 /* 100 MHz */
-#define PARENT_RATE			33333333 /* fixed clock - xtal */
+#define PARENT_RATE_33			33333333 /* fixed clock - xtal */
+#define PARENT_RATE_27			27000000 /* fixed clock - xtal */
 #define CGU_MAX_CLOCKS			26
 
 #define CGU_SYS_CLOCKS			16
@@ -237,6 +242,7 @@ struct hsdk_cgu_clk {
 };
 
 struct hsdk_pll_devdata {
+	const u32 parent_rate;
 	const struct hsdk_pll_cfg *pll_cfg;
 	int (*update_rate)(struct hsdk_cgu_clk *clk, unsigned long rate,
 			   const struct hsdk_pll_cfg *cfg);
@@ -248,16 +254,19 @@ static int hsdk_pll_comm_update_rate(struct hsdk_cgu_clk *, unsigned long,
 				     const struct hsdk_pll_cfg *);
 
 static const struct hsdk_pll_devdata core_pll_dat = {
+	.parent_rate = PARENT_RATE_33,
 	.pll_cfg = asdt_pll_cfg,
 	.update_rate = hsdk_pll_core_update_rate,
 };
 
 static const struct hsdk_pll_devdata sdt_pll_dat = {
+	.parent_rate = PARENT_RATE_33,
 	.pll_cfg = asdt_pll_cfg,
 	.update_rate = hsdk_pll_comm_update_rate,
 };
 
 static const struct hsdk_pll_devdata hdmi_pll_dat = {
+	.parent_rate = PARENT_RATE_27,
 	.pll_cfg = hdmi_pll_cfg,
 	.update_rate = hsdk_pll_comm_update_rate,
 };
@@ -372,19 +381,20 @@ static ulong pll_get(struct clk *sclk)
 	u64 rate;
 	u32 idiv, fbdiv, odiv;
 	struct hsdk_cgu_clk *clk = dev_get_priv(sclk->dev);
+	u32 parent_rate = clk->pll_devdata->parent_rate;
 
 	val = hsdk_pll_read(clk, CGU_PLL_CTRL);
 
 	pr_debug("current configurarion: %#x\n", val);
 
+	/* Check if PLL is bypassed */
+	if (val & CGU_PLL_CTRL_BYPASS)
+		return parent_rate;
+
 	/* Check if PLL is disabled */
 	if (val & CGU_PLL_CTRL_PD)
 		return 0;
 
-	/* Check if PLL is bypassed */
-	if (val & CGU_PLL_CTRL_BYPASS)
-		return PARENT_RATE;
-
 	/* input divider = reg.idiv + 1 */
 	idiv = 1 + ((val & CGU_PLL_CTRL_IDIV_MASK) >> CGU_PLL_CTRL_IDIV_SHIFT);
 	/* fb divider = 2*(reg.fbdiv + 1) */
@@ -392,7 +402,7 @@ static ulong pll_get(struct clk *sclk)
 	/* output divider = 2^(reg.odiv) */
 	odiv = 1 << ((val & CGU_PLL_CTRL_ODIV_MASK) >> CGU_PLL_CTRL_ODIV_SHIFT);
 
-	rate = (u64)PARENT_RATE * fbdiv;
+	rate = (u64)parent_rate * fbdiv;
 	do_div(rate, idiv * odiv);
 
 	return rate;
@@ -490,7 +500,8 @@ static ulong pll_set(struct clk *sclk, ulong rate)
 		}
 	}
 
-	pr_err("invalid rate=%ld Hz, parent_rate=%d Hz\n", best_rate, PARENT_RATE);
+	pr_err("invalid rate=%ld Hz, parent_rate=%d Hz\n", best_rate,
+	       clk->pll_devdata->parent_rate);
 
 	return -EINVAL;
 }