Merge tag 'arc-fixes-for-2020.04-rc2' of https://gitlab.denx.de/u-boot/custodians/u-boot-arc

As usual a bit late a couple of tiny fixes and improvements for ARC.

1. Switch from ARC UART to a convenient DW UART on ARC
   simulation platforms. This became avaialble when nSIM got support
   of that much more standard UART (starting from nSIM v2019.06).
   FWIW also available now in Free nSIM [1].

   This among other things allows us finally to use the same one binary
   on all our simulators & FPGA-based emulators.

2. Disable networking support on simulated platforms as there's no
   network interface in them.

3. Add Virtio net & block devices for the configuration supported
   by QEMU so that we may leverage those virtual peripherals and
   in fact it's possible to load uImage from TFTP server and bootm it.

4. Minor fixes for HSDK clocks.

5. Rework of how we chose and use compiler options for ARC-based boards.
   In real world ARC-based designs are customized more or less but very
   rarely match any of our "templates" thus it makes not much sense to
   pretend we have some fixed configs, instead we now will fully reply
   on a SoC or even board on getting precise set of compiler options
   preferably even extracted from real HW via "tcfgen" utility.

6. Well and finally yet another simplification - switch to generic
   written in C accessors which are much more universal and just work
   for any target supported by the complier as compared to GAS
   implementation which is much more target-dependent.

   This one was heavily "inspired" by similar implementation for RISCV
   and ARM.

[1] https://www.synopsys.com/cgi-bin/dwarcnsim/req1.cgi
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 0cb9720..545fc3e 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -160,7 +160,7 @@
 	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 @@
 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 18005d9..6fa29ad 100644
--- a/arch/arc/config.mk
+++ b/arch/arc/config.mk
@@ -22,26 +22,6 @@
 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 243ecb1..c2899ef 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 fa844b5..70d0505 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,136 +54,99 @@
 	/* 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 @@
  *
  * 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 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_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 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 0000000..9e8dee4
--- /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 27e5509..0000000
--- 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 81ff498..ccac544 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 67fd7bf..5bd1044 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 9e280f9..5ae22fa 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 1207335..bd8f09e 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 0000000..b6966b2
--- /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 0000000..ad23c83
--- /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 0000000..6aaffff
--- /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 0000000..40f9578
--- /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 0000000..f384f70
--- /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 5633113..5e89769 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 40f7ec7..0391271 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 2820a6f..910c2ce 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 e533fae..72472af 100644
--- a/configs/nsim_hs38be_defconfig
+++ b/configs/nsim_hs38be_defconfig
@@ -2,22 +2,24 @@
 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 56ef08c..4637b9f 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_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 @@
 				     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 @@
 	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 @@
 	/* 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 @@
 		}
 	}
 
-	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;
 }